about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs33
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs123
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs34
-rw-r--r--compiler/rustc_hir_analysis/src/check_unused.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs24
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs15
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs124
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs59
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/explicit.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/utils.rs2
20 files changed, 245 insertions, 269 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index b5c06751405..3904f14b0f6 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -46,13 +46,9 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
             .emit();
         }
         None => {
-            tcx.node_span_lint(
-                UNSUPPORTED_CALLING_CONVENTIONS,
-                hir_id,
-                span,
-                "use of calling convention not supported on this target",
-                |_| {},
-            );
+            tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
+                lint.primary_message("use of calling convention not supported on this target");
+            });
         }
     }
 
@@ -243,8 +239,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
             UNINHABITED_STATIC,
             tcx.local_def_id_to_hir_id(def_id),
             span,
-            "static of uninhabited type",
             |lint| {
+                lint.primary_message("static of uninhabited type");
                 lint
                 .note("uninhabited statics cannot be initialized, and any access would be an immediate error");
             },
@@ -538,11 +534,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
                 // the cases that were stabilized with the `impl_trait_projection`
                 // feature -- see <https://github.com/rust-lang/rust/pull/115659>.
                 if let DefKind::LifetimeParam = tcx.def_kind(def_id)
-                    && let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
-                    | ty::ReLateParam(ty::LateParamRegion {
-                        bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
-                        ..
-                    }) = *tcx.map_opaque_lifetime_to_parent_lifetime(def_id.expect_local())
+                    && let Some(def_id) = tcx
+                        .map_opaque_lifetime_to_parent_lifetime(def_id.expect_local())
+                        .opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id()))
                 {
                     shadowed_captures.insert(def_id);
                 }
@@ -585,12 +579,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
                     // Check if the lifetime param was captured but isn't named in the precise captures list.
                     if variances[param.index as usize] == ty::Invariant {
                         if let DefKind::OpaqueTy = tcx.def_kind(tcx.parent(param.def_id))
-                            && let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
-                            | ty::ReLateParam(ty::LateParamRegion {
-                                bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
-                                ..
-                            }) = *tcx
+                            && let Some(def_id) = tcx
                                 .map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local())
+                                .opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id()))
                         {
                             tcx.dcx().emit_err(errors::LifetimeNotCaptured {
                                 opaque_span,
@@ -1315,9 +1306,11 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
                     REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
                     tcx.local_def_id_to_hir_id(adt.did().expect_local()),
                     span,
-                    "zero-sized fields in `repr(transparent)` cannot \
-                    contain external non-exhaustive types",
                     |lint| {
+                        lint.primary_message(
+                            "zero-sized fields in `repr(transparent)` cannot \
+                             contain external non-exhaustive types",
+                        );
                         let note = if non_exhaustive {
                             "is marked with `#[non_exhaustive]`"
                         } else {
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 44bf8fd2d93..8928711253c 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -449,7 +449,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
 pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_m_def_id: LocalDefId,
-) -> Result<&'tcx DefIdMap<ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed> {
+) -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> {
     let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
     let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
     let impl_trait_ref =
@@ -876,7 +876,8 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
             ty::ReLateParam(_) => {}
             // Remap early-bound regions as long as they don't come from the `impl` itself,
             // in which case we don't really need to renumber them.
-            ty::ReEarlyParam(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {}
+            ty::ReEarlyParam(ebr)
+                if ebr.index >= self.tcx.generics_of(self.impl_def_id).count() as u32 => {}
             _ => return Ok(region),
         }
 
@@ -889,12 +890,8 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
                 );
             }
         } else {
-            let guar = match region.kind() {
-                ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
-                | ty::ReLateParam(ty::LateParamRegion {
-                    bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
-                    ..
-                }) => {
+            let guar = match region.opt_param_def_id(self.tcx, self.tcx.parent(self.def_id)) {
+                Some(def_id) => {
                     let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
                         self.tcx.def_span(opaque_ty.def_id)
                     } else {
@@ -914,7 +911,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
                         .with_note(format!("hidden type inferred to be `{}`", self.ty))
                         .emit()
                 }
-                _ => {
+                None => {
                     // This code path is not reached in any tests, but may be
                     // reachable. If this is triggered, it should be converted
                     // to `delayed_bug` and the triggering case turned into a
@@ -928,7 +925,6 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
         Ok(ty::Region::new_early_param(
             self.tcx,
             ty::EarlyParamRegion {
-                def_id: e.def_id,
                 name: e.name,
                 index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
             },
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index d829e720d9e..f7989aeab41 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -130,6 +130,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
         | sym::is_val_statically_known
         | sym::ptr_mask
         | sym::aggregate_raw_ptr
+        | sym::ptr_metadata
         | sym::ub_checks
         | sym::fadd_algebraic
         | sym::fsub_algebraic
@@ -164,9 +165,8 @@ pub fn check_intrinsic_type(
 ) {
     let generics = tcx.generics_of(intrinsic_id);
     let param = |n| {
-        if let Some(&ty::GenericParamDef {
-            name, kind: ty::GenericParamDefKind::Type { .. }, ..
-        }) = generics.opt_param_at(n as usize, tcx)
+        if let &ty::GenericParamDef { name, kind: ty::GenericParamDefKind::Type { .. }, .. } =
+            generics.param_at(n as usize, tcx)
         {
             Ty::new_param(tcx, n, name)
         } else {
@@ -577,6 +577,7 @@ pub fn check_intrinsic_type(
             // This type check is not particularly useful, but the `where` bounds
             // on the definition in `core` do the heavy lifting for checking it.
             sym::aggregate_raw_ptr => (3, 1, vec![param(1), param(2)], param(0)),
+            sym::ptr_metadata => (2, 1, vec![Ty::new_imm_ptr(tcx, param(0))], param(1)),
 
             sym::ub_checks => (0, 1, Vec::new(), tcx.types.bool),
 
@@ -607,6 +608,7 @@ pub fn check_intrinsic_type(
             | sym::simd_bitreverse
             | sym::simd_ctlz
             | sym::simd_cttz
+            | sym::simd_ctpop
             | sym::simd_fsqrt
             | sym::simd_fsin
             | sym::simd_fcos
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index b09de1a4a09..2672614a895 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -281,8 +281,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                     lint::builtin::ASM_SUB_REGISTER,
                     expr.hir_id,
                     spans,
-                    "formatting may not be suitable for sub-register argument",
                     |lint| {
+                        lint.primary_message("formatting may not be suitable for sub-register argument");
                         lint.span_label(expr.span, "for this argument");
                         lint.help(format!(
                             "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}` (for {suggested_size}-bit values)",
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index 4540310937d..8b0adebfaf4 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -6,7 +6,7 @@
 //!
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
 
-use rustc_ast::visit::walk_list;
+use rustc_ast::visit::visit_opt;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
@@ -168,7 +168,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
                 hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => visitor.visit_stmt(statement),
             }
         }
-        walk_list!(visitor, visit_expr, &blk.expr);
+        visit_opt!(visitor, visit_expr, &blk.expr);
     }
 
     visitor.cx = prev_cx;
@@ -407,11 +407,14 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
     match expr.kind {
         // Manually recurse over closures and inline consts, because they are the only
         // case of nested bodies that share the parent environment.
-        hir::ExprKind::Closure(&hir::Closure { body, .. })
-        | hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) => {
+        hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
             let body = visitor.tcx.hir().body(body);
             visitor.visit_body(body);
         }
+        hir::ExprKind::ConstBlock(expr) => visitor.enter_body(expr.hir_id, |this| {
+            this.cx.var_parent = None;
+            resolve_local(this, None, Some(expr));
+        }),
         hir::ExprKind::AssignOp(_, left_expr, right_expr) => {
             debug!(
                 "resolve_expr - enabling pessimistic_yield, was previously {}",
@@ -782,25 +785,8 @@ impl<'tcx> RegionResolutionVisitor<'tcx> {
         }
         self.enter_scope(Scope { id, data: ScopeData::Node });
     }
-}
-
-impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
-    fn visit_block(&mut self, b: &'tcx Block<'tcx>) {
-        resolve_block(self, b);
-    }
-
-    fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) {
-        let body_id = body.id();
-        let owner_id = self.tcx.hir().body_owner_def_id(body_id);
-
-        debug!(
-            "visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})",
-            owner_id,
-            self.tcx.sess.source_map().span_to_diagnostic_string(body.value.span),
-            body_id,
-            self.cx.parent
-        );
 
+    fn enter_body(&mut self, hir_id: hir::HirId, f: impl FnOnce(&mut Self)) {
         // Save all state that is specific to the outer function
         // body. These will be restored once down below, once we've
         // visited the body.
@@ -812,43 +798,12 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
         // control flow assumptions. This doesn't apply to nested
         // bodies within the `+=` statements. See #69307.
         let outer_pessimistic_yield = mem::replace(&mut self.pessimistic_yield, false);
-        self.terminating_scopes.insert(body.value.hir_id.local_id);
-
-        self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::CallSite });
-        self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::Arguments });
+        self.terminating_scopes.insert(hir_id.local_id);
 
-        // The arguments and `self` are parented to the fn.
-        self.cx.var_parent = self.cx.parent.take();
-        for param in body.params {
-            self.visit_pat(param.pat);
-        }
+        self.enter_scope(Scope { id: hir_id.local_id, data: ScopeData::CallSite });
+        self.enter_scope(Scope { id: hir_id.local_id, data: ScopeData::Arguments });
 
-        // The body of the every fn is a root scope.
-        self.cx.parent = self.cx.var_parent;
-        if self.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() {
-            self.visit_expr(body.value)
-        } else {
-            // Only functions have an outer terminating (drop) scope, while
-            // temporaries in constant initializers may be 'static, but only
-            // according to rvalue lifetime semantics, using the same
-            // syntactical rules used for let initializers.
-            //
-            // e.g., in `let x = &f();`, the temporary holding the result from
-            // the `f()` call lives for the entirety of the surrounding block.
-            //
-            // Similarly, `const X: ... = &f();` would have the result of `f()`
-            // live for `'static`, implying (if Drop restrictions on constants
-            // ever get lifted) that the value *could* have a destructor, but
-            // it'd get leaked instead of the destructor running during the
-            // evaluation of `X` (if at all allowed by CTFE).
-            //
-            // However, `const Y: ... = g(&f());`, like `let y = g(&f());`,
-            // would *not* let the `f()` temporary escape into an outer scope
-            // (i.e., `'static`), which means that after `g` returns, it drops,
-            // and all the associated destruction scope rules apply.
-            self.cx.var_parent = None;
-            resolve_local(self, None, Some(body.value));
-        }
+        f(self);
 
         // Restore context we had at the start.
         self.expr_and_pat_count = outer_ec;
@@ -856,6 +811,60 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
         self.terminating_scopes = outer_ts;
         self.pessimistic_yield = outer_pessimistic_yield;
     }
+}
+
+impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
+    fn visit_block(&mut self, b: &'tcx Block<'tcx>) {
+        resolve_block(self, b);
+    }
+
+    fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) {
+        let body_id = body.id();
+        let owner_id = self.tcx.hir().body_owner_def_id(body_id);
+
+        debug!(
+            "visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})",
+            owner_id,
+            self.tcx.sess.source_map().span_to_diagnostic_string(body.value.span),
+            body_id,
+            self.cx.parent
+        );
+
+        self.enter_body(body.value.hir_id, |this| {
+            if this.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() {
+                // The arguments and `self` are parented to the fn.
+                this.cx.var_parent = this.cx.parent.take();
+                for param in body.params {
+                    this.visit_pat(param.pat);
+                }
+
+                // The body of the every fn is a root scope.
+                this.cx.parent = this.cx.var_parent;
+                this.visit_expr(body.value)
+            } else {
+                // Only functions have an outer terminating (drop) scope, while
+                // temporaries in constant initializers may be 'static, but only
+                // according to rvalue lifetime semantics, using the same
+                // syntactical rules used for let initializers.
+                //
+                // e.g., in `let x = &f();`, the temporary holding the result from
+                // the `f()` call lives for the entirety of the surrounding block.
+                //
+                // Similarly, `const X: ... = &f();` would have the result of `f()`
+                // live for `'static`, implying (if Drop restrictions on constants
+                // ever get lifted) that the value *could* have a destructor, but
+                // it'd get leaked instead of the destructor running during the
+                // evaluation of `X` (if at all allowed by CTFE).
+                //
+                // However, `const Y: ... = g(&f());`, like `let y = g(&f());`,
+                // would *not* let the `f()` temporary escape into an outer scope
+                // (i.e., `'static`), which means that after `g` returns, it drops,
+                // and all the associated destruction scope rules apply.
+                this.cx.var_parent = None;
+                resolve_local(this, None, Some(body.value));
+            }
+        })
+    }
 
     fn visit_arm(&mut self, a: &'tcx Arm<'tcx>) {
         resolve_arm(self, a);
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index e8ede804c3f..81e3d8c7ece 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -675,11 +675,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
                 let region_param = gat_generics.param_at(*region_a_idx, tcx);
                 let region_param = ty::Region::new_early_param(
                     tcx,
-                    ty::EarlyParamRegion {
-                        def_id: region_param.def_id,
-                        index: region_param.index,
-                        name: region_param.name,
-                    },
+                    ty::EarlyParamRegion { index: region_param.index, name: region_param.name },
                 );
                 // The predicate we expect to see. (In our example,
                 // `Self: 'me`.)
@@ -708,21 +704,13 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
                 let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
                 let region_a_param = ty::Region::new_early_param(
                     tcx,
-                    ty::EarlyParamRegion {
-                        def_id: region_a_param.def_id,
-                        index: region_a_param.index,
-                        name: region_a_param.name,
-                    },
+                    ty::EarlyParamRegion { index: region_a_param.index, name: region_a_param.name },
                 );
                 // Same for the region.
                 let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
                 let region_b_param = ty::Region::new_early_param(
                     tcx,
-                    ty::EarlyParamRegion {
-                        def_id: region_b_param.def_id,
-                        index: region_b_param.index,
-                        name: region_b_param.name,
-                    },
+                    ty::EarlyParamRegion { index: region_b_param.index, name: region_b_param.name },
                 );
                 // The predicate we expect to see.
                 bounds.insert(
@@ -2101,16 +2089,14 @@ fn lint_redundant_lifetimes<'tcx>(
         }
 
         for &victim in &lifetimes[(idx + 1)..] {
-            // We should only have late-bound lifetimes of the `BrNamed` variety,
-            // since we get these signatures straight from `hir_lowering`. And any
-            // other regions (ReError/ReStatic/etc.) shouldn't matter, since we
+            // All region parameters should have a `DefId` available as:
+            // - Late-bound parameters should be of the`BrNamed` variety,
+            // since we get these signatures straight from `hir_lowering`.
+            // - Early-bound parameters unconditionally have a `DefId` available.
+            //
+            // Any other regions (ReError/ReStatic/etc.) shouldn't matter, since we
             // can't really suggest to remove them.
-            let (ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
-            | ty::ReLateParam(ty::LateParamRegion {
-                bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
-                ..
-            })) = victim.kind()
-            else {
+            let Some(def_id) = victim.opt_param_def_id(tcx, owner_id.to_def_id()) else {
                 continue;
             };
 
diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs
index aa5db4f6aa7..ed23dc2a827 100644
--- a/compiler/rustc_hir_analysis/src/check_unused.rs
+++ b/compiler/rustc_hir_analysis/src/check_unused.rs
@@ -35,11 +35,12 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
             continue;
         }
         let (path, _) = item.expect_use();
-        let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
-            format!("unused import: `{snippet}`")
-        } else {
-            "unused import".to_owned()
-        };
-        tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, msg, |_| {});
+        tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| {
+            if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
+                lint.primary_message(format!("unused import: `{snippet}`"));
+            } else {
+                lint.primary_message("unused import");
+            }
+        });
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index aa28b2c8e2c..75e35e7bf50 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -453,7 +453,6 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
                                         poly_trait_ref,
                                         |_| {
                                             ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
-                                                def_id: item_def_id,
                                                 index: 0,
                                                 name: Symbol::intern(&lt_name),
                                             })
@@ -1117,8 +1116,24 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
 
     let is_marker = tcx.has_attr(def_id, sym::marker);
     let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive);
-    let skip_array_during_method_dispatch =
-        tcx.has_attr(def_id, sym::rustc_skip_array_during_method_dispatch);
+
+    // FIXME: We could probably do way better attribute validation here.
+    let mut skip_array_during_method_dispatch = false;
+    let mut skip_boxed_slice_during_method_dispatch = false;
+    for attr in tcx.get_attrs(def_id, sym::rustc_skip_during_method_dispatch) {
+        if let Some(lst) = attr.meta_item_list() {
+            for item in lst {
+                if let Some(ident) = item.ident() {
+                    match ident.as_str() {
+                        "array" => skip_array_during_method_dispatch = true,
+                        "boxed_slice" => skip_boxed_slice_during_method_dispatch = true,
+                        _ => (),
+                    }
+                }
+            }
+        }
+    }
+
     let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) {
         ty::trait_def::TraitSpecializationKind::Marker
     } else if tcx.has_attr(def_id, sym::rustc_specialization_trait) {
@@ -1253,6 +1268,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
         is_marker,
         is_coinductive: rustc_coinductive || is_auto,
         skip_array_during_method_dispatch,
+        skip_boxed_slice_during_method_dispatch,
         specialization_kind,
         must_implement_one_of,
         implement_via_object,
@@ -1261,7 +1277,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
 }
 
 #[instrument(level = "debug", skip(tcx))]
-fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<'_>> {
+fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFnSig<'_>> {
     use rustc_hir::Node::*;
     use rustc_hir::*;
 
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 6b41f79cf1e..9af959681fb 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -177,10 +177,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                 }
             }
         }
-        Node::ConstBlock(_)
-        | Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
-            Some(tcx.typeck_root_def_id(def_id.to_def_id()))
-        }
+        Node::Expr(&hir::Expr {
+            kind: hir::ExprKind::Closure { .. } | hir::ExprKind::ConstBlock { .. },
+            ..
+        }) => Some(tcx.typeck_root_def_id(def_id.to_def_id())),
         Node::Item(item) => match item.kind {
             ItemKind::OpaqueTy(&hir::OpaqueTy {
                 origin:
@@ -317,8 +317,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                             lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
                             param.hir_id,
                             param.span,
-                            TYPE_DEFAULT_NOT_ALLOWED,
-                            |_| {},
+                            |lint| {
+                                lint.primary_message(TYPE_DEFAULT_NOT_ALLOWED);
+                            },
                         );
                     }
                     Defaults::Deny => {
@@ -414,7 +415,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
     }
 
     // provide junk type parameter defs for const blocks.
-    if let Node::ConstBlock(_) = node {
+    if let Node::Expr(Expr { kind: ExprKind::ConstBlock(..), .. }) = node {
         own_params.push(ty::GenericParamDef {
             index: next_index(),
             name: Symbol::intern("<const_ty>"),
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index dd1d209389d..50c93e9f1d7 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -82,14 +82,14 @@ fn opaque_type_bounds<'tcx>(
 pub(super) fn explicit_item_bounds(
     tcx: TyCtxt<'_>,
     def_id: LocalDefId,
-) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
+) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> {
     explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::All)
 }
 
 pub(super) fn explicit_item_super_predicates(
     tcx: TyCtxt<'_>,
     def_id: LocalDefId,
-) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
+) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> {
     explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::SelfOnly)
 }
 
@@ -97,7 +97,7 @@ pub(super) fn explicit_item_bounds_with_filter(
     tcx: TyCtxt<'_>,
     def_id: LocalDefId,
     filter: PredicateFilter,
-) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
+) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> {
     match tcx.opt_rpitit_info(def_id.to_def_id()) {
         // RPITIT's bounds are the same as opaque type bounds, but with
         // a projection self type.
@@ -166,7 +166,7 @@ pub(super) fn explicit_item_bounds_with_filter(
     ty::EarlyBinder::bind(bounds)
 }
 
-pub(super) fn item_bounds(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<ty::Clauses<'_>> {
+pub(super) fn item_bounds(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<'_, ty::Clauses<'_>> {
     tcx.explicit_item_bounds(def_id).map_bound(|bounds| {
         tcx.mk_clauses_from_iter(util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)))
     })
@@ -175,7 +175,7 @@ pub(super) fn item_bounds(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<ty:
 pub(super) fn item_super_predicates(
     tcx: TyCtxt<'_>,
     def_id: DefId,
-) -> ty::EarlyBinder<ty::Clauses<'_>> {
+) -> ty::EarlyBinder<'_, ty::Clauses<'_>> {
     tcx.explicit_item_super_predicates(def_id).map_bound(|bounds| {
         tcx.mk_clauses_from_iter(
             util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)).filter_only_self(),
@@ -186,7 +186,7 @@ pub(super) fn item_super_predicates(
 pub(super) fn item_non_self_assumptions(
     tcx: TyCtxt<'_>,
     def_id: DefId,
-) -> ty::EarlyBinder<ty::Clauses<'_>> {
+) -> ty::EarlyBinder<'_, ty::Clauses<'_>> {
     let all_bounds: FxIndexSet<_> = tcx.item_bounds(def_id).skip_binder().iter().collect();
     let own_bounds: FxIndexSet<_> =
         tcx.item_super_predicates(def_id).skip_binder().iter().collect();
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index db36aba7edf..072bb727901 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -323,7 +323,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
         if let ty::ReEarlyParam(..) = *orig_lifetime {
             let dup_lifetime = ty::Region::new_early_param(
                 tcx,
-                ty::EarlyParamRegion { def_id: param.def_id, index: param.index, name: param.name },
+                ty::EarlyParamRegion { index: param.index, name: param.name },
             );
             let span = tcx.def_span(param.def_id);
             predicates.push((
@@ -461,83 +461,55 @@ pub(super) fn explicit_predicates_of<'tcx>(
             }
         }
     } else {
-        if matches!(def_kind, DefKind::AnonConst) && tcx.features().generic_const_exprs {
-            let hir_id = tcx.local_def_id_to_hir_id(def_id);
-            let parent_def_id = tcx.hir().get_parent_item(hir_id);
-
-            if let Some(defaulted_param_def_id) =
-                tcx.hir().opt_const_param_default_param_def_id(hir_id)
-            {
-                // In `generics_of` we set the generics' parent to be our parent's parent which means that
-                // we lose out on the predicates of our actual parent if we dont return those predicates here.
-                // (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
-                //
-                // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
-                //        ^^^                     ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
-                //        ^^^                                             explicit_predicates_of on
-                //        parent item we dont have set as the
-                //        parent of generics returned by `generics_of`
-                //
-                // In the above code we want the anon const to have predicates in its param env for `T: Trait`
-                // and we would be calling `explicit_predicates_of(Foo)` here
-                let parent_preds = tcx.explicit_predicates_of(parent_def_id);
-
-                // If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter
-                // will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
-                // to #106994 is implemented.
-                let filtered_predicates = parent_preds
-                    .predicates
-                    .into_iter()
-                    .filter(|(pred, _)| {
-                        if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() {
-                            match ct.kind() {
-                                ty::ConstKind::Param(param_const) => {
-                                    let defaulted_param_idx = tcx
-                                        .generics_of(parent_def_id)
-                                        .param_def_id_to_index[&defaulted_param_def_id.to_def_id()];
-                                    param_const.index < defaulted_param_idx
-                                }
-                                _ => bug!(
-                                    "`ConstArgHasType` in `predicates_of`\
-                                 that isn't a `Param` const"
-                                ),
+        if matches!(def_kind, DefKind::AnonConst)
+            && tcx.features().generic_const_exprs
+            && let Some(defaulted_param_def_id) =
+                tcx.hir().opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id))
+        {
+            // In `generics_of` we set the generics' parent to be our parent's parent which means that
+            // we lose out on the predicates of our actual parent if we dont return those predicates here.
+            // (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
+            //
+            // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
+            //        ^^^                     ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
+            //        ^^^                                             explicit_predicates_of on
+            //        parent item we dont have set as the
+            //        parent of generics returned by `generics_of`
+            //
+            // In the above code we want the anon const to have predicates in its param env for `T: Trait`
+            // and we would be calling `explicit_predicates_of(Foo)` here
+            let parent_def_id = tcx.local_parent(def_id);
+            let parent_preds = tcx.explicit_predicates_of(parent_def_id);
+
+            // If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter
+            // will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
+            // to #106994 is implemented.
+            let filtered_predicates = parent_preds
+                .predicates
+                .into_iter()
+                .filter(|(pred, _)| {
+                    if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() {
+                        match ct.kind() {
+                            ty::ConstKind::Param(param_const) => {
+                                let defaulted_param_idx = tcx
+                                    .generics_of(parent_def_id)
+                                    .param_def_id_to_index[&defaulted_param_def_id.to_def_id()];
+                                param_const.index < defaulted_param_idx
                             }
-                        } else {
-                            true
+                            _ => bug!(
+                                "`ConstArgHasType` in `predicates_of`\
+                                 that isn't a `Param` const"
+                            ),
                         }
-                    })
-                    .cloned();
-                return GenericPredicates {
-                    parent: parent_preds.parent,
-                    predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
-                };
-            }
-
-            let parent_def_kind = tcx.def_kind(parent_def_id);
-            if matches!(parent_def_kind, DefKind::OpaqueTy) {
-                // In `instantiate_identity` we inherit the predicates of our parent.
-                // However, opaque types do not have a parent (see `gather_explicit_predicates_of`), which means
-                // that we lose out on the predicates of our actual parent if we dont return those predicates here.
-                //
-                //
-                // fn foo<T: Trait>() -> impl Iterator<Output = Another<{ <T as Trait>::ASSOC }> > { todo!() }
-                //                                                        ^^^^^^^^^^^^^^^^^^^ the def id we are calling
-                //                                                                            explicit_predicates_of on
-                //
-                // In the above code we want the anon const to have predicates in its param env for `T: Trait`.
-                // However, the anon const cannot inherit predicates from its parent since it's opaque.
-                //
-                // To fix this, we call `explicit_predicates_of` directly on `foo`, the parent's parent.
-
-                // In the above example this is `foo::{opaque#0}` or `impl Iterator`
-                let parent_hir_id = tcx.local_def_id_to_hir_id(parent_def_id.def_id);
-
-                // In the above example this is the function `foo`
-                let item_def_id = tcx.hir().get_parent_item(parent_hir_id);
-
-                // In the above code example we would be calling `explicit_predicates_of(foo)` here
-                return tcx.explicit_predicates_of(item_def_id);
-            }
+                    } else {
+                        true
+                    }
+                })
+                .cloned();
+            return GenericPredicates {
+                parent: parent_preds.parent,
+                predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
+            };
         }
         gather_explicit_predicates_of(tcx, def_id)
     }
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 1475e53c47c..d497617f644 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -309,7 +309,7 @@ fn get_path_containing_arg_in_pat<'hir>(
     arg_path
 }
 
-pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty<'_>> {
+pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, Ty<'_>> {
     use rustc_hir::*;
     use rustc_middle::ty::Ty;
 
@@ -484,8 +484,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
         }
 
         Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
-
-        Node::ConstBlock(_) => {
+        Node::Expr(&Expr { kind: ExprKind::ConstBlock(..), .. }) => {
             let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
             args.as_inline_const().ty()
         }
@@ -512,7 +511,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
 pub(super) fn type_of_opaque(
     tcx: TyCtxt<'_>,
     def_id: DefId,
-) -> Result<ty::EarlyBinder<Ty<'_>>, CyclePlaceholder> {
+) -> Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
     if let Some(def_id) = def_id.as_local() {
         use rustc_hir::*;
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 00356ece585..9c687d3282b 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -18,7 +18,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::traits::FulfillmentError;
 use rustc_middle::bug;
 use rustc_middle::query::Key;
-use rustc_middle::ty::print::PrintTraitRefExt as _;
+use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::{self, suggest_constraining_type_param};
 use rustc_middle::ty::{AdtDef, Ty, TyCtxt, TypeVisitableExt};
@@ -1382,7 +1382,7 @@ pub enum GenericsArgsErrExtend<'tcx> {
         span: Span,
     },
     SelfTyParam(Span),
-    TyParam(DefId),
+    Param(DefId),
     DefVariant,
     None,
 }
@@ -1498,11 +1498,11 @@ fn generics_args_err_extend<'a>(
         GenericsArgsErrExtend::DefVariant => {
             err.note("enum variants can't have type parameters");
         }
-        GenericsArgsErrExtend::TyParam(def_id) => {
-            if let Some(span) = tcx.def_ident_span(def_id) {
-                let name = tcx.item_name(def_id);
-                err.span_note(span, format!("type parameter `{name}` defined here"));
-            }
+        GenericsArgsErrExtend::Param(def_id) => {
+            let span = tcx.def_ident_span(def_id).unwrap();
+            let kind = tcx.def_descr(def_id);
+            let name = tcx.item_name(def_id);
+            err.span_note(span, format!("{kind} `{name}` defined here"));
         }
         GenericsArgsErrExtend::SelfTyParam(span) => {
             err.span_suggestion_verbose(
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
index 749f78e7920..7b67030836d 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
@@ -646,8 +646,9 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
                 LATE_BOUND_LIFETIME_ARGUMENTS,
                 args.args[0].hir_id(),
                 multispan,
-                msg,
-                |_| {},
+                |lint| {
+                    lint.primary_message(msg);
+                },
             );
         }
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index d9d36f5299b..997db338a43 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -72,8 +72,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
             diag.stash(self_ty.span, StashKey::TraitMissingMethod);
         } else {
-            let msg = "trait objects without an explicit `dyn` are deprecated";
-            tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
+            tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| {
+                lint.primary_message("trait objects without an explicit `dyn` are deprecated");
                 if self_ty.span.can_be_used_for_suggestions() {
                     lint.multipart_suggestion_verbose(
                         "if this is an object-safe trait, use `dyn`",
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 8caeb85204b..3f66f971b17 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -40,6 +40,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::middle::stability::AllowUnstable;
 use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
+use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
 use rustc_middle::ty::{
     self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
     TypeVisitableExt,
@@ -279,7 +280,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
                 let generics = tcx.generics_of(item_def_id);
                 let index = generics.param_def_id_to_index[&def_id];
-                ty::Region::new_early_param(tcx, ty::EarlyParamRegion { def_id, index, name })
+                ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
             }
 
             Some(rbv::ResolvedArg::Free(scope, id)) => {
@@ -1164,33 +1165,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let ty = self.lower_assoc_ty(span, assoc_ty_did, assoc_segment, bound);
 
         if let Some(variant_def_id) = variant_resolution {
-            tcx.node_span_lint(
-                AMBIGUOUS_ASSOCIATED_ITEMS,
-                hir_ref_id,
-                span,
-                "ambiguous associated item",
-                |lint| {
-                    let mut could_refer_to = |kind: DefKind, def_id, also| {
-                        let note_msg = format!(
-                            "`{}` could{} refer to the {} defined here",
-                            assoc_ident,
-                            also,
-                            tcx.def_kind_descr(kind, def_id)
-                        );
-                        lint.span_note(tcx.def_span(def_id), note_msg);
-                    };
+            tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| {
+                lint.primary_message("ambiguous associated item");
+                let mut could_refer_to = |kind: DefKind, def_id, also| {
+                    let note_msg = format!(
+                        "`{}` could{} refer to the {} defined here",
+                        assoc_ident,
+                        also,
+                        tcx.def_kind_descr(kind, def_id)
+                    );
+                    lint.span_note(tcx.def_span(def_id), note_msg);
+                };
 
-                    could_refer_to(DefKind::Variant, variant_def_id, "");
-                    could_refer_to(DefKind::AssocTy, assoc_ty_did, " also");
+                could_refer_to(DefKind::Variant, variant_def_id, "");
+                could_refer_to(DefKind::AssocTy, assoc_ty_did, " also");
 
-                    lint.span_suggestion(
-                        span,
-                        "use fully-qualified syntax",
-                        format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
-                        Applicability::MachineApplicable,
-                    );
-                },
-            );
+                lint.span_suggestion(
+                    span,
+                    "use fully-qualified syntax",
+                    format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
+                    Applicability::MachineApplicable,
+                );
+            });
         }
         Ok((ty, DefKind::AssocTy, assoc_ty_did))
     }
@@ -1757,7 +1753,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 assert_eq!(opt_self_ty, None);
                 let _ = self.prohibit_generic_args(
                     path.segments.iter(),
-                    GenericsArgsErrExtend::TyParam(def_id),
+                    GenericsArgsErrExtend::Param(def_id),
                 );
                 self.lower_ty_param(hir_id)
             }
@@ -2190,10 +2186,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
                                 hir::ExprKind::Path(hir::QPath::Resolved(
                                     _,
-                                    &hir::Path {
-                                        res: Res::Def(DefKind::ConstParam, def_id), ..
+                                    path @ &hir::Path {
+                                        res: Res::Def(DefKind::ConstParam, def_id),
+                                        ..
                                     },
                                 )) => {
+                                    let _ = self.prohibit_generic_args(
+                                        path.segments.iter(),
+                                        GenericsArgsErrExtend::Param(def_id),
+                                    );
                                     let ty = tcx
                                         .type_of(def_id)
                                         .no_bound_vars()
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index d1e50e13894..65b02a2ec56 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -68,7 +68,6 @@ This API is completely unstable and subject to change.
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(never_type)]
-#![feature(lazy_cell)]
 #![feature(slice_partition_dedup)]
 #![feature(try_blocks)]
 
@@ -191,10 +190,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
         }
     });
 
-    // Freeze definitions as we don't add new ones at this point. This improves performance by
-    // allowing lock-free access to them.
-    tcx.untracked().definitions.freeze();
-
     // FIXME: Remove this when we implement creating `DefId`s
     // for anon constants during their parents' typeck.
     // Typeck all body owners in parallel will produce queries
@@ -206,6 +201,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
         }
     });
 
+    // Freeze definitions as we don't add new ones at this point. This improves performance by
+    // allowing lock-free access to them.
+    tcx.untracked().definitions.freeze();
+
     tcx.ensure().check_unused_traits(());
 }
 
diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs
index 1de7a0f7bc7..bbfadbb5c30 100644
--- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs
@@ -6,7 +6,7 @@ use super::utils::*;
 
 #[derive(Debug)]
 pub struct ExplicitPredicatesMap<'tcx> {
-    map: FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
+    map: FxIndexMap<DefId, ty::EarlyBinder<'tcx, RequiredPredicates<'tcx>>>,
 }
 
 impl<'tcx> ExplicitPredicatesMap<'tcx> {
@@ -18,7 +18,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
         &mut self,
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-    ) -> &ty::EarlyBinder<RequiredPredicates<'tcx>> {
+    ) -> &ty::EarlyBinder<'tcx, RequiredPredicates<'tcx>> {
         self.map.entry(def_id).or_insert_with(|| {
             let predicates = if def_id.is_local() {
                 tcx.explicit_predicates_of(def_id)
diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
index e6c582667ba..af08f50f655 100644
--- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
@@ -15,7 +15,7 @@ use super::utils::*;
 ///     now be filled with inferred predicates.
 pub(super) fn infer_predicates(
     tcx: TyCtxt<'_>,
-) -> FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'_>>> {
+) -> FxIndexMap<DefId, ty::EarlyBinder<'_, RequiredPredicates<'_>>> {
     debug!("infer_predicates");
 
     let mut explicit_map = ExplicitPredicatesMap::new();
@@ -101,7 +101,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
     tcx: TyCtxt<'tcx>,
     ty: Ty<'tcx>,
     span: Span,
-    global_inferred_outlives: &FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
+    global_inferred_outlives: &FxIndexMap<DefId, ty::EarlyBinder<'tcx, RequiredPredicates<'tcx>>>,
     required_predicates: &mut RequiredPredicates<'tcx>,
     explicit_map: &mut ExplicitPredicatesMap<'tcx>,
 ) {
@@ -322,7 +322,7 @@ fn check_inferred_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
     args: ty::GenericArgsRef<'tcx>,
-    global_inferred_outlives: &FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
+    global_inferred_outlives: &FxIndexMap<DefId, ty::EarlyBinder<'tcx, RequiredPredicates<'tcx>>>,
     required_predicates: &mut RequiredPredicates<'tcx>,
 ) {
     // Load the current set of inferred and explicit predicates from `global_inferred_outlives`
diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs
index 95290bbecf2..5086c2af3f6 100644
--- a/compiler/rustc_hir_analysis/src/outlives/utils.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs
@@ -9,7 +9,7 @@ use smallvec::smallvec;
 /// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred
 /// must be added to the struct header.
 pub(crate) type RequiredPredicates<'tcx> =
-    FxIndexMap<ty::OutlivesPredicate<GenericArg<'tcx>, ty::Region<'tcx>>, Span>;
+    FxIndexMap<ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>, Span>;
 
 /// Given a requirement `T: 'a` or `'b: 'a`, deduce the
 /// outlives_component and add it to `required_predicates`