about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-02-12 14:40:27 +0000
committerbors <bors@rust-lang.org>2021-02-12 14:40:27 +0000
commitd416093209d0dd77a4cdeb5a2f1b5de1316787ec (patch)
tree5346fc9e189c71ddfd57402bb3bf9dce8653a1a1
parenta118ee2c13cc96ceb27bd5030c1cca1052377604 (diff)
parentff8b7f20d9e5e9bb4257f4fc1a41075ad8c5ec1a (diff)
downloadrust-d416093209d0dd77a4cdeb5a2f1b5de1316787ec.tar.gz
rust-d416093209d0dd77a4cdeb5a2f1b5de1316787ec.zip
Auto merge of #82025 - JohnTitor:rollup-cohp0gy, r=JohnTitor
Rollup of 16 pull requests

Successful merges:

 - #79983 (fix indefinite article in cell.rs)
 - #81831 (Don't display `mut` in arguments for functions documentation)
 - #81947 (Relax ItemCtxt::to_ty lifetime)
 - #81954 (RELEASES.md 1.50: Group platform support notes together)
 - #81955 (bootstrap: Locate llvm-dwp based on llvm-config bindir)
 - #81959 (Fix assosiated typo)
 - #81964 (Fix documentation not showing on localStorage error)
 - #81968 (bootstrap: fix wrong docs installation path)
 - #81990 (Make suggestion of changing mutability of arguments broader)
 - #81994 (Improve long explanation for E0542 and E0546)
 - #81997 (dist: include src/build_helper as part of the crate graph for rustc-dev)
 - #82003 (Stack probes: fix error message)
 - #82004 (clean up clean::Static struct)
 - #82011 (Fix private intra-doc warnings on associated items)
 - #82013 (Tell user how to fix CI file being not up to date)
 - #82017 (Fix typo in mod.rs)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--RELEASES.md2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0542.md2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0546.md2
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs31
-rw-r--r--compiler/rustc_typeck/src/collect.rs2
-rw-r--r--compiler/rustc_typeck/src/lib.rs3
-rw-r--r--library/core/src/cell.rs2
-rw-r--r--src/bootstrap/compile.rs7
-rw-r--r--src/bootstrap/dist.rs8
-rw-r--r--src/bootstrap/install.rs2
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs26
-rw-r--r--src/librustdoc/clean/types.rs7
-rw-r--r--src/librustdoc/clean/utils.rs78
-rw-r--r--src/librustdoc/html/static/storage.js31
-rw-r--r--src/librustdoc/json/conversions.rs90
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs9
-rw-r--r--src/test/rustdoc-ui/intra-doc/private.private.stderr12
-rw-r--r--src/test/rustdoc-ui/intra-doc/private.public.stderr12
-rw-r--r--src/test/rustdoc-ui/intra-doc/private.rs7
-rw-r--r--src/test/rustdoc/mut-params.rs18
-rw-r--r--src/test/rustdoc/range-arg-pattern.rs2
-rw-r--r--src/test/ui/suggestions/suggest-change-mut.rs21
-rw-r--r--src/test/ui/suggestions/suggest-change-mut.stderr35
-rw-r--r--src/tools/expand-yaml-anchors/src/main.rs6
28 files changed, 288 insertions, 135 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 18492213a5d..f5b71f295c6 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 dbbc34a71be..7cb58f9d0cb 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 0073357b5ea..a33dcb7a9ac 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_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index ee12c0e786d..251f8c0afe6 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 0467bf76afe..98450f5a547 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 7a93bac72ca..0e55c4ec0b7 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 756281450d7..3233d1e048b 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 e5045f906df..66d158b0ee9 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 fd44bafab6f..542fa1a5acc 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 885422732e4..cb772458e50 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1622,7 +1622,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// `UnsafeCell<T>` is a type that wraps some `T` and indicates unsafe interior operations on the
 /// wrapped type. Types with an `UnsafeCell<T>` field are considered to have an 'unsafe interior'.
 /// The `UnsafeCell<T>` 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 833c13e9a26..dee0c154201 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 af9c0fb04bc..3ebfdb24879 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 fd0acc3a919..22124ec67f5 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 cdff37cbd51..cacca542284 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 331bb2a73f9..a0ab6ed4a4c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -408,7 +408,7 @@ impl Clean<Constant> 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<Arguments> 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<Item> 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<Item> 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<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
         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<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
                         },
                     })
                 }
-                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 754f1c2eeeb..9b8e04a1d23 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<BodyId>,
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 8f005be7cf7..59af49b0d8a 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<Item>) {
     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::<Vec<String>>()
+                .join(", "),
+            if etc { ", .." } else { "" }
+        ),
+        PatKind::Or(ref pats) => pats
+            .iter()
+            .map(|p| name_from_pat(&**p).to_string())
+            .collect::<Vec<String>>()
+            .join(" | "),
+        PatKind::Tuple(ref elts, _) => format!(
+            "({})",
+            elts.iter()
+                .map(|p| name_from_pat(&**p).to_string())
+                .collect::<Vec<String>>()
+                .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::<Vec<_>>().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 9c5ac1625af..a50ed5b662b 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 e021faa5041..f96f6d52088 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<clean::ItemKind> 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<clean::OpaqueTy> for OpaqueTy {
     }
 }
 
-impl From<clean::Static> 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 532a0cf9329..a54b4adc132 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 6e11ec3e87b..94a833fcc1a 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 3a6a4b66452..21a60638d5e 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 613236d75d2..3782864305f 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 00000000000..1ef7e304fa2
--- /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 f4cc36b1055..c08faaad0ec 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/suggest-change-mut.rs b/src/test/ui/suggestions/suggest-change-mut.rs
new file mode 100644
index 00000000000..8b465aae66b
--- /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<T: Read + Write>(mut stream: T) {
+    let initial_message = format!("Hello world");
+    let mut buffer: Vec<u8> = 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 00000000000..cb156f7c787
--- /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::<R>::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<R> {
+   | ----------------------- 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 f8cf18a9309..8992d165d5d 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)
+                    ),
                 })?;
             }
         }