about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-10-30 08:52:35 +0000
committerbors <bors@rust-lang.org>2022-10-30 08:52:35 +0000
commit962bf63dbfcb190bd752e2dbff7d133ab1101f5c (patch)
tree0d0567de3defda59316b51e53e7687b36025df6f /compiler/rustc_hir_analysis/src
parentc162fd36d250f1a76e00ffa55b9d827d0db7e0bc (diff)
parent0b49a5d17354c3b0980c3148f8291e429fc9a194 (diff)
downloadrust-962bf63dbfcb190bd752e2dbff7d133ab1101f5c.tar.gz
rust-962bf63dbfcb190bd752e2dbff7d133ab1101f5c.zip
Auto merge of #2639 - RalfJung:rustup, r=RalfJung
Rustup
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs70
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs62
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_method.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs62
-rw-r--r--compiler/rustc_hir_analysis/src/check_unused.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/unsafety.rs32
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs53
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs27
-rw-r--r--compiler/rustc_hir_analysis/src/collect/lifetimes.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs48
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs33
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/test.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/variance/test.rs7
21 files changed, 304 insertions, 159 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index a0350c26d82..38f195dabb9 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -36,7 +36,7 @@ use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECT
 use rustc_span::edition::Edition;
 use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::symbol::{kw, Ident, Symbol};
-use rustc_span::Span;
+use rustc_span::{sym, Span};
 use rustc_target::spec::abi;
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::astconv_object_safety_violations;
@@ -275,6 +275,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             item_segment.args(),
             item_segment.infer_args,
             None,
+            None,
         );
         if let Some(b) = item_segment.args().bindings.first() {
             Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
@@ -324,6 +325,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         generic_args: &'a hir::GenericArgs<'_>,
         infer_args: bool,
         self_ty: Option<Ty<'tcx>>,
+        constness: Option<ty::BoundConstness>,
     ) -> (SubstsRef<'tcx>, GenericArgCountResult) {
         // If the type is parameterized by this region, then replace this
         // region with the current anon region binding (in other words,
@@ -534,6 +536,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             &mut substs_ctx,
         );
 
+        if let Some(ty::BoundConstness::ConstIfConst) = constness
+            && generics.has_self && !tcx.has_attr(def_id, sym::const_trait)
+        {
+            tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } );
+        }
+
         (substs, arg_count)
     }
 
@@ -601,6 +609,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             item_segment.args(),
             item_segment.infer_args,
             None,
+            None,
         );
 
         if let Some(b) = item_segment.args().bindings.first() {
@@ -620,6 +629,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         trait_ref: &hir::TraitRef<'_>,
         self_ty: Ty<'tcx>,
+        constness: ty::BoundConstness,
     ) -> ty::TraitRef<'tcx> {
         self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
 
@@ -629,6 +639,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             self_ty,
             trait_ref.path.segments.last().unwrap(),
             true,
+            Some(constness),
         )
     }
 
@@ -655,6 +666,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             args,
             infer_args,
             Some(self_ty),
+            Some(constness),
         );
 
         let tcx = self.tcx();
@@ -680,6 +692,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 speculative,
                 &mut dup_bindings,
                 binding_span.unwrap_or(binding.span),
+                constness,
             );
             // Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
         }
@@ -783,6 +796,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         self_ty: Ty<'tcx>,
         trait_segment: &hir::PathSegment<'_>,
         is_impl: bool,
+        constness: Option<ty::BoundConstness>,
     ) -> ty::TraitRef<'tcx> {
         let (substs, _) = self.create_substs_for_ast_trait_ref(
             span,
@@ -790,6 +804,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             self_ty,
             trait_segment,
             is_impl,
+            constness,
         );
         if let Some(b) = trait_segment.args().bindings.first() {
             Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
@@ -805,6 +820,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         self_ty: Ty<'tcx>,
         trait_segment: &'a hir::PathSegment<'a>,
         is_impl: bool,
+        constness: Option<ty::BoundConstness>,
     ) -> (SubstsRef<'tcx>, GenericArgCountResult) {
         self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
 
@@ -816,6 +832,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             trait_segment.args(),
             trait_segment.infer_args,
             Some(self_ty),
+            constness,
         )
     }
 
@@ -1027,6 +1044,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         speculative: bool,
         dup_bindings: &mut FxHashMap<DefId, Span>,
         path_span: Span,
+        constness: ty::BoundConstness,
     ) -> Result<(), ErrorGuaranteed> {
         // Given something like `U: SomeTrait<T = X>`, we want to produce a
         // predicate like `<U as SomeTrait>::T = X`. This is somewhat
@@ -1122,10 +1140,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 trait_ref.substs,
             );
 
-            debug!(
-                "add_predicates_for_ast_type_binding: substs for trait-ref and assoc_item: {:?}",
-                substs_trait_ref_and_assoc_item
-            );
+            debug!(?substs_trait_ref_and_assoc_item);
 
             ty::ProjectionTy {
                 item_def_id: assoc_item.def_id,
@@ -1146,8 +1161,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     tcx.collect_constrained_late_bound_regions(&projection_ty);
                 let late_bound_in_ty =
                     tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty));
-                debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
-                debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
+                debug!(?late_bound_in_trait_ref);
+                debug!(?late_bound_in_ty);
 
                 // FIXME: point at the type params that don't have appropriate lifetimes:
                 // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
@@ -1648,6 +1663,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
     // Checks that `bounds` contains exactly one element and reports appropriate
     // errors otherwise.
+    #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, is_equality), ret)]
     fn one_bound_for_assoc_type<I>(
         &self,
         all_candidates: impl Fn() -> I,
@@ -1677,10 +1693,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 return Err(reported);
             }
         };
-        debug!("one_bound_for_assoc_type: bound = {:?}", bound);
+        debug!(?bound);
 
         if let Some(bound2) = next_cand {
-            debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
+            debug!(?bound2);
 
             let is_equality = is_equality();
             let bounds = IntoIterator::into_iter([bound, bound2]).chain(matching_candidates);
@@ -1776,6 +1792,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     // parameter or `Self`.
     // NOTE: When this function starts resolving `Trait::AssocTy` successfully
     // it should also start reporting the `BARE_TRAIT_OBJECTS` lint.
+    #[instrument(level = "debug", skip(self, hir_ref_id, span, qself, assoc_segment), fields(assoc_ident=?assoc_segment.ident), ret)]
     pub fn associated_path_to_ty(
         &self,
         hir_ref_id: hir::HirId,
@@ -1793,8 +1810,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             Res::Err
         };
 
-        debug!("associated_path_to_ty: {:?}::{}", qself_ty, assoc_ident);
-
         // Check if we have an enum variant.
         let mut variant_resolution = None;
         if let ty::Adt(adt_def, _) = qself_ty.kind() {
@@ -2050,6 +2065,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         item_def_id: DefId,
         trait_segment: &hir::PathSegment<'_>,
         item_segment: &hir::PathSegment<'_>,
+        constness: ty::BoundConstness,
     ) -> Ty<'tcx> {
         let tcx = self.tcx();
 
@@ -2094,8 +2110,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         debug!("qpath_to_ty: self_type={:?}", self_ty);
 
-        let trait_ref =
-            self.ast_path_to_mono_trait_ref(span, trait_def_id, self_ty, trait_segment, false);
+        let trait_ref = self.ast_path_to_mono_trait_ref(
+            span,
+            trait_def_id,
+            self_ty,
+            trait_segment,
+            false,
+            Some(constness),
+        );
 
         let item_substs = self.create_substs_for_associated_item(
             span,
@@ -2534,12 +2556,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             Res::Def(DefKind::AssocTy, def_id) => {
                 debug_assert!(path.segments.len() >= 2);
                 self.prohibit_generics(path.segments[..path.segments.len() - 2].iter(), |_| {});
+                // HACK: until we support `<Type as ~const Trait>`, assume all of them are.
+                let constness = if tcx.has_attr(tcx.parent(def_id), sym::const_trait) {
+                    ty::BoundConstness::ConstIfConst
+                } else {
+                    ty::BoundConstness::NotConst
+                };
                 self.qpath_to_ty(
                     span,
                     opt_self_ty,
                     def_id,
                     &path.segments[path.segments.len() - 2],
                     path.segments.last().unwrap(),
+                    constness,
                 )
             }
             Res::PrimTy(prim_ty) => {
@@ -2632,7 +2661,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
             hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
                 let opaque_ty = tcx.hir().item(item_id);
-                let def_id = item_id.def_id.to_def_id();
+                let def_id = item_id.owner_id.to_def_id();
 
                 match opaque_ty.kind {
                     hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
@@ -2658,6 +2687,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     &GenericArgs::none(),
                     true,
                     None,
+                    None,
                 );
                 EarlyBinder(self.normalize_ty(span, tcx.at(span).type_of(def_id)))
                     .subst(tcx, substs)
@@ -2766,6 +2796,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         }
     }
 
+    #[instrument(level = "debug", skip(self, hir_id, unsafety, abi, decl, generics, hir_ty), ret)]
     pub fn ty_of_fn(
         &self,
         hir_id: hir::HirId,
@@ -2775,8 +2806,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         generics: Option<&hir::Generics<'_>>,
         hir_ty: Option<&hir::Ty<'_>>,
     ) -> ty::PolyFnSig<'tcx> {
-        debug!("ty_of_fn");
-
         let tcx = self.tcx();
         let bound_vars = tcx.late_bound_vars(hir_id);
         debug!(?bound_vars);
@@ -2826,7 +2855,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             hir::FnRetTy::DefaultReturn(..) => tcx.mk_unit(),
         };
 
-        debug!("ty_of_fn: output_ty={:?}", output_ty);
+        debug!(?output_ty);
 
         let fn_ty = tcx.mk_fn_sig(input_tys.into_iter(), output_ty, decl.c_variadic, unsafety, abi);
         let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
@@ -2903,8 +2932,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(i), .. }) =
                 hir.get(hir.get_parent_node(fn_hir_id)) else { bug!("ImplItem should have Impl parent") };
 
-        let trait_ref =
-            self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty));
+        let trait_ref = self.instantiate_mono_trait_ref(
+            i.of_trait.as_ref()?,
+            self.ast_ty_to_ty(i.self_ty),
+            ty::BoundConstness::NotConst,
+        );
 
         let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
             tcx,
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index a1faf802519..b70ac02058d 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -114,7 +114,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
                 _ => {
                     // Fallback case: allow `ManuallyDrop` and things that are `Copy`.
                     ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop())
-                        || ty.is_copy_modulo_regions(tcx.at(span), param_env)
+                        || ty.is_copy_modulo_regions(tcx, param_env)
                 }
             }
         }
@@ -227,17 +227,17 @@ fn check_opaque<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
         return;
     }
 
-    let substs = InternalSubsts::identity_for_item(tcx, item.def_id.to_def_id());
-    let span = tcx.def_span(item.def_id.def_id);
+    let substs = InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id());
+    let span = tcx.def_span(item.owner_id.def_id);
 
-    check_opaque_for_inheriting_lifetimes(tcx, item.def_id.def_id, span);
-    if tcx.type_of(item.def_id.def_id).references_error() {
+    check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
+    if tcx.type_of(item.owner_id.def_id).references_error() {
         return;
     }
-    if check_opaque_for_cycles(tcx, item.def_id.def_id, substs, span, &origin).is_err() {
+    if check_opaque_for_cycles(tcx, item.owner_id.def_id, substs, span, &origin).is_err() {
         return;
     }
-    check_opaque_meets_bounds(tcx, item.def_id.def_id, substs, span, &origin);
+    check_opaque_meets_bounds(tcx, item.owner_id.def_id, substs, span, &origin);
 }
 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
 /// in "inheriting lifetimes".
@@ -492,25 +492,25 @@ fn check_opaque_meets_bounds<'tcx>(
 fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
     debug!(
         "check_item_type(it.def_id={:?}, it.name={})",
-        id.def_id,
-        tcx.def_path_str(id.def_id.to_def_id())
+        id.owner_id,
+        tcx.def_path_str(id.owner_id.to_def_id())
     );
     let _indenter = indenter();
-    match tcx.def_kind(id.def_id) {
+    match tcx.def_kind(id.owner_id) {
         DefKind::Static(..) => {
-            tcx.ensure().typeck(id.def_id.def_id);
-            maybe_check_static_with_link_section(tcx, id.def_id.def_id);
-            check_static_inhabited(tcx, id.def_id.def_id);
+            tcx.ensure().typeck(id.owner_id.def_id);
+            maybe_check_static_with_link_section(tcx, id.owner_id.def_id);
+            check_static_inhabited(tcx, id.owner_id.def_id);
         }
         DefKind::Const => {
-            tcx.ensure().typeck(id.def_id.def_id);
+            tcx.ensure().typeck(id.owner_id.def_id);
         }
         DefKind::Enum => {
             let item = tcx.hir().item(id);
             let hir::ItemKind::Enum(ref enum_definition, _) = item.kind else {
                 return;
             };
-            check_enum(tcx, &enum_definition.variants, item.def_id.def_id);
+            check_enum(tcx, &enum_definition.variants, item.owner_id.def_id);
         }
         DefKind::Fn => {} // entirely within check_item_body
         DefKind::Impl => {
@@ -518,12 +518,12 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
             let hir::ItemKind::Impl(ref impl_) = it.kind else {
                 return;
             };
-            debug!("ItemKind::Impl {} with id {:?}", it.ident, it.def_id);
-            if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.def_id) {
+            debug!("ItemKind::Impl {} with id {:?}", it.ident, it.owner_id);
+            if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.owner_id) {
                 check_impl_items_against_trait(
                     tcx,
                     it.span,
-                    it.def_id.def_id,
+                    it.owner_id.def_id,
                     impl_trait_ref,
                     &impl_.items,
                 );
@@ -545,15 +545,15 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
                         fn_maybe_err(tcx, item.ident.span, abi);
                     }
                     hir::TraitItemKind::Type(.., Some(default)) => {
-                        let assoc_item = tcx.associated_item(item.def_id);
+                        let assoc_item = tcx.associated_item(item.owner_id);
                         let trait_substs =
-                            InternalSubsts::identity_for_item(tcx, it.def_id.to_def_id());
+                            InternalSubsts::identity_for_item(tcx, it.owner_id.to_def_id());
                         let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
                             tcx,
                             assoc_item,
                             assoc_item,
                             default.span,
-                            ty::TraitRef { def_id: it.def_id.to_def_id(), substs: trait_substs },
+                            ty::TraitRef { def_id: it.owner_id.to_def_id(), substs: trait_substs },
                         );
                     }
                     _ => {}
@@ -561,16 +561,16 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
             }
         }
         DefKind::Struct => {
-            check_struct(tcx, id.def_id.def_id);
+            check_struct(tcx, id.owner_id.def_id);
         }
         DefKind::Union => {
-            check_union(tcx, id.def_id.def_id);
+            check_union(tcx, id.owner_id.def_id);
         }
         DefKind::OpaqueTy => {
             check_opaque(tcx, id);
         }
         DefKind::ImplTraitPlaceholder => {
-            let parent = tcx.impl_trait_in_trait_parent(id.def_id.to_def_id());
+            let parent = tcx.impl_trait_in_trait_parent(id.owner_id.to_def_id());
             // Only check the validity of this opaque type if the function has a default body
             if let hir::Node::TraitItem(hir::TraitItem {
                 kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
@@ -581,8 +581,8 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
             }
         }
         DefKind::TyAlias => {
-            let pty_ty = tcx.type_of(id.def_id);
-            let generics = tcx.generics_of(id.def_id);
+            let pty_ty = tcx.type_of(id.owner_id);
+            let generics = tcx.generics_of(id.owner_id);
             check_type_params_are_used(tcx, &generics, pty_ty);
         }
         DefKind::ForeignMod => {
@@ -604,7 +604,7 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
                 }
             } else {
                 for item in items {
-                    let def_id = item.id.def_id.def_id;
+                    let def_id = item.id.owner_id.def_id;
                     let generics = tcx.generics_of(def_id);
                     let own_counts = generics.own_counts();
                     if generics.params.len() - own_counts.lifetimes != 0 {
@@ -659,7 +659,7 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
 
 pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
     // an error would be reported if this fails.
-    let _ = traits::OnUnimplementedDirective::of_item(tcx, item.def_id.to_def_id());
+    let _ = traits::OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id());
 }
 
 pub(super) fn check_specialization_validity<'tcx>(
@@ -746,7 +746,7 @@ fn check_impl_items_against_trait<'tcx>(
     let trait_def = tcx.trait_def(impl_trait_ref.def_id);
 
     for impl_item in impl_item_refs {
-        let ty_impl_item = tcx.associated_item(impl_item.id.def_id);
+        let ty_impl_item = tcx.associated_item(impl_item.id.owner_id);
         let ty_trait_item = if let Some(trait_item_id) = ty_impl_item.trait_item_def_id {
             tcx.associated_item(trait_item_id)
         } else {
@@ -758,7 +758,7 @@ fn check_impl_items_against_trait<'tcx>(
         match impl_item_full.kind {
             hir::ImplItemKind::Const(..) => {
                 let _ = tcx.compare_assoc_const_impl_item_with_trait_item((
-                    impl_item.id.def_id.def_id,
+                    impl_item.id.owner_id.def_id,
                     ty_impl_item.trait_item_def_id.unwrap(),
                 ));
             }
@@ -1180,7 +1180,7 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
         }
     }
 
-    if tcx.adt_def(def_id).repr().int.is_none() && tcx.features().arbitrary_enum_discriminant {
+    if tcx.adt_def(def_id).repr().int.is_none() {
         let is_unit = |var: &hir::Variant<'_>| matches!(var.data, hir::VariantData::Unit(..));
 
         let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs
index e72f18012ab..32f66b06f83 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_method.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs
@@ -597,7 +597,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
                 let num_trait_substs = trait_to_impl_substs.len();
                 let num_impl_substs = tcx.generics_of(impl_m.container_id(tcx)).params.len();
                 let ty = tcx.fold_regions(ty, |region, _| {
-                    let ty::ReFree(_) = region.kind() else { return region; };
+                    let (ty::ReFree(_) | ty::ReEarlyBound(_)) = region.kind() else { return region; };
                     let Some(ty::ReEarlyBound(e)) = map.get(&region.into()).map(|r| r.expect_region().kind())
                     else {
                         tcx
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 8be1cf04f8b..609095c9cea 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -26,7 +26,7 @@ fn equate_intrinsic_type<'tcx>(
 ) {
     let (own_counts, span) = match &it.kind {
         hir::ForeignItemKind::Fn(.., generics) => {
-            let own_counts = tcx.generics_of(it.def_id.to_def_id()).own_counts();
+            let own_counts = tcx.generics_of(it.owner_id.to_def_id()).own_counts();
             (own_counts, generics.span)
         }
         _ => {
@@ -57,7 +57,7 @@ fn equate_intrinsic_type<'tcx>(
     {
         let fty = tcx.mk_fn_ptr(sig);
         let cause = ObligationCause::new(it.span, it.hir_id(), ObligationCauseCode::IntrinsicType);
-        require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.def_id)), fty);
+        require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.owner_id)), fty);
     }
 }
 
@@ -129,7 +129,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
 /// and in `library/core/src/intrinsics.rs`.
 pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
     let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)));
-    let intrinsic_id = it.def_id.to_def_id();
+    let intrinsic_id = it.owner_id.to_def_id();
     let intrinsic_name = tcx.item_name(intrinsic_id);
     let name_str = intrinsic_name.as_str();
 
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index a026f8033c8..17c4d0d482f 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -33,7 +33,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
     fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
         // Type still may have region variables, but `Sized` does not depend
         // on those, so just erase them before querying.
-        if ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
+        if ty.is_sized(self.tcx, self.param_env) {
             return true;
         }
         if let ty::Foreign(..) = ty.kind() {
@@ -128,7 +128,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
 
         // Check that the type implements Copy. The only case where this can
         // possibly fail is for SIMD types which don't #[derive(Copy)].
-        if !ty.is_copy_modulo_regions(self.tcx.at(expr.span), self.param_env) {
+        if !ty.is_copy_modulo_regions(self.tcx, self.param_env) {
             let msg = "arguments for inline assembly must be copyable";
             let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
             err.note(&format!("`{ty}` does not implement the Copy trait"));
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 33ed3b96aa8..a2357500465 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -147,10 +147,10 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) {
 /// the types first.
 #[instrument(skip(tcx), level = "debug")]
 fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
-    let def_id = item.def_id.def_id;
+    let def_id = item.owner_id.def_id;
 
     debug!(
-        ?item.def_id,
+        ?item.owner_id,
         item.name = ? tcx.def_path_str(def_id.to_def_id())
     );
 
@@ -246,10 +246,10 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
 }
 
 fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
-    let def_id = item.def_id.def_id;
+    let def_id = item.owner_id.def_id;
 
     debug!(
-        ?item.def_id,
+        ?item.owner_id,
         item.name = ? tcx.def_path_str(def_id.to_def_id())
     );
 
@@ -263,7 +263,7 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
 }
 
 fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
-    let def_id = trait_item.def_id.def_id;
+    let def_id = trait_item.owner_id.def_id;
 
     let (method_sig, span) = match trait_item.kind {
         hir::TraitItemKind::Fn(ref sig, _) => (Some(sig), trait_item.span),
@@ -275,7 +275,7 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
 
     let encl_trait_def_id = tcx.local_parent(def_id);
     let encl_trait = tcx.hir().expect_item(encl_trait_def_id);
-    let encl_trait_def_id = encl_trait.def_id.to_def_id();
+    let encl_trait_def_id = encl_trait.owner_id.to_def_id();
     let fn_lang_item_name = if Some(encl_trait_def_id) == tcx.lang_items().fn_trait() {
         Some("fn")
     } else if Some(encl_trait_def_id) == tcx.lang_items().fn_mut_trait() {
@@ -348,7 +348,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
     loop {
         let mut should_continue = false;
         for gat_item in associated_items {
-            let gat_def_id = gat_item.id.def_id;
+            let gat_def_id = gat_item.id.owner_id;
             let gat_item = tcx.associated_item(gat_def_id);
             // If this item is not an assoc ty, or has no substs, then it's not a GAT
             if gat_item.kind != ty::AssocKind::Type {
@@ -365,7 +365,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
             // constrains the GAT with individually.
             let mut new_required_bounds: Option<FxHashSet<ty::Predicate<'_>>> = None;
             for item in associated_items {
-                let item_def_id = item.id.def_id;
+                let item_def_id = item.id.owner_id;
                 // Skip our own GAT, since it does not constrain itself at all.
                 if item_def_id == gat_def_id {
                     continue;
@@ -713,6 +713,10 @@ fn resolve_regions_with_wf_tys<'tcx>(
 
     add_constraints(&infcx, region_bound_pairs);
 
+    infcx.process_registered_region_obligations(
+        outlives_environment.region_bound_pairs(),
+        param_env,
+    );
     let errors = infcx.resolve_regions(&outlives_environment);
 
     debug!(?errors, "errors");
@@ -786,7 +790,7 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem
     let (trait_name, trait_def_id) =
         match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) {
             hir::Node::Item(item) => match item.kind {
-                hir::ItemKind::Trait(..) => (item.ident, item.def_id),
+                hir::ItemKind::Trait(..) => (item.ident, item.owner_id),
                 _ => return,
             },
             _ => return,
@@ -841,7 +845,7 @@ fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) {
         _ => (None, impl_item.span),
     };
 
-    check_associated_item(tcx, impl_item.def_id.def_id, span, method_sig);
+    check_associated_item(tcx, impl_item.owner_id.def_id, span, method_sig);
 }
 
 fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
@@ -1041,11 +1045,11 @@ fn check_type_defn<'tcx, F>(
 ) where
     F: FnMut(&WfCheckingCtxt<'_, 'tcx>) -> Vec<AdtVariant<'tcx>>,
 {
-    let _ = tcx.representability(item.def_id.def_id);
+    let _ = tcx.representability(item.owner_id.def_id);
 
-    enter_wf_checking_ctxt(tcx, item.span, item.def_id.def_id, |wfcx| {
+    enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
         let variants = lookup_fields(wfcx);
-        let packed = tcx.adt_def(item.def_id).repr().packed();
+        let packed = tcx.adt_def(item.owner_id).repr().packed();
 
         for variant in &variants {
             // All field types must be well-formed.
@@ -1069,7 +1073,7 @@ fn check_type_defn<'tcx, F>(
                         // Just treat unresolved type expression as if it needs drop.
                         true
                     } else {
-                        ty.needs_drop(tcx, tcx.param_env(item.def_id))
+                        ty.needs_drop(tcx, tcx.param_env(item.owner_id))
                     }
                 }
             };
@@ -1117,15 +1121,15 @@ fn check_type_defn<'tcx, F>(
             }
         }
 
-        check_where_clauses(wfcx, item.span, item.def_id.def_id);
+        check_where_clauses(wfcx, item.span, item.owner_id.def_id);
     });
 }
 
 #[instrument(skip(tcx, item))]
 fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
-    debug!(?item.def_id);
+    debug!(?item.owner_id);
 
-    let def_id = item.def_id.def_id;
+    let def_id = item.owner_id.def_id;
     let trait_def = tcx.trait_def(def_id);
     if trait_def.is_marker
         || matches!(trait_def.specialization_kind, TraitSpecializationKind::Marker)
@@ -1236,13 +1240,13 @@ fn check_impl<'tcx>(
     ast_trait_ref: &Option<hir::TraitRef<'_>>,
     constness: hir::Constness,
 ) {
-    enter_wf_checking_ctxt(tcx, item.span, item.def_id.def_id, |wfcx| {
+    enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
         match *ast_trait_ref {
             Some(ref ast_trait_ref) => {
                 // `#[rustc_reservation_impl]` impls are not real impls and
                 // therefore don't need to be WF (the trait's `Self: Trait` predicate
                 // won't hold).
-                let trait_ref = tcx.impl_trait_ref(item.def_id).unwrap();
+                let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap();
                 let trait_ref = wfcx.normalize(ast_trait_ref.path.span, None, trait_ref);
                 let trait_pred = ty::TraitPredicate {
                     trait_ref,
@@ -1264,7 +1268,7 @@ fn check_impl<'tcx>(
                 wfcx.register_obligations(obligations);
             }
             None => {
-                let self_ty = tcx.type_of(item.def_id);
+                let self_ty = tcx.type_of(item.owner_id);
                 let self_ty = wfcx.normalize(
                     item.span,
                     Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
@@ -1278,7 +1282,7 @@ fn check_impl<'tcx>(
             }
         }
 
-        check_where_clauses(wfcx, item.span, item.def_id.def_id);
+        check_where_clauses(wfcx, item.span, item.owner_id.def_id);
     });
 }
 
@@ -1774,14 +1778,14 @@ fn check_variances_for_type_defn<'tcx>(
     item: &hir::Item<'tcx>,
     hir_generics: &hir::Generics<'_>,
 ) {
-    let ty = tcx.type_of(item.def_id);
+    let ty = tcx.type_of(item.owner_id);
     if tcx.has_error_field(ty) {
         return;
     }
 
-    let ty_predicates = tcx.predicates_of(item.def_id);
+    let ty_predicates = tcx.predicates_of(item.owner_id);
     assert_eq!(ty_predicates.parent, None);
-    let variances = tcx.variances_of(item.def_id);
+    let variances = tcx.variances_of(item.owner_id);
 
     let mut constrained_parameters: FxHashSet<_> = variances
         .iter()
@@ -1794,7 +1798,7 @@ fn check_variances_for_type_defn<'tcx>(
 
     // Lazily calculated because it is only needed in case of an error.
     let explicitly_bounded_params = LazyCell::new(|| {
-        let icx = crate::collect::ItemCtxt::new(tcx, item.def_id.to_def_id());
+        let icx = crate::collect::ItemCtxt::new(tcx, item.owner_id.to_def_id());
         hir_generics
             .predicates
             .iter()
@@ -1915,10 +1919,10 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
 
 fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalDefId) {
     let items = tcx.hir_module_items(module);
-    items.par_items(|item| tcx.ensure().check_well_formed(item.def_id));
-    items.par_impl_items(|item| tcx.ensure().check_well_formed(item.def_id));
-    items.par_trait_items(|item| tcx.ensure().check_well_formed(item.def_id));
-    items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.def_id));
+    items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id));
+    items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id));
+    items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id));
+    items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id));
 }
 
 ///////////////////////////////////////////////////////////////////////////
diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs
index 922833f8580..d0c31733481 100644
--- a/compiler/rustc_hir_analysis/src/check_unused.rs
+++ b/compiler/rustc_hir_analysis/src/check_unused.rs
@@ -1,5 +1,6 @@
 use crate::errors::{ExternCrateNotIdiomatic, UnusedExternCrate};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::unord::UnordSet;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -8,12 +9,12 @@ use rustc_session::lint;
 use rustc_span::{Span, Symbol};
 
 pub fn check_crate(tcx: TyCtxt<'_>) {
-    let mut used_trait_imports: FxHashSet<LocalDefId> = FxHashSet::default();
+    let mut used_trait_imports: UnordSet<LocalDefId> = Default::default();
 
     for item_def_id in tcx.hir().body_owners() {
         let imports = tcx.used_trait_imports(item_def_id);
         debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
-        used_trait_imports.extend(imports.iter());
+        used_trait_imports.extend(imports.items().copied());
     }
 
     for &id in tcx.maybe_unused_trait_imports(()) {
@@ -89,11 +90,11 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
     let mut crates_to_lint = vec![];
 
     for id in tcx.hir().items() {
-        if matches!(tcx.def_kind(id.def_id), DefKind::ExternCrate) {
+        if matches!(tcx.def_kind(id.owner_id), DefKind::ExternCrate) {
             let item = tcx.hir().item(id);
             if let hir::ItemKind::ExternCrate(orig_name) = item.kind {
                 crates_to_lint.push(ExternCrateToLint {
-                    def_id: item.def_id.to_def_id(),
+                    def_id: item.owner_id.to_def_id(),
                     span: item.span,
                     orig_name,
                     warn_if_unused: !item.ident.as_str().starts_with('_'),
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index 308ad5d5fc2..2890c149b3a 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -58,7 +58,7 @@ const ADD_ATTR: &str =
 
 impl<'tcx> InherentCollect<'tcx> {
     fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId) {
-        let impl_def_id = item.def_id;
+        let impl_def_id = item.owner_id;
         if let Some(def_id) = def_id.as_local() {
             // Add the implementation to the mapping from implementation to base
             // type def ID, if there is a base type for this implementation and
@@ -89,7 +89,7 @@ impl<'tcx> InherentCollect<'tcx> {
             for impl_item in items {
                 if !self
                     .tcx
-                    .has_attr(impl_item.id.def_id.to_def_id(), sym::rustc_allow_incoherent_impl)
+                    .has_attr(impl_item.id.owner_id.to_def_id(), sym::rustc_allow_incoherent_impl)
                 {
                     struct_span_err!(
                         self.tcx.sess,
@@ -135,7 +135,7 @@ impl<'tcx> InherentCollect<'tcx> {
                 for item in items {
                     if !self
                         .tcx
-                        .has_attr(item.id.def_id.to_def_id(), sym::rustc_allow_incoherent_impl)
+                        .has_attr(item.id.owner_id.to_def_id(), sym::rustc_allow_incoherent_impl)
                     {
                         struct_span_err!(
                             self.tcx.sess,
@@ -177,7 +177,7 @@ impl<'tcx> InherentCollect<'tcx> {
     }
 
     fn check_item(&mut self, id: hir::ItemId) {
-        if !matches!(self.tcx.def_kind(id.def_id), DefKind::Impl) {
+        if !matches!(self.tcx.def_kind(id.owner_id), DefKind::Impl) {
             return;
         }
 
@@ -186,7 +186,7 @@ impl<'tcx> InherentCollect<'tcx> {
             return;
         };
 
-        let self_ty = self.tcx.type_of(item.def_id);
+        let self_ty = self.tcx.type_of(item.owner_id);
         match *self_ty.kind() {
             ty::Adt(def, _) => {
                 self.check_def_id(item, self_ty, def.did());
@@ -221,7 +221,7 @@ impl<'tcx> InherentCollect<'tcx> {
             | ty::Never
             | ty::FnPtr(_)
             | ty::Tuple(..) => {
-                self.check_primitive_impl(item.def_id.def_id, self_ty, items, ty.span)
+                self.check_primitive_impl(item.owner_id.def_id, self_ty, items, ty.span)
             }
             ty::Projection(..) | ty::Opaque(..) | ty::Param(_) => {
                 let mut err = struct_span_err!(
@@ -243,7 +243,7 @@ impl<'tcx> InherentCollect<'tcx> {
             | ty::Bound(..)
             | ty::Placeholder(_)
             | ty::Infer(_) => {
-                bug!("unexpected impl self type of impl: {:?} {:?}", item.def_id, self_ty);
+                bug!("unexpected impl self type of impl: {:?} {:?}", item.owner_id, self_ty);
             }
             ty::Error(_) => {}
         }
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index 130eb8005b0..972769eb197 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -156,14 +156,14 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
     }
 
     fn check_item(&mut self, id: hir::ItemId) {
-        let def_kind = self.tcx.def_kind(id.def_id);
+        let def_kind = self.tcx.def_kind(id.owner_id);
         if !matches!(def_kind, DefKind::Enum | DefKind::Struct | DefKind::Trait | DefKind::Union) {
             return;
         }
 
-        let impls = self.tcx.inherent_impls(id.def_id);
+        let impls = self.tcx.inherent_impls(id.owner_id);
 
-        let overlap_mode = OverlapMode::get(self.tcx, id.def_id.to_def_id());
+        let overlap_mode = OverlapMode::get(self.tcx, id.owner_id.to_def_id());
 
         let impls_items = impls
             .iter()
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 1307f74f210..bb45c3823d8 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -101,7 +101,7 @@ fn do_orphan_check_impl<'tcx>(
         span_bug!(sp, "opaque type not found, but `has_opaque_types` is set")
     }
 
-    match traits::orphan_check(tcx, item.def_id.to_def_id()) {
+    match traits::orphan_check(tcx, item.owner_id.to_def_id()) {
         Ok(()) => {}
         Err(err) => emit_orphan_check_error(
             tcx,
diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
index e45fb5fe41c..a34815b45b3 100644
--- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
@@ -13,7 +13,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     let item = tcx.hir().expect_item(def_id);
     let hir::ItemKind::Impl(ref impl_) = item.kind else { bug!() };
 
-    if let Some(trait_ref) = tcx.impl_trait_ref(item.def_id) {
+    if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) {
         let trait_def = tcx.trait_def(trait_ref.def_id);
         let unsafe_attr =
             impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
@@ -26,6 +26,12 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     "implementing the trait `{}` is not unsafe",
                     trait_ref.print_only_trait_path()
                 )
+                .span_suggestion_verbose(
+                    item.span.with_hi(item.span.lo() + rustc_span::BytePos(7)),
+                    "remove `unsafe` from this trait implementation",
+                    "",
+                    rustc_errors::Applicability::MachineApplicable,
+                )
                 .emit();
             }
 
@@ -37,6 +43,18 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     "the trait `{}` requires an `unsafe impl` declaration",
                     trait_ref.print_only_trait_path()
                 )
+                .note(format!(
+                    "the trait `{}` enforces invariants that the compiler can't check. \
+                    Review the trait documentation and make sure this implementation \
+                    upholds those invariants before adding the `unsafe` keyword",
+                    trait_ref.print_only_trait_path()
+                ))
+                .span_suggestion_verbose(
+                    item.span.shrink_to_lo(),
+                    "add `unsafe` to this trait implementation",
+                    "unsafe ",
+                    rustc_errors::Applicability::MaybeIncorrect,
+                )
                 .emit();
             }
 
@@ -48,6 +66,18 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     "requires an `unsafe impl` declaration due to `#[{}]` attribute",
                     attr_name
                 )
+                .note(format!(
+                    "the trait `{}` enforces invariants that the compiler can't check. \
+                    Review the trait documentation and make sure this implementation \
+                    upholds those invariants before adding the `unsafe` keyword",
+                    trait_ref.print_only_trait_path()
+                ))
+                .span_suggestion_verbose(
+                    item.span.shrink_to_lo(),
+                    "add `unsafe` to this trait implementation",
+                    "unsafe ",
+                    rustc_errors::Applicability::MaybeIncorrect,
+                )
                 .emit();
             }
 
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 66ca7d7aa08..346d2e2fc4b 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -571,7 +571,7 @@ fn get_new_lifetime_name<'tcx>(
 fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
     let it = tcx.hir().item(item_id);
     debug!("convert: item {} with id {}", it.ident, it.hir_id());
-    let def_id = item_id.def_id.def_id;
+    let def_id = item_id.owner_id.def_id;
 
     match it.kind {
         // These don't define types.
@@ -583,11 +583,11 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
         hir::ItemKind::ForeignMod { items, .. } => {
             for item in items {
                 let item = tcx.hir().foreign_item(item.id);
-                tcx.ensure().generics_of(item.def_id);
-                tcx.ensure().type_of(item.def_id);
-                tcx.ensure().predicates_of(item.def_id);
+                tcx.ensure().generics_of(item.owner_id);
+                tcx.ensure().type_of(item.owner_id);
+                tcx.ensure().predicates_of(item.owner_id);
                 match item.kind {
-                    hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.def_id),
+                    hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.owner_id),
                     hir::ForeignItemKind::Static(..) => {
                         let mut visitor = HirPlaceholderCollector::default();
                         visitor.visit_foreign_item(item);
@@ -683,7 +683,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
 
 fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
     let trait_item = tcx.hir().trait_item(trait_item_id);
-    let def_id = trait_item_id.def_id;
+    let def_id = trait_item_id.owner_id;
     tcx.ensure().generics_of(def_id);
 
     match trait_item.kind {
@@ -730,7 +730,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
 }
 
 fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
-    let def_id = impl_item_id.def_id;
+    let def_id = impl_item_id.owner_id;
     tcx.ensure().generics_of(def_id);
     tcx.ensure().type_of(def_id);
     tcx.ensure().predicates_of(def_id);
@@ -1010,7 +1010,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
 
                 match item {
                     Some(item) if matches!(item.kind, hir::AssocItemKind::Fn { .. }) => {
-                        if !tcx.impl_defaultness(item.id.def_id).has_value() {
+                        if !tcx.impl_defaultness(item.id.owner_id).has_value() {
                             tcx.sess
                                 .struct_span_err(
                                     item.span,
@@ -1143,7 +1143,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
         }
 
         ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => {
-            // Do not try to inference the return type for a impl method coming from a trait
+            // Do not try to infer the return type for a impl method coming from a trait
             if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) =
                 tcx.hir().get(tcx.hir().get_parent_node(hir_id))
                 && i.of_trait.is_some()
@@ -1286,15 +1286,46 @@ fn infer_return_ty_for_fn_sig<'tcx>(
 
 fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
     let icx = ItemCtxt::new(tcx, def_id);
-    match tcx.hir().expect_item(def_id.expect_local()).kind {
+    let item = tcx.hir().expect_item(def_id.expect_local());
+    match item.kind {
         hir::ItemKind::Impl(ref impl_) => impl_.of_trait.as_ref().map(|ast_trait_ref| {
             let selfty = tcx.type_of(def_id);
-            <dyn AstConv<'_>>::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
+            <dyn AstConv<'_>>::instantiate_mono_trait_ref(
+                &icx,
+                ast_trait_ref,
+                selfty,
+                check_impl_constness(tcx, impl_.constness, ast_trait_ref),
+            )
         }),
         _ => bug!(),
     }
 }
 
+fn check_impl_constness(
+    tcx: TyCtxt<'_>,
+    constness: hir::Constness,
+    ast_trait_ref: &hir::TraitRef<'_>,
+) -> ty::BoundConstness {
+    match constness {
+        hir::Constness::Const => {
+            if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) {
+                let trait_name = tcx.item_name(trait_def_id).to_string();
+                tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
+                    trait_ref_span: ast_trait_ref.path.span,
+                    trait_name,
+                    local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
+                    marking: (),
+                    adding: (),
+                });
+                ty::BoundConstness::NotConst
+            } else {
+                ty::BoundConstness::ConstIfConst
+            }
+        },
+        hir::Constness::NotConst => ty::BoundConstness::NotConst,
+    }
+}
+
 fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
     let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
     let item = tcx.hir().expect_item(def_id.expect_local());
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 707fd6c7527..c7777a94689 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -249,6 +249,11 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
     // Now create the real type and const parameters.
     let type_start = own_start - has_self as u32 + params.len() as u32;
     let mut i = 0;
+    let mut next_index = || {
+        let prev = i;
+        i += 1;
+        prev as u32 + type_start
+    };
 
     const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \
     `struct`, `enum`, `type`, or `trait` definitions";
@@ -278,15 +283,13 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
 
             let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic };
 
-            let param_def = ty::GenericParamDef {
-                index: type_start + i as u32,
+            Some(ty::GenericParamDef {
+                index: next_index(),
                 name: param.name.ident().name,
                 def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
                 pure_wrt_drop: param.pure_wrt_drop,
                 kind,
-            };
-            i += 1;
-            Some(param_def)
+            })
         }
         GenericParamKind::Const { default, .. } => {
             if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() {
@@ -297,15 +300,13 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
                 );
             }
 
-            let param_def = ty::GenericParamDef {
-                index: type_start + i as u32,
+            Some(ty::GenericParamDef {
+                index: next_index(),
                 name: param.name.ident().name,
                 def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
                 pure_wrt_drop: param.pure_wrt_drop,
                 kind: ty::GenericParamDefKind::Const { has_default: default.is_some() },
-            };
-            i += 1;
-            Some(param_def)
+            })
         }
     }));
 
@@ -323,8 +324,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
             &["<closure_kind>", "<closure_signature>", "<upvars>"][..]
         };
 
-        params.extend(dummy_args.iter().enumerate().map(|(i, &arg)| ty::GenericParamDef {
-            index: type_start + i as u32,
+        params.extend(dummy_args.iter().map(|&arg| ty::GenericParamDef {
+            index: next_index(),
             name: Symbol::intern(arg),
             def_id,
             pure_wrt_drop: false,
@@ -337,7 +338,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
         let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
         if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node {
             params.push(ty::GenericParamDef {
-                index: type_start,
+                index: next_index(),
                 name: Symbol::intern("<const_ty>"),
                 def_id,
                 pure_wrt_drop: false,
diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs
index c1214698cf7..3f263a6de24 100644
--- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs
+++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs
@@ -331,8 +331,8 @@ fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetime
 /// `resolve_lifetimes`.
 fn resolve_lifetimes_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: hir::OwnerId) -> &'tcx ResolveLifetimes {
     let item_id = item_for(tcx, def_id.def_id);
-    let local_def_id = item_id.def_id.def_id;
-    if item_id.def_id == def_id {
+    let local_def_id = item_id.owner_id.def_id;
+    if item_id.owner_id == def_id {
         let item = tcx.hir().item(item_id);
         match item.kind {
             hir::ItemKind::Trait(..) => tcx.resolve_lifetimes_trait_definition(local_def_id),
@@ -557,11 +557,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 // their owner, we can keep going until we find the Item that owns that. We then
                 // conservatively add all resolved lifetimes. Otherwise we run into problems in
                 // cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`.
-                for (_hir_id, node) in self.tcx.hir().parent_iter(item.def_id.into()) {
+                for (_hir_id, node) in self.tcx.hir().parent_iter(item.owner_id.into()) {
                     match node {
                         hir::Node::Item(parent_item) => {
                             let resolved_lifetimes: &ResolveLifetimes = self.tcx.resolve_lifetimes(
-                                item_for(self.tcx, parent_item.def_id.def_id).def_id.def_id,
+                                item_for(self.tcx, parent_item.owner_id.def_id).owner_id.def_id,
                             );
                             // We need to add *all* deps, since opaque tys may want them from *us*
                             for (&owner, defs) in resolved_lifetimes.defs.iter() {
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 32f359a8158..c29a645eb4a 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -319,7 +319,15 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     }
                 }
                 ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty),
-                ItemKind::Impl(hir::Impl { self_ty, .. }) => icx.to_ty(*self_ty),
+                ItemKind::Impl(hir::Impl { self_ty, .. }) => {
+                    match self_ty.find_self_aliases() {
+                        spans if spans.len() > 0 => {
+                            tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: (), });
+                            tcx.ty_error()
+                        },
+                        _ => icx.to_ty(*self_ty),
+                    }
+                },
                 ItemKind::Fn(..) => {
                     let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
                     tcx.mk_fn_def(def_id.to_def_id(), substs)
@@ -635,24 +643,24 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
             intravisit::walk_expr(self, ex);
         }
         fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
-            trace!(?it.def_id);
+            trace!(?it.owner_id);
             // The opaque type itself or its children are not within its reveal scope.
-            if it.def_id.def_id != self.def_id {
-                self.check(it.def_id.def_id);
+            if it.owner_id.def_id != self.def_id {
+                self.check(it.owner_id.def_id);
                 intravisit::walk_item(self, it);
             }
         }
         fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) {
-            trace!(?it.def_id);
+            trace!(?it.owner_id);
             // The opaque type itself or its children are not within its reveal scope.
-            if it.def_id.def_id != self.def_id {
-                self.check(it.def_id.def_id);
+            if it.owner_id.def_id != self.def_id {
+                self.check(it.owner_id.def_id);
                 intravisit::walk_impl_item(self, it);
             }
         }
         fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
-            trace!(?it.def_id);
-            self.check(it.def_id.def_id);
+            trace!(?it.owner_id);
+            self.check(it.owner_id.def_id);
             intravisit::walk_trait_item(self, it);
         }
     }
@@ -693,6 +701,12 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
         tcx.sess.emit_err(UnconstrainedOpaqueType {
             span: tcx.def_span(def_id),
             name: tcx.item_name(tcx.local_parent(def_id).to_def_id()),
+            what: match tcx.hir().get(scope) {
+                _ if scope == hir::CRATE_HIR_ID => "module",
+                Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module",
+                Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl",
+                _ => "item",
+            },
         });
         return tcx.ty_error();
     };
@@ -764,24 +778,24 @@ fn find_opaque_ty_constraints_for_rpit(
             intravisit::walk_expr(self, ex);
         }
         fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
-            trace!(?it.def_id);
+            trace!(?it.owner_id);
             // The opaque type itself or its children are not within its reveal scope.
-            if it.def_id.def_id != self.def_id {
-                self.check(it.def_id.def_id);
+            if it.owner_id.def_id != self.def_id {
+                self.check(it.owner_id.def_id);
                 intravisit::walk_item(self, it);
             }
         }
         fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) {
-            trace!(?it.def_id);
+            trace!(?it.owner_id);
             // The opaque type itself or its children are not within its reveal scope.
-            if it.def_id.def_id != self.def_id {
-                self.check(it.def_id.def_id);
+            if it.owner_id.def_id != self.def_id {
+                self.check(it.owner_id.def_id);
                 intravisit::walk_impl_item(self, it);
             }
         }
         fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
-            trace!(?it.def_id);
-            self.check(it.def_id.def_id);
+            trace!(?it.owner_id);
+            self.check(it.owner_id.def_id);
             intravisit::walk_trait_item(self, it);
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 9457da32ce6..d5b1a7ce1c2 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1,7 +1,7 @@
 //! Errors emitted by `rustc_hir_analysis`.
 
-use rustc_errors::IntoDiagnostic;
 use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler};
+use rustc_errors::{IntoDiagnostic, MultiSpan};
 use rustc_macros::{Diagnostic, LintDiagnostic};
 use rustc_middle::ty::Ty;
 use rustc_span::{symbol::Ident, Span, Symbol};
@@ -143,6 +143,7 @@ pub struct UnconstrainedOpaqueType {
     #[primary_span]
     pub span: Span,
     pub name: Symbol,
+    pub what: &'static str,
 }
 
 pub struct MissingTypeParams {
@@ -249,3 +250,33 @@ pub struct ExpectedUsedSymbol {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_const_impl_for_non_const_trait)]
+pub struct ConstImplForNonConstTrait {
+    #[primary_span]
+    pub trait_ref_span: Span,
+    pub trait_name: String,
+    #[suggestion(applicability = "machine-applicable", code = "#[const_trait]")]
+    pub local_trait_span: Option<Span>,
+    #[note]
+    pub marking: (),
+    #[note(adding)]
+    pub adding: (),
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_const_bound_for_non_const_trait)]
+pub struct ConstBoundForNonConstTrait {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_self_in_impl_self)]
+pub struct SelfInImplSelf {
+    #[primary_span]
+    pub span: MultiSpan,
+    #[note]
+    pub note: (),
+}
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index a84257b939c..136f6199911 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -55,10 +55,10 @@ fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
     let min_specialization = tcx.features().min_specialization;
     let module = tcx.hir_module_items(module_def_id);
     for id in module.items() {
-        if matches!(tcx.def_kind(id.def_id), DefKind::Impl) {
-            enforce_impl_params_are_constrained(tcx, id.def_id.def_id);
+        if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) {
+            enforce_impl_params_are_constrained(tcx, id.owner_id.def_id);
             if min_specialization {
-                check_min_specialization(tcx, id.def_id.def_id);
+                check_min_specialization(tcx, id.owner_id.def_id);
             }
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index dba505149de..525cd24190a 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -381,7 +381,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
                         error = true;
                     }
                     if let hir::IsAsync::Async = sig.header.asyncness {
-                        let span = tcx.def_span(it.def_id);
+                        let span = tcx.def_span(it.owner_id);
                         struct_span_err!(
                             tcx.sess,
                             span,
diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
index 064a70107fe..90c6edb65e4 100644
--- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
@@ -29,7 +29,7 @@ pub(super) fn infer_predicates<'tcx>(
 
         // Visit all the crates and infer predicates
         for id in tcx.hir().items() {
-            let item_did = id.def_id;
+            let item_did = id.owner_id;
 
             debug!("InferVisitor::visit_item(item={:?})", item_did);
 
diff --git a/compiler/rustc_hir_analysis/src/outlives/test.rs b/compiler/rustc_hir_analysis/src/outlives/test.rs
index eb0e1203405..fa2ac56593b 100644
--- a/compiler/rustc_hir_analysis/src/outlives/test.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/test.rs
@@ -6,11 +6,11 @@ pub fn test_inferred_outlives(tcx: TyCtxt<'_>) {
     for id in tcx.hir().items() {
         // For unit testing: check for a special "rustc_outlives"
         // attribute and report an error with various results if found.
-        if tcx.has_attr(id.def_id.to_def_id(), sym::rustc_outlives) {
-            let inferred_outlives_of = tcx.inferred_outlives_of(id.def_id);
+        if tcx.has_attr(id.owner_id.to_def_id(), sym::rustc_outlives) {
+            let inferred_outlives_of = tcx.inferred_outlives_of(id.owner_id);
             struct_span_err!(
                 tcx.sess,
-                tcx.def_span(id.def_id),
+                tcx.def_span(id.owner_id),
                 E0640,
                 "{:?}",
                 inferred_outlives_of
diff --git a/compiler/rustc_hir_analysis/src/variance/test.rs b/compiler/rustc_hir_analysis/src/variance/test.rs
index 2ba87db880b..83ed3e44b3d 100644
--- a/compiler/rustc_hir_analysis/src/variance/test.rs
+++ b/compiler/rustc_hir_analysis/src/variance/test.rs
@@ -6,9 +6,10 @@ pub fn test_variance(tcx: TyCtxt<'_>) {
     // For unit testing: check for a special "rustc_variance"
     // attribute and report an error with various results if found.
     for id in tcx.hir().items() {
-        if tcx.has_attr(id.def_id.to_def_id(), sym::rustc_variance) {
-            let variances_of = tcx.variances_of(id.def_id);
-            struct_span_err!(tcx.sess, tcx.def_span(id.def_id), E0208, "{:?}", variances_of).emit();
+        if tcx.has_attr(id.owner_id.to_def_id(), sym::rustc_variance) {
+            let variances_of = tcx.variances_of(id.owner_id);
+            struct_span_err!(tcx.sess, tcx.def_span(id.owner_id), E0208, "{:?}", variances_of)
+                .emit();
         }
     }
 }