diff --git a/RELEASES.md b/RELEASES.md index 18492213a5dd3..f5b71f295c629 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -12,6 +12,7 @@ Compiler - [Added tier 3\* support for the `armv5te-unknown-linux-uclibceabi` target.][78142] - [Added tier 3 support for the `aarch64-apple-ios-macabi` target.][77484] - [The `x86_64-unknown-freebsd` is now built with the full toolset.][79484] +- [Dropped support for all cloudabi targets.][78439] \* Refer to Rust's [platform support page][forge-platform-support] for more information on Rust's tiered platform support. @@ -77,7 +78,6 @@ Compatibility Notes - [`#![test]` as an inner attribute is now considered unstable like other inner macro attributes, and reports an error by default through the `soft_unstable` lint.][79003] - [Overriding a `forbid` lint at the same level that it was set is now a hard error.][78864] -- [Dropped support for all cloudabi targets.][78439] - [You can no longer intercept `panic!` calls by supplying your own macro.][78343] It's recommended to use the `#[panic_handler]` attribute to provide your own implementation. - [Semi-colons after item statements (e.g. `struct Foo {};`) now produce a warning.][78296] diff --git a/compiler/rustc_error_codes/src/error_codes/E0542.md b/compiler/rustc_error_codes/src/error_codes/E0542.md index dbbc34a71be2c..7cb58f9d0cb74 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0542.md +++ b/compiler/rustc_error_codes/src/error_codes/E0542.md @@ -19,7 +19,7 @@ fn _stable_const_fn() {} fn _deprecated_fn() {} ``` -To fix the issue you need to provide the `since` field. +To fix this issue, you need to provide the `since` field. Example: ``` #![feature(staged_api)] diff --git a/compiler/rustc_error_codes/src/error_codes/E0546.md b/compiler/rustc_error_codes/src/error_codes/E0546.md index 0073357b5ea84..a33dcb7a9ac58 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0546.md +++ b/compiler/rustc_error_codes/src/error_codes/E0546.md @@ -13,7 +13,7 @@ fn unstable_fn() {} fn stable_fn() {} ``` -To fix the issue you need to provide the `feature` field. +To fix this issue, you need to provide the `feature` field. Example: ``` #![feature(staged_api)] diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 84aa19aedebf8..63f8a7293d899 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2248,13 +2248,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "...", ); if let Some(infer::RelateParamBound(_, t)) = origin { + let return_impl_trait = self + .in_progress_typeck_results + .map(|typeck_results| typeck_results.borrow().hir_owner) + .and_then(|owner| self.tcx.return_type_impl_trait(owner)) + .is_some(); let t = self.resolve_vars_if_possible(t); match t.kind() { // We've got: // fn get_later(g: G, dest: &mut T) -> impl FnOnce() + '_ // suggest: // fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a - ty::Closure(_, _substs) | ty::Opaque(_, _substs) => { + ty::Closure(_, _substs) | ty::Opaque(_, _substs) if return_impl_trait => { new_binding_suggestion(&mut err, type_param_span, bound_kind); } _ => { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index ee12c0e786d41..251f8c0afe63d 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -285,7 +285,7 @@ impl<'hir> Map<'hir> { let owner = self.tcx.hir_owner_nodes(id.owner); owner.and_then(|owner| { let node = owner.nodes[id.local_id].as_ref(); - // FIXME(eddyb) use a single generic type insted of having both + // FIXME(eddyb) use a single generic type instead of having both // `Entry` and `ParentedNode`, which are effectively the same. // Alternatively, rewrite code using `Entry` to use `ParentedNode`. node.map(|node| Entry { diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs index 0467bf76afecc..98450f5a547da 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs @@ -540,7 +540,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); } - // Attempt to search similar mutable assosiated items for suggestion. + // Attempt to search similar mutable associated items for suggestion. // In the future, attempt in all path but initially for RHS of for_loop fn suggest_similar_mut_method_for_for_loop(&self, err: &mut DiagnosticBuilder<'_>) { let hir = self.infcx.tcx.hir(); diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 7a93bac72ca07..0e55c4ec0b7cb 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -589,7 +589,7 @@ impl StackProbeType { Ok(StackProbeType::InlineOrCall { min_llvm_version_for_inline }) } _ => Err(String::from( - "`kind` expected to be one of `inline-or-none`, `call` or `inline-or-call`", + "`kind` expected to be one of `none`, `inline`, `call` or `inline-or-call`", )), } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 756281450d723..3233d1e048bf7 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -468,22 +468,21 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { trait_ref, obligation.cause.body_id, ); - } else { - if !have_alt_message { - // Can't show anything else useful, try to find similar impls. - let impl_candidates = self.find_similar_impl_candidates(trait_ref); - self.report_similar_impl_candidates(impl_candidates, &mut err); - } - // Changing mutability doesn't make a difference to whether we have - // an `Unsize` impl (Fixes ICE in #71036) - if !is_unsize { - self.suggest_change_mut( - &obligation, - &mut err, - trait_ref, - points_at_arg, - ); - } + } else if !have_alt_message { + // Can't show anything else useful, try to find similar impls. + let impl_candidates = self.find_similar_impl_candidates(trait_ref); + self.report_similar_impl_candidates(impl_candidates, &mut err); + } + + // Changing mutability doesn't make a difference to whether we have + // an `Unsize` impl (Fixes ICE in #71036) + if !is_unsize { + self.suggest_change_mut( + &obligation, + &mut err, + trait_ref, + points_at_arg, + ); } // If this error is due to `!: Trait` not implemented but `(): Trait` is diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index e5045f906df59..66d158b0ee965 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -280,7 +280,7 @@ impl ItemCtxt<'tcx> { ItemCtxt { tcx, item_def_id } } - pub fn to_ty(&self, ast_ty: &'tcx hir::Ty<'tcx>) -> Ty<'tcx> { + pub fn to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> { AstConv::ast_ty_to_ty(self, ast_ty) } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index fd44bafab6f76..542fa1a5acce0 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -421,8 +421,7 @@ pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> { let env_node_id = tcx.hir().get_parent_item(hir_ty.hir_id); let env_def_id = tcx.hir().local_def_id(env_node_id); let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id()); - - astconv::AstConv::ast_ty_to_ty(&item_cx, hir_ty) + item_cx.to_ty(hir_ty) } pub fn hir_trait_to_predicates<'tcx>( diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 885422732e401..cb772458e50b6 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1622,7 +1622,7 @@ impl fmt::Display for RefMut<'_, T> { /// `UnsafeCell` is a type that wraps some `T` and indicates unsafe interior operations on the /// wrapped type. Types with an `UnsafeCell` field are considered to have an 'unsafe interior'. /// The `UnsafeCell` type is the only legal way to obtain aliasable data that is considered -/// mutable. In general, transmuting an `&T` type into an `&mut T` is considered undefined behavior. +/// mutable. In general, transmuting a `&T` type into a `&mut T` is considered undefined behavior. /// /// If you have a reference `&SomeStruct`, then normally in Rust all fields of `SomeStruct` are /// immutable. The compiler makes optimizations based on the knowledge that `&T` is not mutably diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 833c13e9a2615..dee0c15420136 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1075,8 +1075,11 @@ impl Step for Assemble { let src_exe = exe("llvm-dwp", target_compiler.host); let dst_exe = exe("rust-llvm-dwp", target_compiler.host); let llvm_config_bin = builder.ensure(native::Llvm { target: target_compiler.host }); - let llvm_bin_dir = llvm_config_bin.parent().unwrap(); - builder.copy(&llvm_bin_dir.join(&src_exe), &libdir_bin.join(&dst_exe)); + if !builder.config.dry_run { + let llvm_bin_dir = output(Command::new(llvm_config_bin).arg("--bindir")); + let llvm_bin_dir = Path::new(llvm_bin_dir.trim()); + builder.copy(&llvm_bin_dir.join(&src_exe), &libdir_bin.join(&dst_exe)); + } } // Ensure that `libLLVM.so` ends up in the newly build compiler directory, diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index af9c0fb04bc9d..3ebfdb24879fa 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -645,6 +645,14 @@ impl Step for RustcDev { &[], &tarball.image_dir().join("lib/rustlib/rustc-src/rust"), ); + // This particular crate is used as a build dependency of the above. + copy_src_dirs( + builder, + &builder.src, + &["src/build_helper"], + &[], + &tarball.image_dir().join("lib/rustlib/rustc-src/rust"), + ); for file in src_files { tarball.add_file(builder.src.join(file), "lib/rustlib/rustc-src/rust", 0o644); } diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index fd0acc3a919b0..22124ec67f5f3 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -29,7 +29,7 @@ fn install_sh( let prefix = default_path(&builder.config.prefix, "/usr/local"); let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc")); let datadir = prefix.join(default_path(&builder.config.datadir, "share")); - let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc")); + let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust")); let mandir = prefix.join(default_path(&builder.config.mandir, "share/man")); let libdir = prefix.join(default_path(&builder.config.libdir, "lib")); let bindir = prefix.join(&builder.config.bindir); // Default in config.rs diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index cdff37cbd51f4..cacca542284d9 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -510,7 +510,7 @@ fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static clean::Static { type_: cx.tcx.type_of(did).clean(cx), mutability: if mutable { Mutability::Mut } else { Mutability::Not }, - expr: "\n\n\n".to_string(), // trigger the "[definition]" links + expr: None, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 331bb2a73f962..a0ab6ed4a4c88 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -408,7 +408,7 @@ impl Clean for hir::ConstArg { .tcx .type_of(cx.tcx.hir().body_owner_def_id(self.value.body).to_def_id()) .clean(cx), - expr: print_const_expr(cx, self.value.body), + expr: print_const_expr(cx.tcx, self.value.body), value: None, is_literal: is_literal_expr(cx, self.value.body.hir_id), } @@ -961,7 +961,7 @@ impl<'a> Clean for (&'a [hir::Ty<'a>], hir::BodyId) { .iter() .enumerate() .map(|(i, ty)| Argument { - name: Symbol::intern(&rustc_hir_pretty::param_to_string(&body.params[i])), + name: name_from_pat(&body.params[i].pat), type_: ty.clean(cx), }) .collect(), @@ -1052,7 +1052,7 @@ impl Clean for hir::TraitItem<'_> { cx.with_param_env(local_did, || { let inner = match self.kind { hir::TraitItemKind::Const(ref ty, default) => { - AssocConstItem(ty.clean(cx), default.map(|e| print_const_expr(cx, e))) + AssocConstItem(ty.clean(cx), default.map(|e| print_const_expr(cx.tcx, e))) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { let mut m = (sig, &self.generics, body).clean(cx); @@ -1093,7 +1093,7 @@ impl Clean for hir::ImplItem<'_> { cx.with_param_env(local_did, || { let inner = match self.kind { hir::ImplItemKind::Const(ref ty, expr) => { - AssocConstItem(ty.clean(cx), Some(print_const_expr(cx, expr))) + AssocConstItem(ty.clean(cx), Some(print_const_expr(cx.tcx, expr))) } hir::ImplItemKind::Fn(ref sig, body) => { let mut m = (sig, &self.generics, body).clean(cx); @@ -1954,14 +1954,12 @@ impl Clean> for (&hir::Item<'_>, Option) { let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id)); cx.with_param_env(def_id, || { let kind = match item.kind { - ItemKind::Static(ty, mutability, body_id) => StaticItem(Static { - type_: ty.clean(cx), - mutability, - expr: print_const_expr(cx, body_id), - }), + ItemKind::Static(ty, mutability, body_id) => { + StaticItem(Static { type_: ty.clean(cx), mutability, expr: Some(body_id) }) + } ItemKind::Const(ty, body_id) => ConstantItem(Constant { type_: ty.clean(cx), - expr: print_const_expr(cx, body_id), + expr: print_const_expr(cx.tcx, body_id), value: print_evaluated_const(cx, def_id), is_literal: is_literal_expr(cx, body_id.hir_id), }), @@ -2263,11 +2261,9 @@ impl Clean for (&hir::ForeignItem<'_>, Option) { }, }) } - hir::ForeignItemKind::Static(ref ty, mutability) => ForeignStaticItem(Static { - type_: ty.clean(cx), - mutability, - expr: String::new(), - }), + hir::ForeignItemKind::Static(ref ty, mutability) => { + ForeignStaticItem(Static { type_: ty.clean(cx), mutability, expr: None }) + } hir::ForeignItemKind::Type => ForeignTypeItem, }; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 754f1c2eeeb21..9b8e04a1d239d 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -19,7 +19,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex}; use rustc_hir::lang_items::LangItem; -use rustc_hir::Mutability; +use rustc_hir::{BodyId, Mutability}; use rustc_index::vec::IndexVec; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::Session; @@ -1955,10 +1955,7 @@ crate struct BareFunctionDecl { crate struct Static { crate type_: Type, crate mutability: Mutability, - /// It's useful to have the value of a static documented, but I have no - /// desire to represent expressions (that'd basically be all of the AST, - /// which is huge!). So, have a string. - crate expr: String, + crate expr: Option, } #[derive(Clone, PartialEq, Eq, Hash, Debug)] diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 8f005be7cf789..59af49b0d8a28 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -195,6 +195,25 @@ crate fn strip_path(path: &Path) -> Path { Path { global: path.global, res: path.res, segments } } +crate fn qpath_to_string(p: &hir::QPath<'_>) -> String { + let segments = match *p { + hir::QPath::Resolved(_, ref path) => &path.segments, + hir::QPath::TypeRelative(_, ref segment) => return segment.ident.to_string(), + hir::QPath::LangItem(lang_item, ..) => return lang_item.name().to_string(), + }; + + let mut s = String::new(); + for (i, seg) in segments.iter().enumerate() { + if i > 0 { + s.push_str("::"); + } + if seg.ident.name != kw::PathRoot { + s.push_str(&seg.ident.as_str()); + } + } + s +} + crate fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec) { let tcx = cx.tcx; @@ -232,12 +251,60 @@ impl ToSource for rustc_span::Span { } } +crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { + use rustc_hir::*; + debug!("trying to get a name from pattern: {:?}", p); + + Symbol::intern(&match p.kind { + PatKind::Wild => return kw::Underscore, + PatKind::Binding(_, _, ident, _) => return ident.name, + PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p), + PatKind::Struct(ref name, ref fields, etc) => format!( + "{} {{ {}{} }}", + qpath_to_string(name), + fields + .iter() + .map(|fp| format!("{}: {}", fp.ident, name_from_pat(&fp.pat))) + .collect::>() + .join(", "), + if etc { ", .." } else { "" } + ), + PatKind::Or(ref pats) => pats + .iter() + .map(|p| name_from_pat(&**p).to_string()) + .collect::>() + .join(" | "), + PatKind::Tuple(ref elts, _) => format!( + "({})", + elts.iter() + .map(|p| name_from_pat(&**p).to_string()) + .collect::>() + .join(", ") + ), + PatKind::Box(ref p) => return name_from_pat(&**p), + PatKind::Ref(ref p, _) => return name_from_pat(&**p), + PatKind::Lit(..) => { + warn!( + "tried to get argument name from PatKind::Lit, which is silly in function arguments" + ); + return Symbol::intern("()"); + } + PatKind::Range(..) => return kw::Underscore, + PatKind::Slice(ref begin, ref mid, ref end) => { + let begin = begin.iter().map(|p| name_from_pat(&**p).to_string()); + let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter(); + let end = end.iter().map(|p| name_from_pat(&**p).to_string()); + format!("[{}]", begin.chain(mid).chain(end).collect::>().join(", ")) + } + }) +} + crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String { match n.val { ty::ConstKind::Unevaluated(def, _, promoted) => { let mut s = if let Some(def) = def.as_local() { let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def.did); - print_const_expr(cx, cx.tcx.hir().body_owned_by(hir_id)) + print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(hir_id)) } else { inline::print_inlined_const(cx, def.did) }; @@ -326,16 +393,17 @@ crate fn is_literal_expr(cx: &DocContext<'_>, hir_id: hir::HirId) -> bool { false } -crate fn print_const_expr(cx: &DocContext<'_>, body: hir::BodyId) -> String { - let value = &cx.tcx.hir().body(body).value; +crate fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String { + let hir = tcx.hir(); + let value = &hir.body(body).value; let snippet = if !value.span.from_expansion() { - cx.sess().source_map().span_to_snippet(value.span).ok() + tcx.sess.source_map().span_to_snippet(value.span).ok() } else { None }; - snippet.unwrap_or_else(|| rustc_hir_pretty::id_to_string(&cx.tcx.hir(), body.hir_id)) + snippet.unwrap_or_else(|| rustc_hir_pretty::id_to_string(&hir, body.hir_id)) } /// Given a type Path, resolve it to a Type using the TyCtxt diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index 9c5ac1625afea..a50ed5b662bf6 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -89,35 +89,20 @@ function hasOwnProperty(obj, property) { return Object.prototype.hasOwnProperty.call(obj, property); } -function usableLocalStorage() { - // Check if the browser supports localStorage at all: - if (typeof Storage === "undefined") { - return false; - } - // Check if we can access it; this access will fail if the browser - // preferences deny access to localStorage, e.g., to prevent storage of - // "cookies" (or cookie-likes, as is the case here). - try { - return window.localStorage !== null && window.localStorage !== undefined; - } catch(err) { - // Storage is supported, but browser preferences deny access to it. - return false; - } -} - function updateLocalStorage(name, value) { - if (usableLocalStorage()) { - localStorage[name] = value; - } else { - // No Web Storage support so we do nothing + try { + window.localStorage.setItem(name, value); + } catch(e) { + // localStorage is not accessible, do nothing } } function getCurrentValue(name) { - if (usableLocalStorage() && localStorage[name] !== undefined) { - return localStorage[name]; + try { + return window.localStorage.getItem(name); + } catch(e) { + return null; } - return null; } function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index e021faa50412e..f96f6d52088a4 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -6,12 +6,14 @@ use std::convert::From; use rustc_ast::ast; use rustc_hir::def::CtorKind; +use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{DefId, CRATE_DEF_INDEX}; use rustc_span::Pos; use rustdoc_json_types::*; use crate::clean; +use crate::clean::utils::print_const_expr; use crate::formats::item_type::ItemType; use crate::json::JsonRenderer; @@ -43,7 +45,7 @@ impl JsonRenderer<'_> { .collect(), deprecation: deprecation.map(from_deprecation), kind: item_type.into(), - inner: kind.into(), + inner: from_clean_item_kind(kind, self.tcx), }), } } @@ -144,44 +146,42 @@ crate fn from_def_id(did: DefId) -> Id { Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index))) } -impl From for ItemEnum { - fn from(item: clean::ItemKind) -> Self { - use clean::ItemKind::*; - match item { - ModuleItem(m) => ItemEnum::ModuleItem(m.into()), - ExternCrateItem(c, a) => { - ItemEnum::ExternCrateItem { name: c.to_string(), rename: a.map(|x| x.to_string()) } - } - ImportItem(i) => ItemEnum::ImportItem(i.into()), - StructItem(s) => ItemEnum::StructItem(s.into()), - UnionItem(u) => ItemEnum::UnionItem(u.into()), - StructFieldItem(f) => ItemEnum::StructFieldItem(f.into()), - EnumItem(e) => ItemEnum::EnumItem(e.into()), - VariantItem(v) => ItemEnum::VariantItem(v.into()), - FunctionItem(f) => ItemEnum::FunctionItem(f.into()), - ForeignFunctionItem(f) => ItemEnum::FunctionItem(f.into()), - TraitItem(t) => ItemEnum::TraitItem(t.into()), - TraitAliasItem(t) => ItemEnum::TraitAliasItem(t.into()), - MethodItem(m, _) => ItemEnum::MethodItem(from_function_method(m, true)), - TyMethodItem(m) => ItemEnum::MethodItem(from_function_method(m, false)), - ImplItem(i) => ItemEnum::ImplItem(i.into()), - StaticItem(s) => ItemEnum::StaticItem(s.into()), - ForeignStaticItem(s) => ItemEnum::StaticItem(s.into()), - ForeignTypeItem => ItemEnum::ForeignTypeItem, - TypedefItem(t, _) => ItemEnum::TypedefItem(t.into()), - OpaqueTyItem(t) => ItemEnum::OpaqueTyItem(t.into()), - ConstantItem(c) => ItemEnum::ConstantItem(c.into()), - MacroItem(m) => ItemEnum::MacroItem(m.source), - ProcMacroItem(m) => ItemEnum::ProcMacroItem(m.into()), - AssocConstItem(t, s) => ItemEnum::AssocConstItem { type_: t.into(), default: s }, - AssocTypeItem(g, t) => ItemEnum::AssocTypeItem { - bounds: g.into_iter().map(Into::into).collect(), - default: t.map(Into::into), - }, - StrippedItem(inner) => (*inner).into(), - PrimitiveItem(_) | KeywordItem(_) => { - panic!("{:?} is not supported for JSON output", item) - } +fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>) -> ItemEnum { + use clean::ItemKind::*; + match item { + ModuleItem(m) => ItemEnum::ModuleItem(m.into()), + ExternCrateItem(c, a) => { + ItemEnum::ExternCrateItem { name: c.to_string(), rename: a.map(|x| x.to_string()) } + } + ImportItem(i) => ItemEnum::ImportItem(i.into()), + StructItem(s) => ItemEnum::StructItem(s.into()), + UnionItem(u) => ItemEnum::UnionItem(u.into()), + StructFieldItem(f) => ItemEnum::StructFieldItem(f.into()), + EnumItem(e) => ItemEnum::EnumItem(e.into()), + VariantItem(v) => ItemEnum::VariantItem(v.into()), + FunctionItem(f) => ItemEnum::FunctionItem(f.into()), + ForeignFunctionItem(f) => ItemEnum::FunctionItem(f.into()), + TraitItem(t) => ItemEnum::TraitItem(t.into()), + TraitAliasItem(t) => ItemEnum::TraitAliasItem(t.into()), + MethodItem(m, _) => ItemEnum::MethodItem(from_function_method(m, true)), + TyMethodItem(m) => ItemEnum::MethodItem(from_function_method(m, false)), + ImplItem(i) => ItemEnum::ImplItem(i.into()), + StaticItem(s) => ItemEnum::StaticItem(from_clean_static(s, tcx)), + ForeignStaticItem(s) => ItemEnum::StaticItem(from_clean_static(s, tcx)), + ForeignTypeItem => ItemEnum::ForeignTypeItem, + TypedefItem(t, _) => ItemEnum::TypedefItem(t.into()), + OpaqueTyItem(t) => ItemEnum::OpaqueTyItem(t.into()), + ConstantItem(c) => ItemEnum::ConstantItem(c.into()), + MacroItem(m) => ItemEnum::MacroItem(m.source), + ProcMacroItem(m) => ItemEnum::ProcMacroItem(m.into()), + AssocConstItem(t, s) => ItemEnum::AssocConstItem { type_: t.into(), default: s }, + AssocTypeItem(g, t) => ItemEnum::AssocTypeItem { + bounds: g.into_iter().map(Into::into).collect(), + default: t.map(Into::into), + }, + StrippedItem(inner) => from_clean_item_kind(*inner, tcx).into(), + PrimitiveItem(_) | KeywordItem(_) => { + panic!("{:?} is not supported for JSON output", item) } } } @@ -535,13 +535,11 @@ impl From for OpaqueTy { } } -impl From for Static { - fn from(stat: clean::Static) -> Self { - Static { - type_: stat.type_.into(), - mutable: stat.mutability == ast::Mutability::Mut, - expr: stat.expr, - } +fn from_clean_static(stat: clean::Static, tcx: TyCtxt<'_>) -> Static { + Static { + type_: stat.type_.into(), + mutable: stat.mutability == ast::Mutability::Mut, + expr: stat.expr.map(|e| print_const_expr(tcx, e)).unwrap_or_default(), } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 532a0cf932904..a54b4adc13295 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1151,11 +1151,12 @@ impl LinkCollector<'_, '_> { }; let verify = |kind: DefKind, id: DefId| { - debug!("intra-doc link to {} resolved to {:?}", path_str, res); + let (kind, id) = self.kind_side_channel.take().unwrap_or((kind, id)); + debug!("intra-doc link to {} resolved to {:?} (id: {:?})", path_str, res, id); // Disallow e.g. linking to enums with `struct@` debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator); - match (self.kind_side_channel.take().map(|(kind, _)| kind).unwrap_or(kind), disambiguator) { + match (kind, disambiguator) { | (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const))) // NOTE: this allows 'method' to mean both normal functions and associated functions // This can't cause ambiguity because both are in the same namespace. @@ -1190,7 +1191,7 @@ impl LinkCollector<'_, '_> { } } - Some((kind, id)) + Some(()) }; match res { @@ -1241,7 +1242,7 @@ impl LinkCollector<'_, '_> { Some(ItemLink { link: ori_link.link, link_text, did: None, fragment }) } Res::Def(kind, id) => { - let (kind, id) = verify(kind, id)?; + verify(kind, id)?; let id = clean::register_res(cx, rustc_hir::def::Res::Def(kind, id)); Some(ItemLink { link: ori_link.link, link_text, did: Some(id), fragment }) } diff --git a/src/test/rustdoc-ui/intra-doc/private.private.stderr b/src/test/rustdoc-ui/intra-doc/private.private.stderr index 6e11ec3e87bf9..94a833fcc1a15 100644 --- a/src/test/rustdoc-ui/intra-doc/private.private.stderr +++ b/src/test/rustdoc-ui/intra-doc/private.private.stderr @@ -1,11 +1,19 @@ warning: public documentation for `DocMe` links to private item `DontDocMe` --> $DIR/private.rs:5:11 | -LL | /// docs [DontDocMe] +LL | /// docs [DontDocMe] [DontDocMe::f] | ^^^^^^^^^ this item is private | = note: `#[warn(private_intra_doc_links)]` on by default = note: this link resolves only because you passed `--document-private-items`, but will break without -warning: 1 warning emitted +warning: public documentation for `DocMe` links to private item `DontDocMe::f` + --> $DIR/private.rs:5:23 + | +LL | /// docs [DontDocMe] [DontDocMe::f] + | ^^^^^^^^^^^^ this item is private + | + = note: this link resolves only because you passed `--document-private-items`, but will break without + +warning: 2 warnings emitted diff --git a/src/test/rustdoc-ui/intra-doc/private.public.stderr b/src/test/rustdoc-ui/intra-doc/private.public.stderr index 3a6a4b664522a..21a60638d5efc 100644 --- a/src/test/rustdoc-ui/intra-doc/private.public.stderr +++ b/src/test/rustdoc-ui/intra-doc/private.public.stderr @@ -1,11 +1,19 @@ warning: public documentation for `DocMe` links to private item `DontDocMe` --> $DIR/private.rs:5:11 | -LL | /// docs [DontDocMe] +LL | /// docs [DontDocMe] [DontDocMe::f] | ^^^^^^^^^ this item is private | = note: `#[warn(private_intra_doc_links)]` on by default = note: this link will resolve properly if you pass `--document-private-items` -warning: 1 warning emitted +warning: public documentation for `DocMe` links to private item `DontDocMe::f` + --> $DIR/private.rs:5:23 + | +LL | /// docs [DontDocMe] [DontDocMe::f] + | ^^^^^^^^^^^^ this item is private + | + = note: this link will resolve properly if you pass `--document-private-items` + +warning: 2 warnings emitted diff --git a/src/test/rustdoc-ui/intra-doc/private.rs b/src/test/rustdoc-ui/intra-doc/private.rs index 613236d75d2ee..3782864305f1f 100644 --- a/src/test/rustdoc-ui/intra-doc/private.rs +++ b/src/test/rustdoc-ui/intra-doc/private.rs @@ -2,8 +2,13 @@ // revisions: public private // [private]compile-flags: --document-private-items -/// docs [DontDocMe] +/// docs [DontDocMe] [DontDocMe::f] //~^ WARNING public documentation for `DocMe` links to private item `DontDocMe` +//~| WARNING public documentation for `DocMe` links to private item `DontDocMe::f` // FIXME: for [private] we should also make sure the link was actually generated pub struct DocMe; struct DontDocMe; + +impl DontDocMe { + fn f() {} +} diff --git a/src/test/rustdoc/mut-params.rs b/src/test/rustdoc/mut-params.rs new file mode 100644 index 0000000000000..1ef7e304fa256 --- /dev/null +++ b/src/test/rustdoc/mut-params.rs @@ -0,0 +1,18 @@ +// Rustdoc shouldn't display `mut` in function arguments, which are +// implementation details. Regression test for #81289. + +#![crate_name = "foo"] + +pub struct Foo; + +// @count foo/struct.Foo.html '//*[@class="impl-items"]//*[@class="method"]' 2 +// @!has - '//*[@class="impl-items"]//*[@class="method"]' 'mut' +impl Foo { + pub fn foo(mut self) {} + + pub fn bar(mut bar: ()) {} +} + +// @count foo/fn.baz.html '//*[@class="rust fn"]' 1 +// @!has - '//*[@class="rust fn"]' 'mut' +pub fn baz(mut foo: Foo) {} diff --git a/src/test/rustdoc/range-arg-pattern.rs b/src/test/rustdoc/range-arg-pattern.rs index f4cc36b1055ad..c08faaad0eccf 100644 --- a/src/test/rustdoc/range-arg-pattern.rs +++ b/src/test/rustdoc/range-arg-pattern.rs @@ -1,5 +1,5 @@ #![crate_name = "foo"] // @has foo/fn.f.html -// @has - '//*[@class="rust fn"]' 'pub fn f(0u8 ...255: u8)' +// @has - '//*[@class="rust fn"]' 'pub fn f(_: u8)' pub fn f(0u8...255: u8) {} diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs new file mode 100644 index 0000000000000..c6802ac6cc704 --- /dev/null +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs @@ -0,0 +1,26 @@ +// Regression test for #81650 + +struct Foo<'a> { + x: &'a mut &'a i32, +} + +impl<'a> Foo<'a> { + fn bar(&self, f: F) + where + F: FnOnce(&Foo<'a>) -> T, + F: 'a, + {} +} + +trait Test { + fn test(&self); +} + +fn func(foo: &Foo, t: T) { + foo.bar(move |_| { + //~^ ERROR the parameter type `T` may not live long enough + t.test(); + }); +} + +fn main() {} diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr new file mode 100644 index 0000000000000..c7def9b668d9c --- /dev/null +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr @@ -0,0 +1,21 @@ +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/missing-lifetimes-in-signature-2.rs:20:9 + | +LL | fn func(foo: &Foo, t: T) { + | -- help: consider adding an explicit lifetime bound...: `T: 'a +` +LL | foo.bar(move |_| { + | ^^^ + | +note: the parameter type `T` must be valid for the anonymous lifetime #2 defined on the function body at 19:1... + --> $DIR/missing-lifetimes-in-signature-2.rs:19:1 + | +LL | fn func(foo: &Foo, t: T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature-2.rs:20:13: 23:6]` will meet its required lifetime bounds + --> $DIR/missing-lifetimes-in-signature-2.rs:20:9 + | +LL | foo.bar(move |_| { + | ^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/suggestions/suggest-change-mut.rs b/src/test/ui/suggestions/suggest-change-mut.rs new file mode 100644 index 0000000000000..8b465aae66b6e --- /dev/null +++ b/src/test/ui/suggestions/suggest-change-mut.rs @@ -0,0 +1,21 @@ +#![allow(warnings)] + +use std::io::{BufRead, BufReader, Read, Write}; + +fn issue_81421(mut stream: T) { + let initial_message = format!("Hello world"); + let mut buffer: Vec = Vec::new(); + let bytes_written = stream.write_all(initial_message.as_bytes()); + let flush = stream.flush(); + + loop { + let mut stream_reader = BufReader::new(&stream); + //~^ ERROR the trait bound `&T: std::io::Read` is not satisfied [E0277] + //~| HELP consider removing the leading `&`-reference + //~| HELP consider changing this borrow's mutability + stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed"); + //~^ ERROR the method `read_until` exists for struct `BufReader<&T>`, + } +} + +fn main() {} diff --git a/src/test/ui/suggestions/suggest-change-mut.stderr b/src/test/ui/suggestions/suggest-change-mut.stderr new file mode 100644 index 0000000000000..cb156f7c7877a --- /dev/null +++ b/src/test/ui/suggestions/suggest-change-mut.stderr @@ -0,0 +1,35 @@ +error[E0277]: the trait bound `&T: std::io::Read` is not satisfied + --> $DIR/suggest-change-mut.rs:12:48 + | +LL | let mut stream_reader = BufReader::new(&stream); + | ^^^^^^^ the trait `std::io::Read` is not implemented for `&T` + | + = note: required by `BufReader::::new` +help: consider removing the leading `&`-reference + | +LL | let mut stream_reader = BufReader::new(stream); + | -- +help: consider changing this borrow's mutability + | +LL | let mut stream_reader = BufReader::new(&mut stream); + | ^^^^ + +error[E0599]: the method `read_until` exists for struct `BufReader<&T>`, but its trait bounds were not satisfied + --> $DIR/suggest-change-mut.rs:16:23 + | +LL | stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed"); + | ^^^^^^^^^^ method cannot be called on `BufReader<&T>` due to unsatisfied trait bounds + | + ::: $SRC_DIR/std/src/io/buffered/bufreader.rs:LL:COL + | +LL | pub struct BufReader { + | ----------------------- doesn't satisfy `BufReader<&T>: BufRead` + | + = note: the following trait bounds were not satisfied: + `&T: std::io::Read` + which is required by `BufReader<&T>: BufRead` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/tools/expand-yaml-anchors/src/main.rs b/src/tools/expand-yaml-anchors/src/main.rs index f8cf18a9309ec..8992d165d5d50 100644 --- a/src/tools/expand-yaml-anchors/src/main.rs +++ b/src/tools/expand-yaml-anchors/src/main.rs @@ -76,7 +76,11 @@ impl App { self.path(&path), self.path(&dest_path) ), - Mode::Check => format!("{} is not up to date", self.path(&dest_path)), + Mode::Check => format!( + "{} is not up to date; please run \ + `x.py run src/tools/expand-yaml-anchors`.", + self.path(&dest_path) + ), })?; } }