about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-05-06 20:14:01 +0000
committerbors <bors@rust-lang.org>2022-05-06 20:14:01 +0000
commit77652b9ef3fc98e2df0e260efedb80aa68c08c06 (patch)
tree4432c37cab5ef0de178ce0e3411f4baffda60d0f
parentd60b4f52c92facae291151dd5a23399f8044d01e (diff)
parenta0e2c7e8bbd7773e2c709ac812c75d0902d6cf6a (diff)
downloadrust-77652b9ef3fc98e2df0e260efedb80aa68c08c06.tar.gz
rust-77652b9ef3fc98e2df0e260efedb80aa68c08c06.zip
Auto merge of #96785 - GuillaumeGomez:rollup-rgiwa57, r=GuillaumeGomez
Rollup of 10 pull requests

Successful merges:

 - #96557 (Allow inline consts to reference generic params)
 - #96590 (rustdoc: when running a function-signature search, tweak the tab bar)
 - #96650 (Collect function instance used in `global_asm!` sym operand)
 - #96733 (turn `append_place_to_string` from recursion into iteration)
 - #96748 (Fixes reexports in search)
 - #96752 (Put the incompatible_closure_captures lint messages in alphabetical order)
 - #96754 (rustdoc: ensure HTML/JS side implementors don't have dups)
 - #96772 (Suggest fully qualified path with appropriate params)
 - #96776 (Fix two minor issues in hir.rs)
 - #96782 (a small `mirror_expr` cleanup)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs210
-rw-r--r--compiler/rustc_hir/src/hir.rs7
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs23
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs37
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs9
-rw-r--r--compiler/rustc_resolve/src/late.rs9
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs4
-rw-r--r--src/librustdoc/formats/cache.rs11
-rw-r--r--src/librustdoc/html/render/mod.rs11
-rw-r--r--src/librustdoc/html/render/print_item.rs109
-rw-r--r--src/librustdoc/html/render/write_shared.rs9
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css5
-rw-r--r--src/librustdoc/html/static/js/main.js8
-rw-r--r--src/librustdoc/html/static/js/search.js72
-rw-r--r--src/test/assembly/asm/global_asm.rs5
-rw-r--r--src/test/rustdoc-gui/implementors.goml7
-rw-r--r--src/test/rustdoc-gui/search-reexport.goml29
-rw-r--r--src/test/rustdoc-gui/search-tab-change-title-fn-sig.goml64
-rw-r--r--src/test/rustdoc-gui/search-tab-selection-if-current-is-empty.goml23
-rw-r--r--src/test/rustdoc-gui/sidebar.goml19
-rw-r--r--src/test/rustdoc-gui/src/lib2/implementors/lib.rs9
-rw-r--r--src/test/rustdoc-gui/src/lib2/lib.rs7
-rw-r--r--src/test/rustdoc-gui/src/test_docs/lib.rs3
-rw-r--r--src/test/rustdoc/hidden-impls.rs2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr2
-rw-r--r--src/test/ui/inline-const/const-expr-generic-err.rs15
-rw-r--r--src/test/ui/inline-const/const-expr-generic-err.stderr29
-rw-r--r--src/test/ui/inline-const/const-expr-generic-err2.rs10
-rw-r--r--src/test/ui/inline-const/const-expr-generic-err2.stderr10
-rw-r--r--src/test/ui/inline-const/const-expr-generic.rs15
-rw-r--r--src/test/ui/inline-const/const-match-pat-generic.rs3
-rw-r--r--src/test/ui/inline-const/const-match-pat-generic.stderr6
-rw-r--r--src/test/ui/traits/suggest-fully-qualified-path-with-appropriate-params.rs24
-rw-r--r--src/test/ui/traits/suggest-fully-qualified-path-with-appropriate-params.stderr61
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.stderr2
38 files changed, 625 insertions, 252 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 368c0be794b..05d29503180 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1,5 +1,6 @@
 //! Borrow checker diagnostics.
 
+use itertools::Itertools;
 use rustc_const_eval::util::{call_kind, CallDesugaringKind};
 use rustc_errors::{Applicability, Diagnostic};
 use rustc_hir as hir;
@@ -161,158 +162,103 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     }
 
     /// End-user visible description of `place` if one can be found.
-    /// If the place is a temporary for instance, None will be returned.
+    /// If the place is a temporary for instance, `None` will be returned.
     pub(super) fn describe_place(&self, place_ref: PlaceRef<'tcx>) -> Option<String> {
         self.describe_place_with_options(place_ref, IncludingDowncast(false))
     }
 
-    /// End-user visible description of `place` if one can be found. If the
-    /// place is a temporary for instance, None will be returned.
-    /// `IncludingDowncast` parameter makes the function return `Err` if `ProjectionElem` is
+    /// End-user visible description of `place` if one can be found. If the place is a temporary
+    /// for instance, `None` will be returned.
+    /// `IncludingDowncast` parameter makes the function return `None` if `ProjectionElem` is
     /// `Downcast` and `IncludingDowncast` is true
     pub(super) fn describe_place_with_options(
         &self,
         place: PlaceRef<'tcx>,
         including_downcast: IncludingDowncast,
     ) -> Option<String> {
+        let local = place.local;
+        let mut autoderef_index = None;
         let mut buf = String::new();
-        match self.append_place_to_string(place, &mut buf, false, &including_downcast) {
-            Ok(()) => Some(buf),
-            Err(()) => None,
-        }
-    }
-
-    /// Appends end-user visible description of `place` to `buf`.
-    fn append_place_to_string(
-        &self,
-        place: PlaceRef<'tcx>,
-        buf: &mut String,
-        mut autoderef: bool,
-        including_downcast: &IncludingDowncast,
-    ) -> Result<(), ()> {
-        match place {
-            PlaceRef { local, projection: [] } => {
-                self.append_local_to_string(local, buf)?;
-            }
-            PlaceRef { local, projection: [ProjectionElem::Deref] }
-                if self.body.local_decls[local].is_ref_for_guard() =>
-            {
-                self.append_place_to_string(
-                    PlaceRef { local, projection: &[] },
-                    buf,
-                    autoderef,
-                    &including_downcast,
-                )?;
-            }
-            PlaceRef { local, projection: [ProjectionElem::Deref] }
-                if self.body.local_decls[local].is_ref_to_static() =>
-            {
-                let local_info = &self.body.local_decls[local].local_info;
-                if let Some(box LocalInfo::StaticRef { def_id, .. }) = *local_info {
-                    buf.push_str(self.infcx.tcx.item_name(def_id).as_str());
-                } else {
-                    unreachable!();
-                }
-            }
-            PlaceRef { local, projection: [proj_base @ .., elem] } => {
-                match elem {
-                    ProjectionElem::Deref => {
-                        let upvar_field_projection = self.is_upvar_field_projection(place);
-                        if let Some(field) = upvar_field_projection {
-                            let var_index = field.index();
-                            let name = self.upvars[var_index].place.to_string(self.infcx.tcx);
-                            if self.upvars[var_index].by_ref {
-                                buf.push_str(&name);
-                            } else {
-                                buf.push('*');
-                                buf.push_str(&name);
-                            }
-                        } else {
-                            if autoderef {
-                                // FIXME turn this recursion into iteration
-                                self.append_place_to_string(
-                                    PlaceRef { local, projection: proj_base },
-                                    buf,
-                                    autoderef,
-                                    &including_downcast,
-                                )?;
-                            } else {
-                                buf.push('*');
-                                self.append_place_to_string(
-                                    PlaceRef { local, projection: proj_base },
-                                    buf,
-                                    autoderef,
-                                    &including_downcast,
-                                )?;
-                            }
+        let mut ok = self.append_local_to_string(local, &mut buf);
+
+        for (index, elem) in place.projection.into_iter().enumerate() {
+            match elem {
+                ProjectionElem::Deref => {
+                    if index == 0 {
+                        if self.body.local_decls[local].is_ref_for_guard() {
+                            continue;
                         }
-                    }
-                    ProjectionElem::Downcast(..) => {
-                        self.append_place_to_string(
-                            PlaceRef { local, projection: proj_base },
-                            buf,
-                            autoderef,
-                            &including_downcast,
-                        )?;
-                        if including_downcast.0 {
-                            return Err(());
+                        if let Some(box LocalInfo::StaticRef { def_id, .. }) =
+                            &self.body.local_decls[local].local_info
+                        {
+                            buf.push_str(self.infcx.tcx.item_name(*def_id).as_str());
+                            ok = Ok(());
+                            continue;
                         }
                     }
-                    ProjectionElem::Field(field, _ty) => {
-                        autoderef = true;
-
-                        // FIXME(project-rfc_2229#36): print capture precisely here.
-                        let upvar_field_projection = self.is_upvar_field_projection(place);
-                        if let Some(field) = upvar_field_projection {
-                            let var_index = field.index();
-                            let name = self.upvars[var_index].place.to_string(self.infcx.tcx);
-                            buf.push_str(&name);
-                        } else {
-                            let field_name = self
-                                .describe_field(PlaceRef { local, projection: proj_base }, *field);
-                            self.append_place_to_string(
-                                PlaceRef { local, projection: proj_base },
-                                buf,
-                                autoderef,
-                                &including_downcast,
-                            )?;
-                            buf.push('.');
-                            buf.push_str(&field_name);
+                    if let Some(field) = self.is_upvar_field_projection(PlaceRef {
+                        local,
+                        projection: place.projection.split_at(index + 1).0,
+                    }) {
+                        let var_index = field.index();
+                        buf = self.upvars[var_index].place.to_string(self.infcx.tcx);
+                        ok = Ok(());
+                        if !self.upvars[var_index].by_ref {
+                            buf.insert(0, '*');
                         }
-                    }
-                    ProjectionElem::Index(index) => {
-                        autoderef = true;
-
-                        self.append_place_to_string(
-                            PlaceRef { local, projection: proj_base },
-                            buf,
-                            autoderef,
-                            &including_downcast,
-                        )?;
-                        buf.push('[');
-                        if self.append_local_to_string(*index, buf).is_err() {
-                            buf.push('_');
+                    } else {
+                        if autoderef_index.is_none() {
+                            autoderef_index =
+                                match place.projection.into_iter().rev().find_position(|elem| {
+                                    !matches!(
+                                        elem,
+                                        ProjectionElem::Deref | ProjectionElem::Downcast(..)
+                                    )
+                                }) {
+                                    Some((index, _)) => Some(place.projection.len() - index),
+                                    None => Some(0),
+                                };
+                        }
+                        if index >= autoderef_index.unwrap() {
+                            buf.insert(0, '*');
                         }
-                        buf.push(']');
                     }
-                    ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
-                        autoderef = true;
-                        // Since it isn't possible to borrow an element on a particular index and
-                        // then use another while the borrow is held, don't output indices details
-                        // to avoid confusing the end-user
-                        self.append_place_to_string(
-                            PlaceRef { local, projection: proj_base },
-                            buf,
-                            autoderef,
-                            &including_downcast,
-                        )?;
-                        buf.push_str("[..]");
+                }
+                ProjectionElem::Downcast(..) if including_downcast.0 => return None,
+                ProjectionElem::Downcast(..) => (),
+                ProjectionElem::Field(field, _ty) => {
+                    // FIXME(project-rfc_2229#36): print capture precisely here.
+                    if let Some(field) = self.is_upvar_field_projection(PlaceRef {
+                        local,
+                        projection: place.projection.split_at(index + 1).0,
+                    }) {
+                        buf = self.upvars[field.index()].place.to_string(self.infcx.tcx);
+                        ok = Ok(());
+                    } else {
+                        let field_name = self.describe_field(
+                            PlaceRef { local, projection: place.projection.split_at(index).0 },
+                            *field,
+                        );
+                        buf.push('.');
+                        buf.push_str(&field_name);
                     }
-                };
+                }
+                ProjectionElem::Index(index) => {
+                    buf.push('[');
+                    if self.append_local_to_string(*index, &mut buf).is_err() {
+                        buf.push('_');
+                    }
+                    buf.push(']');
+                }
+                ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
+                    // Since it isn't possible to borrow an element on a particular index and
+                    // then use another while the borrow is held, don't output indices details
+                    // to avoid confusing the end-user
+                    buf.push_str("[..]");
+                }
             }
         }
-
-        Ok(())
+        ok.ok().map(|_| buf)
     }
 
     /// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index dfeee3f356f..cc6ddad2e15 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1441,7 +1441,7 @@ pub enum AsyncGeneratorKind {
     /// An explicit `async` block written by the user.
     Block,
 
-    /// An explicit `async` block written by the user.
+    /// An explicit `async` closure written by the user.
     Closure,
 
     /// The `async` block generated as the body of an async function.
@@ -2078,10 +2078,7 @@ pub enum YieldSource {
 
 impl YieldSource {
     pub fn is_await(&self) -> bool {
-        match self {
-            YieldSource::Await { .. } => true,
-            YieldSource::Yield => false,
-        }
+        matches!(self, YieldSource::Await { .. })
     }
 }
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index b1eb9f0da87..78e0864d918 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -731,6 +731,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 //    |               help: specify type like: `<Impl as Into<u32>>::into(foo_impl)`
                 //    |
                 //    = note: cannot satisfy `Impl: Into<_>`
+                debug!(?segment);
                 if !impl_candidates.is_empty() && e.span.contains(span)
                     && let Some(expr) = exprs.first()
                     && let ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
@@ -739,9 +740,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     let mut eraser = TypeParamEraser(self.tcx);
                     let candidate_len = impl_candidates.len();
                     let mut suggestions: Vec<_> = impl_candidates.iter().map(|candidate| {
+                        let trait_item = self.tcx
+                            .associated_items(candidate.def_id)
+                            .find_by_name_and_kind(
+                                self.tcx,
+                                segment.ident,
+                                ty::AssocKind::Fn,
+                                candidate.def_id
+                            );
+                        let prefix = if let Some(trait_item) = trait_item
+                            && let Some(trait_m) = trait_item.def_id.as_local()
+                            && let hir::TraitItemKind::Fn(fn_, _) = &self.tcx.hir().trait_item(hir::TraitItemId { def_id: trait_m }).kind
+                        {
+                            match fn_.decl.implicit_self {
+                                hir::ImplicitSelfKind::ImmRef => "&",
+                                hir::ImplicitSelfKind::MutRef => "&mut ",
+                                _ => "",
+                            }
+                        } else {
+                            ""
+                        };
                         let candidate = candidate.super_fold_with(&mut eraser);
                         vec![
-                            (expr.span.shrink_to_lo(), format!("{}::{}(", candidate, segment.ident)),
+                            (expr.span.shrink_to_lo(), format!("{}::{}({}", candidate, segment.ident, prefix)),
                             if exprs.len() == 1 {
                                 (expr.span.shrink_to_hi().with_hi(e.span.hi()), ")".to_string())
                             } else {
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 3fe68f723ec..a1d1b6b3a78 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -136,6 +136,10 @@ pub trait Printer<'tcx>: Sized {
                     match key.disambiguated_data.data {
                         // Closures' own generics are only captures, don't print them.
                         DefPathData::ClosureExpr => {}
+                        // This covers both `DefKind::AnonConst` and `DefKind::InlineConst`.
+                        // Anon consts doesn't have their own generics, and inline consts' own
+                        // generics are their inferred types, so don't print them.
+                        DefPathData::AnonConst => {}
 
                         // If we have any generic arguments to print, we do that
                         // on top of the same path, but without its own generics.
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index f382f79af29..147c136e651 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -158,6 +158,7 @@ impl<'tcx> Cx<'tcx> {
     }
 
     fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
+        let tcx = self.tcx;
         let expr_ty = self.typeck_results().expr_ty(expr);
         let expr_span = expr.span;
         let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
@@ -196,7 +197,7 @@ impl<'tcx> Cx<'tcx> {
 
                     let arg_tys = args.iter().map(|e| self.typeck_results().expr_ty_adjusted(e));
                     let tupled_args = Expr {
-                        ty: self.tcx.mk_tup(arg_tys),
+                        ty: tcx.mk_tup(arg_tys),
                         temp_lifetime,
                         span: expr.span,
                         kind: ExprKind::Tuple { fields: self.mirror_exprs(args) },
@@ -488,24 +489,24 @@ impl<'tcx> Cx<'tcx> {
                             out_expr: out_expr.as_ref().map(|expr| self.mirror_expr(expr)),
                         },
                         hir::InlineAsmOperand::Const { ref anon_const } => {
-                            let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
+                            let anon_const_def_id = tcx.hir().local_def_id(anon_const.hir_id);
                             let value = mir::ConstantKind::from_anon_const(
-                                self.tcx,
+                                tcx,
                                 anon_const_def_id,
                                 self.param_env,
                             );
-                            let span = self.tcx.hir().span(anon_const.hir_id);
+                            let span = tcx.hir().span(anon_const.hir_id);
 
                             InlineAsmOperand::Const { value, span }
                         }
                         hir::InlineAsmOperand::SymFn { ref anon_const } => {
-                            let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
+                            let anon_const_def_id = tcx.hir().local_def_id(anon_const.hir_id);
                             let value = mir::ConstantKind::from_anon_const(
-                                self.tcx,
+                                tcx,
                                 anon_const_def_id,
                                 self.param_env,
                             );
-                            let span = self.tcx.hir().span(anon_const.hir_id);
+                            let span = tcx.hir().span(anon_const.hir_id);
 
                             InlineAsmOperand::SymFn { value, span }
                         }
@@ -519,21 +520,16 @@ impl<'tcx> Cx<'tcx> {
             },
 
             hir::ExprKind::ConstBlock(ref anon_const) => {
-                let tcx = self.tcx;
-                let local_def_id = tcx.hir().local_def_id(anon_const.hir_id);
-                let anon_const_def_id = local_def_id.to_def_id();
-
-                // Need to include the parent substs
-                let hir_id = tcx.hir().local_def_id_to_hir_id(local_def_id);
-                let ty = tcx.typeck(local_def_id).node_type(hir_id);
-                let typeck_root_def_id = tcx.typeck_root_def_id(anon_const_def_id);
+                let ty = self.typeck_results().node_type(anon_const.hir_id);
+                let did = tcx.hir().local_def_id(anon_const.hir_id).to_def_id();
+                let typeck_root_def_id = tcx.typeck_root_def_id(did);
                 let parent_substs =
                     tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id));
                 let substs =
                     InlineConstSubsts::new(tcx, InlineConstSubstsParts { parent_substs, ty })
                         .substs;
 
-                ExprKind::ConstBlock { did: anon_const_def_id, substs }
+                ExprKind::ConstBlock { did, substs }
             }
             // Now comes the rote stuff:
             hir::ExprKind::Repeat(ref v, _) => {
@@ -591,7 +587,7 @@ impl<'tcx> Cx<'tcx> {
             }
             hir::ExprKind::Field(ref source, ..) => ExprKind::Field {
                 lhs: self.mirror_expr(source),
-                name: Field::new(self.tcx.field_index(expr.hir_id, self.typeck_results)),
+                name: Field::new(tcx.field_index(expr.hir_id, self.typeck_results)),
             },
             hir::ExprKind::Cast(ref source, ref cast_ty) => {
                 // Check for a user-given type annotation on this `cast`
@@ -640,7 +636,7 @@ impl<'tcx> Cx<'tcx> {
                                     let (d, o) = adt_def.discriminant_def_for_variant(idx);
                                     use rustc_middle::ty::util::IntTypeExt;
                                     let ty = adt_def.repr().discr_type();
-                                    let ty = ty.to_ty(self.tcx());
+                                    let ty = ty.to_ty(tcx);
                                     Some((d, o, ty))
                                 }
                                 _ => None,
@@ -652,8 +648,7 @@ impl<'tcx> Cx<'tcx> {
 
                     let source = if let Some((did, offset, var_ty)) = var {
                         let param_env_ty = self.param_env.and(var_ty);
-                        let size = self
-                            .tcx
+                        let size = tcx
                             .layout_of(param_env_ty)
                             .unwrap_or_else(|e| {
                                 panic!("could not compute layout for {:?}: {:?}", param_env_ty, e)
@@ -671,7 +666,7 @@ impl<'tcx> Cx<'tcx> {
                             Some(did) => {
                                 // in case we are offsetting from a computed discriminant
                                 // and not the beginning of discriminants (which is always `0`)
-                                let substs = InternalSubsts::identity_for_item(self.tcx(), did);
+                                let substs = InternalSubsts::identity_for_item(tcx, did);
                                 let kind =
                                     ExprKind::NamedConst { def_id: did, substs, user_ty: None };
                                 let lhs = self.thir.exprs.push(Expr {
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 1828aecb375..18f32b04fad 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -445,12 +445,9 @@ fn collect_items_rec<'tcx>(
                             // depend on any other items.
                         }
                         hir::InlineAsmOperand::SymFn { anon_const } => {
-                            let def_id = tcx.hir().body_owner_def_id(anon_const.body).to_def_id();
-                            if let Ok(val) = tcx.const_eval_poly(def_id) {
-                                rustc_data_structures::stack::ensure_sufficient_stack(|| {
-                                    collect_const_value(tcx, val, &mut neighbors);
-                                });
-                            }
+                            let fn_ty =
+                                tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
+                            visit_fn_use(tcx, fn_ty, false, *op_sp, &mut neighbors);
                         }
                         hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
                             let instance = Instance::mono(tcx, *def_id);
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index df6733ac45f..723e66e9ef6 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -3105,6 +3105,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         );
     }
 
+    fn resolve_inline_const(&mut self, constant: &'ast AnonConst) {
+        debug!("resolve_anon_const {constant:?}");
+        self.with_constant_rib(IsRepeatExpr::No, HasGenericParams::Yes, None, |this| {
+            visit::walk_anon_const(this, constant);
+        });
+    }
+
     fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
         // First, record candidate traits for this expression if it could
         // result in the invocation of a method call.
@@ -3261,7 +3268,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 });
             }
             ExprKind::ConstBlock(ref ct) => {
-                self.resolve_anon_const(ct, IsRepeatExpr::No);
+                self.resolve_inline_const(ct);
             }
             ExprKind::Index(ref elem, ref idx) => {
                 self.resolve_expr(elem, Some(expr));
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index 9dbb8132932..c1d4bb92173 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -914,6 +914,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         reasons.auto_traits.extend(auto_trait_reasons);
         reasons.drop_order = drop_order;
 
+        // `auto_trait_reasons` are in hashset order, so sort them to put the
+        // diagnostics we emit later in a cross-platform-consistent order.
+        reasons.auto_traits.sort_unstable();
+
         reasons
     }
 
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index b4d2772b31d..30190138750 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -248,7 +248,16 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
         }
 
         // Index this method for searching later on.
-        if let Some(ref s) = item.name {
+        if let Some(ref s) = item.name.or_else(|| {
+            if item.is_stripped() {
+                None
+            } else if let clean::ImportItem(ref i) = *item.kind &&
+                let clean::ImportKind::Simple(s) = i.kind {
+                Some(s)
+            } else {
+                None
+            }
+        }) {
             let (parent, is_inherent_impl_item) = match *item.kind {
                 clean::StrippedItem(..) => ((None, None), false),
                 clean::AssocConstItem(..) | clean::AssocTypeItem(..)
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index fedeb449b2e..19582481910 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2542,7 +2542,16 @@ fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) {
 
     let item_sections_in_use: FxHashSet<_> = items
         .iter()
-        .filter(|it| !it.is_stripped() && it.name.is_some())
+        .filter(|it| {
+            !it.is_stripped()
+                && it
+                    .name
+                    .or_else(|| {
+                        if let clean::ImportItem(ref i) = *it.kind &&
+                            let clean::ImportKind::Simple(s) = i.kind { Some(s) } else { None }
+                    })
+                    .is_some()
+        })
         .map(|it| item_ty_to_section(it.type_()))
         .collect();
     for &sec in ItemSection::ALL.iter().filter(|sec| item_sections_in_use.contains(sec)) {
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index f1915920b6d..fbb3d3e4584 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -3,7 +3,7 @@ use clean::AttributesExt;
 use std::cmp::Ordering;
 use std::fmt;
 
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::DefId;
@@ -346,7 +346,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
                 w.write_str(ITEM_TABLE_ROW_OPEN);
                 write!(
                     w,
-                    "<div class=\"item-left {stab}{add}import-item\">\
+                    "<div class=\"item-left {stab}{add}import-item\"{id}>\
                          <code>{vis}{imp}</code>\
                      </div>\
                      <div class=\"item-right docblock-short\">{stab_tags}</div>",
@@ -355,6 +355,11 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
                     vis = myitem.visibility.print_with_space(myitem.item_id, cx),
                     imp = import.print(cx),
                     stab_tags = stab_tags.unwrap_or_default(),
+                    id = match import.kind {
+                        clean::ImportKind::Simple(s) =>
+                            format!(" id=\"{}\"", cx.derive_id(format!("reexport.{}", s))),
+                        clean::ImportKind::Glob => String::new(),
+                    },
                 );
                 w.write_str(ITEM_TABLE_ROW_CLOSE);
             }
@@ -790,16 +795,18 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
     render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All);
 
     let cache = cx.cache();
+    let mut extern_crates = FxHashSet::default();
     if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
         // The DefId is for the first Type found with that name. The bool is
         // if any Types with the same name but different DefId have been found.
         let mut implementor_dups: FxHashMap<Symbol, (DefId, bool)> = FxHashMap::default();
         for implementor in implementors {
-            match implementor.inner_impl().for_ {
-                clean::Type::Path { ref path }
-                | clean::BorrowedRef { type_: box clean::Type::Path { ref path }, .. }
-                    if !path.is_assoc_ty() =>
-                {
+            if let Some(did) = implementor.inner_impl().for_.without_borrowed_ref().def_id(cx.cache()) &&
+                !did.is_local() {
+                extern_crates.insert(did.krate);
+            }
+            match implementor.inner_impl().for_.without_borrowed_ref() {
+                clean::Type::Path { ref path } if !path.is_assoc_ty() => {
                     let did = path.def_id();
                     let &mut (prev_did, ref mut has_duplicates) =
                         implementor_dups.entry(path.last()).or_insert((did, false));
@@ -898,20 +905,96 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
         }
     }
 
+    // Include implementors in crates that depend on the current crate.
+    //
+    // This is complicated by the way rustdoc is invoked, which is basically
+    // the same way rustc is invoked: it gets called, one at a time, for each
+    // crate. When building the rustdocs for the current crate, rustdoc can
+    // see crate metadata for its dependencies, but cannot see metadata for its
+    // dependents.
+    //
+    // To make this work, we generate a "hook" at this stage, and our
+    // dependents can "plug in" to it when they build. For simplicity's sake,
+    // it's [JSONP]: a JavaScript file with the data we need (and can parse),
+    // surrounded by a tiny wrapper that the Rust side ignores, but allows the
+    // JavaScript side to include without having to worry about Same Origin
+    // Policy. The code for *that* is in `write_shared.rs`.
+    //
+    // This is further complicated by `#[doc(inline)]`. We want all copies
+    // of an inlined trait to reference the same JS file, to address complex
+    // dependency graphs like this one (lower crates depend on higher crates):
+    //
+    // ```text
+    //  --------------------------------------------
+    //  |            crate A: trait Foo            |
+    //  --------------------------------------------
+    //      |                               |
+    //  --------------------------------    |
+    //  | crate B: impl A::Foo for Bar |    |
+    //  --------------------------------    |
+    //      |                               |
+    //  ---------------------------------------------
+    //  | crate C: #[doc(inline)] use A::Foo as Baz |
+    //  |          impl Baz for Quux                |
+    //  ---------------------------------------------
+    // ```
+    //
+    // Basically, we want `C::Baz` and `A::Foo` to show the same set of
+    // impls, which is easier if they both treat `/implementors/A/trait.Foo.js`
+    // as the Single Source of Truth.
+    //
+    // We also want the `impl Baz for Quux` to be written to
+    // `trait.Foo.js`. However, when we generate plain HTML for `C::Baz`,
+    // we're going to want to generate plain HTML for `impl Baz for Quux` too,
+    // because that'll load faster, and it's better for SEO. And we don't want
+    // the same impl to show up twice on the same page.
+    //
+    // To make this work, the implementors JS file has a structure kinda
+    // like this:
+    //
+    // ```js
+    // JSONP({
+    // "B": {"impl A::Foo for Bar"},
+    // "C": {"impl Baz for Quux"},
+    // });
+    // ```
+    //
+    // First of all, this means we can rebuild a crate, and it'll replace its own
+    // data if something changes. That is, `rustdoc` is idempotent. The other
+    // advantage is that we can list the crates that get included in the HTML,
+    // and ignore them when doing the JavaScript-based part of rendering.
+    // So C's HTML will have something like this:
+    //
+    // ```html
+    // <script type="text/javascript" src="/implementors/A/trait.Foo.js"
+    //     data-ignore-extern-crates="A,B" async></script>
+    // ```
+    //
+    // And, when the JS runs, anything in data-ignore-extern-crates is known
+    // to already be in the HTML, and will be ignored.
+    //
+    // [JSONP]: https://en.wikipedia.org/wiki/JSONP
     let mut js_src_path: UrlPartsBuilder = std::iter::repeat("..")
         .take(cx.current.len())
         .chain(std::iter::once("implementors"))
         .collect();
-    if it.item_id.is_local() {
-        js_src_path.extend(cx.current.iter().copied());
+    if let Some(did) = it.item_id.as_def_id() &&
+        let get_extern = { || cache.external_paths.get(&did).map(|s| s.0.clone()) } &&
+        let Some(fqp) = cache.exact_paths.get(&did).cloned().or_else(get_extern) {
+        js_src_path.extend(fqp[..fqp.len() - 1].iter().copied());
+        js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), fqp.last().unwrap()));
     } else {
-        let (ref path, _) = cache.external_paths[&it.item_id.expect_def_id()];
-        js_src_path.extend(path[..path.len() - 1].iter().copied());
+        js_src_path.extend(cx.current.iter().copied());
+        js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), it.name.unwrap()));
     }
-    js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), it.name.unwrap()));
+    let extern_crates = extern_crates
+        .into_iter()
+        .map(|cnum| cx.shared.tcx.crate_name(cnum).to_string())
+        .collect::<Vec<_>>()
+        .join(",");
     write!(
         w,
-        "<script type=\"text/javascript\" src=\"{src}\" async></script>",
+        "<script type=\"text/javascript\" src=\"{src}\" data-ignore-extern-crates=\"{extern_crates}\" async></script>",
         src = js_src_path.finish(),
     );
 }
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 7c202e471ad..e8e5fa17993 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -501,10 +501,13 @@ pub(super) fn write_shared(
         //
         // FIXME: this is a vague explanation for why this can't be a `get`, in
         //        theory it should be...
-        let &(ref remote_path, remote_item_type) = match cache.paths.get(&did) {
-            Some(p) => p,
+        let (remote_path, remote_item_type) = match cache.exact_paths.get(&did) {
+            Some(p) => match cache.paths.get(&did).or_else(|| cache.external_paths.get(&did)) {
+                Some((_, t)) => (p, t),
+                None => continue,
+            },
             None => match cache.external_paths.get(&did) {
-                Some(p) => p,
+                Some((p, t)) => (p, t),
                 None => continue,
             },
         };
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 12059e0b9c4..eb3ce37e313 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1333,6 +1333,11 @@ pre.rust {
 	border-top: 2px solid;
 }
 
+#titles > button:first-child:last-child {
+	margin-right: 1px;
+	width: calc(100% - 1px);
+}
+
 #titles > button:not(:last-child) {
 	margin-right: 1px;
 	width: calc(33.3% - 1px);
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 66a7d484f33..2d8339e8394 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -759,8 +759,14 @@ function loadCss(cssFileName) {
         const traitName = document.querySelector("h1.fqn > .in-band > .trait").textContent;
         const baseIdName = "impl-" + traitName + "-";
         const libs = Object.getOwnPropertyNames(imp);
+        // We don't want to include impls from this JS file, when the HTML already has them.
+        // The current crate should always be ignored. Other crates that should also be
+        // ignored are included in the attribute `data-ignore-extern-crates`.
+        const ignoreExternCrates = document
+            .querySelector("script[data-ignore-extern-crates]")
+            .getAttribute("data-ignore-extern-crates");
         for (const lib of libs) {
-            if (lib === window.currentCrate) {
+            if (lib === window.currentCrate || ignoreExternCrates.indexOf(lib) !== -1) {
                 continue;
             }
             const structs = imp[lib];
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 54ce2508c46..2eafa540a1a 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -45,26 +45,33 @@ const TY_KEYWORD = itemTypes.indexOf("keyword");
 
 // In the search display, allows to switch between tabs.
 function printTab(nb) {
-    if (nb === 0 || nb === 1 || nb === 2) {
-        searchState.currentTab = nb;
-    }
-    let nb_copy = nb;
+    let iter = 0;
+    let foundCurrentTab = false;
+    let foundCurrentResultSet = false;
     onEachLazy(document.getElementById("titles").childNodes, elem => {
-        if (nb_copy === 0) {
+        if (nb === iter) {
             addClass(elem, "selected");
+            foundCurrentTab = true;
         } else {
             removeClass(elem, "selected");
         }
-        nb_copy -= 1;
+        iter += 1;
     });
+    iter = 0;
     onEachLazy(document.getElementById("results").childNodes, elem => {
-        if (nb === 0) {
+        if (nb === iter) {
             addClass(elem, "active");
+            foundCurrentResultSet = true;
         } else {
             removeClass(elem, "active");
         }
-        nb -= 1;
+        iter += 1;
     });
+    if (foundCurrentTab && foundCurrentResultSet) {
+        searchState.currentTab = nb;
+    } else if (nb != 0) {
+        printTab(0);
+    }
 }
 
 /**
@@ -1409,18 +1416,12 @@ window.initSearch = rawSearchIndex => {
                     for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) {
                         row = searchIndex[i];
                         in_returned = checkReturned(row, elem, parsedQuery.typeFilter);
-                        addIntoResults(results_returned, row.id, i, -1, in_returned);
+                        addIntoResults(results_others, row.id, i, -1, in_returned);
                     }
                 }
             } else if (parsedQuery.foundElems > 0) {
-                let container = results_others;
-                // In the special case where only a "returned" information is available, we want to
-                // put the information into the "results_returned" dict.
-                if (parsedQuery.returned.length !== 0 && parsedQuery.elems.length === 0) {
-                    container = results_returned;
-                }
                 for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) {
-                    handleArgs(searchIndex[i], i, container);
+                    handleArgs(searchIndex[i], i, results_others);
                 }
             }
         }
@@ -1509,6 +1510,9 @@ window.initSearch = rawSearchIndex => {
             displayPath = path + "::";
             href = window.rootPath + path.replace(/::/g, "/") + "/" +
                    name + "/index.html";
+        } else if (type === "import") {
+            displayPath = item.path + "::";
+            href = window.rootPath + item.path.replace(/::/g, "/") + "/index.html#reexport." + name;
         } else if (type === "primitive" || type === "keyword") {
             displayPath = "";
             href = window.rootPath + path.replace(/::/g, "/") +
@@ -1725,12 +1729,26 @@ window.initSearch = rawSearchIndex => {
             `${typeFilter}</h1> in ${crates} </div>`;
         if (results.query.error !== null) {
             output += `<h3>Query parser error: "${results.query.error}".</h3>`;
+            output += '<div id="titles">' +
+                makeTabHeader(0, "In Names", ret_others[1]) +
+                "</div>";
+            currentTab = 0;
+        } else if (results.query.foundElems <= 1 && results.query.returned.length === 0) {
+            output += `<div id="titles">` +
+                makeTabHeader(0, "In Names", ret_others[1]) +
+                makeTabHeader(1, "In Parameters", ret_in_args[1]) +
+                makeTabHeader(2, "In Return Types", ret_returned[1]) +
+                "</div>";
+        } else {
+            const signatureTabTitle =
+                results.query.elems.length === 0 ? "In Function Return Types" :
+                results.query.returned.length === 0 ? "In Function Parameters" :
+                "In Function Signatures";
+            output += '<div id="titles">' +
+                makeTabHeader(0, signatureTabTitle, ret_others[1]) +
+                "</div>";
+            currentTab = 0;
         }
-        output += `<div id="titles">` +
-            makeTabHeader(0, "In Names", ret_others[1]) +
-            makeTabHeader(1, "In Parameters", ret_in_args[1]) +
-            makeTabHeader(2, "In Return Types", ret_returned[1]) +
-            "</div>";
 
         const resultsElem = document.createElement("div");
         resultsElem.id = "results";
@@ -1745,12 +1763,16 @@ window.initSearch = rawSearchIndex => {
         }
         search.appendChild(resultsElem);
         // Reset focused elements.
-        searchState.focusedByTab = [null, null, null];
         searchState.showResults(search);
         const elems = document.getElementById("titles").childNodes;
-        elems[0].onclick = () => { printTab(0); };
-        elems[1].onclick = () => { printTab(1); };
-        elems[2].onclick = () => { printTab(2); };
+        searchState.focusedByTab = [];
+        let i = 0;
+        for (const elem of elems) {
+            const j = i;
+            elem.onclick = () => { printTab(j); };
+            searchState.focusedByTab.push(null);
+            i += 1;
+        }
         printTab(currentTab);
     }
 
diff --git a/src/test/assembly/asm/global_asm.rs b/src/test/assembly/asm/global_asm.rs
index b76ce7ac387..4cf73b40faf 100644
--- a/src/test/assembly/asm/global_asm.rs
+++ b/src/test/assembly/asm/global_asm.rs
@@ -2,6 +2,7 @@
 // only-linux
 // assembly-output: emit-asm
 // compile-flags: -C llvm-args=--x86-asm-syntax=intel
+// compile-flags: -C symbol-mangling-version=v0
 
 #![feature(asm_const, asm_sym)]
 #![crate_type = "rlib"]
@@ -24,3 +25,7 @@ global_asm!("movl ${}, %ecx", const 5, options(att_syntax));
 global_asm!("call {}", sym my_func);
 // CHECK: lea rax, [rip + MY_STATIC]
 global_asm!("lea rax, [rip + {}]", sym MY_STATIC);
+// CHECK: call _RNvCsiubXh4Yz005_10global_asm6foobar
+global_asm!("call {}", sym foobar);
+// CHECK: _RNvCsiubXh4Yz005_10global_asm6foobar:
+fn foobar() { loop {} }
diff --git a/src/test/rustdoc-gui/implementors.goml b/src/test/rustdoc-gui/implementors.goml
index 6460a917e92..f29613f78b1 100644
--- a/src/test/rustdoc-gui/implementors.goml
+++ b/src/test/rustdoc-gui/implementors.goml
@@ -18,3 +18,10 @@ assert: "#implementors-list .impl:nth-child(2) > .code-header.in-band"
 goto: file://|DOC_PATH|/test_docs/struct.HasEmptyTraits.html
 compare-elements-position-near-false: ("#impl-EmptyTrait1", "#impl-EmptyTrait2", {"y": 30})
 compare-elements-position-near: ("#impl-EmptyTrait3 h3", "#impl-EmptyTrait3 .item-info", {"y": 30})
+
+// Now check that re-exports work correctly.
+// There should be exactly one impl shown on both of these pages.
+goto: file://|DOC_PATH|/lib2/trait.TraitToReexport.html
+assert-count: ("#implementors-list .impl", 1)
+goto: file://|DOC_PATH|/implementors/trait.TraitToReexport.html
+assert-count: ("#implementors-list .impl", 1)
diff --git a/src/test/rustdoc-gui/search-reexport.goml b/src/test/rustdoc-gui/search-reexport.goml
new file mode 100644
index 00000000000..557781d4810
--- /dev/null
+++ b/src/test/rustdoc-gui/search-reexport.goml
@@ -0,0 +1,29 @@
+// Checks that the reexports are present in the search index, can have
+// doc aliases and are highligted when their ID is the hash of the page.
+goto: file://|DOC_PATH|/test_docs/index.html
+local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
+reload:
+// First we check that the reexport has the correct ID and no background color.
+assert-text: ("//*[@id='reexport.TheStdReexport']", "pub use ::std as TheStdReexport;")
+assert-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgba(0, 0, 0, 0)"})
+write: (".search-input", "TheStdReexport")
+wait-for: "//a[@class='result-import']"
+assert-attribute: (
+    "//a[@class='result-import']",
+    {"href": "../test_docs/index.html#reexport.TheStdReexport"},
+)
+assert-text: ("//a[@class='result-import']", "test_docs::TheStdReexport")
+click: "//a[@class='result-import']"
+// We check that it has the background modified thanks to the focus.
+wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgb(73, 74, 61)"})
+
+// We now check that the alias is working as well on the reexport.
+write: (".search-input", "AliasForTheStdReexport")
+wait-for: "//a[@class='result-import']"
+assert-text: (
+    "//a[@class='result-import']",
+    "AliasForTheStdReexport - see test_docs::TheStdReexport",
+)
+// Same thing again, we click on it to ensure the background is once again set as expected.
+click: "//a[@class='result-import']"
+wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgb(73, 74, 61)"})
diff --git a/src/test/rustdoc-gui/search-tab-change-title-fn-sig.goml b/src/test/rustdoc-gui/search-tab-change-title-fn-sig.goml
new file mode 100644
index 00000000000..763927f9d0f
--- /dev/null
+++ b/src/test/rustdoc-gui/search-tab-change-title-fn-sig.goml
@@ -0,0 +1,64 @@
+// Checks that the search tab results work correctly with function signature syntax
+// First, try a search-by-name
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "Foo")
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+assert-text: ("#titles > button:nth-of-type(1)", "In Names", STARTS_WITH)
+assert: "input.search-input:focus"
+// Use left-right keys
+press-key: "ArrowDown"
+assert: "#results > .search-results.active > a:nth-of-type(1):focus"
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(2)", {"class": "selected"})
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(3)", {"class": "selected"})
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+press-key: "ArrowLeft"
+wait-for-attribute: ("#titles > button:nth-of-type(3)", {"class": "selected"})
+
+// Now try search-by-return
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "-> String")
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+assert-text: ("#titles > button:nth-of-type(1)", "In Function Return Types", STARTS_WITH)
+assert: "input.search-input:focus"
+// Use left-right keys
+press-key: "ArrowDown"
+assert: "#results > .search-results.active > a:nth-of-type(1):focus"
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+press-key: "ArrowLeft"
+wait-for-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+
+// Try with a search-by-return with no results
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "-> Something")
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+assert-text: ("#titles > button:nth-of-type(1)", "In Function Return Types", STARTS_WITH)
+
+// Try with a search-by-parameter
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "usize pattern")
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+assert-text: ("#titles > button:nth-of-type(1)", "In Function Parameters", STARTS_WITH)
+
+// Try with a search-by-parameter-and-return
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "pattern -> str")
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+assert-text: ("#titles > button:nth-of-type(1)", "In Function Signatures", STARTS_WITH)
diff --git a/src/test/rustdoc-gui/search-tab-selection-if-current-is-empty.goml b/src/test/rustdoc-gui/search-tab-selection-if-current-is-empty.goml
deleted file mode 100644
index 52b3ceae7b1..00000000000
--- a/src/test/rustdoc-gui/search-tab-selection-if-current-is-empty.goml
+++ /dev/null
@@ -1,23 +0,0 @@
-// Checks that the first non-empty search result tab is selected if the default/currently selected
-// one is empty.
-goto: file://|DOC_PATH|/test_docs/index.html
-write: (".search-input", "Foo")
-// Waiting for the search results to appear...
-wait-for: "#titles"
-assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
-
-// To go back to the original "state"
-goto: file://|DOC_PATH|/test_docs/index.html
-write: (".search-input", "-> String")
-// Waiting for the search results to appear...
-wait-for: "#titles"
-// With this search, only the last tab shouldn't be empty so it should be selected.
-assert-attribute: ("#titles > button:nth-of-type(3)", {"class": "selected"})
-
-// To go back to the original "state"
-goto: file://|DOC_PATH|/test_docs/index.html
-write: (".search-input", "-> Something")
-// Waiting for the search results to appear...
-wait-for: "#titles"
-// With this search, all the tabs are empty so the first one should remain selected.
-assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
diff --git a/src/test/rustdoc-gui/sidebar.goml b/src/test/rustdoc-gui/sidebar.goml
index 6b79b00d3f7..32fe3334f36 100644
--- a/src/test/rustdoc-gui/sidebar.goml
+++ b/src/test/rustdoc-gui/sidebar.goml
@@ -13,15 +13,16 @@ assert-css: ("#all-types", {"color": "rgb(53, 109, 164)"})
 // We check that we have the crates list and that the "current" on is "test_docs".
 assert-text: (".sidebar-elems .crate > ul > li > a.current", "test_docs")
 // And we're also supposed to have the list of items in the current module.
-assert-text: (".sidebar-elems section ul > li:nth-child(1)", "Modules")
-assert-text: (".sidebar-elems section ul > li:nth-child(2)", "Macros")
-assert-text: (".sidebar-elems section ul > li:nth-child(3)", "Structs")
-assert-text: (".sidebar-elems section ul > li:nth-child(4)", "Enums")
-assert-text: (".sidebar-elems section ul > li:nth-child(5)", "Traits")
-assert-text: (".sidebar-elems section ul > li:nth-child(6)", "Functions")
-assert-text: (".sidebar-elems section ul > li:nth-child(7)", "Type Definitions")
-assert-text: (".sidebar-elems section ul > li:nth-child(8)", "Unions")
-assert-text: (".sidebar-elems section ul > li:nth-child(9)", "Keywords")
+assert-text: (".sidebar-elems section ul > li:nth-child(1)", "Re-exports")
+assert-text: (".sidebar-elems section ul > li:nth-child(2)", "Modules")
+assert-text: (".sidebar-elems section ul > li:nth-child(3)", "Macros")
+assert-text: (".sidebar-elems section ul > li:nth-child(4)", "Structs")
+assert-text: (".sidebar-elems section ul > li:nth-child(5)", "Enums")
+assert-text: (".sidebar-elems section ul > li:nth-child(6)", "Traits")
+assert-text: (".sidebar-elems section ul > li:nth-child(7)", "Functions")
+assert-text: (".sidebar-elems section ul > li:nth-child(8)", "Type Definitions")
+assert-text: (".sidebar-elems section ul > li:nth-child(9)", "Unions")
+assert-text: (".sidebar-elems section ul > li:nth-child(10)", "Keywords")
 assert-text: ("#structs + .item-table .item-left > a", "Foo")
 click: "#structs + .item-table .item-left > a"
 
diff --git a/src/test/rustdoc-gui/src/lib2/implementors/lib.rs b/src/test/rustdoc-gui/src/lib2/implementors/lib.rs
index 6417a6ac5af..1620e842291 100644
--- a/src/test/rustdoc-gui/src/lib2/implementors/lib.rs
+++ b/src/test/rustdoc-gui/src/lib2/implementors/lib.rs
@@ -9,3 +9,12 @@ pub struct Struct;
 impl Whatever for Struct {
     type Foo = u8;
 }
+
+mod traits {
+    pub trait TraitToReexport {
+        fn method() {}
+    }
+}
+
+#[doc(inline)]
+pub use traits::TraitToReexport;
diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs
index 83e86c43934..d06b46f952d 100644
--- a/src/test/rustdoc-gui/src/lib2/lib.rs
+++ b/src/test/rustdoc-gui/src/lib2/lib.rs
@@ -43,6 +43,13 @@ impl implementors::Whatever for Foo {
     type Foo = u32;
 }
 
+#[doc(inline)]
+pub use implementors::TraitToReexport;
+
+pub struct StructToImplOnReexport;
+
+impl TraitToReexport for StructToImplOnReexport {}
+
 pub mod sub_mod {
     /// ```txt
     /// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
index 348b1a65c78..b6fe9eb2565 100644
--- a/src/test/rustdoc-gui/src/test_docs/lib.rs
+++ b/src/test/rustdoc-gui/src/test_docs/lib.rs
@@ -274,3 +274,6 @@ impl EmptyTrait3 for HasEmptyTraits {}
 
 mod macros;
 pub use macros::*;
+
+#[doc(alias = "AliasForTheStdReexport")]
+pub use ::std as TheStdReexport;
diff --git a/src/test/rustdoc/hidden-impls.rs b/src/test/rustdoc/hidden-impls.rs
index 935bfb26863..8f33a6604c2 100644
--- a/src/test/rustdoc/hidden-impls.rs
+++ b/src/test/rustdoc/hidden-impls.rs
@@ -12,6 +12,6 @@ pub mod __hidden {
 
 // @has foo/trait.Clone.html
 // @!has - 'Foo'
-// @has implementors/foo/trait.Clone.js
+// @has implementors/core/clone/trait.Clone.js
 // @!has - 'Foo'
 pub use std::clone::Clone;
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
index ee4907bb755..a8367766ae1 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
@@ -29,8 +29,8 @@ error: changes to closure capture in Rust 2021 will affect which traits the clos
 LL |     thread::spawn(move || unsafe {
    |                   ^^^^^^^^^^^^^^
    |                   |
-   |                   in Rust 2018, this closure implements `Sync` as `fptr` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` because `fptr` is not fully captured and `fptr.0.0` does not implement `Sync`
    |                   in Rust 2018, this closure implements `Send` as `fptr` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr` is not fully captured and `fptr.0.0` does not implement `Send`
+   |                   in Rust 2018, this closure implements `Sync` as `fptr` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` because `fptr` is not fully captured and `fptr.0.0` does not implement `Sync`
 ...
 LL |         *fptr.0.0 = 20;
    |         --------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0.0`
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
index 6594ec31653..2648b00435b 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
@@ -4,8 +4,8 @@ error: changes to closure capture in Rust 2021 will affect which traits the clos
 LL |     let result = panic::catch_unwind(move || {
    |                                      ^^^^^^^
    |                                      |
-   |                                      in Rust 2018, this closure implements `UnwindSafe` as `f` implements `UnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe` because `f` is not fully captured and `f.0` does not implement `UnwindSafe`
    |                                      in Rust 2018, this closure implements `RefUnwindSafe` as `f` implements `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `RefUnwindSafe` because `f` is not fully captured and `f.0` does not implement `RefUnwindSafe`
+   |                                      in Rust 2018, this closure implements `UnwindSafe` as `f` implements `UnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe` because `f` is not fully captured and `f.0` does not implement `UnwindSafe`
 ...
 LL |         f.0()
    |         --- in Rust 2018, this closure captures all of `f`, but in Rust 2021, it will only capture `f.0`
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
index 0008f1b2c07..483eae6bb4b 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
@@ -94,8 +94,8 @@ error: changes to closure capture in Rust 2021 will affect which traits the clos
 LL |     thread::spawn(move || unsafe {
    |                   ^^^^^^^^^^^^^^
    |                   |
-   |                   in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` because `fptr1` is not fully captured and `fptr1.0.0` does not implement `Sync`
    |                   in Rust 2018, this closure implements `Send` as `fptr1` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr1` is not fully captured and `fptr1.0.0` does not implement `Send`
+   |                   in Rust 2018, this closure implements `Sync` as `fptr1` implements `Sync`, but in Rust 2021, this closure will no longer implement `Sync` because `fptr1` is not fully captured and `fptr1.0.0` does not implement `Sync`
    |                   in Rust 2018, this closure implements `Send` as `fptr2` implements `Send`, but in Rust 2021, this closure will no longer implement `Send` because `fptr2` is not fully captured and `fptr2.0` does not implement `Send`
 ...
 LL |         *fptr1.0.0 = 20;
diff --git a/src/test/ui/inline-const/const-expr-generic-err.rs b/src/test/ui/inline-const/const-expr-generic-err.rs
new file mode 100644
index 00000000000..4e8879af54a
--- /dev/null
+++ b/src/test/ui/inline-const/const-expr-generic-err.rs
@@ -0,0 +1,15 @@
+// build-fail
+#![feature(inline_const)]
+
+fn foo<T>() {
+    const { assert!(std::mem::size_of::<T>() == 0); } //~ ERROR E0080
+}
+
+fn bar<const N: usize>() -> usize {
+    const { N - 1 } //~ ERROR E0080
+}
+
+fn main() {
+    foo::<i32>();
+    bar::<0>();
+}
diff --git a/src/test/ui/inline-const/const-expr-generic-err.stderr b/src/test/ui/inline-const/const-expr-generic-err.stderr
new file mode 100644
index 00000000000..db0d85a2d4e
--- /dev/null
+++ b/src/test/ui/inline-const/const-expr-generic-err.stderr
@@ -0,0 +1,29 @@
+error[E0080]: evaluation of `foo::<i32>::{constant#0}` failed
+  --> $DIR/const-expr-generic-err.rs:5:13
+   |
+LL |     const { assert!(std::mem::size_of::<T>() == 0); }
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::<T>() == 0', $DIR/const-expr-generic-err.rs:5:13
+   |
+   = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: the above error was encountered while instantiating `fn foo::<i32>`
+  --> $DIR/const-expr-generic-err.rs:13:5
+   |
+LL |     foo::<i32>();
+   |     ^^^^^^^^^^^^
+
+error[E0080]: evaluation of `bar::<0_usize>::{constant#0}` failed
+  --> $DIR/const-expr-generic-err.rs:9:13
+   |
+LL |     const { N - 1 }
+   |             ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
+
+note: the above error was encountered while instantiating `fn bar::<0_usize>`
+  --> $DIR/const-expr-generic-err.rs:14:5
+   |
+LL |     bar::<0>();
+   |     ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/inline-const/const-expr-generic-err2.rs b/src/test/ui/inline-const/const-expr-generic-err2.rs
new file mode 100644
index 00000000000..e097cbe9dd6
--- /dev/null
+++ b/src/test/ui/inline-const/const-expr-generic-err2.rs
@@ -0,0 +1,10 @@
+#![feature(inline_const)]
+
+fn foo<T>() {
+    let _ = [0u8; const { std::mem::size_of::<T>() }];
+    //~^ ERROR: constant expression depends on a generic parameter
+}
+
+fn main() {
+    foo::<i32>();
+}
diff --git a/src/test/ui/inline-const/const-expr-generic-err2.stderr b/src/test/ui/inline-const/const-expr-generic-err2.stderr
new file mode 100644
index 00000000000..00b716cd259
--- /dev/null
+++ b/src/test/ui/inline-const/const-expr-generic-err2.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/const-expr-generic-err2.rs:4:19
+   |
+LL |     let _ = [0u8; const { std::mem::size_of::<T>() }];
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/inline-const/const-expr-generic.rs b/src/test/ui/inline-const/const-expr-generic.rs
new file mode 100644
index 00000000000..3207bfa0e89
--- /dev/null
+++ b/src/test/ui/inline-const/const-expr-generic.rs
@@ -0,0 +1,15 @@
+// check-pass
+#![feature(inline_const)]
+
+fn foo<T>() -> usize {
+    const { std::mem::size_of::<T>() }
+}
+
+fn bar<const N: usize>() -> usize {
+    const { N + 1 }
+}
+
+fn main() {
+    foo::<i32>();
+    bar::<1>();
+}
diff --git a/src/test/ui/inline-const/const-match-pat-generic.rs b/src/test/ui/inline-const/const-match-pat-generic.rs
index be7e1d8d449..e1946467583 100644
--- a/src/test/ui/inline-const/const-match-pat-generic.rs
+++ b/src/test/ui/inline-const/const-match-pat-generic.rs
@@ -1,6 +1,5 @@
 #![allow(incomplete_features)]
 #![feature(inline_const_pat)]
-#![feature(generic_const_exprs)]
 
 // rust-lang/rust#82518: ICE with inline-const in match referencing const-generic parameter
 
@@ -16,7 +15,7 @@ const fn f(x: usize) -> usize {
     x + 1
 }
 
-fn bar<const V: usize>() where [(); f(V)]: {
+fn bar<const V: usize>() {
     match 0 {
         const { f(V) } => {},
         //~^ ERROR constant pattern depends on a generic parameter
diff --git a/src/test/ui/inline-const/const-match-pat-generic.stderr b/src/test/ui/inline-const/const-match-pat-generic.stderr
index 5fe5a7a6dad..ade200d99ba 100644
--- a/src/test/ui/inline-const/const-match-pat-generic.stderr
+++ b/src/test/ui/inline-const/const-match-pat-generic.stderr
@@ -1,17 +1,17 @@
 error[E0158]: const parameters cannot be referenced in patterns
-  --> $DIR/const-match-pat-generic.rs:9:9
+  --> $DIR/const-match-pat-generic.rs:8:9
    |
 LL |         const { V } => {},
    |         ^^^^^^^^^^^
 
 error: constant pattern depends on a generic parameter
-  --> $DIR/const-match-pat-generic.rs:21:9
+  --> $DIR/const-match-pat-generic.rs:20:9
    |
 LL |         const { f(V) } => {},
    |         ^^^^^^^^^^^^^^
 
 error: constant pattern depends on a generic parameter
-  --> $DIR/const-match-pat-generic.rs:21:9
+  --> $DIR/const-match-pat-generic.rs:20:9
    |
 LL |         const { f(V) } => {},
    |         ^^^^^^^^^^^^^^
diff --git a/src/test/ui/traits/suggest-fully-qualified-path-with-appropriate-params.rs b/src/test/ui/traits/suggest-fully-qualified-path-with-appropriate-params.rs
new file mode 100644
index 00000000000..da68b996be9
--- /dev/null
+++ b/src/test/ui/traits/suggest-fully-qualified-path-with-appropriate-params.rs
@@ -0,0 +1,24 @@
+struct Thing;
+
+trait Method<T> {
+    fn method(&self) -> T;
+    fn mut_method(&mut self) -> T;
+}
+
+impl Method<i32> for Thing {
+    fn method(&self) -> i32 { 0 }
+    fn mut_method(&mut self) -> i32 { 0 }
+}
+
+impl Method<u32> for Thing {
+    fn method(&self) -> u32 { 0 }
+    fn mut_method(&mut self) -> u32 { 0 }
+}
+
+fn main() {
+    let thing = Thing;
+    thing.method();
+    //~^ ERROR type annotations needed
+    //~| ERROR type annotations needed
+    thing.mut_method(); //~ ERROR type annotations needed
+}
diff --git a/src/test/ui/traits/suggest-fully-qualified-path-with-appropriate-params.stderr b/src/test/ui/traits/suggest-fully-qualified-path-with-appropriate-params.stderr
new file mode 100644
index 00000000000..0c4962417e9
--- /dev/null
+++ b/src/test/ui/traits/suggest-fully-qualified-path-with-appropriate-params.stderr
@@ -0,0 +1,61 @@
+error[E0282]: type annotations needed
+  --> $DIR/suggest-fully-qualified-path-with-appropriate-params.rs:20:11
+   |
+LL |     thing.method();
+   |     ------^^^^^^--
+   |     |     |
+   |     |     cannot infer type for type parameter `T` declared on the trait `Method`
+   |     this method call resolves to `T`
+
+error[E0283]: type annotations needed
+  --> $DIR/suggest-fully-qualified-path-with-appropriate-params.rs:20:11
+   |
+LL |     thing.method();
+   |     ------^^^^^^--
+   |     |     |
+   |     |     cannot infer type for type parameter `T` declared on the trait `Method`
+   |     this method call resolves to `T`
+   |
+note: multiple `impl`s satisfying `Thing: Method<_>` found
+  --> $DIR/suggest-fully-qualified-path-with-appropriate-params.rs:8:1
+   |
+LL | impl Method<i32> for Thing {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | impl Method<u32> for Thing {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: use the fully qualified path for the potential candidates
+   |
+LL |     <Thing as Method<i32>>::method(&thing);
+   |     ++++++++++++++++++++++++++++++++     ~
+LL |     <Thing as Method<u32>>::method(&thing);
+   |     ++++++++++++++++++++++++++++++++     ~
+
+error[E0283]: type annotations needed
+  --> $DIR/suggest-fully-qualified-path-with-appropriate-params.rs:23:11
+   |
+LL |     thing.mut_method();
+   |     ------^^^^^^^^^^--
+   |     |     |
+   |     |     cannot infer type for type parameter `T` declared on the trait `Method`
+   |     this method call resolves to `T`
+   |
+note: multiple `impl`s satisfying `Thing: Method<_>` found
+  --> $DIR/suggest-fully-qualified-path-with-appropriate-params.rs:8:1
+   |
+LL | impl Method<i32> for Thing {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | impl Method<u32> for Thing {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: use the fully qualified path for the potential candidates
+   |
+LL |     <Thing as Method<i32>>::mut_method(&mut thing);
+   |     +++++++++++++++++++++++++++++++++++++++      ~
+LL |     <Thing as Method<u32>>::mut_method(&mut thing);
+   |     +++++++++++++++++++++++++++++++++++++++      ~
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0282, E0283.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
index 83a36f407d5..6ae700753f0 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
@@ -1,4 +1,4 @@
-error[E0080]: evaluation of `main::{constant#3}::<&i32>` failed
+error[E0080]: evaluation of `main::{constant#3}` failed
   --> $DIR/indexing_slicing_index.rs:31:14
    |
 LL |     const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.