about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2022-03-05 07:28:41 +1100
committerNicholas Nethercote <n.nethercote@gmail.com>2022-03-11 13:31:24 +1100
commitca5525d5643f4eb7de5c5e69d0691fc8f1cacfca (patch)
treecbe3682d3e3ff0d1a48b76f972f0322ea28c9542
parent5f4e0677190b82e61dc507e3e72caf89da8e5e28 (diff)
downloadrust-ca5525d5643f4eb7de5c5e69d0691fc8f1cacfca.tar.gz
rust-ca5525d5643f4eb7de5c5e69d0691fc8f1cacfca.zip
Improve `AdtDef` interning.
This commit makes `AdtDef` use `Interned`. Much the commit is tedious
changes to introduce getter functions. The interesting changes are in
`compiler/rustc_middle/src/ty/adt.rs`.
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs6
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs6
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs12
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/unsize.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/value_and_place.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/type_of.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/type_of.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/glue.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs6
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs12
-rw-r--r--compiler/rustc_const_eval/src/util/alignment.rs2
-rw-r--r--compiler/rustc_const_eval/src/util/call_kind.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs16
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs4
-rw-r--r--compiler/rustc_lint/src/builtin.rs30
-rw-r--r--compiler/rustc_lint/src/context.rs2
-rw-r--r--compiler/rustc_lint/src/internal.rs2
-rw-r--r--compiler/rustc_lint/src/methods.rs4
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs2
-rw-r--r--compiler/rustc_lint/src/pass_by_value.rs4
-rw-r--r--compiler/rustc_lint/src/types.rs43
-rw-r--r--compiler/rustc_lint/src/unused.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs30
-rw-r--r--compiler/rustc_middle/src/arena.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs8
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_middle/src/thir.rs6
-rw-r--r--compiler/rustc_middle/src/traits/chalk.rs2
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs175
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs4
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs20
-rw-r--r--compiler/rustc_middle/src/ty/context.rs56
-rw-r--r--compiler/rustc_middle/src/ty/error.rs2
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs2
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs8
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs79
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs6
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs2
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs6
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs14
-rw-r--r--compiler/rustc_middle/src/ty/util.rs8
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs14
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs10
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs22
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs8
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs28
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/util.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs37
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/mod.rs6
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs2
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs8
-rw-r--r--compiler/rustc_mir_transform/src/remove_uninit_drops.rs2
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs4
-rw-r--r--compiler/rustc_mir_transform/src/simplify_try.rs2
-rw-r--r--compiler/rustc_passes/src/dead.rs12
-rw-r--r--compiler/rustc_passes/src/intrinsicck.rs12
-rw-r--r--compiler/rustc_privacy/src/lib.rs9
-rw-r--r--compiler/rustc_save_analysis/src/lib.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_match.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs2
-rw-r--r--compiler/rustc_traits/src/chalk/db.rs18
-rw-r--r--compiler/rustc_traits/src/dropck_outlives.rs2
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs23
-rw-r--r--compiler/rustc_ty_utils/src/representability.rs14
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs8
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs10
-rw-r--r--compiler/rustc_typeck/src/check/check.rs44
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs23
-rw-r--r--compiler/rustc_typeck/src/check/dropck.rs4
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs12
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs2
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/checks.rs4
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs2
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior.rs2
-rw-r--r--compiler/rustc_typeck/src/check/method/mod.rs4
-rw-r--r--compiler/rustc_typeck/src/check/method/prelude2021.rs2
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs2
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs30
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs8
-rw-r--r--compiler/rustc_typeck/src/check/op.rs2
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs8
-rw-r--r--compiler/rustc_typeck/src/check/place_op.rs3
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs6
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs2
-rw-r--r--compiler/rustc_typeck/src/coherence/builtin.rs10
-rw-r--r--compiler/rustc_typeck/src/coherence/inherent_impls.rs2
-rw-r--r--compiler/rustc_typeck/src/coherence/orphan.rs10
-rw-r--r--compiler/rustc_typeck/src/collect.rs4
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs2
-rw-r--r--compiler/rustc_typeck/src/expr_use_visitor.rs2
-rw-r--r--compiler/rustc_typeck/src/mem_categorization.rs2
-rw-r--r--compiler/rustc_typeck/src/outlives/implicit_infer.rs4
-rw-r--r--compiler/rustc_typeck/src/variance/constraints.rs2
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/html/render/print_item.rs2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/await_holding_invalid.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/utils.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/default.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_enum.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_clike.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/eq_op.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/format.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_enum_variant.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_flatten.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/str_splitn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_key.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_update.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/new_without_default.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/self_named_constructors.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/try_err.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/eager_or_lazy.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs26
169 files changed, 702 insertions, 687 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 2217c0e14b2..ffea15bdc33 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -138,7 +138,7 @@ impl BorrowExplanation {
                 let mut ty = local_decl.ty;
                 if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
                     if let ty::Adt(adt, substs) = local_decl.ty.kind() {
-                        if tcx.is_diagnostic_item(sym::Option, adt.did) {
+                        if tcx.is_diagnostic_item(sym::Option, adt.did()) {
                             // in for loop desugaring, only look at the `Some(..)` inner type
                             ty = substs.type_at(0);
                         }
@@ -148,7 +148,7 @@ impl BorrowExplanation {
                     // If type is an ADT that implements Drop, then
                     // simplify output by reporting just the ADT name.
                     ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => {
-                        ("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did)))
+                        ("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did())))
                     }
 
                     // Otherwise, just report the whole type (and use
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 164ebfed0f7..c2b5c16517a 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -370,7 +370,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 ty::Adt(def, _) => {
                     let variant = if let Some(idx) = variant_index {
                         assert!(def.is_enum());
-                        &def.variants[idx]
+                        &def.variant(idx)
                     } else {
                         def.non_enum_variant()
                     };
@@ -701,7 +701,7 @@ impl<'tcx> BorrowedContentSource<'tcx> {
             BorrowedContentSource::DerefMutableRef => "a mutable reference".to_string(),
             BorrowedContentSource::OverloadedDeref(ty) => ty
                 .ty_adt_def()
-                .and_then(|adt| match tcx.get_diagnostic_name(adt.did)? {
+                .and_then(|adt| match tcx.get_diagnostic_name(adt.did())? {
                     name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
                     _ => None,
                 })
@@ -731,7 +731,7 @@ impl<'tcx> BorrowedContentSource<'tcx> {
             }
             BorrowedContentSource::OverloadedDeref(ty) => ty
                 .ty_adt_def()
-                .and_then(|adt| match tcx.get_diagnostic_name(adt.did)? {
+                .and_then(|adt| match tcx.get_diagnostic_name(adt.did())? {
                     name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
                     _ => None,
                 })
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index f76ec031aa9..48a70abc0b6 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -388,7 +388,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         };
         let ty = move_place.ty(self.body, self.infcx.tcx).ty;
         let def_id = match *ty.kind() {
-            ty::Adt(self_def, _) => self_def.did,
+            ty::Adt(self_def, _) => self_def.did(),
             ty::Foreign(def_id)
             | ty::FnDef(def_id, _)
             | ty::Closure(def_id, _)
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 38b16fedd3a..1df7e826343 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -345,8 +345,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     ty::Adt(adt, substs) => {
                         let generic_arg = substs[param_index as usize];
                         let identity_substs =
-                            InternalSubsts::identity_for_item(self.infcx.tcx, adt.did);
-                        let base_ty = self.infcx.tcx.mk_adt(adt, identity_substs);
+                            InternalSubsts::identity_for_item(self.infcx.tcx, adt.did());
+                        let base_ty = self.infcx.tcx.mk_adt(*adt, identity_substs);
                         let base_generic_arg = identity_substs[param_index as usize];
                         let adt_desc = adt.descr();
 
@@ -410,7 +410,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 "returns a closure that contains a reference to a captured variable, which then \
                  escapes the closure body"
             }
-            ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did) => {
+            ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => {
                 "returns an `async` block that contains a reference to a captured variable, which then \
                  escapes the closure body"
             }
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 95018e51b0e..a7cf25d43d2 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -736,13 +736,13 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
             }
             ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() {
                 ty::Adt(adt_def, _substs) if adt_def.is_enum() => {
-                    if index.as_usize() >= adt_def.variants.len() {
+                    if index.as_usize() >= adt_def.variants().len() {
                         PlaceTy::from_ty(span_mirbug_and_err!(
                             self,
                             place,
                             "cast to variant #{:?} but enum only has {:?}",
                             index,
-                            adt_def.variants.len()
+                            adt_def.variants().len()
                         ))
                     } else {
                         PlaceTy { ty: base_ty, variant_index: Some(index) }
@@ -816,7 +816,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
 
         let (variant, substs) = match base_ty {
             PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
-                ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
+                ty::Adt(adt_def, substs) => (adt_def.variant(variant_index), substs),
                 ty::Generator(def_id, substs, _) => {
                     let mut variants = substs.as_generator().state_tys(def_id, tcx);
                     let Some(mut variant) = variants.nth(variant_index.into()) else {
@@ -835,7 +835,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
             },
             PlaceTy { ty, variant_index: None } => match *ty.kind() {
                 ty::Adt(adt_def, substs) if !adt_def.is_enum() => {
-                    (&adt_def.variants[VariantIdx::new(0)], substs)
+                    (adt_def.variant(VariantIdx::new(0)), substs)
                 }
                 ty::Closure(_, substs) => {
                     return match substs
@@ -1449,7 +1449,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         );
                     }
                 };
-                if variant_index.as_usize() >= adt.variants.len() {
+                if variant_index.as_usize() >= adt.variants().len() {
                     span_bug!(
                         stmt.source_info.span,
                         "bad set discriminant ({:?} = {:?}): value of of range",
@@ -1928,7 +1928,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         match *ak {
             AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => {
                 let def = tcx.adt_def(adt_did);
-                let variant = &def.variants[variant_index];
+                let variant = &def.variant(variant_index);
                 let adj_field_index = active_field_index.unwrap_or(field_index);
                 if let Some(field) = variant.fields.get(adj_field_index) {
                     Ok(self.normalize(field.ty(tcx, substs), location))
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index d3e36be3244..89fd0bfa8bb 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -67,7 +67,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
                 pointer_ty(tcx)
             }
         }
-        ty::Adt(adt_def, _) if adt_def.repr.simd() => {
+        ty::Adt(adt_def, _) if adt_def.repr().simd() => {
             let (element, count) = match &tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().abi
             {
                 Abi::Vector { element, count } => (element.clone(), *count),
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index 8cae506e0cb..fd63c3ecddb 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -127,7 +127,7 @@ pub(crate) fn coerce_unsized_into<'tcx>(
         (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
             assert_eq!(def_a, def_b);
 
-            for i in 0..def_a.variants[VariantIdx::new(0)].fields.len() {
+            for i in 0..def_a.variant(VariantIdx::new(0)).fields.len() {
                 let src_f = src.value_field(fx, mir::Field::new(i));
                 let dst_f = dst.place_field(fx, mir::Field::new(i));
 
@@ -200,7 +200,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
 
             // Packed types ignore the alignment of their fields.
             if let ty::Adt(def, _) = layout.ty.kind() {
-                if def.repr.packed() {
+                if def.repr().packed() {
                     unsized_align = sized_align;
                 }
             }
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index b016af5174e..afe8797a030 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -24,7 +24,7 @@ fn codegen_field<'tcx>(
         }
         match field_layout.ty.kind() {
             ty::Slice(..) | ty::Str | ty::Foreign(..) => simple(fx),
-            ty::Adt(def, _) if def.repr.packed() => {
+            ty::Adt(def, _) if def.repr().packed() => {
                 assert_eq!(layout.align.abi.bytes(), 1);
                 simple(fx)
             }
@@ -816,7 +816,7 @@ pub(crate) fn assert_assignable<'tcx>(
             // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
         }
         (&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b))
-            if adt_def_a.did == adt_def_b.did =>
+            if adt_def_a.did() == adt_def_b.did() =>
         {
             let mut types_a = substs_a.types();
             let mut types_b = substs_b.types();
diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs
index 0ada20cad2c..649ffc16249 100644
--- a/compiler/rustc_codegen_gcc/src/type_of.rs
+++ b/compiler/rustc_codegen_gcc/src/type_of.rs
@@ -56,8 +56,8 @@ pub fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLa
             if let (&ty::Adt(def, _), &Variants::Single { index }) =
                 (layout.ty.kind(), &layout.variants)
             {
-                if def.is_enum() && !def.variants.is_empty() {
-                    write!(&mut name, "::{}", def.variants[index].name).unwrap();
+                if def.is_enum() && !def.variants().is_empty() {
+                    write!(&mut name, "::{}", def.variant(index).name).unwrap();
                 }
             }
             if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 89fc8980037..6dfa752dee5 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -639,7 +639,7 @@ pub fn type_metadata<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll
             AdtKind::Struct => prepare_struct_metadata(cx, t, unique_type_id).finalize(cx),
             AdtKind::Union => prepare_union_metadata(cx, t, unique_type_id).finalize(cx),
             AdtKind::Enum => {
-                prepare_enum_metadata(cx, t, def.did, unique_type_id, vec![]).finalize(cx)
+                prepare_enum_metadata(cx, t, def.did(), unique_type_id, vec![]).finalize(cx)
             }
         },
         ty::Tuple(tys) => {
@@ -1207,7 +1207,7 @@ fn prepare_struct_metadata<'ll, 'tcx>(
     let struct_name = compute_debuginfo_type_name(cx.tcx, struct_type, false);
 
     let (struct_def_id, variant) = match struct_type.kind() {
-        ty::Adt(def, _) => (def.did, def.non_enum_variant()),
+        ty::Adt(def, _) => (def.did(), def.non_enum_variant()),
         _ => bug!("prepare_struct_metadata on a non-ADT"),
     };
 
@@ -1384,7 +1384,7 @@ fn prepare_union_metadata<'ll, 'tcx>(
     let union_name = compute_debuginfo_type_name(cx.tcx, union_type, false);
 
     let (union_def_id, variant) = match union_type.kind() {
-        ty::Adt(def, _) => (def.did, def.non_enum_variant()),
+        ty::Adt(def, _) => (def.did(), def.non_enum_variant()),
         _ => bug!("prepare_union_metadata on a non-ADT"),
     };
 
@@ -1466,7 +1466,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
         };
 
         let variant_info_for = |index: VariantIdx| match *self.enum_type.kind() {
-            ty::Adt(adt, _) => VariantInfo::Adt(&adt.variants[index], index),
+            ty::Adt(adt, _) => VariantInfo::Adt(&adt.variant(index), index),
             ty::Generator(def_id, _, _) => {
                 let (generator_layout, generator_saved_local_names) =
                     generator_variant_info_data.as_ref().unwrap();
@@ -1490,7 +1490,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
         match self.layout.variants {
             Variants::Single { index } => {
                 if let ty::Adt(adt, _) = self.enum_type.kind() {
-                    if adt.variants.is_empty() {
+                    if adt.variants().is_empty() {
                         return vec![];
                     }
                 }
@@ -1940,7 +1940,7 @@ fn prepare_enum_metadata<'ll, 'tcx>(
 
     let discriminant_type_metadata = |discr: Primitive| {
         let enumerators_metadata: Vec<_> = match enum_type.kind() {
-            ty::Adt(def, _) => iter::zip(def.discriminants(tcx), &def.variants)
+            ty::Adt(def, _) => iter::zip(def.discriminants(tcx), def.variants())
                 .map(|((_, discr), v)| {
                     let name = v.name.as_str();
                     let is_unsigned = match discr.ty.kind() {
@@ -2311,7 +2311,7 @@ fn set_members_of_composite_type<'ll, 'tcx>(
 fn compute_type_parameters<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> &'ll DIArray {
     if let ty::Adt(def, substs) = *ty.kind() {
         if substs.types().next().is_some() {
-            let generics = cx.tcx.generics_of(def.did);
+            let generics = cx.tcx.generics_of(def.did());
             let names = get_parameter_names(cx, generics);
             let template_params: Vec<_> = iter::zip(substs, names)
                 .filter_map(|(kind, name)| {
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 1b4a193dbf1..34013b5f737 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -524,7 +524,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                             {
                                 Some(type_metadata(cx, impl_self_ty))
                             } else {
-                                Some(namespace::item_namespace(cx, def.did))
+                                Some(namespace::item_namespace(cx, def.did()))
                             }
                         }
                         _ => None,
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index da378dc6493..757aa9a1011 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -53,8 +53,8 @@ fn uncached_llvm_type<'a, 'tcx>(
             if let (&ty::Adt(def, _), &Variants::Single { index }) =
                 (layout.ty.kind(), &layout.variants)
             {
-                if def.is_enum() && !def.variants.is_empty() {
-                    write!(&mut name, "::{}", def.variants[index].name).unwrap();
+                if def.is_enum() && !def.variants().is_empty() {
+                    write!(&mut name, "::{}", def.variant(index).name).unwrap();
                 }
             }
             if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 11f32d92e44..0b31e4b5582 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -255,7 +255,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
             assert_eq!(def_a, def_b);
 
-            for i in 0..def_a.variants[VariantIdx::new(0)].fields.len() {
+            for i in 0..def_a.variant(VariantIdx::new(0)).fields.len() {
                 let src_f = src.project_field(bx, i);
                 let dst_f = dst.project_field(bx, i);
 
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 62a297937d4..67df64e9b1b 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -74,7 +74,7 @@ fn push_debuginfo_type_name<'tcx>(
             if def.is_enum() && cpp_like_debuginfo {
                 msvc_enum_fallback(tcx, t, def, substs, output, visited);
             } else {
-                push_item_name(tcx, def.did, qualified, output);
+                push_item_name(tcx, def.did(), qualified, output);
                 push_generic_params_internal(tcx, substs, output, visited);
             }
         }
@@ -405,15 +405,15 @@ fn push_debuginfo_type_name<'tcx>(
     fn msvc_enum_fallback<'tcx>(
         tcx: TyCtxt<'tcx>,
         ty: Ty<'tcx>,
-        def: &AdtDef,
+        def: AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
         output: &mut String,
         visited: &mut FxHashSet<Ty<'tcx>>,
     ) {
-        let layout = tcx.layout_of(tcx.param_env(def.did).and(ty)).expect("layout error");
+        let layout = tcx.layout_of(tcx.param_env(def.did()).and(ty)).expect("layout error");
 
         output.push_str("enum$<");
-        push_item_name(tcx, def.did, true, output);
+        push_item_name(tcx, def.did(), true, output);
         push_generic_params_internal(tcx, substs, output, visited);
 
         if let Variants::Multiple {
@@ -435,14 +435,14 @@ fn push_debuginfo_type_name<'tcx>(
             let max = dataful_discriminant_range.end;
             let max = tag.value.size(&tcx).truncate(max);
 
-            let dataful_variant_name = def.variants[*dataful_variant].name.as_str();
+            let dataful_variant_name = def.variant(*dataful_variant).name.as_str();
 
             output.push_str(&format!(", {}, {}, {}", min, max, dataful_variant_name));
         } else if let Variants::Single { index: variant_idx } = &layout.variants {
             // Uninhabited enums can't be constructed and should never need to be visualized so
             // skip this step for them.
-            if def.variants.len() != 0 {
-                let variant = def.variants[*variant_idx].name.as_str();
+            if def.variants().len() != 0 {
+                let variant = def.variant(*variant_idx).name.as_str();
 
                 output.push_str(&format!(", {}", variant));
             }
diff --git a/compiler/rustc_codegen_ssa/src/glue.rs b/compiler/rustc_codegen_ssa/src/glue.rs
index 2c4e6bbe9a5..694f5434e9a 100644
--- a/compiler/rustc_codegen_ssa/src/glue.rs
+++ b/compiler/rustc_codegen_ssa/src/glue.rs
@@ -74,7 +74,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
             // Packed types ignore the alignment of their fields.
             if let ty::Adt(def, _) = t.kind() {
-                if def.repr.packed() {
+                if def.repr().packed() {
                     unsized_align = sized_align;
                 }
             }
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 809d6447908..2b8fa3be56d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -149,7 +149,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
             _ if !field.is_unsized() => return simple(),
             ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(),
             ty::Adt(def, _) => {
-                if def.repr.packed() {
+                if def.repr().packed() {
                     // FIXME(eddyb) generalize the adjustment when we
                     // start supporting packing to larger alignments.
                     assert_eq!(self.layout.align.abi.bytes(), 1);
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index c49c5ecac26..6fd7f707e7e 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -105,13 +105,13 @@ fn const_to_valtree_inner<'tcx>(
         ty::Array(_, len) => branches(usize::try_from(len.eval_usize(ecx.tcx.tcx, ecx.param_env)).unwrap(), None),
 
         ty::Adt(def, _) => {
-            if def.variants.is_empty() {
+            if def.variants().is_empty() {
                 bug!("uninhabited types should have errored and never gotten converted to valtree")
             }
 
             let variant = ecx.read_discriminant(&place.into()).unwrap().1;
 
-            branches(def.variants[variant].fields.len(), def.is_enum().then_some(variant))
+            branches(def.variant(variant).fields.len(), def.is_enum().then_some(variant))
         }
 
         ty::Never
@@ -150,11 +150,11 @@ pub(crate) fn try_destructure_const<'tcx>(
         // Checks if we have any variants, to avoid downcasting to a non-existing variant (when
         // there are no variants `read_discriminant` successfully returns a non-existing variant
         // index).
-        ty::Adt(def, _) if def.variants.is_empty() => throw_ub!(Unreachable),
+        ty::Adt(def, _) if def.variants().is_empty() => throw_ub!(Unreachable),
         ty::Adt(def, _) => {
             let variant = ecx.read_discriminant(&op)?.1;
             let down = ecx.operand_downcast(&op, variant)?;
-            (def.variants[variant].fields.len(), Some(variant), down)
+            (def.variant(variant).fields.len(), Some(variant), down)
         }
         ty::Tuple(substs) => (substs.len(), None, op),
         _ => bug!("cannot destructure constant {:?}", val),
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index fa8151a1f3c..9f507bface2 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -174,7 +174,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
         }
 
         if let Some(def) = mplace.layout.ty.ty_adt_def() {
-            if Some(def.did) == self.ecx.tcx.lang_items().unsafe_cell_type() {
+            if Some(def.did()) == self.ecx.tcx.lang_items().unsafe_cell_type() {
                 // We are crossing over an `UnsafeCell`, we can mutate again. This means that
                 // References we encounter inside here are interned as pointing to mutable
                 // allocations.
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 715b174491b..537dff14329 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -73,7 +73,9 @@ crate fn eval_nullary_intrinsic<'tcx>(
         }
         sym::variant_count => match tp_ty.kind() {
             // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
-            ty::Adt(ref adt, _) => ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx),
+            ty::Adt(ref adt, _) => {
+                ConstValue::from_machine_usize(adt.variants().len() as u64, &tcx)
+            }
             ty::Projection(_)
             | ty::Opaque(_, _)
             | ty::Param(_)
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
index dfc1a6e4d38..447797f915c 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
@@ -1,3 +1,4 @@
+use rustc_data_structures::intern::Interned;
 use rustc_hir::def_id::CrateNum;
 use rustc_hir::definitions::DisambiguatedDefPathData;
 use rustc_middle::mir::interpret::{Allocation, ConstAllocation};
@@ -56,7 +57,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
             }
 
             // Types with identity (print the module path).
-            ty::Adt(&ty::AdtDef { did: def_id, .. }, substs)
+            ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
             | ty::FnDef(def_id, substs)
             | ty::Opaque(def_id, substs)
             | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index fb4fe41bdbc..2fae53bb9bd 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -759,7 +759,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                                 .ty
                                 .ty_adt_def()
                                 .expect("tagged layout for non adt")
-                                .variants
+                                .variants()
                                 .len();
                             assert!(usize::try_from(variant_index).unwrap() < variants_len);
                             VariantIdx::from_u32(variant_index)
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 5cacab82386..8fad5e63baf 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -267,7 +267,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                 match layout.variants {
                     Variants::Single { index } => {
                         // Inside a variant
-                        PathElem::Field(def.variants[index].fields[field].name)
+                        PathElem::Field(def.variant(index).fields[field].name)
                     }
                     Variants::Multiple { .. } => bug!("we handled variants above"),
                 }
@@ -734,7 +734,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
         new_op: &OpTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx> {
         let name = match old_op.layout.ty.kind() {
-            ty::Adt(adt, _) => PathElem::Variant(adt.variants[variant_id].name),
+            ty::Adt(adt, _) => PathElem::Variant(adt.variant(variant_id).name),
             // Generators also have variants
             ty::Generator(..) => PathElem::GeneratorState(variant_id),
             _ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty),
@@ -771,7 +771,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
         // Special check preventing `UnsafeCell` in the inner part of constants
         if let Some(def) = op.layout.ty.ty_adt_def() {
             if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { inner: true, .. }))
-                && Some(def.did) == self.ecx.tcx.lang_items().unsafe_cell_type()
+                && Some(def.did()) == self.ecx.tcx.lang_items().unsafe_cell_type()
             {
                 throw_validation_failure!(self.path, { "`UnsafeCell` in a `const`" });
             }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 6421ba9df0f..4ea21b4d06d 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -71,7 +71,7 @@ pub trait Qualif {
     /// Returning `true` for `in_adt_inherently` but `false` for `in_any_value_of_ty` is unsound.
     fn in_adt_inherently<'tcx>(
         cx: &ConstCx<'_, 'tcx>,
-        adt: &'tcx AdtDef,
+        adt: AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
     ) -> bool;
 }
@@ -96,12 +96,12 @@ impl Qualif for HasMutInterior {
 
     fn in_adt_inherently<'tcx>(
         cx: &ConstCx<'_, 'tcx>,
-        adt: &'tcx AdtDef,
+        adt: AdtDef<'tcx>,
         _: SubstsRef<'tcx>,
     ) -> bool {
         // Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
         // It arises structurally for all other types.
-        Some(adt.did) == cx.tcx.lang_items().unsafe_cell_type()
+        Some(adt.did()) == cx.tcx.lang_items().unsafe_cell_type()
     }
 }
 
@@ -126,7 +126,7 @@ impl Qualif for NeedsDrop {
 
     fn in_adt_inherently<'tcx>(
         cx: &ConstCx<'_, 'tcx>,
-        adt: &'tcx AdtDef,
+        adt: AdtDef<'tcx>,
         _: SubstsRef<'tcx>,
     ) -> bool {
         adt.has_dtor(cx.tcx)
@@ -205,7 +205,7 @@ impl Qualif for NeedsNonConstDrop {
 
     fn in_adt_inherently<'tcx>(
         cx: &ConstCx<'_, 'tcx>,
-        adt: &'tcx AdtDef,
+        adt: AdtDef<'tcx>,
         _: SubstsRef<'tcx>,
     ) -> bool {
         adt.has_non_const_dtor(cx.tcx)
@@ -233,7 +233,7 @@ impl Qualif for CustomEq {
 
     fn in_adt_inherently<'tcx>(
         cx: &ConstCx<'_, 'tcx>,
-        adt: &'tcx AdtDef,
+        adt: AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
     ) -> bool {
         let ty = cx.tcx.mk_ty(ty::Adt(adt, substs));
diff --git a/compiler/rustc_const_eval/src/util/alignment.rs b/compiler/rustc_const_eval/src/util/alignment.rs
index e4528b68907..fe4a726fe12 100644
--- a/compiler/rustc_const_eval/src/util/alignment.rs
+++ b/compiler/rustc_const_eval/src/util/alignment.rs
@@ -55,7 +55,7 @@ where
             ProjectionElem::Field(..) => {
                 let ty = place_base.ty(local_decls, tcx).ty;
                 match ty.kind() {
-                    ty::Adt(def, _) => return def.repr.pack,
+                    ty::Adt(def, _) => return def.repr().pack,
                     _ => {}
                 }
             }
diff --git a/compiler/rustc_const_eval/src/util/call_kind.rs b/compiler/rustc_const_eval/src/util/call_kind.rs
index 11bb9508a1f..2165989b398 100644
--- a/compiler/rustc_const_eval/src/util/call_kind.rs
+++ b/compiler/rustc_const_eval/src/util/call_kind.rs
@@ -132,7 +132,7 @@ pub fn call_kind<'tcx>(
             .parent(method_did)
             .filter(|did| tcx.def_kind(*did) == rustc_hir::def::DefKind::Impl)
             .and_then(|did| match tcx.type_of(did).kind() {
-                ty::Adt(def, ..) => Some(def.did),
+                ty::Adt(def, ..) => Some(def.did()),
                 _ => None,
             });
         let is_option_or_result = parent_self_ty.map_or(false, |def_id| {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index bf4882d4595..abc25d51776 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -582,7 +582,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) =
                     (exp_found.expected.kind(), exp_found.found.kind())
                 {
-                    report_path_match(err, exp_adt.did, found_adt.did);
+                    report_path_match(err, exp_adt.did(), found_adt.did());
                 }
             }
             TypeError::Traits(ref exp_found) => {
@@ -914,7 +914,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 return Some(());
             }
             if let ty::Adt(def, _) = ta.kind() {
-                let path_ = self.tcx.def_path_str(def.did);
+                let path_ = self.tcx.def_path_str(def.did());
                 if path_ == other_path {
                     self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty);
                     return Some(());
@@ -1126,12 +1126,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         // process starts here
         match (t1.kind(), t2.kind()) {
             (&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => {
-                let sub_no_defaults_1 = self.strip_generic_default_params(def1.did, sub1);
-                let sub_no_defaults_2 = self.strip_generic_default_params(def2.did, sub2);
+                let did1 = def1.did();
+                let did2 = def2.did();
+                let sub_no_defaults_1 = self.strip_generic_default_params(did1, sub1);
+                let sub_no_defaults_2 = self.strip_generic_default_params(did2, sub2);
                 let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
-                let path1 = self.tcx.def_path_str(def1.did);
-                let path2 = self.tcx.def_path_str(def2.did);
-                if def1.did == def2.did {
+                let path1 = self.tcx.def_path_str(did1);
+                let path2 = self.tcx.def_path_str(did2);
+                if did1 == did2 {
                     // Easy case. Replace same types with `_` to shorten the output and highlight
                     // the differing ones.
                     //     let x: Foo<Bar, Qux> = y::<Foo<Quz, Qux>>();
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 16f7504cbbe..a9a92fdbd64 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -958,7 +958,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
         let t = match t.kind() {
             // We'll hide this type only if all its type params are hidden as well.
             ty::Adt(def, substs) => {
-                let generics = self.tcx().generics_of(def.did);
+                let generics = self.tcx().generics_of(def.did());
                 // Account for params with default values, like `Vec`, where we
                 // want to show `Vec<T>`, not `Vec<T, _>`. If we replaced that
                 // subst, then we'd get the incorrect output, so we passthrough.
@@ -985,7 +985,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
                 };
                 if self.level == 1 || substs.iter().any(should_keep) {
                     let substs = self.tcx().intern_substs(&substs[..]);
-                    self.tcx().mk_ty(ty::Adt(def, substs))
+                    self.tcx().mk_ty(ty::Adt(*def, substs))
                 } else {
                     self.tcx().ty_error()
                 }
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index b6b73ba4539..53ad8374349 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -658,7 +658,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id());
             let impl_ty = cx.tcx.type_of(parent);
             let outerdef = match impl_ty.kind() {
-                ty::Adt(def, _) => Some(def.did),
+                ty::Adt(def, _) => Some(def.did()),
                 ty::Foreign(def_id) => Some(*def_id),
                 _ => None,
             };
@@ -841,7 +841,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
             let mut impls = LocalDefIdSet::default();
             cx.tcx.for_each_impl(debug, |d| {
                 if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() {
-                    if let Some(def_id) = ty_def.did.as_local() {
+                    if let Some(def_id) = ty_def.did().as_local() {
                         impls.insert(def_id);
                     }
                 }
@@ -2535,9 +2535,9 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
 
         /// Test if this enum has several actually "existing" variants.
         /// Zero-sized uninhabited variants do not always have a tag assigned and thus do not "exist".
-        fn is_multi_variant(adt: &ty::AdtDef) -> bool {
+        fn is_multi_variant<'tcx>(adt: ty::AdtDef<'tcx>) -> bool {
             // As an approximation, we only count dataless variants. Those are definitely inhabited.
-            let existing_variants = adt.variants.iter().filter(|v| v.fields.is_empty()).count();
+            let existing_variants = adt.variants().iter().filter(|v| v.fields.is_empty()).count();
             existing_variants > 1
         }
 
@@ -2571,7 +2571,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
                 Adt(adt_def, substs) if !adt_def.is_union() => {
                     // First check if this ADT has a layout attribute (like `NonNull` and friends).
                     use std::ops::Bound;
-                    match tcx.layout_scalar_valid_range(adt_def.did) {
+                    match tcx.layout_scalar_valid_range(adt_def.did()) {
                         // We exploit here that `layout_scalar_valid_range` will never
                         // return `Bound::Excluded`.  (And we have tests checking that we
                         // handle the attribute correctly.)
@@ -2592,12 +2592,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
                         _ => {}
                     }
                     // Now, recurse.
-                    match adt_def.variants.len() {
+                    match adt_def.variants().len() {
                         0 => Some(("enums with no variants have no valid value".to_string(), None)),
                         1 => {
                             // Struct, or enum with exactly one variant.
                             // Proceed recursively, check all fields.
-                            let variant = &adt_def.variants[VariantIdx::from_u32(0)];
+                            let variant = &adt_def.variant(VariantIdx::from_u32(0));
                             variant.fields.iter().find_map(|field| {
                                 ty_find_init_error(tcx, field.ty(tcx, substs), init).map(
                                     |(mut msg, span)| {
@@ -2622,8 +2622,8 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
                         }
                         // Multi-variant enum.
                         _ => {
-                            if init == InitKind::Uninit && is_multi_variant(adt_def) {
-                                let span = tcx.def_span(adt_def.did);
+                            if init == InitKind::Uninit && is_multi_variant(*adt_def) {
+                                let span = tcx.def_span(adt_def.did());
                                 Some((
                                     "enums have to be initialized to a variant".to_string(),
                                     Some(span),
@@ -2819,15 +2819,15 @@ impl ClashingExternDeclarations {
                 let mut ty = ty;
                 loop {
                     if let ty::Adt(def, substs) = *ty.kind() {
-                        let is_transparent = def.subst(tcx, substs).repr.transparent();
-                        let is_non_null = crate::types::nonnull_optimization_guaranteed(tcx, &def);
+                        let is_transparent = def.subst(tcx, substs).repr().transparent();
+                        let is_non_null = crate::types::nonnull_optimization_guaranteed(tcx, def);
                         debug!(
                             "non_transparent_ty({:?}) -- type is transparent? {}, type is non-null? {}",
                             ty, is_transparent, is_non_null
                         );
                         if is_transparent && !is_non_null {
-                            debug_assert!(def.variants.len() == 1);
-                            let v = &def.variants[VariantIdx::new(0)];
+                            debug_assert!(def.variants().len() == 1);
+                            let v = &def.variant(VariantIdx::new(0));
                             ty = transparent_newtype_field(tcx, v)
                                 .expect(
                                     "single-variant transparent structure with zero-sized field",
@@ -2892,8 +2892,8 @@ impl ClashingExternDeclarations {
                             }
 
                             // Grab a flattened representation of all fields.
-                            let a_fields = a_def.variants.iter().flat_map(|v| v.fields.iter());
-                            let b_fields = b_def.variants.iter().flat_map(|v| v.fields.iter());
+                            let a_fields = a_def.variants().iter().flat_map(|v| v.fields.iter());
+                            let b_fields = b_def.variants().iter().flat_map(|v| v.fields.iter());
 
                             // Perform a structural comparison for each field.
                             a_fields.eq_by(
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index b892e520d3b..d3c019ad70e 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -1050,7 +1050,7 @@ impl<'tcx> LateContext<'tcx> {
             ) -> Result<Self::Path, Self::Error> {
                 if trait_ref.is_none() {
                     if let ty::Adt(def, substs) = self_ty.kind() {
-                        return self.print_def_path(def.did, substs);
+                        return self.print_def_path(def.did(), substs);
                     }
                 }
 
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 5078c240ec7..27d44da6dfc 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -202,7 +202,7 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, ty: &Ty<'_>) -> Option<String> {
             Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => {
                 if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
                     if let Some(name @ (sym::Ty | sym::TyCtxt)) =
-                        cx.tcx.get_diagnostic_name(adt.did)
+                        cx.tcx.get_diagnostic_name(adt.did())
                     {
                         // NOTE: This path is currently unreachable as `Ty<'tcx>` is
                         // defined as a type alias meaning that `impl<'tcx> Ty<'tcx>`
diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs
index ae936834754..b6a45676a30 100644
--- a/compiler/rustc_lint/src/methods.rs
+++ b/compiler/rustc_lint/src/methods.rs
@@ -84,9 +84,9 @@ fn lint_cstring_as_ptr(
 ) {
     let source_type = cx.typeck_results().expr_ty(source);
     if let ty::Adt(def, substs) = source_type.kind() {
-        if cx.tcx.is_diagnostic_item(sym::Result, def.did) {
+        if cx.tcx.is_diagnostic_item(sym::Result, def.did()) {
             if let ty::Adt(adt, _) = substs.type_at(0).kind() {
-                if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did) {
+                if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did()) {
                     cx.struct_span_lint(TEMPORARY_CSTRING_AS_PTR, as_ptr_span, |diag| {
                         let mut diag = diag
                             .build("getting the inner pointer of a temporary `CString`");
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index 3130d57c2a9..f21f25c3584 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -149,7 +149,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
                 ty::Ref(_, r, _) if *r.kind() == ty::Str,
             ) || matches!(
                 ty.ty_adt_def(),
-                Some(ty_def) if cx.tcx.is_diagnostic_item(sym::String, ty_def.did),
+                Some(ty_def) if cx.tcx.is_diagnostic_item(sym::String, ty_def.did()),
             );
 
             let (suggest_display, suggest_debug) = cx.tcx.infer_ctxt().enter(|infcx| {
diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs
index c47fdc063a9..2c8b41d7214 100644
--- a/compiler/rustc_lint/src/pass_by_value.rs
+++ b/compiler/rustc_lint/src/pass_by_value.rs
@@ -57,8 +57,8 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<Stri
             }
             Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => {
                 if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
-                    if cx.tcx.has_attr(adt.did, sym::rustc_pass_by_value) {
-                        return Some(cx.tcx.def_path_str_with_substs(adt.did, substs));
+                    if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) {
+                        return Some(cx.tcx.def_path_str_with_substs(adt.did(), substs));
                     }
                 }
             }
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index d4dac640cc7..ed5578c754d 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -667,8 +667,8 @@ enum FfiResult<'tcx> {
     FfiUnsafe { ty: Ty<'tcx>, reason: String, help: Option<String> },
 }
 
-crate fn nonnull_optimization_guaranteed<'tcx>(tcx: TyCtxt<'tcx>, def: &ty::AdtDef) -> bool {
-    tcx.get_attrs(def.did).iter().any(|a| a.has_name(sym::rustc_nonnull_optimization_guaranteed))
+crate fn nonnull_optimization_guaranteed<'tcx>(tcx: TyCtxt<'tcx>, def: ty::AdtDef<'tcx>) -> bool {
+    tcx.get_attrs(def.did()).iter().any(|a| a.has_name(sym::rustc_nonnull_optimization_guaranteed))
 }
 
 /// `repr(transparent)` structs can have a single non-ZST field, this function returns that
@@ -692,8 +692,8 @@ fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKi
         ty::FnPtr(_) => true,
         ty::Ref(..) => true,
         ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true,
-        ty::Adt(def, substs) if def.repr.transparent() && !def.is_union() => {
-            let marked_non_null = nonnull_optimization_guaranteed(tcx, &def);
+        ty::Adt(def, substs) if def.repr().transparent() && !def.is_union() => {
+            let marked_non_null = nonnull_optimization_guaranteed(tcx, *def);
 
             if marked_non_null {
                 return true;
@@ -701,11 +701,11 @@ fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKi
 
             // Types with a `#[repr(no_niche)]` attribute have their niche hidden.
             // The attribute is used by the UnsafeCell for example (the only use so far).
-            if def.repr.hide_niche() {
+            if def.repr().hide_niche() {
                 return false;
             }
 
-            def.variants
+            def.variants()
                 .iter()
                 .filter_map(|variant| transparent_newtype_field(cx.tcx, variant))
                 .any(|field| ty_is_known_nonnull(cx, field.ty(tcx, substs), mode))
@@ -721,8 +721,10 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
     Some(match *ty.kind() {
         ty::Adt(field_def, field_substs) => {
             let inner_field_ty = {
-                let first_non_zst_ty =
-                    field_def.variants.iter().filter_map(|v| transparent_newtype_field(cx.tcx, v));
+                let first_non_zst_ty = field_def
+                    .variants()
+                    .iter()
+                    .filter_map(|v| transparent_newtype_field(cx.tcx, v));
                 debug_assert_eq!(
                     first_non_zst_ty.clone().count(),
                     1,
@@ -771,7 +773,7 @@ crate fn repr_nullable_ptr<'tcx>(
 ) -> Option<Ty<'tcx>> {
     debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty);
     if let ty::Adt(ty_def, substs) = ty.kind() {
-        let field_ty = match &ty_def.variants.raw[..] {
+        let field_ty = match &ty_def.variants().raw[..] {
             [var_one, var_two] => match (&var_one.fields[..], &var_two.fields[..]) {
                 ([], [field]) | ([field], []) => field.ty(cx.tcx, substs),
                 _ => return None,
@@ -845,13 +847,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         &self,
         cache: &mut FxHashSet<Ty<'tcx>>,
         ty: Ty<'tcx>,
-        def: &ty::AdtDef,
+        def: ty::AdtDef<'tcx>,
         variant: &ty::VariantDef,
         substs: SubstsRef<'tcx>,
     ) -> FfiResult<'tcx> {
         use FfiResult::*;
 
-        if def.repr.transparent() {
+        if def.repr().transparent() {
             // Can assume that at most one field is not a ZST, so only check
             // that field's type for FFI-safety.
             if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
@@ -925,7 +927,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                     AdtKind::Struct | AdtKind::Union => {
                         let kind = if def.is_struct() { "struct" } else { "union" };
 
-                        if !def.repr.c() && !def.repr.transparent() {
+                        if !def.repr().c() && !def.repr().transparent() {
                             return FfiUnsafe {
                                 ty,
                                 reason: format!("this {} has unspecified layout", kind),
@@ -939,7 +941,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
                         let is_non_exhaustive =
                             def.non_enum_variant().is_field_list_non_exhaustive();
-                        if is_non_exhaustive && !def.did.is_local() {
+                        if is_non_exhaustive && !def.did().is_local() {
                             return FfiUnsafe {
                                 ty,
                                 reason: format!("this {} is non-exhaustive", kind),
@@ -958,14 +960,15 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                         self.check_variant_for_ffi(cache, ty, def, def.non_enum_variant(), substs)
                     }
                     AdtKind::Enum => {
-                        if def.variants.is_empty() {
+                        if def.variants().is_empty() {
                             // Empty enums are okay... although sort of useless.
                             return FfiSafe;
                         }
 
                         // Check for a repr() attribute to specify the size of the
                         // discriminant.
-                        if !def.repr.c() && !def.repr.transparent() && def.repr.int.is_none() {
+                        if !def.repr().c() && !def.repr().transparent() && def.repr().int.is_none()
+                        {
                             // Special-case types like `Option<extern fn()>`.
                             if repr_nullable_ptr(self.cx, ty, self.mode).is_none() {
                                 return FfiUnsafe {
@@ -981,7 +984,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                             }
                         }
 
-                        if def.is_variant_list_non_exhaustive() && !def.did.is_local() {
+                        if def.is_variant_list_non_exhaustive() && !def.did().is_local() {
                             return FfiUnsafe {
                                 ty,
                                 reason: "this enum is non-exhaustive".into(),
@@ -990,7 +993,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                         }
 
                         // Check the contained variants.
-                        for variant in &def.variants {
+                        for variant in def.variants() {
                             let is_non_exhaustive = variant.is_field_list_non_exhaustive();
                             if is_non_exhaustive && !variant.def_id.is_local() {
                                 return FfiUnsafe {
@@ -1161,7 +1164,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             }
             diag.note(note);
             if let ty::Adt(def, _) = ty.kind() {
-                if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did) {
+                if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did()) {
                     diag.span_note(sp, "the type is defined here");
                 }
             }
@@ -1464,9 +1467,9 @@ impl InvalidAtomicOrdering {
             && let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def()
             // skip extension traits, only lint functions from the standard library
             && cx.tcx.trait_id_of_impl(impl_did).is_none()
-            && let Some(parent) = cx.tcx.parent(adt.did)
+            && let Some(parent) = cx.tcx.parent(adt.did())
             && cx.tcx.is_diagnostic_item(sym::atomic_mod, parent)
-            && ATOMIC_TYPES.contains(&cx.tcx.item_name(adt.did))
+            && ATOMIC_TYPES.contains(&cx.tcx.item_name(adt.did()))
         {
             return Some((method_path.ident.name, args));
         }
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 16d222f68a3..abe34a8a39f 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -202,7 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
                     let descr_pre = &format!("{}boxed ", descr_pre);
                     check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len)
                 }
-                ty::Adt(def, _) => check_must_use_def(cx, def.did, span, descr_pre, descr_post),
+                ty::Adt(def, _) => check_must_use_def(cx, def.did(), span, descr_pre, descr_post),
                 ty::Opaque(def, _) => {
                     let mut has_emitted = false;
                     for &(predicate, _) in cx.tcx.explicit_item_bounds(def) {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index e5e0cce198f..2e6ce7b7040 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -979,7 +979,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         )
     }
 
-    fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef {
+    fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> {
         let kind = self.kind(item_id);
         let did = self.local_def_id(item_id);
 
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 06f73c1c916..924e5f92103 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1029,9 +1029,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
     }
 
-    fn encode_enum_variant_info(&mut self, def: &ty::AdtDef, index: VariantIdx) {
+    fn encode_enum_variant_info(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
         let tcx = self.tcx;
-        let variant = &def.variants[index];
+        let variant = &def.variant(index);
         let def_id = variant.def_id;
         debug!("EncodeContext::encode_enum_variant_info({:?})", def_id);
 
@@ -1057,9 +1057,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         }
     }
 
-    fn encode_enum_variant_ctor(&mut self, def: &ty::AdtDef, index: VariantIdx) {
+    fn encode_enum_variant_ctor(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
         let tcx = self.tcx;
-        let variant = &def.variants[index];
+        let variant = &def.variant(index);
         let def_id = variant.ctor_def_id.unwrap();
         debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
 
@@ -1122,11 +1122,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
     fn encode_field(
         &mut self,
-        adt_def: &ty::AdtDef,
+        adt_def: ty::AdtDef<'tcx>,
         variant_index: VariantIdx,
         field_index: usize,
     ) {
-        let variant = &adt_def.variants[variant_index];
+        let variant = &adt_def.variant(variant_index);
         let field = &variant.fields[field_index];
 
         let def_id = field.did;
@@ -1137,7 +1137,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         self.encode_item_type(def_id);
     }
 
-    fn encode_struct_ctor(&mut self, adt_def: &ty::AdtDef, def_id: DefId) {
+    fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>, def_id: DefId) {
         debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
         let tcx = self.tcx;
         let variant = adt_def.non_enum_variant();
@@ -1149,7 +1149,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             is_non_exhaustive: variant.is_field_list_non_exhaustive(),
         };
 
-        record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr));
+        record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr()));
         self.encode_item_type(def_id);
         if variant.ctor_kind == CtorKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
@@ -1414,7 +1414,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 self.encode_explicit_item_bounds(def_id);
                 EntryKind::OpaqueTy
             }
-            hir::ItemKind::Enum(..) => EntryKind::Enum(self.tcx.adt_def(def_id).repr),
+            hir::ItemKind::Enum(..) => EntryKind::Enum(self.tcx.adt_def(def_id).repr()),
             hir::ItemKind::Struct(ref struct_def, _) => {
                 let adt_def = self.tcx.adt_def(def_id);
                 let variant = adt_def.non_enum_variant();
@@ -1433,7 +1433,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                         ctor,
                         is_non_exhaustive: variant.is_field_list_non_exhaustive(),
                     }),
-                    adt_def.repr,
+                    adt_def.repr(),
                 )
             }
             hir::ItemKind::Union(..) => {
@@ -1447,7 +1447,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                         ctor: None,
                         is_non_exhaustive: variant.is_field_list_non_exhaustive(),
                     }),
-                    adt_def.repr,
+                    adt_def.repr(),
                 )
             }
             hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
@@ -1500,7 +1500,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         // FIXME(eddyb) there should be a nicer way to do this.
         match item.kind {
             hir::ItemKind::Enum(..) => record!(self.tables.children[def_id] <-
-                self.tcx.adt_def(def_id).variants.iter().map(|v| {
+                self.tcx.adt_def(def_id).variants().iter().map(|v| {
                     assert!(v.def_id.is_local());
                     v.def_id.index
                 })
@@ -1926,8 +1926,8 @@ impl<'a, 'tcx> Visitor<'tcx> for EncodeContext<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
-    fn encode_fields(&mut self, adt_def: &ty::AdtDef) {
-        for (variant_index, variant) in adt_def.variants.iter_enumerated() {
+    fn encode_fields(&mut self, adt_def: ty::AdtDef<'tcx>) {
+        for (variant_index, variant) in adt_def.variants().iter_enumerated() {
             for (field_index, _field) in variant.fields.iter().enumerate() {
                 self.encode_field(adt_def, variant_index, field_index);
             }
@@ -1991,7 +1991,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 let def = self.tcx.adt_def(item.def_id.to_def_id());
                 self.encode_fields(def);
 
-                for (i, variant) in def.variants.iter_enumerated() {
+                for (i, variant) in def.variants().iter_enumerated() {
                     self.encode_enum_variant_info(def, i);
 
                     if let Some(_ctor_def_id) = variant.ctor_def_id {
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index 825dc79129d..f6d8fc5b81f 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -9,7 +9,7 @@ macro_rules! arena_types {
             [] layout: rustc_target::abi::LayoutS<'tcx>,
             [] fn_abi: rustc_target::abi::call::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>,
             // AdtDef are interned and compared by address
-            [decode] adt_def: rustc_middle::ty::AdtDef,
+            [decode] adt_def: rustc_middle::ty::AdtDefData,
             [] steal_thir: rustc_data_structures::steal::Steal<rustc_middle::thir::Thir<'tcx>>,
             [] steal_mir: rustc_data_structures::steal::Steal<rustc_middle::mir::Body<'tcx>>,
             [decode] mir: rustc_middle::mir::Body<'tcx>,
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 39d6b1267a5..31f12407fad 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2425,7 +2425,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
 
                     AggregateKind::Adt(adt_did, variant, substs, _user_ty, _) => {
                         ty::tls::with(|tcx| {
-                            let variant_def = &tcx.adt_def(adt_did).variants[variant];
+                            let variant_def = &tcx.adt_def(adt_did).variant(variant);
                             let substs = tcx.lift(substs).expect("could not lift for printing");
                             let name = FmtPrinter::new(tcx, Namespace::ValueNS)
                                 .print_def_path(variant_def.def_id, substs)?
@@ -2753,7 +2753,7 @@ impl<'tcx> UserTypeProjections {
         self.map_projections(|pat_ty_proj| pat_ty_proj.leaf(field))
     }
 
-    pub fn variant(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx, field: Field) -> Self {
+    pub fn variant(self, adt_def: AdtDef<'tcx>, variant_index: VariantIdx, field: Field) -> Self {
         self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field))
     }
 }
@@ -2804,12 +2804,12 @@ impl UserTypeProjection {
 
     pub(crate) fn variant(
         mut self,
-        adt_def: &AdtDef,
+        adt_def: AdtDef<'_>,
         variant_index: VariantIdx,
         field: Field,
     ) -> Self {
         self.projs.push(ProjectionElem::Downcast(
-            Some(adt_def.variants[variant_index].name),
+            Some(adt_def.variant(variant_index).name),
             variant_index,
         ));
         self.projs.push(ProjectionElem::Field(field, ()));
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 6f85854fc74..51d8113840a 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -40,7 +40,7 @@ impl<'tcx> PlaceTy<'tcx> {
                     None => adt_def.non_enum_variant(),
                     Some(variant_index) => {
                         assert!(adt_def.is_enum());
-                        &adt_def.variants[variant_index]
+                        &adt_def.variant(variant_index)
                     }
                 };
                 let field_def = &variant_def.fields[f.index()];
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 6b572690e21..2acfede87ae 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -523,7 +523,7 @@ rustc_queries! {
         storage(ArenaCacheSelector<'tcx>)
         separate_provide_extern
     }
-    query adt_def(key: DefId) -> &'tcx ty::AdtDef {
+    query adt_def(key: DefId) -> ty::AdtDef<'tcx> {
         desc { |tcx| "computing ADT definition for `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 04bc0c8b521..785d3ee7709 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -128,7 +128,7 @@ pub struct Block {
 #[derive(Debug, HashStable)]
 pub struct Adt<'tcx> {
     /// The ADT we're constructing.
-    pub adt_def: &'tcx AdtDef,
+    pub adt_def: AdtDef<'tcx>,
     /// The variant of the ADT.
     pub variant_index: VariantIdx,
     pub substs: SubstsRef<'tcx>,
@@ -617,7 +617,7 @@ pub enum PatKind<'tcx> {
     /// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with
     /// multiple variants.
     Variant {
-        adt_def: &'tcx AdtDef,
+        adt_def: AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
         variant_index: VariantIdx,
         subpatterns: Vec<FieldPat<'tcx>>,
@@ -714,7 +714,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
             PatKind::Variant { ref subpatterns, .. } | PatKind::Leaf { ref subpatterns } => {
                 let variant = match *self.kind {
                     PatKind::Variant { adt_def, variant_index, .. } => {
-                        Some(&adt_def.variants[variant_index])
+                        Some(adt_def.variant(variant_index))
                     }
                     _ => self.ty.ty_adt_def().and_then(|adt| {
                         if !adt.is_enum() { Some(adt.non_enum_variant()) } else { None }
diff --git a/compiler/rustc_middle/src/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs
index 09a28249cce..015bdb5783f 100644
--- a/compiler/rustc_middle/src/traits/chalk.rs
+++ b/compiler/rustc_middle/src/traits/chalk.rs
@@ -75,7 +75,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
     type InternedVariances = Vec<chalk_ir::Variance>;
     type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
     type DefId = DefId;
-    type InternedAdtId = &'tcx AdtDef;
+    type InternedAdtId = AdtDef<'tcx>;
     type Identifier = ();
     type FnAbi = Abi;
 
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index d5a8f586361..cad77f6436e 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -4,6 +4,7 @@ use crate::ty::util::{Discr, IntTypeExt};
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::intern::Interned;
 use rustc_data_structures::stable_hasher::HashingControls;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_errors::ErrorGuaranteed;
@@ -89,62 +90,62 @@ bitflags! {
 /// where `x` here represents the `DefId` of `S.x`. Then, the `DefId`
 /// can be used with [`TyCtxt::type_of()`] to get the type of the field.
 #[derive(TyEncodable, TyDecodable)]
-pub struct AdtDef {
+pub struct AdtDefData {
     /// The `DefId` of the struct, enum or union item.
     pub did: DefId,
     /// Variants of the ADT. If this is a struct or union, then there will be a single variant.
-    pub variants: IndexVec<VariantIdx, VariantDef>,
+    variants: IndexVec<VariantIdx, VariantDef>,
     /// Flags of the ADT (e.g., is this a struct? is this non-exhaustive?).
     flags: AdtFlags,
     /// Repr options provided by the user.
-    pub repr: ReprOptions,
+    repr: ReprOptions,
 }
 
-impl PartialOrd for AdtDef {
-    fn partial_cmp(&self, other: &AdtDef) -> Option<Ordering> {
+impl PartialOrd for AdtDefData {
+    fn partial_cmp(&self, other: &AdtDefData) -> Option<Ordering> {
         Some(self.cmp(&other))
     }
 }
 
 /// There should be only one AdtDef for each `did`, therefore
 /// it is fine to implement `Ord` only based on `did`.
-impl Ord for AdtDef {
-    fn cmp(&self, other: &AdtDef) -> Ordering {
+impl Ord for AdtDefData {
+    fn cmp(&self, other: &AdtDefData) -> Ordering {
         self.did.cmp(&other.did)
     }
 }
 
 /// There should be only one AdtDef for each `did`, therefore
 /// it is fine to implement `PartialEq` only based on `did`.
-impl PartialEq for AdtDef {
+impl PartialEq for AdtDefData {
     #[inline]
     fn eq(&self, other: &Self) -> bool {
         self.did == other.did
     }
 }
 
-impl Eq for AdtDef {}
+impl Eq for AdtDefData {}
 
 /// There should be only one AdtDef for each `did`, therefore
 /// it is fine to implement `Hash` only based on `did`.
-impl Hash for AdtDef {
+impl Hash for AdtDefData {
     #[inline]
     fn hash<H: Hasher>(&self, s: &mut H) {
         self.did.hash(s)
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for AdtDef {
+impl<'a> HashStable<StableHashingContext<'a>> for AdtDefData {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         thread_local! {
             static CACHE: RefCell<FxHashMap<(usize, HashingControls), Fingerprint>> = Default::default();
         }
 
         let hash: Fingerprint = CACHE.with(|cache| {
-            let addr = self as *const AdtDef as usize;
+            let addr = self as *const AdtDefData as usize;
             let hashing_controls = hcx.hashing_controls();
             *cache.borrow_mut().entry((addr, hashing_controls)).or_insert_with(|| {
-                let ty::AdtDef { did, ref variants, ref flags, ref repr } = *self;
+                let ty::AdtDefData { did, ref variants, ref flags, ref repr } = *self;
 
                 let mut hasher = StableHasher::new();
                 did.hash_stable(hcx, &mut hasher);
@@ -160,6 +161,32 @@ impl<'a> HashStable<StableHashingContext<'a>> for AdtDef {
     }
 }
 
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)]
+#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
+pub struct AdtDef<'tcx>(pub Interned<'tcx, AdtDefData>);
+
+impl<'tcx> AdtDef<'tcx> {
+    pub fn did(self) -> DefId {
+        self.0.0.did
+    }
+
+    pub fn variants(self) -> &'tcx IndexVec<VariantIdx, VariantDef> {
+        &self.0.0.variants
+    }
+
+    pub fn variant(self, idx: VariantIdx) -> &'tcx VariantDef {
+        &self.0.0.variants[idx]
+    }
+
+    pub fn flags(self) -> AdtFlags {
+        self.0.0.flags
+    }
+
+    pub fn repr(self) -> ReprOptions {
+        self.0.0.repr
+    }
+}
+
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, TyEncodable, TyDecodable)]
 pub enum AdtKind {
     Struct,
@@ -177,8 +204,8 @@ impl Into<DataTypeKind> for AdtKind {
     }
 }
 
-impl<'tcx> AdtDef {
-    /// Creates a new `AdtDef`.
+impl AdtDefData {
+    /// Creates a new `AdtDefData`.
     pub(super) fn new(
         tcx: TyCtxt<'_>,
         did: DefId,
@@ -218,36 +245,38 @@ impl<'tcx> AdtDef {
             flags |= AdtFlags::IS_MANUALLY_DROP;
         }
 
-        AdtDef { did, variants, flags, repr }
+        AdtDefData { did, variants, flags, repr }
     }
+}
 
+impl<'tcx> AdtDef<'tcx> {
     /// Returns `true` if this is a struct.
     #[inline]
-    pub fn is_struct(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_STRUCT)
+    pub fn is_struct(self) -> bool {
+        self.flags().contains(AdtFlags::IS_STRUCT)
     }
 
     /// Returns `true` if this is a union.
     #[inline]
-    pub fn is_union(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_UNION)
+    pub fn is_union(self) -> bool {
+        self.flags().contains(AdtFlags::IS_UNION)
     }
 
     /// Returns `true` if this is an enum.
     #[inline]
-    pub fn is_enum(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_ENUM)
+    pub fn is_enum(self) -> bool {
+        self.flags().contains(AdtFlags::IS_ENUM)
     }
 
     /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`.
     #[inline]
-    pub fn is_variant_list_non_exhaustive(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
+    pub fn is_variant_list_non_exhaustive(self) -> bool {
+        self.flags().contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
     }
 
     /// Returns the kind of the ADT.
     #[inline]
-    pub fn adt_kind(&self) -> AdtKind {
+    pub fn adt_kind(self) -> AdtKind {
         if self.is_enum() {
             AdtKind::Enum
         } else if self.is_union() {
@@ -258,7 +287,7 @@ impl<'tcx> AdtDef {
     }
 
     /// Returns a description of this abstract data type.
-    pub fn descr(&self) -> &'static str {
+    pub fn descr(self) -> &'static str {
         match self.adt_kind() {
             AdtKind::Struct => "struct",
             AdtKind::Union => "union",
@@ -268,7 +297,7 @@ impl<'tcx> AdtDef {
 
     /// Returns a description of a variant of this abstract data type.
     #[inline]
-    pub fn variant_descr(&self) -> &'static str {
+    pub fn variant_descr(self) -> &'static str {
         match self.adt_kind() {
             AdtKind::Struct => "struct",
             AdtKind::Union => "union",
@@ -278,65 +307,65 @@ impl<'tcx> AdtDef {
 
     /// If this function returns `true`, it implies that `is_struct` must return `true`.
     #[inline]
-    pub fn has_ctor(&self) -> bool {
-        self.flags.contains(AdtFlags::HAS_CTOR)
+    pub fn has_ctor(self) -> bool {
+        self.flags().contains(AdtFlags::HAS_CTOR)
     }
 
     /// Returns `true` if this type is `#[fundamental]` for the purposes
     /// of coherence checking.
     #[inline]
-    pub fn is_fundamental(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_FUNDAMENTAL)
+    pub fn is_fundamental(self) -> bool {
+        self.flags().contains(AdtFlags::IS_FUNDAMENTAL)
     }
 
     /// Returns `true` if this is `PhantomData<T>`.
     #[inline]
-    pub fn is_phantom_data(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_PHANTOM_DATA)
+    pub fn is_phantom_data(self) -> bool {
+        self.flags().contains(AdtFlags::IS_PHANTOM_DATA)
     }
 
     /// Returns `true` if this is Box<T>.
     #[inline]
-    pub fn is_box(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_BOX)
+    pub fn is_box(self) -> bool {
+        self.flags().contains(AdtFlags::IS_BOX)
     }
 
     /// Returns `true` if this is `ManuallyDrop<T>`.
     #[inline]
-    pub fn is_manually_drop(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_MANUALLY_DROP)
+    pub fn is_manually_drop(self) -> bool {
+        self.flags().contains(AdtFlags::IS_MANUALLY_DROP)
     }
 
     /// Returns `true` if this type has a destructor.
-    pub fn has_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
+    pub fn has_dtor(self, tcx: TyCtxt<'tcx>) -> bool {
         self.destructor(tcx).is_some()
     }
 
-    pub fn has_non_const_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
+    pub fn has_non_const_dtor(self, tcx: TyCtxt<'tcx>) -> bool {
         matches!(self.destructor(tcx), Some(Destructor { constness: hir::Constness::NotConst, .. }))
     }
 
     /// Asserts this is a struct or union and returns its unique variant.
-    pub fn non_enum_variant(&self) -> &VariantDef {
+    pub fn non_enum_variant(self) -> &'tcx VariantDef {
         assert!(self.is_struct() || self.is_union());
-        &self.variants[VariantIdx::new(0)]
+        &self.variant(VariantIdx::new(0))
     }
 
     #[inline]
-    pub fn predicates(&self, tcx: TyCtxt<'tcx>) -> GenericPredicates<'tcx> {
-        tcx.predicates_of(self.did)
+    pub fn predicates(self, tcx: TyCtxt<'tcx>) -> GenericPredicates<'tcx> {
+        tcx.predicates_of(self.did())
     }
 
     /// Returns an iterator over all fields contained
     /// by this ADT.
     #[inline]
-    pub fn all_fields(&self) -> impl Iterator<Item = &FieldDef> + Clone {
-        self.variants.iter().flat_map(|v| v.fields.iter())
+    pub fn all_fields(self) -> impl Iterator<Item = &'tcx FieldDef> + Clone {
+        self.variants().iter().flat_map(|v| v.fields.iter())
     }
 
     /// Whether the ADT lacks fields. Note that this includes uninhabited enums,
     /// e.g., `enum Void {}` is considered payload free as well.
-    pub fn is_payloadfree(&self) -> bool {
+    pub fn is_payloadfree(self) -> bool {
         // Treat the ADT as not payload-free if arbitrary_enum_discriminant is used (#88621).
         // This would disallow the following kind of enum from being casted into integer.
         // ```
@@ -347,31 +376,31 @@ impl<'tcx> AdtDef {
         // }
         // ```
         if self
-            .variants
+            .variants()
             .iter()
             .any(|v| matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind != CtorKind::Const)
         {
             return false;
         }
-        self.variants.iter().all(|v| v.fields.is_empty())
+        self.variants().iter().all(|v| v.fields.is_empty())
     }
 
     /// Return a `VariantDef` given a variant id.
-    pub fn variant_with_id(&self, vid: DefId) -> &VariantDef {
-        self.variants.iter().find(|v| v.def_id == vid).expect("variant_with_id: unknown variant")
+    pub fn variant_with_id(self, vid: DefId) -> &'tcx VariantDef {
+        self.variants().iter().find(|v| v.def_id == vid).expect("variant_with_id: unknown variant")
     }
 
     /// Return a `VariantDef` given a constructor id.
-    pub fn variant_with_ctor_id(&self, cid: DefId) -> &VariantDef {
-        self.variants
+    pub fn variant_with_ctor_id(self, cid: DefId) -> &'tcx VariantDef {
+        self.variants()
             .iter()
             .find(|v| v.ctor_def_id == Some(cid))
             .expect("variant_with_ctor_id: unknown variant")
     }
 
     /// Return the index of `VariantDef` given a variant id.
-    pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx {
-        self.variants
+    pub fn variant_index_with_id(self, vid: DefId) -> VariantIdx {
+        self.variants()
             .iter_enumerated()
             .find(|(_, v)| v.def_id == vid)
             .expect("variant_index_with_id: unknown variant")
@@ -379,15 +408,15 @@ impl<'tcx> AdtDef {
     }
 
     /// Return the index of `VariantDef` given a constructor id.
-    pub fn variant_index_with_ctor_id(&self, cid: DefId) -> VariantIdx {
-        self.variants
+    pub fn variant_index_with_ctor_id(self, cid: DefId) -> VariantIdx {
+        self.variants()
             .iter_enumerated()
             .find(|(_, v)| v.ctor_def_id == Some(cid))
             .expect("variant_index_with_ctor_id: unknown variant")
             .0
     }
 
-    pub fn variant_of_res(&self, res: Res) -> &VariantDef {
+    pub fn variant_of_res(self, res: Res) -> &'tcx VariantDef {
         match res {
             Res::Def(DefKind::Variant, vid) => self.variant_with_id(vid),
             Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
@@ -402,10 +431,10 @@ impl<'tcx> AdtDef {
     }
 
     #[inline]
-    pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
+    pub fn eval_explicit_discr(self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
         assert!(self.is_enum());
         let param_env = tcx.param_env(expr_did);
-        let repr_type = self.repr.discr_type();
+        let repr_type = self.repr().discr_type();
         match tcx.const_eval_poly(expr_did) {
             Ok(val) => {
                 let ty = repr_type.to_ty(tcx);
@@ -437,14 +466,14 @@ impl<'tcx> AdtDef {
 
     #[inline]
     pub fn discriminants(
-        &'tcx self,
+        self,
         tcx: TyCtxt<'tcx>,
     ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
         assert!(self.is_enum());
-        let repr_type = self.repr.discr_type();
+        let repr_type = self.repr().discr_type();
         let initial = repr_type.initial_discriminant(tcx);
         let mut prev_discr = None::<Discr<'tcx>>;
-        self.variants.iter_enumerated().map(move |(i, v)| {
+        self.variants().iter_enumerated().map(move |(i, v)| {
             let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
             if let VariantDiscr::Explicit(expr_did) = v.discr {
                 if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
@@ -458,8 +487,8 @@ impl<'tcx> AdtDef {
     }
 
     #[inline]
-    pub fn variant_range(&self) -> Range<VariantIdx> {
-        VariantIdx::new(0)..VariantIdx::new(self.variants.len())
+    pub fn variant_range(self) -> Range<VariantIdx> {
+        VariantIdx::new(0)..VariantIdx::new(self.variants().len())
     }
 
     /// Computes the discriminant value used by a specific variant.
@@ -469,7 +498,7 @@ impl<'tcx> AdtDef {
     /// assuming there are no constant-evaluation errors there.
     #[inline]
     pub fn discriminant_for_variant(
-        &self,
+        self,
         tcx: TyCtxt<'tcx>,
         variant_index: VariantIdx,
     ) -> Discr<'tcx> {
@@ -477,19 +506,19 @@ impl<'tcx> AdtDef {
         let (val, offset) = self.discriminant_def_for_variant(variant_index);
         let explicit_value = val
             .and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did))
-            .unwrap_or_else(|| self.repr.discr_type().initial_discriminant(tcx));
+            .unwrap_or_else(|| self.repr().discr_type().initial_discriminant(tcx));
         explicit_value.checked_add(tcx, offset as u128).0
     }
 
     /// Yields a `DefId` for the discriminant and an offset to add to it
     /// Alternatively, if there is no explicit discriminant, returns the
     /// inferred discriminant directly.
-    pub fn discriminant_def_for_variant(&self, variant_index: VariantIdx) -> (Option<DefId>, u32) {
-        assert!(!self.variants.is_empty());
+    pub fn discriminant_def_for_variant(self, variant_index: VariantIdx) -> (Option<DefId>, u32) {
+        assert!(!self.variants().is_empty());
         let mut explicit_index = variant_index.as_u32();
         let expr_did;
         loop {
-            match self.variants[VariantIdx::from_u32(explicit_index)].discr {
+            match self.variant(VariantIdx::from_u32(explicit_index)).discr {
                 ty::VariantDiscr::Relative(0) => {
                     expr_did = None;
                     break;
@@ -506,8 +535,8 @@ impl<'tcx> AdtDef {
         (expr_did, variant_index.as_u32() - explicit_index)
     }
 
-    pub fn destructor(&self, tcx: TyCtxt<'tcx>) -> Option<Destructor> {
-        tcx.adt_destructor(self.did)
+    pub fn destructor(self, tcx: TyCtxt<'tcx>) -> Option<Destructor> {
+        tcx.adt_destructor(self.did())
     }
 
     /// Returns a list of types such that `Self: Sized` if and only
@@ -520,7 +549,7 @@ impl<'tcx> AdtDef {
     ///
     /// Due to normalization being eager, this applies even if
     /// the associated type is behind a pointer (e.g., issue #31299).
-    pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] {
-        tcx.adt_sized_constraint(self.did).0
+    pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] {
+        tcx.adt_sized_constraint(self.did()).0
     }
 }
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index 8ba6c1f67c9..47a1712cad5 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -164,7 +164,7 @@ impl<'tcx> CapturedPlace<'tcx> {
                         write!(
                             &mut symbol,
                             "__{}",
-                            def.variants[variant].fields[idx as usize].name.as_str(),
+                            def.variant(variant).fields[idx as usize].name.as_str(),
                         )
                         .unwrap();
                     }
@@ -330,7 +330,7 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc
                     curr_string = format!(
                         "{}.{}",
                         curr_string,
-                        def.variants[variant].fields[idx as usize].name.as_str()
+                        def.variant(variant).fields[idx as usize].name.as_str()
                     );
                 }
                 ty::Tuple(_) => {
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 69455951c57..7fcc46cc7c2 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -15,7 +15,7 @@ use crate::mir::{
 use crate::thir;
 use crate::traits;
 use crate::ty::subst::SubstsRef;
-use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::{self, AdtDef, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_span::Span;
@@ -156,6 +156,12 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ConstAllocation<'tcx> {
     }
 }
 
+impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AdtDef<'tcx> {
+    fn encode(&self, e: &mut E) -> Result<(), E::Error> {
+        self.0.0.encode(e)
+    }
+}
+
 impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
         e.encode_alloc_id(self)
@@ -178,8 +184,7 @@ encodable_via_deref! {
     &'tcx mir::Body<'tcx>,
     &'tcx mir::UnsafetyCheckResult,
     &'tcx mir::BorrowCheckResult<'tcx>,
-    &'tcx mir::coverage::CodeRegion,
-    &'tcx ty::AdtDef
+    &'tcx mir::coverage::CodeRegion
 }
 
 pub trait TyDecoder<'tcx>: Decoder {
@@ -367,6 +372,12 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ConstAllocation<'tcx> {
     }
 }
 
+impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AdtDef<'tcx> {
+    fn decode(decoder: &mut D) -> Self {
+        decoder.tcx().intern_adt_def(Decodable::decode(decoder))
+    }
+}
+
 impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, Span)] {
     fn decode(decoder: &mut D) -> &'tcx Self {
         decoder.tcx().arena.alloc_from_iter(
@@ -409,8 +420,7 @@ impl_decodable_via_ref! {
     &'tcx mir::UnsafetyCheckResult,
     &'tcx mir::BorrowCheckResult<'tcx>,
     &'tcx mir::coverage::CodeRegion,
-    &'tcx ty::List<ty::BoundVariableKind>,
-    &'tcx ty::AdtDef
+    &'tcx ty::List<ty::BoundVariableKind>
 }
 
 #[macro_export]
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 99dd4ab1bf5..494535f3d59 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -17,7 +17,7 @@ use crate::ty::query::{self, TyCtxtAt};
 use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
 use crate::ty::TyKind::*;
 use crate::ty::{
-    self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
+    self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
     ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy,
     FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
     ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
@@ -115,7 +115,7 @@ pub struct CtxtInterners<'tcx> {
     const_allocation: InternedSet<'tcx, Allocation>,
     bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
     layout: InternedSet<'tcx, LayoutS<'tcx>>,
-    adt_def: InternedSet<'tcx, AdtDef>,
+    adt_def: InternedSet<'tcx, AdtDefData>,
 }
 
 impl<'tcx> CtxtInterners<'tcx> {
@@ -1123,8 +1123,8 @@ impl<'tcx> TyCtxt<'tcx> {
         kind: AdtKind,
         variants: IndexVec<VariantIdx, ty::VariantDef>,
         repr: ReprOptions,
-    ) -> &'tcx ty::AdtDef {
-        self.intern_adt_def(ty::AdtDef::new(self, did, kind, variants, repr))
+    ) -> ty::AdtDef<'tcx> {
+        self.intern_adt_def(ty::AdtDefData::new(self, did, kind, variants, repr))
     }
 
     /// Allocates a read-only byte or string literal for `mir::interpret`.
@@ -2147,47 +2147,7 @@ direct_interners! {
     const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
     const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
     layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>,
-}
-
-macro_rules! direct_interners_old {
-    ($($name:ident: $method:ident($ty:ty),)+) => {
-        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
-            fn borrow<'a>(&'a self) -> &'a $ty {
-                &self.0
-            }
-        }
-
-        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
-            fn eq(&self, other: &Self) -> bool {
-                // The `Borrow` trait requires that `x.borrow() == y.borrow()`
-                // equals `x == y`.
-                self.0 == other.0
-            }
-        }
-
-        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
-
-        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
-            fn hash<H: Hasher>(&self, s: &mut H) {
-                // The `Borrow` trait requires that `x.borrow().hash(s) ==
-                // x.hash(s)`.
-                self.0.hash(s)
-            }
-        }
-
-        impl<'tcx> TyCtxt<'tcx> {
-            pub fn $method(self, v: $ty) -> &'tcx $ty {
-                self.interners.$name.intern(v, |v| {
-                    InternedInSet(self.interners.arena.alloc(v))
-                }).0
-            }
-        })+
-    }
-}
-
-// FIXME: eventually these should all be converted to `direct_interners`.
-direct_interners_old! {
-    adt_def: intern_adt_def(AdtDef),
+    adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
 }
 
 macro_rules! slice_interners {
@@ -2341,7 +2301,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     #[inline]
-    pub fn mk_adt(self, def: &'tcx AdtDef, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
+    pub fn mk_adt(self, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
         // Take a copy of substs so that we own the vectors inside.
         self.mk_ty(Adt(def, substs))
     }
@@ -2563,12 +2523,12 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn mk_place_downcast(
         self,
         place: Place<'tcx>,
-        adt_def: &'tcx AdtDef,
+        adt_def: AdtDef<'tcx>,
         variant_index: VariantIdx,
     ) -> Place<'tcx> {
         self.mk_place_elem(
             place,
-            PlaceElem::Downcast(Some(adt_def.variants[variant_index].name), variant_index),
+            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
         )
     }
 
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 708bd64578c..599845bae79 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -247,7 +247,7 @@ impl<'tcx> Ty<'tcx> {
             }
             ty::Tuple(ref tys) if tys.is_empty() => format!("`{}`", self).into(),
 
-            ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(),
+            ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did())).into(),
             ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
             ty::Array(t, n) => {
                 if t.is_simple_ty() {
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index c0dd4db2945..9c018dc685c 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -86,7 +86,7 @@ pub fn simplify_type<'tcx>(
         ty::Int(int_type) => Some(IntSimplifiedType(int_type)),
         ty::Uint(uint_type) => Some(UintSimplifiedType(uint_type)),
         ty::Float(float_type) => Some(FloatSimplifiedType(float_type)),
-        ty::Adt(def, _) => Some(AdtSimplifiedType(def.did)),
+        ty::Adt(def, _) => Some(AdtSimplifiedType(def.did())),
         ty::Str => Some(StrSimplifiedType),
         ty::Array(..) => Some(ArraySimplifiedType),
         ty::Slice(..) => Some(SliceSimplifiedType),
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index e2289b44b5c..2c78c1f63d8 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -105,21 +105,21 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 }
 
-impl<'tcx> AdtDef {
+impl<'tcx> AdtDef<'tcx> {
     /// Calculates the forest of `DefId`s from which this ADT is visibly uninhabited.
     fn uninhabited_from(
-        &self,
+        self,
         tcx: TyCtxt<'tcx>,
         substs: SubstsRef<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> DefIdForest<'tcx> {
         // Non-exhaustive ADTs from other crates are always considered inhabited.
-        if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
+        if self.is_variant_list_non_exhaustive() && !self.did().is_local() {
             DefIdForest::empty()
         } else {
             DefIdForest::intersection(
                 tcx,
-                self.variants
+                self.variants()
                     .iter()
                     .map(|v| v.uninhabited_from(tcx, substs, self.adt_kind(), param_env)),
             )
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 23664640aae..5b92b33f6d4 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -733,7 +733,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             }
 
             // SIMD vector types.
-            ty::Adt(def, substs) if def.repr.simd() => {
+            ty::Adt(def, substs) if def.repr().simd() => {
                 if !def.is_struct() {
                     // Should have yielded E0517 by now.
                     tcx.sess.delay_span_bug(
@@ -853,7 +853,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             ty::Adt(def, substs) => {
                 // Cache the field layouts.
                 let variants = def
-                    .variants
+                    .variants()
                     .iter()
                     .map(|v| {
                         v.fields
@@ -864,22 +864,22 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
 
                 if def.is_union() {
-                    if def.repr.pack.is_some() && def.repr.align.is_some() {
+                    if def.repr().pack.is_some() && def.repr().align.is_some() {
                         self.tcx.sess.delay_span_bug(
-                            tcx.def_span(def.did),
+                            tcx.def_span(def.did()),
                             "union cannot be packed and aligned",
                         );
                         return Err(LayoutError::Unknown(ty));
                     }
 
                     let mut align =
-                        if def.repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
+                        if def.repr().pack.is_some() { dl.i8_align } else { dl.aggregate_align };
 
-                    if let Some(repr_align) = def.repr.align {
+                    if let Some(repr_align) = def.repr().align {
                         align = align.max(AbiAndPrefAlign::new(repr_align));
                     }
 
-                    let optimize = !def.repr.inhibit_union_abi_opt();
+                    let optimize = !def.repr().inhibit_union_abi_opt();
                     let mut size = Size::ZERO;
                     let mut abi = Abi::Aggregate { sized: true };
                     let index = VariantIdx::new(0);
@@ -915,7 +915,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         size = cmp::max(size, field.size);
                     }
 
-                    if let Some(pack) = def.repr.pack {
+                    if let Some(pack) = def.repr().pack {
                         align = align.min(AbiAndPrefAlign::new(pack));
                     }
 
@@ -963,7 +963,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     // Only one variant is present.
                     (present_second.is_none() &&
                     // Representation optimizations are allowed.
-                    !def.repr.inhibit_enum_layout_opt());
+                    !def.repr().inhibit_enum_layout_opt());
                 if is_struct {
                     // Struct, or univariant enum equivalent to a struct.
                     // (Typechecking will reject discriminant-sizing attrs.)
@@ -972,8 +972,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     let kind = if def.is_enum() || variants[v].is_empty() {
                         StructKind::AlwaysSized
                     } else {
-                        let param_env = tcx.param_env(def.did);
-                        let last_field = def.variants[v].fields.last().unwrap();
+                        let param_env = tcx.param_env(def.did());
+                        let last_field = def.variant(v).fields.last().unwrap();
                         let always_sized =
                             tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env);
                         if !always_sized {
@@ -983,9 +983,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         }
                     };
 
-                    let mut st = self.univariant_uninterned(ty, &variants[v], &def.repr, kind)?;
+                    let mut st = self.univariant_uninterned(ty, &variants[v], &def.repr(), kind)?;
                     st.variants = Variants::Single { index: v };
-                    let (start, end) = self.tcx.layout_scalar_valid_range(def.did);
+                    let (start, end) = self.tcx.layout_scalar_valid_range(def.did());
                     match st.abi {
                         Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => {
                             // the asserts ensure that we are not using the
@@ -1011,7 +1011,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                             }
 
                             // Update `largest_niche` if we have introduced a larger niche.
-                            let niche = if def.repr.hide_niche() {
+                            let niche = if def.repr().hide_niche() {
                                 None
                             } else {
                                 Niche::from_scalar(dl, Size::ZERO, *scalar)
@@ -1049,14 +1049,14 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 // instead of actual discriminants, so dataful enums with
                 // explicit discriminants (RFC #2363) would misbehave.
                 let no_explicit_discriminants = def
-                    .variants
+                    .variants()
                     .iter_enumerated()
                     .all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));
 
                 let mut niche_filling_layout = None;
 
                 // Niche-filling enum optimization.
-                if !def.repr.inhibit_enum_layout_opt() && no_explicit_discriminants {
+                if !def.repr().inhibit_enum_layout_opt() && no_explicit_discriminants {
                     let mut dataful_variant = None;
                     let mut niche_variants = VariantIdx::MAX..=VariantIdx::new(0);
 
@@ -1107,7 +1107,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                                     let mut st = self.univariant_uninterned(
                                         ty,
                                         v,
-                                        &def.repr,
+                                        &def.repr(),
                                         StructKind::AlwaysSized,
                                     )?;
                                     st.variants = Variants::Single { index: j };
@@ -1169,7 +1169,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 }
 
                 let (mut min, mut max) = (i128::MAX, i128::MIN);
-                let discr_type = def.repr.discr_type();
+                let discr_type = def.repr().discr_type();
                 let bits = Integer::from_attr(self, discr_type).size().bits();
                 for (i, discr) in def.discriminants(tcx) {
                     if variants[i].iter().any(|f| f.abi.is_uninhabited()) {
@@ -1193,7 +1193,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     max = 0;
                 }
                 assert!(min <= max, "discriminant range is {}...{}", min, max);
-                let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
+                let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr(), min, max);
 
                 let mut align = dl.aggregate_align;
                 let mut size = Size::ZERO;
@@ -1208,7 +1208,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 // determining the alignment of the overall enum, and the
                 // determining the alignment of the payload after the tag.)
                 let mut prefix_align = min_ity.align(dl).abi;
-                if def.repr.c() {
+                if def.repr().c() {
                     for fields in &variants {
                         for field in fields {
                             prefix_align = prefix_align.max(field.align.abi);
@@ -1223,7 +1223,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         let mut st = self.univariant_uninterned(
                             ty,
                             &field_layouts,
-                            &def.repr,
+                            &def.repr(),
                             StructKind::Prefixed(min_ity.size(), prefix_align),
                         )?;
                         st.variants = Variants::Single { index: i };
@@ -1250,7 +1250,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     return Err(LayoutError::SizeOverflow(ty));
                 }
 
-                let typeck_ity = Integer::from_attr(dl, def.repr.discr_type());
+                let typeck_ity = Integer::from_attr(dl, def.repr().discr_type());
                 if typeck_ity < min_ity {
                     // It is a bug if Layout decided on a greater discriminant size than typeck for
                     // some reason at this point (based on values discriminant can take on). Mostly
@@ -1280,7 +1280,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 // won't be so conservative.
 
                 // Use the initial field alignment
-                let mut ity = if def.repr.c() || def.repr.int.is_some() {
+                let mut ity = if def.repr().c() || def.repr().int.is_some() {
                     min_ity
                 } else {
                     Integer::for_align(dl, start_align).unwrap_or(min_ity)
@@ -1821,7 +1821,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         };
 
         let adt_kind = adt_def.adt_kind();
-        let adt_packed = adt_def.repr.pack.is_some();
+        let adt_packed = adt_def.repr().pack.is_some();
 
         let build_variant_info = |n: Option<Symbol>, flds: &[Symbol], layout: TyAndLayout<'tcx>| {
             let mut min_size = Size::ZERO;
@@ -1855,12 +1855,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
 
         match layout.variants {
             Variants::Single { index } => {
-                if !adt_def.variants.is_empty() && layout.fields != FieldsShape::Primitive {
+                if !adt_def.variants().is_empty() && layout.fields != FieldsShape::Primitive {
                     debug!(
                         "print-type-size `{:#?}` variant {}",
-                        layout, adt_def.variants[index].name
+                        layout,
+                        adt_def.variant(index).name
                     );
-                    let variant_def = &adt_def.variants[index];
+                    let variant_def = &adt_def.variant(index);
                     let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
                     record(
                         adt_kind.into(),
@@ -1879,10 +1880,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 debug!(
                     "print-type-size `{:#?}` adt general variants def {}",
                     layout.ty,
-                    adt_def.variants.len()
+                    adt_def.variants().len()
                 );
                 let variant_infos: Vec<_> = adt_def
-                    .variants
+                    .variants()
                     .iter_enumerated()
                     .map(|(i, variant_def)| {
                         let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
@@ -1964,17 +1965,17 @@ impl<'tcx> SizeSkeleton<'tcx> {
 
             ty::Adt(def, substs) => {
                 // Only newtypes and enums w/ nullable pointer optimization.
-                if def.is_union() || def.variants.is_empty() || def.variants.len() > 2 {
+                if def.is_union() || def.variants().is_empty() || def.variants().len() > 2 {
                     return Err(err);
                 }
 
                 // Get a zero-sized variant or a pointer newtype.
                 let zero_or_ptr_variant = |i| {
                     let i = VariantIdx::new(i);
-                    let fields = def.variants[i]
-                        .fields
-                        .iter()
-                        .map(|field| SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env));
+                    let fields =
+                        def.variant(i).fields.iter().map(|field| {
+                            SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env)
+                        });
                     let mut ptr = None;
                     for field in fields {
                         let field = field?;
@@ -1997,11 +1998,11 @@ impl<'tcx> SizeSkeleton<'tcx> {
 
                 let v0 = zero_or_ptr_variant(0)?;
                 // Newtype.
-                if def.variants.len() == 1 {
+                if def.variants().len() == 1 {
                     if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 {
                         return Ok(SizeSkeleton::Pointer {
                             non_zero: non_zero
-                                || match tcx.layout_scalar_valid_range(def.did) {
+                                || match tcx.layout_scalar_valid_range(def.did()) {
                                     (Bound::Included(start), Bound::Unbounded) => start > 0,
                                     (Bound::Included(start), Bound::Included(end)) => {
                                         0 < start && start < end
@@ -2262,9 +2263,9 @@ where
                 }
 
                 let fields = match this.ty.kind() {
-                    ty::Adt(def, _) if def.variants.is_empty() =>
+                    ty::Adt(def, _) if def.variants().is_empty() =>
                         bug!("for_variant called on zero-variant enum"),
-                    ty::Adt(def, _) => def.variants[variant_index].fields.len(),
+                    ty::Adt(def, _) => def.variant(variant_index).fields.len(),
                     _ => bug!(),
                 };
                 tcx.intern_layout(LayoutS {
@@ -2405,7 +2406,7 @@ where
                 ty::Adt(def, substs) => {
                     match this.variants {
                         Variants::Single { index } => {
-                            TyMaybeWithLayout::Ty(def.variants[index].fields[i].ty(tcx, substs))
+                            TyMaybeWithLayout::Ty(def.variant(index).fields[i].ty(tcx, substs))
                         }
 
                         // Discriminant field for enums (where applicable).
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 8d7f6d84c7c..c74b3e9d0fc 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -274,7 +274,7 @@ fn characteristic_def_id_of_type_cached<'a>(
     visited: &mut SsoHashSet<Ty<'a>>,
 ) -> Option<DefId> {
     match *ty.kind() {
-        ty::Adt(adt_def, _) => Some(adt_def.did),
+        ty::Adt(adt_def, _) => Some(adt_def.did()),
 
         ty::Dynamic(data, ..) => data.principal_def_id(),
 
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 0927dc2d266..00cb9907d95 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -618,7 +618,7 @@ pub trait PrettyPrinter<'tcx>:
                 ty::BoundTyKind::Param(p) => p!(write("{}", p)),
             },
             ty::Adt(def, substs) => {
-                p!(print_def_path(def.did, substs));
+                p!(print_def_path(def.did(), substs));
             }
             ty::Dynamic(data, r) => {
                 let print_r = self.should_print_region(r);
@@ -1487,7 +1487,7 @@ pub trait PrettyPrinter<'tcx>:
                         }
                         p!(")");
                     }
-                    ty::Adt(def, _) if def.variants.is_empty() => {
+                    ty::Adt(def, _) if def.variants().is_empty() => {
                         self = self.typed_value(
                             |mut this| {
                                 write!(this, "unreachable()")?;
@@ -1500,7 +1500,7 @@ pub trait PrettyPrinter<'tcx>:
                     ty::Adt(def, substs) => {
                         let variant_idx =
                             contents.variant.expect("destructed const of adt without variant idx");
-                        let variant_def = &def.variants[variant_idx];
+                        let variant_def = &def.variant(variant_idx);
                         p!(print_value_path(variant_def.def_id, substs));
 
                         match variant_def.ctor_kind {
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 42ddbcc1e2f..81ee7942c4d 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -406,7 +406,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
         (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a),
 
         (&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs)) if a_def == b_def => {
-            let substs = relation.relate_item_substs(a_def.did, a_substs, b_substs)?;
+            let substs = relation.relate_item_substs(a_def.did(), a_substs, b_substs)?;
             Ok(tcx.mk_adt(a_def, substs))
         }
 
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 2d51462221c..5c7910db362 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -33,13 +33,13 @@ impl fmt::Debug for ty::TraitDef {
     }
 }
 
-impl fmt::Debug for ty::AdtDef {
+impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         ty::tls::with(|tcx| {
             with_no_trimmed_paths!({
                 f.write_str(
                     &FmtPrinter::new(tcx, Namespace::TypeNS)
-                        .print_def_path(self.did, &[])?
+                        .print_def_path(self.did(), &[])?
                         .into_buffer(),
                 )
             })
@@ -672,7 +672,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
 // TypeFoldable implementations.
 
 /// AdtDefs are basically the same as a DefId.
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
+impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> {
     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
         self,
         _folder: &mut F,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index da54ad06e04..e89074036f7 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -109,7 +109,7 @@ pub enum TyKind<'tcx> {
     ///
     /// Note that generic parameters in fields only get lazily substituted
     /// by using something like `adt_def.all_fields().map(|field| field.ty(tcx, substs))`.
-    Adt(&'tcx AdtDef, SubstsRef<'tcx>),
+    Adt(AdtDef<'tcx>, SubstsRef<'tcx>),
 
     /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
     Foreign(DefId),
@@ -1903,7 +1903,7 @@ impl<'tcx> Ty<'tcx> {
     #[inline]
     pub fn is_simd(self) -> bool {
         match self.kind() {
-            Adt(def, _) => def.repr.simd(),
+            Adt(def, _) => def.repr().simd(),
             _ => false,
         }
     }
@@ -1919,7 +1919,7 @@ impl<'tcx> Ty<'tcx> {
     pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
         match self.kind() {
             Adt(def, substs) => {
-                assert!(def.repr.simd(), "`simd_size_and_type` called on non-SIMD type");
+                assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type");
                 let variant = def.non_enum_variant();
                 let f0_ty = variant.fields[0].ty(tcx, substs);
 
@@ -2153,9 +2153,9 @@ impl<'tcx> Ty<'tcx> {
     }
 
     #[inline]
-    pub fn ty_adt_def(self) -> Option<&'tcx AdtDef> {
+    pub fn ty_adt_def(self) -> Option<AdtDef<'tcx>> {
         match self.kind() {
-            Adt(adt, _) => Some(adt),
+            Adt(adt, _) => Some(*adt),
             _ => None,
         }
     }
@@ -2194,7 +2194,7 @@ impl<'tcx> Ty<'tcx> {
         variant_index: VariantIdx,
     ) -> Option<Discr<'tcx>> {
         match self.kind() {
-            TyKind::Adt(adt, _) if adt.variants.is_empty() => {
+            TyKind::Adt(adt, _) if adt.variants().is_empty() => {
                 // This can actually happen during CTFE, see
                 // https://github.com/rust-lang/rust/issues/89765.
                 None
@@ -2212,7 +2212,7 @@ impl<'tcx> Ty<'tcx> {
     /// Returns the type of the discriminant of this type.
     pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match self.kind() {
-            ty::Adt(adt, _) if adt.is_enum() => adt.repr.discr_type().to_ty(tcx),
+            ty::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(tcx),
             ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
 
             ty::Param(_) | ty::Projection(_) | ty::Opaque(..) | ty::Infer(ty::TyVar(_)) => {
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 04e766d16cc..f957e914273 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -377,10 +377,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Note that this returns only the constraints for the
     /// destructor of `def` itself. For the destructors of the
     /// contents, you need `adt_dtorck_constraint`.
-    pub fn destructor_constraints(self, def: &'tcx ty::AdtDef) -> Vec<ty::subst::GenericArg<'tcx>> {
+    pub fn destructor_constraints(self, def: ty::AdtDef<'tcx>) -> Vec<ty::subst::GenericArg<'tcx>> {
         let dtor = match def.destructor(self) {
             None => {
-                debug!("destructor_constraints({:?}) - no dtor", def.did);
+                debug!("destructor_constraints({:?}) - no dtor", def.did());
                 return vec![];
             }
             Some(dtor) => dtor.did,
@@ -415,7 +415,7 @@ impl<'tcx> TyCtxt<'tcx> {
             _ => bug!(),
         };
 
-        let item_substs = match *self.type_of(def.did).kind() {
+        let item_substs = match *self.type_of(def.did()).kind() {
             ty::Adt(def_, substs) if def_ == def => substs,
             _ => bug!(),
         };
@@ -445,7 +445,7 @@ impl<'tcx> TyCtxt<'tcx> {
             })
             .map(|(item_param, _)| item_param)
             .collect();
-        debug!("destructor_constraint({:?}) = {:?}", def.did, result);
+        debug!("destructor_constraint({:?}) = {:?}", def.did(), result);
         result
     }
 
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index 389f711099b..3b93d127d2c 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -334,8 +334,8 @@ impl<'tcx> PlaceBuilder<'tcx> {
         self.project(PlaceElem::Deref)
     }
 
-    crate fn downcast(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx) -> Self {
-        self.project(PlaceElem::Downcast(Some(adt_def.variants[variant_index].name), variant_index))
+    crate fn downcast(self, adt_def: AdtDef<'tcx>, variant_index: VariantIdx) -> Self {
+        self.project(PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index))
     }
 
     fn index(self, index: Local) -> Self {
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 9c7c7203f47..8092f999311 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -332,7 +332,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     .collect();
 
                 let field_names: Vec<_> =
-                    (0..adt_def.variants[variant_index].fields.len()).map(Field::new).collect();
+                    (0..adt_def.variant(variant_index).fields.len()).map(Field::new).collect();
 
                 let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base {
                     let place_builder =
@@ -367,7 +367,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     })
                 });
                 let adt = Box::new(AggregateKind::Adt(
-                    adt_def.did,
+                    adt_def.did(),
                     variant_index,
                     substs,
                     user_ty,
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 44fe93ba363..c724e3e1b8f 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -946,7 +946,7 @@ enum TestKind<'tcx> {
     /// Test what enum variant a value is.
     Switch {
         /// The enum type being tested.
-        adt_def: &'tcx ty::AdtDef,
+        adt_def: ty::AdtDef<'tcx>,
         /// The set of variants that we should create a branch for. We also
         /// create an additional "otherwise" case.
         variants: BitSet<VariantIdx>,
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index 4f9a2c0ce77..7f53d9dd705 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -264,7 +264,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
 
             PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => {
-                let irrefutable = adt_def.variants.iter_enumerated().all(|(i, v)| {
+                let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
                     i == variant_index || {
                         self.tcx.features().exhaustive_patterns
                             && !v
@@ -276,7 +276,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                                 )
                                 .is_empty()
                     }
-                }) && (adt_def.did.is_local()
+                }) && (adt_def.did().is_local()
                     || !adt_def.is_variant_list_non_exhaustive());
                 if irrefutable {
                     let place_builder = match_pair.place.downcast(adt_def, variant_index);
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index da9c4b930df..96069f05b40 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -30,11 +30,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// It is a bug to call this with a not-fully-simplified pattern.
     pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> {
         match *match_pair.pattern.kind {
-            PatKind::Variant { ref adt_def, substs: _, variant_index: _, subpatterns: _ } => Test {
+            PatKind::Variant { adt_def, substs: _, variant_index: _, subpatterns: _ } => Test {
                 span: match_pair.pattern.span,
                 kind: TestKind::Switch {
                     adt_def,
-                    variants: BitSet::new_empty(adt_def.variants.len()),
+                    variants: BitSet::new_empty(adt_def.variants().len()),
                 },
             },
 
@@ -174,7 +174,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             TestKind::Switch { adt_def, ref variants } => {
                 let target_blocks = make_target_blocks(self);
                 // Variants is a BitVec of indexes into adt_def.variants.
-                let num_enum_variants = adt_def.variants.len();
+                let num_enum_variants = adt_def.variants().len();
                 debug_assert_eq!(target_blocks.len(), num_enum_variants + 1);
                 let otherwise_block = *target_blocks.last().unwrap();
                 let tcx = self.tcx;
@@ -201,7 +201,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     otherwise_block,
                 );
                 debug!("num_enum_variants: {}, variants: {:?}", num_enum_variants, variants);
-                let discr_ty = adt_def.repr.discr_type().to_ty(tcx);
+                let discr_ty = adt_def.repr().discr_type().to_ty(tcx);
                 let discr = self.temp(discr_ty, test.span);
                 self.cfg.push_assign(
                     block,
@@ -733,7 +733,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     fn candidate_after_variant_switch<'pat>(
         &mut self,
         match_pair_index: usize,
-        adt_def: &'tcx ty::AdtDef,
+        adt_def: ty::AdtDef<'tcx>,
         variant_index: VariantIdx,
         subpatterns: &'pat [FieldPat<'tcx>],
         candidate: &mut Candidate<'pat, 'tcx>,
@@ -744,7 +744,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // we want to create a set of derived match-patterns like
         // `(x as Variant).0 @ P1` and `(x as Variant).1 @ P1`.
         let elem =
-            ProjectionElem::Downcast(Some(adt_def.variants[variant_index].name), variant_index);
+            ProjectionElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index);
         let downcast_place = match_pair.place.project(elem); // `(x as Variant)`
         let consequent_match_pairs = subpatterns.iter().map(|subpattern| {
             // e.g., `(x as Variant).0`
@@ -798,7 +798,7 @@ impl Test<'_> {
                 // variants, we have a target for each variant and the
                 // otherwise case, and we make sure that all of the cases not
                 // specified have the same block.
-                adt_def.variants.len() + 1
+                adt_def.variants().len() + 1
             }
             TestKind::SwitchInt { switch_ty, ref options, .. } => {
                 if switch_ty.is_bool() {
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index b40d3e453e9..2d1198edbc3 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -162,7 +162,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for LayoutConstrainedPlaceVisitor<'a, 'tcx> {
             ExprKind::Field { lhs, .. } => {
                 if let ty::Adt(adt_def, _) = self.thir[lhs].ty.kind() {
                     if (Bound::Unbounded, Bound::Unbounded)
-                        != self.tcx.layout_scalar_valid_range(adt_def.did)
+                        != self.tcx.layout_scalar_valid_range(adt_def.did())
                     {
                         self.found = true;
                     }
@@ -242,7 +242,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                         visit::walk_pat(self, pat);
                         self.in_union_destructure = old_in_union_destructure;
                     } else if (Bound::Unbounded, Bound::Unbounded)
-                        != self.tcx.layout_scalar_valid_range(adt_def.did)
+                        != self.tcx.layout_scalar_valid_range(adt_def.did())
                     {
                         let old_inside_adt = std::mem::replace(&mut self.inside_adt, true);
                         visit::walk_pat(self, pat);
@@ -386,7 +386,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 user_ty: _,
                 fields: _,
                 base: _,
-            }) => match self.tcx.layout_scalar_valid_range(adt_def.did) {
+            }) => match self.tcx.layout_scalar_valid_range(adt_def.did()) {
                 (Bound::Unbounded, Bound::Unbounded) => {}
                 _ => self.requires_unsafe(expr.span, InitializingTypeWith),
             },
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index dc11c76e07b..23ee982489d 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -228,7 +228,7 @@ impl<'tcx> Cx<'tcx> {
                         let user_ty =
                             user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
                                 if let UserType::TypeOf(ref mut did, _) = &mut u_ty.value {
-                                    *did = adt_def.did;
+                                    *did = adt_def.did();
                                 }
                                 u_ty
                             });
@@ -376,7 +376,7 @@ impl<'tcx> Cx<'tcx> {
                         let user_ty = user_provided_types.get(expr.hir_id).copied();
                         debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
                         ExprKind::Adt(Box::new(Adt {
-                            adt_def: adt,
+                            adt_def: *adt,
                             variant_index: VariantIdx::new(0),
                             substs,
                             user_ty,
@@ -402,7 +402,7 @@ impl<'tcx> Cx<'tcx> {
                                 let user_ty = user_provided_types.get(expr.hir_id).copied();
                                 debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
                                 ExprKind::Adt(Box::new(Adt {
-                                    adt_def: adt,
+                                    adt_def: *adt,
                                     variant_index: index,
                                     substs,
                                     user_ty,
@@ -680,7 +680,7 @@ impl<'tcx> Cx<'tcx> {
                                     let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
                                     let (d, o) = adt_def.discriminant_def_for_variant(idx);
                                     use rustc_middle::ty::util::IntTypeExt;
-                                    let ty = adt_def.repr.discr_type();
+                                    let ty = adt_def.repr().discr_type();
                                     let ty = ty.to_ty(self.tcx());
                                     Some((d, o, ty))
                                 }
@@ -924,7 +924,7 @@ impl<'tcx> Cx<'tcx> {
                     // A unit struct/variant which is used as a value.
                     // We return a completely different ExprKind here to account for this special case.
                     ty::Adt(adt_def, substs) => ExprKind::Adt(Box::new(Adt {
-                        adt_def,
+                        adt_def: *adt_def,
                         variant_index: adt_def.variant_index_with_ctor_id(def_id),
                         substs,
                         user_ty: user_provided_type,
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index c94da838680..e2c56df6014 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -395,17 +395,17 @@ fn check_for_bindings_named_same_as_variants(
             && let pat_ty = cx.typeck_results.pat_ty(p).peel_refs()
             && let ty::Adt(edef, _) = pat_ty.kind()
             && edef.is_enum()
-            && edef.variants.iter().any(|variant| {
+            && edef.variants().iter().any(|variant| {
                 variant.ident(cx.tcx) == ident && variant.ctor_kind == CtorKind::Const
             })
         {
-            let variant_count = edef.variants.len();
+            let variant_count = edef.variants().len();
             cx.tcx.struct_span_lint_hir(
                 BINDINGS_WITH_VARIANT_NAME,
                 p.hir_id,
                 p.span,
                 |lint| {
-                    let ty_path = cx.tcx.def_path_str(edef.did);
+                    let ty_path = cx.tcx.def_path_str(edef.did());
                     let mut err = lint.build(&format!(
                         "pattern binding `{}` is named the same as one \
                          of the variants of the type `{}`",
@@ -573,7 +573,7 @@ fn non_exhaustive_match<'p, 'tcx>(
 ) {
     let is_empty_match = arms.is_empty();
     let non_empty_enum = match scrut_ty.kind() {
-        ty::Adt(def, _) => def.is_enum() && !def.variants.is_empty(),
+        ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(),
         _ => false,
     };
     // In the case of an empty match, replace the '`_` not covered' diagnostic with something more
@@ -609,7 +609,7 @@ fn non_exhaustive_match<'p, 'tcx>(
     };
 
     let is_variant_list_non_exhaustive = match scrut_ty.kind() {
-        ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did.is_local() => true,
+        ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local() => true,
         _ => false,
     };
 
@@ -762,17 +762,17 @@ fn adt_defined_here<'p, 'tcx>(
     if let ty::Adt(def, _) = ty.kind() {
         let mut spans = vec![];
         if witnesses.len() < 5 {
-            for sp in maybe_point_at_variant(cx, def, witnesses.iter()) {
+            for sp in maybe_point_at_variant(cx, *def, witnesses.iter()) {
                 spans.push(sp);
             }
         }
         let def_span = cx
             .tcx
             .hir()
-            .get_if_local(def.did)
+            .get_if_local(def.did())
             .and_then(|node| node.ident())
             .map(|ident| ident.span)
-            .unwrap_or_else(|| cx.tcx.def_span(def.did));
+            .unwrap_or_else(|| cx.tcx.def_span(def.did()));
         let mut span: MultiSpan =
             if spans.is_empty() { def_span.into() } else { spans.clone().into() };
 
@@ -786,17 +786,17 @@ fn adt_defined_here<'p, 'tcx>(
 
 fn maybe_point_at_variant<'a, 'p: 'a, 'tcx: 'a>(
     cx: &MatchCheckCtxt<'p, 'tcx>,
-    def: &AdtDef,
+    def: AdtDef<'tcx>,
     patterns: impl Iterator<Item = &'a DeconstructedPat<'p, 'tcx>>,
 ) -> Vec<Span> {
     use Constructor::*;
     let mut covered = vec![];
     for pattern in patterns {
         if let Variant(variant_index) = pattern.ctor() {
-            if let ty::Adt(this_def, _) = pattern.ty().kind() && this_def.did != def.did {
+            if let ty::Adt(this_def, _) = pattern.ty().kind() && this_def.did() != def.did() {
                 continue;
             }
-            let sp = def.variants[*variant_index].ident(cx.tcx).span;
+            let sp = def.variant(*variant_index).ident(cx.tcx).span;
             if covered.contains(&sp) {
                 // Don't point at variants that have already been covered due to other patterns to avoid
                 // visual clutter.
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index b83cbb753df..ae9b44cee4b 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -110,8 +110,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
         self.infcx.tcx
     }
 
-    fn adt_derive_msg(&self, adt_def: &AdtDef) -> String {
-        let path = self.tcx().def_path_str(adt_def.did);
+    fn adt_derive_msg(&self, adt_def: AdtDef<'tcx>) -> String {
+        let path = self.tcx().def_path_str(adt_def.did());
         format!(
             "to use a constant of type `{}` in a pattern, \
             `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
@@ -346,7 +346,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                     adt_def,
                     cv.ty()
                 );
-                let path = tcx.def_path_str(adt_def.did);
+                let path = tcx.def_path_str(adt_def.did());
                 let msg = format!(
                     "to use a constant of type `{}` in a pattern, \
                      `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
@@ -363,7 +363,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
             ty::Adt(adt_def, substs) if adt_def.is_enum() => {
                 let destructured = tcx.destructure_const(param_env.and(cv));
                 PatKind::Variant {
-                    adt_def,
+                    adt_def: *adt_def,
                     substs,
                     variant_index: destructured
                         .variant
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index 002c0b5f7d8..61f1069d571 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -681,7 +681,7 @@ impl<'tcx> Constructor<'tcx> {
     /// This means that the variant has a stdlib unstable feature marking it.
     pub(super) fn is_unstable_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool {
         if let Constructor::Variant(idx) = self && let ty::Adt(adt, _) = pcx.ty.kind() {
-            let variant_def_id = adt.variants[*idx].def_id;
+            let variant_def_id = adt.variant(*idx).def_id;
             // Filter variants that depend on a disabled unstable feature.
             return matches!(
                 pcx.cx.tcx.eval_stability(variant_def_id, None, DUMMY_SP, None),
@@ -695,13 +695,13 @@ impl<'tcx> Constructor<'tcx> {
     /// attribute.
     pub(super) fn is_doc_hidden_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool {
         if let Constructor::Variant(idx) = self && let ty::Adt(adt, _) = pcx.ty.kind() {
-            let variant_def_id = adt.variants[*idx].def_id;
+            let variant_def_id = adt.variant(*idx).def_id;
             return pcx.cx.tcx.is_doc_hidden(variant_def_id);
         }
         false
     }
 
-    fn variant_index_for_adt(&self, adt: &'tcx ty::AdtDef) -> VariantIdx {
+    fn variant_index_for_adt(&self, adt: ty::AdtDef<'tcx>) -> VariantIdx {
         match *self {
             Variant(idx) => idx,
             Single => {
@@ -725,7 +725,7 @@ impl<'tcx> Constructor<'tcx> {
                         // patterns. If we're here we can assume this is a box pattern.
                         1
                     } else {
-                        let variant = &adt.variants[self.variant_index_for_adt(adt)];
+                        let variant = &adt.variant(self.variant_index_for_adt(*adt));
                         Fields::list_variant_nonhidden_fields(pcx.cx, pcx.ty, variant).count()
                     }
                 }
@@ -973,10 +973,10 @@ impl<'tcx> SplitWildcard<'tcx> {
                 // exception is if the pattern is at the top level, because we want empty matches to be
                 // considered exhaustive.
                 let is_secretly_empty =
-                    def.variants.is_empty() && !is_exhaustive_pat_feature && !pcx.is_top_level;
+                    def.variants().is_empty() && !is_exhaustive_pat_feature && !pcx.is_top_level;
 
                 let mut ctors: SmallVec<[_; 1]> = def
-                    .variants
+                    .variants()
                     .iter_enumerated()
                     .filter(|(_, v)| {
                         // If `exhaustive_patterns` is enabled, we exclude variants known to be
@@ -1179,7 +1179,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
     ) -> impl Iterator<Item = (Field, Ty<'tcx>)> + Captures<'a> + Captures<'p> {
         let ty::Adt(adt, substs) = ty.kind() else { bug!() };
         // Whether we must not match the fields of this variant exhaustively.
-        let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did.is_local();
+        let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local();
 
         variant.fields.iter().enumerate().filter_map(move |(i, field)| {
             let ty = field.ty(cx.tcx, substs);
@@ -1213,7 +1213,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
                         // patterns. If we're here we can assume this is a box pattern.
                         Fields::wildcards_from_tys(cx, once(substs.type_at(0)))
                     } else {
-                        let variant = &adt.variants[constructor.variant_index_for_adt(adt)];
+                        let variant = &adt.variant(constructor.variant_index_for_adt(*adt));
                         let tys = Fields::list_variant_nonhidden_fields(cx, ty, variant)
                             .map(|(_, ty)| ty);
                         Fields::wildcards_from_tys(cx, tys)
@@ -1346,7 +1346,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
                             PatKind::Variant { variant_index, .. } => Variant(*variant_index),
                             _ => bug!(),
                         };
-                        let variant = &adt.variants[ctor.variant_index_for_adt(adt)];
+                        let variant = &adt.variant(ctor.variant_index_for_adt(*adt));
                         // For each field in the variant, we store the relevant index into `self.fields` if any.
                         let mut field_id_to_id: Vec<Option<usize>> =
                             (0..variant.fields.len()).map(|_| None).collect();
@@ -1459,15 +1459,15 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
                     PatKind::Deref { subpattern: subpatterns.next().unwrap() }
                 }
                 ty::Adt(adt_def, substs) => {
-                    let variant_index = self.ctor.variant_index_for_adt(adt_def);
-                    let variant = &adt_def.variants[variant_index];
+                    let variant_index = self.ctor.variant_index_for_adt(*adt_def);
+                    let variant = &adt_def.variant(variant_index);
                     let subpatterns = Fields::list_variant_nonhidden_fields(cx, self.ty, variant)
                         .zip(subpatterns)
                         .map(|((field, _ty), pattern)| FieldPat { field, pattern })
                         .collect();
 
                     if adt_def.is_enum() {
-                        PatKind::Variant { adt_def, substs, variant_index, subpatterns }
+                        PatKind::Variant { adt_def: *adt_def, substs, variant_index, subpatterns }
                     } else {
                         PatKind::Leaf { subpatterns }
                     }
@@ -1640,9 +1640,7 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
                 }
                 ty::Adt(..) | ty::Tuple(..) => {
                     let variant = match self.ty.kind() {
-                        ty::Adt(adt, _) => {
-                            Some(&adt.variants[self.ctor.variant_index_for_adt(adt)])
-                        }
+                        ty::Adt(adt, _) => Some(adt.variant(self.ctor.variant_index_for_adt(*adt))),
                         ty::Tuple(_) => None,
                         _ => unreachable!(),
                     };
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 6282b07e6f0..d21fbb9edff 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -653,7 +653,7 @@ macro_rules! CloneImpls {
 
 CloneImpls! { <'tcx>
     Span, Field, Mutability, Symbol, hir::HirId, usize, ty::Const<'tcx>,
-    Region<'tcx>, Ty<'tcx>, BindingMode, &'tcx AdtDef,
+    Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>,
     SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>,
     UserTypeProjection, PatTyProj<'tcx>
 }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index 286473c38e3..176723ab28b 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -325,7 +325,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
     pub(super) fn is_foreign_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool {
         match ty.kind() {
             ty::Adt(def, ..) => {
-                def.is_enum() && def.is_variant_list_non_exhaustive() && !def.did.is_local()
+                def.is_enum() && def.is_variant_list_non_exhaustive() && !def.did().is_local()
             }
             _ => false,
         }
diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs
index aea8667314f..82f97f22cce 100644
--- a/compiler/rustc_mir_build/src/thir/util.rs
+++ b/compiler/rustc_mir_build/src/thir/util.rs
@@ -20,7 +20,7 @@ crate trait UserAnnotatedTyHelpers<'tcx> {
         match ty.kind() {
             ty::Adt(adt_def, ..) => {
                 if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value {
-                    *did = adt_def.did;
+                    *did = adt_def.did();
                 }
                 Some(user_ty)
             }
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 774df752113..84491d0c2ad 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -407,7 +407,7 @@ where
         self.drop_ladder(fields, succ, unwind).0
     }
 
-    fn open_drop_for_box(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock {
+    fn open_drop_for_box(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock {
         debug!("open_drop_for_box({:?}, {:?}, {:?})", self, adt, substs);
 
         let interior = self.tcx().mk_place_deref(self.place);
@@ -420,9 +420,9 @@ where
         self.drop_subpath(interior, interior_path, succ, unwind_succ)
     }
 
-    fn open_drop_for_adt(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock {
+    fn open_drop_for_adt(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock {
         debug!("open_drop_for_adt({:?}, {:?}, {:?})", self, adt, substs);
-        if adt.variants.is_empty() {
+        if adt.variants().is_empty() {
             return self.elaborator.patch().new_block(BasicBlockData {
                 statements: vec![],
                 terminator: Some(Terminator {
@@ -434,7 +434,7 @@ where
         }
 
         let skip_contents =
-            adt.is_union() || Some(adt.did) == self.tcx().lang_items().manually_drop();
+            adt.is_union() || Some(adt.did()) == self.tcx().lang_items().manually_drop();
         let contents_drop = if skip_contents {
             (self.succ, self.unwind)
         } else {
@@ -450,7 +450,7 @@ where
 
     fn open_drop_for_adt_contents(
         &mut self,
-        adt: &'tcx ty::AdtDef,
+        adt: ty::AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
     ) -> (BasicBlock, Unwind) {
         let (succ, unwind) = self.drop_ladder_bottom();
@@ -458,7 +458,7 @@ where
             let fields = self.move_paths_for_fields(
                 self.place,
                 self.path,
-                &adt.variants[VariantIdx::new(0)],
+                &adt.variant(VariantIdx::new(0)),
                 substs,
             );
             self.drop_ladder(fields, succ, unwind)
@@ -469,22 +469,22 @@ where
 
     fn open_drop_for_multivariant(
         &mut self,
-        adt: &'tcx ty::AdtDef,
+        adt: ty::AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
         succ: BasicBlock,
         unwind: Unwind,
     ) -> (BasicBlock, Unwind) {
-        let mut values = Vec::with_capacity(adt.variants.len());
-        let mut normal_blocks = Vec::with_capacity(adt.variants.len());
+        let mut values = Vec::with_capacity(adt.variants().len());
+        let mut normal_blocks = Vec::with_capacity(adt.variants().len());
         let mut unwind_blocks =
-            if unwind.is_cleanup() { None } else { Some(Vec::with_capacity(adt.variants.len())) };
+            if unwind.is_cleanup() { None } else { Some(Vec::with_capacity(adt.variants().len())) };
 
         let mut have_otherwise_with_drop_glue = false;
         let mut have_otherwise = false;
         let tcx = self.tcx();
 
         for (variant_index, discr) in adt.discriminants(tcx) {
-            let variant = &adt.variants[variant_index];
+            let variant = &adt.variant(variant_index);
             let subpath = self.elaborator.downcast_subpath(self.path, variant_index);
 
             if let Some(variant_path) = subpath {
@@ -564,7 +564,7 @@ where
 
     fn adt_switch_block(
         &mut self,
-        adt: &'tcx ty::AdtDef,
+        adt: ty::AdtDef<'tcx>,
         blocks: Vec<BasicBlock>,
         values: &[u128],
         succ: BasicBlock,
@@ -577,7 +577,7 @@ where
         // Additionally, we do not want to switch on the
         // discriminant after it is free-ed, because that
         // way lies only trouble.
-        let discr_ty = adt.repr.discr_type().to_ty(self.tcx());
+        let discr_ty = adt.repr().discr_type().to_ty(self.tcx());
         let discr = Place::from(self.new_temp(discr_ty));
         let discr_rv = Rvalue::Discriminant(self.place);
         let switch_block = BasicBlockData {
@@ -869,9 +869,9 @@ where
             ty::Tuple(fields) => self.open_drop_for_tuple(fields),
             ty::Adt(def, substs) => {
                 if def.is_box() {
-                    self.open_drop_for_box(def, substs)
+                    self.open_drop_for_box(*def, substs)
                 } else {
-                    self.open_drop_for_adt(def, substs)
+                    self.open_drop_for_adt(*def, substs)
                 }
             }
             ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
@@ -927,7 +927,7 @@ where
     /// The contained value will not be dropped.
     fn box_free_block(
         &mut self,
-        adt: &'tcx ty::AdtDef,
+        adt: ty::AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
         target: BasicBlock,
         unwind: Unwind,
@@ -940,7 +940,7 @@ where
     /// value).
     fn unelaborated_free_block(
         &mut self,
-        adt: &'tcx ty::AdtDef,
+        adt: ty::AdtDef<'tcx>,
         substs: SubstsRef<'tcx>,
         target: BasicBlock,
         unwind: Unwind,
@@ -948,7 +948,8 @@ where
         let tcx = self.tcx();
         let unit_temp = Place::from(self.new_temp(tcx.mk_unit()));
         let free_func = tcx.require_lang_item(LangItem::BoxFree, Some(self.source_info.span));
-        let args = adt.variants[VariantIdx::new(0)]
+        let args = adt
+            .variant(VariantIdx::new(0))
             .fields
             .iter()
             .enumerate()
diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs
index 7d6a08d47da..87c1060f552 100644
--- a/compiler/rustc_mir_dataflow/src/impls/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs
@@ -705,14 +705,14 @@ fn switch_on_enum_discriminant<'mir, 'tcx>(
     body: &'mir mir::Body<'tcx>,
     block: &'mir mir::BasicBlockData<'tcx>,
     switch_on: mir::Place<'tcx>,
-) -> Option<(mir::Place<'tcx>, &'tcx ty::AdtDef)> {
+) -> Option<(mir::Place<'tcx>, ty::AdtDef<'tcx>)> {
     for statement in block.statements.iter().rev() {
         match &statement.kind {
             mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated)))
                 if *lhs == switch_on =>
             {
-                match &discriminated.ty(body, tcx).ty.kind() {
-                    ty::Adt(def, _) => return Some((*discriminated, def)),
+                match discriminated.ty(body, tcx).ty.kind() {
+                    ty::Adt(def, _) => return Some((*discriminated, *def)),
 
                     // `Rvalue::Discriminant` is also used to get the active yield point for a
                     // generator, but we do not need edge-specific effects in that case. This may
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index 87b9244c068..9d198ef2f7a 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -336,7 +336,7 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
                 ProjectionElem::Field(..) => {
                     let ty = place_base.ty(&self.body.local_decls, self.tcx).ty;
                     if let ty::Adt(def, _) = ty.kind() {
-                        if self.tcx.layout_scalar_valid_range(def.did)
+                        if self.tcx.layout_scalar_valid_range(def.did())
                             != (Bound::Unbounded, Bound::Unbounded)
                         {
                             let details = if is_mut_use {
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index d9a66cace52..8bc7f5e9ce2 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -210,7 +210,7 @@ struct SuspensionPoint<'tcx> {
 
 struct TransformVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
-    state_adt_ref: &'tcx AdtDef,
+    state_adt_ref: AdtDef<'tcx>,
     state_substs: SubstsRef<'tcx>,
 
     // The type of the discriminant in the generator struct
@@ -243,11 +243,11 @@ impl<'tcx> TransformVisitor<'tcx> {
         val: Operand<'tcx>,
         source_info: SourceInfo,
     ) -> impl Iterator<Item = Statement<'tcx>> {
-        let kind = AggregateKind::Adt(self.state_adt_ref.did, idx, self.state_substs, None, None);
-        assert_eq!(self.state_adt_ref.variants[idx].fields.len(), 1);
+        let kind = AggregateKind::Adt(self.state_adt_ref.did(), idx, self.state_substs, None, None);
+        assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 1);
         let ty = self
             .tcx
-            .type_of(self.state_adt_ref.variants[idx].fields[0].did)
+            .type_of(self.state_adt_ref.variant(idx).fields[0].did)
             .subst(self.tcx, self.state_substs);
         expand_aggregate(
             Place::return_place(),
diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
index 4167f8df11c..d7fb7063114 100644
--- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
+++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
@@ -124,7 +124,7 @@ fn is_needs_drop_and_init<'tcx>(
             //
             // If its projection *is* present in `MoveData`, then the field may have been moved
             // from separate from its parent. Recurse.
-            adt.variants.iter_enumerated().any(|(vid, variant)| {
+            adt.variants().iter_enumerated().any(|(vid, variant)| {
                 // Enums have multiple variants, which are discriminated with a `Downcast` projection.
                 // Structs have a single variant, and don't use a `Downcast` projection.
                 let mpi = if adt.is_enum() {
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 9533e869bc5..bf031b423c2 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -760,10 +760,10 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
 
     let statements = expand_aggregate(
         Place::return_place(),
-        adt_def.variants[variant_index].fields.iter().enumerate().map(|(idx, field_def)| {
+        adt_def.variant(variant_index).fields.iter().enumerate().map(|(idx, field_def)| {
             (Operand::Move(Place::from(Local::new(idx + 1))), field_def.ty(tcx, substs))
         }),
-        AggregateKind::Adt(adt_def.did, variant_index, substs, None, None),
+        AggregateKind::Adt(adt_def.did(), variant_index, substs, None, None),
         source_info,
         tcx,
     )
diff --git a/compiler/rustc_mir_transform/src/simplify_try.rs b/compiler/rustc_mir_transform/src/simplify_try.rs
index abd75c20524..884c5fb765f 100644
--- a/compiler/rustc_mir_transform/src/simplify_try.rs
+++ b/compiler/rustc_mir_transform/src/simplify_try.rs
@@ -726,7 +726,7 @@ impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> {
                 );
                 return StatementEquality::NotEqual;
             }
-            let variant_is_fieldless = adt.variants[variant_index].fields.is_empty();
+            let variant_is_fieldless = adt.variant(variant_index).fields.is_empty();
             if !variant_is_fieldless {
                 trace!("NO: variant {:?} was not fieldless", variant_index);
                 return StatementEquality::NotEqual;
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index e438b521a95..c777074df46 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -259,7 +259,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 if self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads) {
                     let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap();
                     if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() {
-                        if let Some(adt_def_id) = adt_def.did.as_local() {
+                        if let Some(adt_def_id) = adt_def.did().as_local() {
                             self.ignored_derived_traits
                                 .entry(adt_def_id)
                                 .or_default()
@@ -297,7 +297,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 match item.kind {
                     hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
                         let def = self.tcx.adt_def(item.def_id);
-                        self.repr_has_repr_c = def.repr.c();
+                        self.repr_has_repr_c = def.repr().c();
 
                         intravisit::walk_item(self, &item);
                     }
@@ -328,8 +328,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         self.repr_has_repr_c = had_repr_c;
     }
 
-    fn mark_as_used_if_union(&mut self, adt: &ty::AdtDef, fields: &[hir::ExprField<'_>]) {
-        if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did.is_local() {
+    fn mark_as_used_if_union(&mut self, adt: ty::AdtDef<'tcx>, fields: &[hir::ExprField<'_>]) {
+        if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did().is_local() {
             for field in fields {
                 let index = self.tcx.field_index(field.hir_id, self.typeck_results());
                 self.insert_def_id(adt.non_enum_variant().fields[index].did);
@@ -382,8 +382,8 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
             hir::ExprKind::Struct(ref qpath, ref fields, _) => {
                 let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
                 self.handle_res(res);
-                if let ty::Adt(ref adt, _) = self.typeck_results().expr_ty(expr).kind() {
-                    self.mark_as_used_if_union(adt, fields);
+                if let ty::Adt(adt, _) = self.typeck_results().expr_ty(expr).kind() {
+                    self.mark_as_used_if_union(*adt, fields);
                 }
             }
             _ => (),
diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs
index b2129ce9f24..6316f3b8459 100644
--- a/compiler/rustc_passes/src/intrinsicck.rs
+++ b/compiler/rustc_passes/src/intrinsicck.rs
@@ -38,22 +38,22 @@ struct ExprVisitor<'tcx> {
 fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
     let ty::Adt(def, substs) = *ty.kind() else { return ty };
 
-    if def.variants.len() == 2 && !def.repr.c() && def.repr.int.is_none() {
+    if def.variants().len() == 2 && !def.repr().c() && def.repr().int.is_none() {
         let data_idx;
 
         let one = VariantIdx::new(1);
         let zero = VariantIdx::new(0);
 
-        if def.variants[zero].fields.is_empty() {
+        if def.variant(zero).fields.is_empty() {
             data_idx = one;
-        } else if def.variants[one].fields.is_empty() {
+        } else if def.variant(one).fields.is_empty() {
             data_idx = zero;
         } else {
             return ty;
         }
 
-        if def.variants[data_idx].fields.len() == 1 {
-            return def.variants[data_idx].fields[0].ty(tcx, substs);
+        if def.variant(data_idx).fields.len() == 1 {
+            return def.variant(data_idx).fields[0].ty(tcx, substs);
         }
     }
 
@@ -165,7 +165,7 @@ impl<'tcx> ExprVisitor<'tcx> {
             ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => {
                 Some(asm_ty_isize)
             }
-            ty::Adt(adt, substs) if adt.repr.simd() => {
+            ty::Adt(adt, substs) if adt.repr().simd() => {
                 let fields = &adt.non_enum_variant().fields;
                 let elem_ty = fields[0].ty(self.tcx, substs);
                 match elem_ty.kind() {
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index fd1c0239b59..fdda77d01b3 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -9,6 +9,7 @@
 use rustc_ast::MacroDef;
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::intern::Interned;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -182,7 +183,7 @@ where
         let tcx = self.def_id_visitor.tcx();
         // InternalSubsts are not visited here because they are visited below in `super_visit_with`.
         match *ty.kind() {
-            ty::Adt(&ty::AdtDef { did: def_id, .. }, ..)
+            ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), ..)
             | ty::Foreign(def_id)
             | ty::FnDef(def_id, ..)
             | ty::Closure(def_id, ..)
@@ -930,7 +931,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
         &mut self,
         use_ctxt: Span,        // syntax context of the field name at the use site
         span: Span,            // span of the field pattern, e.g., `x: 0`
-        def: &'tcx ty::AdtDef, // definition of the struct or enum
+        def: ty::AdtDef<'tcx>, // definition of the struct or enum
         field: &'tcx ty::FieldDef,
         in_update_syntax: bool,
     ) {
@@ -941,7 +942,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
         // definition of the field
         let ident = Ident::new(kw::Empty, use_ctxt);
         let hir_id = self.tcx.hir().local_def_id_to_hir_id(self.current_item);
-        let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, hir_id).1;
+        let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id).1;
         if !field.vis.is_accessible_from(def_id, self.tcx) {
             let label = if in_update_syntax {
                 format!("field `{}` is private", field.name)
@@ -956,7 +957,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
                 "field `{}` of {} `{}` is private",
                 field.name,
                 def.variant_descr(),
-                self.tcx.def_path_str(def.did)
+                self.tcx.def_path_str(def.did())
             )
             .span_label(span, label)
             .emit();
diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index cf71f9b3fc5..d071d66ffa6 100644
--- a/compiler/rustc_save_analysis/src/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
@@ -554,7 +554,7 @@ impl<'tcx> SaveContext<'tcx> {
                     Some(Data::RefData(Ref {
                         kind: RefKind::Type,
                         span,
-                        ref_id: id_from_def_id(def.did),
+                        ref_id: id_from_def_id(def.did()),
                     }))
                 }
                 _ => {
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index a9c41ce0c4e..c8fdf363f05 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -1,5 +1,6 @@
 use rustc_data_structures::base_n;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::intern::Interned;
 use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{CrateNum, DefId};
@@ -453,7 +454,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
             }
 
             // Mangle all nominal types as paths.
-            ty::Adt(&ty::AdtDef { did: def_id, .. }, substs)
+            ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
             | ty::FnDef(def_id, substs)
             | ty::Opaque(def_id, substs)
             | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
@@ -684,7 +685,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
                     ty::Adt(def, substs) => {
                         let variant_idx =
                             contents.variant.expect("destructed const of adt without variant idx");
-                        let variant_def = &def.variants[variant_idx];
+                        let variant_def = &def.variant(variant_idx);
 
                         self.push("V");
                         self = self.print_def_path(variant_def.def_id, substs)?;
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 63efa951f96..a3d32acc6fb 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -676,7 +676,7 @@ fn fundamental_ty_inner_tys<'tcx>(
             match types.next() {
                 None => {
                     tcx.sess.span_err(
-                        tcx.def_span(def.did),
+                        tcx.def_span(def.did()),
                         "`#[fundamental]` requires at least one type parameter",
                     );
 
@@ -729,7 +729,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool {
             InCrate::Remote => true,
         },
 
-        ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
+        ty::Adt(def, _) => def_id_is_local(def.did(), in_crate),
         ty::Foreign(did) => def_id_is_local(did, in_crate),
         ty::Opaque(..) => {
             // This merits some explanation.
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index ccbd2dedfea..28c596c4e53 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -813,7 +813,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     | ty::Foreign(did)
                     | ty::FnDef(did, _)
                     | ty::Generator(did, ..) => Some(did),
-                    ty::Adt(def, _) => Some(def.did),
+                    ty::Adt(def, _) => Some(def.did()),
                     _ => None,
                 };
 
@@ -1467,7 +1467,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                 ty::Bool => Some(0),
                 ty::Char => Some(1),
                 ty::Str => Some(2),
-                ty::Adt(def, _) if tcx.is_diagnostic_item(sym::String, def.did) => Some(2),
+                ty::Adt(def, _) if tcx.is_diagnostic_item(sym::String, def.did()) => Some(2),
                 ty::Int(..)
                 | ty::Uint(..)
                 | ty::Float(..)
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index 59c88b6603c..d2b1fe2e0df 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -172,7 +172,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             if let Some(def) = self_ty.ty_adt_def() {
                 // We also want to be able to select self's original
                 // signature with no type arguments resolved
-                flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string())));
+                flags.push((sym::_Self, Some(self.tcx.type_of(def.did()).to_string())));
             }
 
             for param in generics.params.iter() {
@@ -190,12 +190,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     if let Some(def) = param_ty.ty_adt_def() {
                         // We also want to be able to select the parameter's
                         // original signature with no type arguments resolved
-                        flags.push((name, Some(self.tcx.type_of(def.did).to_string())));
+                        flags.push((name, Some(self.tcx.type_of(def.did()).to_string())));
                     }
                 }
             }
 
-            if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) {
+            if let Some(true) = self_ty.ty_adt_def().map(|def| def.did().is_local()) {
                 flags.push((sym::crate_local, None));
             }
 
@@ -214,7 +214,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 if let Some(def) = aty.ty_adt_def() {
                     // We also want to be able to select the array's type's original
                     // signature with no type arguments resolved
-                    let type_string = self.tcx.type_of(def.did).to_string();
+                    let type_string = self.tcx.type_of(def.did()).to_string();
                     flags.push((sym::_Self, Some(format!("[{}]", type_string))));
 
                     let len =
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index f2ddc3ea7fa..b617067e66d 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2129,7 +2129,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 if !is_upvar_tys_infer_tuple {
                     let msg = format!("required because it appears within the type `{}`", ty);
                     match ty.kind() {
-                        ty::Adt(def, _) => match self.tcx.opt_item_name(def.did) {
+                        ty::Adt(def, _) => match self.tcx.opt_item_name(def.did()) {
                             Some(ident) => err.span_note(ident.span, &msg),
                             None => err.note(&msg),
                         },
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index c293708dcc9..08308253ced 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -43,7 +43,7 @@ pub fn can_type_implement_copy<'tcx>(
         };
 
         let mut infringing = Vec::new();
-        for variant in &adt.variants {
+        for variant in adt.variants() {
             for field in &variant.fields {
                 let ty = field.ty(tcx, substs);
                 if ty.references_error() {
@@ -56,7 +56,7 @@ pub fn can_type_implement_copy<'tcx>(
                 // If it does not, then this field probably doesn't normalize
                 // to begin with, and point to the bad field's span instead.
                 let cause = if field
-                    .ty(tcx, traits::InternalSubsts::identity_for_item(tcx, adt.did))
+                    .ty(tcx, traits::InternalSubsts::identity_for_item(tcx, adt.did()))
                     .has_param_types_or_consts()
                 {
                     cause.clone()
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index 435d709d37e..2df0d9f0f6f 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -112,7 +112,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
         }
 
         ty::Adt(def, _) => {
-            if Some(def.did) == tcx.lang_items().manually_drop() {
+            if Some(def.did()) == tcx.lang_items().manually_drop() {
                 // `ManuallyDrop` never has a dtor.
                 true
             } else {
diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs
index 2ed7a8f9cf9..67e3bf80486 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs
@@ -12,7 +12,7 @@ use std::ops::ControlFlow;
 
 #[derive(Debug)]
 pub enum NonStructuralMatchTy<'tcx> {
-    Adt(&'tcx AdtDef),
+    Adt(AdtDef<'tcx>),
     Param,
     Dynamic,
     Foreign,
@@ -208,14 +208,14 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
             }
         };
 
-        if !self.seen.insert(adt_def.did) {
+        if !self.seen.insert(adt_def.did()) {
             debug!("Search already seen adt_def: {:?}", adt_def);
             return ControlFlow::CONTINUE;
         }
 
         if !self.type_marked_structural(ty) {
             debug!("Search found ty: {:?}", ty);
-            return ControlFlow::Break(NonStructuralMatchTy::Adt(&adt_def));
+            return ControlFlow::Break(NonStructuralMatchTy::Adt(adt_def));
         }
 
         // structural-match does not care about the
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 943f36efc15..b4ed5b95b10 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -540,7 +540,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
 
                 ty::Adt(def, substs) => {
                     // WfNominalType
-                    let obligations = self.nominal_obligations(def.did, substs);
+                    let obligations = self.nominal_obligations(def.did(), substs);
                     self.out.extend(obligations);
                 }
 
diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs
index 47b1ee04e77..9b85242e90a 100644
--- a/compiler/rustc_traits/src/chalk/db.rs
+++ b/compiler/rustc_traits/src/chalk/db.rs
@@ -166,13 +166,13 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
     ) -> Arc<chalk_solve::rust_ir::AdtDatum<RustInterner<'tcx>>> {
         let adt_def = adt_id.0;
 
-        let bound_vars = bound_vars_for_item(self.interner.tcx, adt_def.did);
+        let bound_vars = bound_vars_for_item(self.interner.tcx, adt_def.did());
         let binders = binders_for(self.interner, bound_vars);
 
-        let where_clauses = self.where_clauses_for(adt_def.did, bound_vars);
+        let where_clauses = self.where_clauses_for(adt_def.did(), bound_vars);
 
         let variants: Vec<_> = adt_def
-            .variants
+            .variants()
             .iter()
             .map(|variant| chalk_solve::rust_ir::AdtVariantDatum {
                 fields: variant
@@ -189,7 +189,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
                 chalk_solve::rust_ir::AdtDatumBound { variants, where_clauses },
             ),
             flags: chalk_solve::rust_ir::AdtFlags {
-                upstream: !adt_def.did.is_local(),
+                upstream: !adt_def.did().is_local(),
                 fundamental: adt_def.is_fundamental(),
                 phantom_data: adt_def.is_phantom_data(),
             },
@@ -209,9 +209,9 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
         let int = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(i)).intern(self.interner);
         let uint = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(i)).intern(self.interner);
         Arc::new(chalk_solve::rust_ir::AdtRepr {
-            c: adt_def.repr.c(),
-            packed: adt_def.repr.packed(),
-            int: adt_def.repr.int.map(|i| match i {
+            c: adt_def.repr().c(),
+            packed: adt_def.repr().packed(),
+            int: adt_def.repr().int.map(|i| match i {
                 attr::IntType::SignedInt(ty) => match ty {
                     ast::IntTy::Isize => int(chalk_ir::IntTy::Isize),
                     ast::IntTy::I8 => int(chalk_ir::IntTy::I8),
@@ -354,7 +354,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             let trait_ref = self.interner.tcx.impl_trait_ref(impl_def_id).unwrap();
             let self_ty = trait_ref.self_ty();
             let provides = match (self_ty.kind(), chalk_ty) {
-                (&ty::Adt(impl_adt_def, ..), Adt(id, ..)) => impl_adt_def.did == id.0.did,
+                (&ty::Adt(impl_adt_def, ..), Adt(id, ..)) => impl_adt_def.did() == id.0.did(),
                 (_, AssociatedType(_ty_id, ..)) => {
                     // FIXME(chalk): See https://github.com/rust-lang/rust/pull/77152#discussion_r494484774
                     false
@@ -671,7 +671,7 @@ impl<'tcx> chalk_ir::UnificationDatabase<RustInterner<'tcx>> for RustIrDatabase<
         &self,
         adt_id: chalk_ir::AdtId<RustInterner<'tcx>>,
     ) -> chalk_ir::Variances<RustInterner<'tcx>> {
-        let variances = self.interner.tcx.variances_of(adt_id.0.did);
+        let variances = self.interner.tcx.variances_of(adt_id.0.did());
         chalk_ir::Variances::from_iter(
             self.interner,
             variances.iter().map(|v| v.lower_into(self.interner)),
diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs
index 3658f8e5735..df5df176186 100644
--- a/compiler/rustc_traits/src/dropck_outlives.rs
+++ b/compiler/rustc_traits/src/dropck_outlives.rs
@@ -268,7 +268,7 @@ fn dtorck_constraint_for_ty<'tcx>(
 
         ty::Adt(def, substs) => {
             let DtorckConstraint { dtorck_types, outlives, overflows } =
-                tcx.at(span).adt_dtorck_constraint(def.did)?;
+                tcx.at(span).adt_dtorck_constraint(def.did())?;
             // FIXME: we can try to recursively `dtorck_constraint_on_ty`
             // there, but that needs some way to handle cycles.
             constraints.dtorck_types.extend(dtorck_types.iter().map(|t| t.subst(tcx, substs)));
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index 322511be817..6195c712c58 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -16,7 +16,7 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>
     // parameter without a `Copy` bound, then we conservatively return that it
     // needs drop.
     let adt_has_dtor =
-        |adt_def: &ty::AdtDef| adt_def.destructor(tcx).map(|_| DtorType::Significant);
+        |adt_def: ty::AdtDef<'tcx>| adt_def.destructor(tcx).map(|_| DtorType::Significant);
     let res =
         drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor, false).next().is_some();
 
@@ -78,7 +78,7 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> {
 
 impl<'tcx, F, I> Iterator for NeedsDropTypes<'tcx, F>
 where
-    F: Fn(&ty::AdtDef, SubstsRef<'tcx>) -> NeedsDropResult<I>,
+    F: Fn(ty::AdtDef<'tcx>, SubstsRef<'tcx>) -> NeedsDropResult<I>,
     I: Iterator<Item = Ty<'tcx>>,
 {
     type Item = NeedsDropResult<Ty<'tcx>>;
@@ -193,7 +193,7 @@ fn drop_tys_helper<'tcx>(
     tcx: TyCtxt<'tcx>,
     ty: Ty<'tcx>,
     param_env: rustc_middle::ty::ParamEnv<'tcx>,
-    adt_has_dtor: impl Fn(&ty::AdtDef) -> Option<DtorType>,
+    adt_has_dtor: impl Fn(ty::AdtDef<'tcx>) -> Option<DtorType>,
     only_significant: bool,
 ) -> impl Iterator<Item = NeedsDropResult<Ty<'tcx>>> {
     fn with_query_cache<'tcx>(
@@ -203,7 +203,7 @@ fn drop_tys_helper<'tcx>(
         iter.into_iter().try_fold(Vec::new(), |mut vec, subty| {
             match subty.kind() {
                 ty::Adt(adt_id, subst) => {
-                    for subty in tcx.adt_drop_tys(adt_id.did)? {
+                    for subty in tcx.adt_drop_tys(adt_id.did())? {
                         vec.push(subty.subst(tcx, subst));
                     }
                 }
@@ -213,7 +213,7 @@ fn drop_tys_helper<'tcx>(
         })
     }
 
-    let adt_components = move |adt_def: &ty::AdtDef, substs: SubstsRef<'tcx>| {
+    let adt_components = move |adt_def: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>| {
         if adt_def.is_manually_drop() {
             debug!("drop_tys_helper: `{:?}` is manually drop", adt_def);
             Ok(Vec::new())
@@ -260,9 +260,9 @@ fn drop_tys_helper<'tcx>(
 
 fn adt_consider_insignificant_dtor<'tcx>(
     tcx: TyCtxt<'tcx>,
-) -> impl Fn(&ty::AdtDef) -> Option<DtorType> + 'tcx {
-    move |adt_def: &ty::AdtDef| {
-        let is_marked_insig = tcx.has_attr(adt_def.did, sym::rustc_insignificant_dtor);
+) -> impl Fn(ty::AdtDef<'tcx>) -> Option<DtorType> + 'tcx {
+    move |adt_def: ty::AdtDef<'tcx>| {
+        let is_marked_insig = tcx.has_attr(adt_def.did(), sym::rustc_insignificant_dtor);
         if is_marked_insig {
             // In some cases like `std::collections::HashMap` where the struct is a wrapper around
             // a type that is a Drop type, and the wrapped type (eg: `hashbrown::HashMap`) lies
@@ -281,11 +281,14 @@ fn adt_consider_insignificant_dtor<'tcx>(
     }
 }
 
-fn adt_drop_tys(tcx: TyCtxt<'_>, def_id: DefId) -> Result<&ty::List<Ty<'_>>, AlwaysRequiresDrop> {
+fn adt_drop_tys<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+) -> Result<&ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
     // This is for the "adt_drop_tys" query, that considers all `Drop` impls, therefore all dtors are
     // significant.
     let adt_has_dtor =
-        |adt_def: &ty::AdtDef| adt_def.destructor(tcx).map(|_| DtorType::Significant);
+        |adt_def: ty::AdtDef<'tcx>| adt_def.destructor(tcx).map(|_| DtorType::Significant);
     // `tcx.type_of(def_id)` identical to `tcx.make_adt(def, identity_substs)`
     drop_tys_helper(tcx, tcx.type_of(def_id), tcx.param_env(def_id), adt_has_dtor, false)
         .collect::<Result<Vec<_>, _>>()
diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs
index 11a57688580..b8f3efe6462 100644
--- a/compiler/rustc_ty_utils/src/representability.rs
+++ b/compiler/rustc_ty_utils/src/representability.rs
@@ -33,7 +33,7 @@ pub fn ty_is_representable<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, sp: Span) -> R
     // cleared when recursing to check A, but `shadow_seen` won't, so that we
     // can catch cases of mutual recursion where A also contains B).
     let mut seen: Vec<Ty<'_>> = Vec::new();
-    let mut shadow_seen: Vec<&'tcx ty::AdtDef> = Vec::new();
+    let mut shadow_seen: Vec<ty::AdtDef<'tcx>> = Vec::new();
     let mut representable_cache = FxHashMap::default();
     let mut force_result = false;
     let r = is_type_structurally_recursive(
@@ -63,7 +63,7 @@ fn are_inner_types_recursive<'tcx>(
     tcx: TyCtxt<'tcx>,
     sp: Span,
     seen: &mut Vec<Ty<'tcx>>,
-    shadow_seen: &mut Vec<&'tcx ty::AdtDef>,
+    shadow_seen: &mut Vec<ty::AdtDef<'tcx>>,
     representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
     ty: Ty<'tcx>,
     force_result: &mut bool,
@@ -150,7 +150,7 @@ fn are_inner_types_recursive<'tcx>(
                             .take(shadow_seen.len() - 1)
                             .any(|seen_def| seen_def == def)
                     {
-                        let adt_def_id = def.did;
+                        let adt_def_id = def.did();
                         let raw_adt_ty = tcx.type_of(adt_def_id);
                         debug!("are_inner_types_recursive: checking nested type: {:?}", raw_adt_ty);
 
@@ -236,7 +236,7 @@ fn are_inner_types_recursive<'tcx>(
     }
 }
 
-fn same_adt<'tcx>(ty: Ty<'tcx>, def: &'tcx ty::AdtDef) -> bool {
+fn same_adt<'tcx>(ty: Ty<'tcx>, def: ty::AdtDef<'tcx>) -> bool {
     match *ty.kind() {
         ty::Adt(ty_def, _) => ty_def == def,
         _ => false,
@@ -249,7 +249,7 @@ fn is_type_structurally_recursive<'tcx>(
     tcx: TyCtxt<'tcx>,
     sp: Span,
     seen: &mut Vec<Ty<'tcx>>,
-    shadow_seen: &mut Vec<&'tcx ty::AdtDef>,
+    shadow_seen: &mut Vec<ty::AdtDef<'tcx>>,
     representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
     ty: Ty<'tcx>,
     force_result: &mut bool,
@@ -281,7 +281,7 @@ fn is_type_structurally_recursive_inner<'tcx>(
     tcx: TyCtxt<'tcx>,
     sp: Span,
     seen: &mut Vec<Ty<'tcx>>,
-    shadow_seen: &mut Vec<&'tcx ty::AdtDef>,
+    shadow_seen: &mut Vec<ty::AdtDef<'tcx>>,
     representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
     ty: Ty<'tcx>,
     force_result: &mut bool,
@@ -332,7 +332,7 @@ fn is_type_structurally_recursive_inner<'tcx>(
             // For structs and enums, track all previously seen types by pushing them
             // onto the 'seen' stack.
             seen.push(ty);
-            shadow_seen.push(def);
+            shadow_seen.push(*def);
             let out = are_inner_types_recursive(
                 tcx,
                 sp,
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index e6ce3447548..44ef0a09a65 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -8,7 +8,7 @@ use rustc_trait_selection::traits;
 
 fn sized_constraint_for_ty<'tcx>(
     tcx: TyCtxt<'tcx>,
-    adtdef: &ty::AdtDef,
+    adtdef: ty::AdtDef<'tcx>,
     ty: Ty<'tcx>,
 ) -> Vec<Ty<'tcx>> {
     use ty::TyKind::*;
@@ -56,7 +56,7 @@ fn sized_constraint_for_ty<'tcx>(
             })
             .without_const()
             .to_predicate(tcx);
-            let predicates = tcx.predicates_of(adtdef.did).predicates;
+            let predicates = tcx.predicates_of(adtdef.did()).predicates;
             if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] }
         }
 
@@ -99,7 +99,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtSizedConstrain
     let def = tcx.adt_def(def_id);
 
     let result = tcx.mk_type_list(
-        def.variants
+        def.variants()
             .iter()
             .flat_map(|v| v.fields.last())
             .flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did))),
@@ -454,7 +454,7 @@ pub fn conservative_is_privately_uninhabited_raw<'tcx>(
             // (a) It has no variants (i.e. an empty `enum`);
             // (b) Each of its variants (a single one in the case of a `struct`) has at least
             //     one uninhabited field.
-            def.variants.iter().all(|var| {
+            def.variants().iter().all(|var| {
                 var.fields.iter().any(|field| {
                     let ty = tcx.type_of(field.did).subst(tcx, substs);
                     tcx.conservative_is_privately_uninhabited(param_env.and(ty))
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index d409cedddda..144953caa4c 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -1788,9 +1788,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         if let ty::Adt(adt_def, _) = qself_ty.kind() {
             if adt_def.is_enum() {
                 let variant_def = adt_def
-                    .variants
+                    .variants()
                     .iter()
-                    .find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident(tcx), adt_def.did));
+                    .find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident(tcx), adt_def.did()));
                 if let Some(variant_def) = variant_def {
                     if permit_variants {
                         tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None);
@@ -1845,7 +1845,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT");
                     if let Some(suggested_name) = find_best_match_for_name(
                         &adt_def
-                            .variants
+                            .variants()
                             .iter()
                             .map(|variant| variant.name)
                             .collect::<Vec<Symbol>>(),
@@ -1865,7 +1865,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         );
                     }
 
-                    if let Some(sp) = tcx.hir().span_if_local(adt_def.did) {
+                    if let Some(sp) = tcx.hir().span_if_local(adt_def.did()) {
                         let sp = tcx.sess.source_map().guess_head_span(sp);
                         err.span_label(sp, format!("variant `{}` not found here", assoc_ident));
                     }
@@ -2154,7 +2154,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let adt_def = self_ty.map(|t| t.ty_adt_def().unwrap());
                 let (generics_def_id, index) = if let Some(adt_def) = adt_def {
                     debug_assert!(adt_def.is_enum());
-                    (adt_def.did, last)
+                    (adt_def.did(), last)
                 } else if last >= 1 && segments[last - 1].args.is_some() {
                     // Everything but the penultimate segment should have no
                     // parameters at all.
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 7c3594175b8..9016a8ffe9a 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -269,7 +269,7 @@ pub(super) fn check_fn<'a, 'tcx>(
                     let arg_is_panic_info = match *inputs[0].kind() {
                         ty::Ref(region, ty, mutbl) => match *ty.kind() {
                             ty::Adt(ref adt, _) => {
-                                adt.did == panic_info_did
+                                adt.did() == panic_info_did
                                     && mutbl == hir::Mutability::Not
                                     && !region.is_static()
                             }
@@ -310,7 +310,7 @@ pub(super) fn check_fn<'a, 'tcx>(
                 let span = hir.span(fn_id);
                 if inputs.len() == 1 {
                     let arg_is_alloc_layout = match inputs[0].kind() {
-                        ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
+                        ty::Adt(ref adt, _) => adt.did() == alloc_layout_did,
                         _ => false,
                     };
 
@@ -345,7 +345,7 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) {
     def.destructor(tcx); // force the destructor to be evaluated
     check_representable(tcx, span, def_id);
 
-    if def.repr.simd() {
+    if def.repr().simd() {
         check_simd(tcx, span, def_id);
     }
 
@@ -1086,7 +1086,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
             }
 
             let len = if let ty::Array(_ty, c) = e.kind() {
-                c.try_eval_usize(tcx, tcx.param_env(def.did))
+                c.try_eval_usize(tcx, tcx.param_env(def.did()))
             } else {
                 Some(fields.len() as u64)
             };
@@ -1137,10 +1137,10 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
     }
 }
 
-pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
-    let repr = def.repr;
+pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
+    let repr = def.repr();
     if repr.packed() {
-        for attr in tcx.get_attrs(def.did).iter() {
+        for attr in tcx.get_attrs(def.did()).iter() {
             for r in attr::find_repr_attrs(&tcx.sess, attr) {
                 if let attr::ReprPacked(pack) = r
                     && let Some(repr_pack) = repr.pack
@@ -1165,7 +1165,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
             )
             .emit();
         } else {
-            if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
+            if let Some(def_spans) = check_packed_inner(tcx, def.did(), &mut vec![]) {
                 let mut err = struct_span_err!(
                     tcx.sess,
                     sp,
@@ -1190,7 +1190,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
                             &if first {
                                 format!(
                                     "`{}` contains a field of type `{}`",
-                                    tcx.type_of(def.did),
+                                    tcx.type_of(def.did()),
                                     ident
                                 )
                             } else {
@@ -1214,16 +1214,16 @@ pub(super) fn check_packed_inner(
 ) -> Option<Vec<(DefId, Span)>> {
     if let ty::Adt(def, substs) = tcx.type_of(def_id).kind() {
         if def.is_struct() || def.is_union() {
-            if def.repr.align.is_some() {
-                return Some(vec![(def.did, DUMMY_SP)]);
+            if def.repr().align.is_some() {
+                return Some(vec![(def.did(), DUMMY_SP)]);
             }
 
             stack.push(def_id);
             for field in &def.non_enum_variant().fields {
                 if let ty::Adt(def, _) = field.ty(tcx, substs).kind() {
-                    if !stack.contains(&def.did) {
-                        if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
-                            defs.push((def.did, field.ident(tcx).span));
+                    if !stack.contains(&def.did()) {
+                        if let Some(mut defs) = check_packed_inner(tcx, def.did(), stack) {
+                            defs.push((def.did(), field.ident(tcx).span));
                             return Some(defs);
                         }
                     }
@@ -1236,8 +1236,8 @@ pub(super) fn check_packed_inner(
     None
 }
 
-pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
-    if !adt.repr.transparent() {
+pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtDef<'tcx>) {
+    if !adt.repr().transparent() {
         return;
     }
     let sp = tcx.sess.source_map().guess_head_span(sp);
@@ -1252,9 +1252,9 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty
         .emit();
     }
 
-    if adt.variants.len() != 1 {
-        bad_variant_count(tcx, adt, sp, adt.did);
-        if adt.variants.is_empty() {
+    if adt.variants().len() != 1 {
+        bad_variant_count(tcx, adt, sp, adt.did());
+        if adt.variants().is_empty() {
             // Don't bother checking the fields. No variants (and thus no fields) exist.
             return;
         }
@@ -1317,7 +1317,7 @@ fn check_enum<'tcx>(
         }
     }
 
-    let repr_type_ty = def.repr.discr_type().to_ty(tcx);
+    let repr_type_ty = def.repr().discr_type().to_ty(tcx);
     if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
         if !tcx.features().repr128 {
             feature_err(
@@ -1336,7 +1336,7 @@ fn check_enum<'tcx>(
         }
     }
 
-    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() && tcx.features().arbitrary_enum_discriminant {
         let is_unit = |var: &hir::Variant<'_>| matches!(var.data, hir::VariantData::Unit(..));
 
         let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
@@ -1355,7 +1355,7 @@ fn check_enum<'tcx>(
     for ((_, discr), v) in iter::zip(def.discriminants(tcx), vs) {
         // Check for duplicate discriminant values
         if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
-            let variant_did = def.variants[VariantIdx::new(i)].def_id;
+            let variant_did = def.variant(VariantIdx::new(i)).def_id;
             let variant_i_hir_id = tcx.hir().local_def_id_to_hir_id(variant_did.expect_local());
             let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
             let i_span = match variant_i.disr_expr {
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index f01843ebaba..58e5c9315c3 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -299,15 +299,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 {
                     if e.hir_id == id {
                         if let Some(span) = expr.span.find_ancestor_inside(block_span) {
-                            let return_suggestions =
-                                if self.tcx.is_diagnostic_item(sym::Result, expected_adt.did) {
-                                    vec!["Ok(())".to_string()]
-                                } else if self.tcx.is_diagnostic_item(sym::Option, expected_adt.did)
-                                {
-                                    vec!["None".to_string(), "Some(())".to_string()]
-                                } else {
-                                    return;
-                                };
+                            let return_suggestions = if self
+                                .tcx
+                                .is_diagnostic_item(sym::Result, expected_adt.did())
+                            {
+                                vec!["Ok(())".to_string()]
+                            } else if self.tcx.is_diagnostic_item(sym::Option, expected_adt.did()) {
+                                vec!["None".to_string(), "Some(())".to_string()]
+                            } else {
+                                return;
+                            };
                             if let Some(indent) =
                                 self.tcx.sess.source_map().indentation_before(span.shrink_to_lo())
                             {
@@ -333,7 +334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
 
             let compatible_variants: Vec<String> = expected_adt
-                .variants
+                .variants()
                 .iter()
                 .filter(|variant| variant.fields.len() == 1)
                 .filter_map(|variant| {
@@ -378,7 +379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     err.multipart_suggestions(
                         &format!(
                             "try wrapping the expression in a variant of `{}`",
-                            self.tcx.def_path_str(expected_adt.did)
+                            self.tcx.def_path_str(expected_adt.did())
                         ),
                         compatible_variants.into_iter().map(|variant| {
                             vec![
diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs
index 26aade16fd4..1849ece9f76 100644
--- a/compiler/rustc_typeck/src/check/dropck.rs
+++ b/compiler/rustc_typeck/src/check/dropck.rs
@@ -40,13 +40,13 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
                 tcx,
                 drop_impl_did.expect_local(),
                 dtor_self_type,
-                adt_def.did,
+                adt_def.did(),
             )?;
 
             ensure_drop_predicates_are_implied_by_item_defn(
                 tcx,
                 dtor_predicates,
-                adt_def.did.expect_local(),
+                adt_def.did().expect_local(),
                 self_to_impl_substs,
             )
         }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 7e7104f62fd..d944bb76241 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1333,7 +1333,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Prohibit struct expressions when non-exhaustive flag is set.
         let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
-        if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
+        if !adt.did().is_local() && variant.is_field_list_non_exhaustive() {
             self.tcx
                 .sess
                 .emit_err(StructExprNonExhaustive { span: expr.span, what: adt.variant_descr() });
@@ -1863,7 +1863,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ty::Adt(base_def, substs) if !base_def.is_enum() => {
                     debug!("struct named {:?}", base_t);
                     let (ident, def_scope) =
-                        self.tcx.adjust_ident_and_get_scope(field, base_def.did, self.body_id);
+                        self.tcx.adjust_ident_and_get_scope(field, base_def.did(), self.body_id);
                     let fields = &base_def.non_enum_variant().fields;
                     if let Some(index) = fields
                         .iter()
@@ -1882,7 +1882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
                             return field_ty;
                         }
-                        private_candidate = Some((adjustments, base_def.did, field_ty));
+                        private_candidate = Some((adjustments, base_def.did(), field_ty));
                     }
                 }
                 ty::Tuple(tys) => {
@@ -2103,9 +2103,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             if let ty::RawPtr(ty_and_mut) = expr_t.kind() {
                 if let ty::Adt(adt_def, _) = ty_and_mut.ty.kind() {
-                    if adt_def.variants.len() == 1
+                    if adt_def.variants().len() == 1
                         && adt_def
-                            .variants
+                            .variants()
                             .iter()
                             .next()
                             .unwrap()
@@ -2154,7 +2154,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn suggest_fields_on_recordish(
         &self,
         err: &mut Diagnostic,
-        def: &'tcx ty::AdtDef,
+        def: ty::AdtDef<'tcx>,
         field: Ident,
         access_span: Span,
     ) {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index b3213451d76..ed70b85e3f1 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -1166,7 +1166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if let Some(self_ty) = self_ty =>
             {
                 let adt_def = self_ty.ty_adt_def().unwrap();
-                user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
+                user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did(), self_ty });
                 is_alias_variant_ctor = true;
             }
             Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index f165093c958..d336573c254 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -577,13 +577,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 return None;
             }
             Res::Def(DefKind::Variant, _) => match ty.kind() {
-                ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
+                ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did(), substs)),
                 _ => bug!("unexpected type: {:?}", ty),
             },
             Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
             | Res::SelfTy { .. } => match ty.kind() {
                 ty::Adt(adt, substs) if !adt.is_enum() => {
-                    Some((adt.non_enum_variant(), adt.did, substs))
+                    Some((adt.non_enum_variant(), adt.did(), substs))
                 }
                 _ => None,
             },
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 523602d5b18..67d61668b6d 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -398,7 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let pin_box_found = self.tcx.mk_lang_item(box_found, LangItem::Pin).unwrap();
         let pin_found = self.tcx.mk_lang_item(found, LangItem::Pin).unwrap();
         match expected.kind() {
-            ty::Adt(def, _) if Some(def.did) == pin_did => {
+            ty::Adt(def, _) if Some(def.did()) == pin_did => {
                 if self.can_coerce(pin_box_found, expected) {
                     debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected);
                     match found.kind() {
diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs
index 9684237be83..48d24170072 100644
--- a/compiler/rustc_typeck/src/check/generator_interior.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior.rs
@@ -496,7 +496,7 @@ pub fn check_must_not_suspend_ty<'tcx>(
             let descr_pre = &format!("{}boxed ", data.descr_pre);
             check_must_not_suspend_ty(fcx, boxed_ty, hir_id, SuspendCheckData { descr_pre, ..data })
         }
-        ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did, hir_id, data),
+        ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did(), hir_id, data),
         // FIXME: support adding the attribute to TAITs
         ty::Opaque(def, _) => {
             let mut has_emitted = false;
diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs
index 7bb84581a82..1ca9c192096 100644
--- a/compiler/rustc_typeck/src/check/method/mod.rs
+++ b/compiler/rustc_typeck/src/check/method/mod.rs
@@ -589,9 +589,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if let ty::Adt(adt_def, _) = self_ty.kind() {
             if adt_def.is_enum() {
                 let variant_def = adt_def
-                    .variants
+                    .variants()
                     .iter()
-                    .find(|vd| tcx.hygienic_eq(method_name, vd.ident(tcx), adt_def.did));
+                    .find(|vd| tcx.hygienic_eq(method_name, vd.ident(tcx), adt_def.did()));
                 if let Some(variant_def) = variant_def {
                     // Braced variants generate unusable names in value namespace (reserved for
                     // possible future use), so variants resolved as associated items may refer to
diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs
index bc2859719e8..dbc4adfb0a3 100644
--- a/compiler/rustc_typeck/src/check/method/prelude2021.rs
+++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs
@@ -297,7 +297,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // for a "<" in `self_ty_name`.
             if !self_ty_name.contains('<') {
                 if let Adt(def, _) = self_ty.kind() {
-                    let generics = self.tcx.generics_of(def.did);
+                    let generics = self.tcx.generics_of(def.did());
                     if !generics.params.is_empty() {
                         let counts = generics.own_counts();
                         self_ty_name += &format!(
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index 876c575781c..e79085fdad2 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -640,7 +640,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 self.assemble_inherent_impl_candidates_for_type(p.def_id());
             }
             ty::Adt(def, _) => {
-                self.assemble_inherent_impl_candidates_for_type(def.did);
+                self.assemble_inherent_impl_candidates_for_type(def.did());
             }
             ty::Foreign(did) => {
                 self.assemble_inherent_impl_candidates_for_type(did);
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 504e1ce8c9f..c024f5b42e4 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -398,7 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 let candidate_found = autoderef.any(|(ty, _)| {
                                     if let ty::Adt(adt_deref, _) = ty.kind() {
                                         self.tcx
-                                            .inherent_impls(adt_deref.did)
+                                            .inherent_impls(adt_deref.did())
                                             .iter()
                                             .filter_map(|def_id| {
                                                 self.associated_value(*def_id, item_name)
@@ -470,7 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
 
                 if let Some(def) = actual.ty_adt_def() {
-                    if let Some(full_sp) = tcx.hir().span_if_local(def.did) {
+                    if let Some(full_sp) = tcx.hir().span_if_local(def.did()) {
                         let def_sp = tcx.sess.source_map().guess_head_span(full_sp);
                         err.span_label(
                             def_sp,
@@ -615,7 +615,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                                 .get(self.tcx.hir().local_def_id_to_hir_id(did)),
                                         )
                                     }
-                                    ty::Adt(def, _) => def.did.as_local().map(|def_id| {
+                                    ty::Adt(def, _) => def.did().as_local().map(|def_id| {
                                         self.tcx
                                             .hir()
                                             .get(self.tcx.hir().local_def_id_to_hir_id(def_id))
@@ -646,7 +646,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         );
                         match &self_ty.kind() {
                             // Point at the type that couldn't satisfy the bound.
-                            ty::Adt(def, _) => bound_spans.push((def_span(def.did), msg)),
+                            ty::Adt(def, _) => bound_spans.push((def_span(def.did()), msg)),
                             // Point at the trait object that couldn't satisfy the bound.
                             ty::Dynamic(preds, _) => {
                                 for pred in preds.iter() {
@@ -885,10 +885,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 ty.is_str()
                                     || matches!(
                                         ty.kind(),
-                                        ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did)
+                                        ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did())
                                     )
                             }
-                            ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did),
+                            ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did()),
                             _ => false,
                         };
                         if is_string_or_ref_str && item_name.name == sym::iter {
@@ -903,7 +903,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let ty::Adt(adt, _) = rcvr_ty.kind() {
                             let mut inherent_impls_candidate = self
                                 .tcx
-                                .inherent_impls(adt.did)
+                                .inherent_impls(adt.did())
                                 .iter()
                                 .copied()
                                 .filter(|def_id| {
@@ -1046,7 +1046,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if unsatisfied_predicates.is_empty() && actual.is_enum() {
                     let adt_def = actual.ty_adt_def().expect("enum is not an ADT");
                     if let Some(suggestion) = lev_distance::find_best_match_for_name(
-                        &adt_def.variants.iter().map(|s| s.name).collect::<Vec<_>>(),
+                        &adt_def.variants().iter().map(|s| s.name).collect::<Vec<_>>(),
                         item_name.name,
                         None,
                     ) {
@@ -1173,7 +1173,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let all_local_types_needing_impls =
             errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() {
                 ty::PredicateKind::Trait(pred) => match pred.self_ty().kind() {
-                    ty::Adt(def, _) => def.did.is_local(),
+                    ty::Adt(def, _) => def.did().is_local(),
                     _ => false,
                 },
                 _ => false,
@@ -1189,7 +1189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let def_ids = preds
             .iter()
             .filter_map(|pred| match pred.self_ty().kind() {
-                ty::Adt(def, _) => Some(def.did),
+                ty::Adt(def, _) => Some(def.did()),
                 _ => None,
             })
             .collect::<FxHashSet<_>>();
@@ -1207,7 +1207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             match pred.self_ty().kind() {
                 ty::Adt(def, _) => {
                     spans.push_span_label(
-                        sm.guess_head_span(self.tcx.def_span(def.did)),
+                        sm.guess_head_span(self.tcx.def_span(def.did())),
                         format!("must implement `{}`", pred.trait_ref.print_only_trait_path()),
                     );
                 }
@@ -1255,7 +1255,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         for (pred, _, _) in unsatisfied_predicates {
             let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder() else { continue };
             let adt = match trait_pred.self_ty().ty_adt_def() {
-                Some(adt) if adt.did.is_local() => adt,
+                Some(adt) if adt.did().is_local() => adt,
                 _ => continue,
             };
             if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) {
@@ -1273,7 +1273,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 };
                 if can_derive {
                     let self_name = trait_pred.self_ty().to_string();
-                    let self_span = self.tcx.def_span(adt.did);
+                    let self_span = self.tcx.def_span(adt.did());
                     if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() {
                         for super_trait in supertraits(self.tcx, poly_trait_ref.to_poly_trait_ref())
                         {
@@ -1336,7 +1336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Print out the type for use in value namespace.
     fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
         match ty.kind() {
-            ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did, substs)),
+            ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did(), substs)),
             _ => self.ty_to_string(ty),
         }
     }
@@ -1930,7 +1930,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> bool {
         fn is_local(ty: Ty<'_>) -> bool {
             match ty.kind() {
-                ty::Adt(def, _) => def.did.is_local(),
+                ty::Adt(def, _) => def.did().is_local(),
                 ty::Foreign(did) => did.is_local(),
                 ty::Dynamic(tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()),
                 ty::Param(_) => true,
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 4c0eab51c35..31cc3fa2ac6 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -822,13 +822,13 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
 }
 
 /// Emit an error when encountering two or more variants in a transparent enum.
-fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
+fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, did: DefId) {
     let variant_spans: Vec<_> = adt
-        .variants
+        .variants()
         .iter()
         .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
         .collect();
-    let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
+    let msg = format!("needs exactly one variant, but has {}", adt.variants().len(),);
     let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
     err.span_label(sp, &msg);
     if let [start @ .., end] = &*variant_spans {
@@ -844,7 +844,7 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, d
 /// enum.
 fn bad_non_zero_sized_fields<'tcx>(
     tcx: TyCtxt<'tcx>,
-    adt: &'tcx ty::AdtDef,
+    adt: ty::AdtDef<'tcx>,
     field_count: usize,
     field_spans: impl Iterator<Item = Span>,
     sp: Span,
diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs
index cd77e6d0384..af154e62a1e 100644
--- a/compiler/rustc_typeck/src/check/op.rs
+++ b/compiler/rustc_typeck/src/check/op.rs
@@ -576,7 +576,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let string_type = self.tcx.get_diagnostic_item(sym::String);
         let is_std_string = |ty: Ty<'tcx>| match ty.ty_adt_def() {
-            Some(ty_def) => Some(ty_def.did) == string_type,
+            Some(ty_def) => Some(ty_def.did()) == string_type,
             None => false,
         };
 
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index 8a369797210..26a1d0c473c 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -850,7 +850,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     _ => {
                         let (type_def_id, item_def_id) = match pat_ty.kind() {
                             Adt(def, _) => match res {
-                                Res::Def(DefKind::Const, def_id) => (Some(def.did), Some(def_id)),
+                                Res::Def(DefKind::Const, def_id) => (Some(def.did()), Some(def_id)),
                                 _ => (None, None),
                             },
                             _ => (None, None),
@@ -1286,7 +1286,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         // Require `..` if struct has non_exhaustive attribute.
-        let non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did.is_local();
+        let non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local();
         if non_exhaustive && !has_rest_pat {
             self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty());
         }
@@ -2042,8 +2042,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .find_map(|(ty, _)| {
                         match ty.kind() {
                             ty::Adt(adt_def, _)
-                                if self.tcx.is_diagnostic_item(sym::Option, adt_def.did)
-                                    || self.tcx.is_diagnostic_item(sym::Result, adt_def.did) =>
+                                if self.tcx.is_diagnostic_item(sym::Option, adt_def.did())
+                                    || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) =>
                             {
                                 // Slicing won't work here, but `.as_deref()` might (issue #91328).
                                 err.span_suggestion(
diff --git a/compiler/rustc_typeck/src/check/place_op.rs b/compiler/rustc_typeck/src/check/place_op.rs
index 318979b4627..42eec177649 100644
--- a/compiler/rustc_typeck/src/check/place_op.rs
+++ b/compiler/rustc_typeck/src/check/place_op.rs
@@ -1,6 +1,7 @@
 use crate::check::method::MethodCallee;
 use crate::check::{has_expected_num_generic_args, FnCtxt, PlaceOp};
 use rustc_ast as ast;
+use rustc_data_structures::intern::Interned;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -125,7 +126,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ) = index_expr.kind
         {
             match adjusted_ty.kind() {
-                ty::Adt(ty::AdtDef { did, .. }, _)
+                ty::Adt(ty::AdtDef(Interned(ty::AdtDefData { did, .. }, _)), _)
                     if self.tcx.is_diagnostic_item(sym::Vec, *did) =>
                 {
                     return self.negative_index(adjusted_ty, index_expr.span, base_expr);
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index 2b5ff11501a..142f976a411 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -1413,7 +1413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ty::Adt(def, substs) => {
                 // Multi-varaint enums are captured in entirety,
                 // which would've been handled in the case of single empty slice in `captured_by_move_projs`.
-                assert_eq!(def.variants.len(), 1);
+                assert_eq!(def.variants().len(), 1);
 
                 // Only Field projections can be applied to a non-box Adt.
                 assert!(
@@ -1422,7 +1422,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ProjectionKind::Field(..)
                     ))
                 );
-                def.variants.get(VariantIdx::new(0)).unwrap().fields.iter().enumerate().any(
+                def.variants().get(VariantIdx::new(0)).unwrap().fields.iter().enumerate().any(
                     |(i, field)| {
                         let paths_using_field = captured_by_move_projs
                             .iter()
@@ -1649,7 +1649,7 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
         // Return true for fields of packed structs, unless those fields have alignment 1.
         match p.kind {
             ProjectionKind::Field(..) => match ty.kind() {
-                ty::Adt(def, _) if def.repr.packed() => {
+                ty::Adt(def, _) if def.repr().packed() => {
                     // We erase regions here because they cannot be hashed
                     match tcx.layout_of(param_env.and(tcx.erase_regions(p.ty))) {
                         Ok(layout) if layout.align.abi.bytes() == 1 => {
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index 8672bf65466..30603d6f487 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -995,7 +995,7 @@ fn check_type_defn<'tcx, F>(
 {
     for_item(tcx, item).with_fcx(|fcx| {
         let variants = lookup_fields(fcx);
-        let packed = tcx.adt_def(item.def_id).repr.packed();
+        let packed = tcx.adt_def(item.def_id).repr().packed();
 
         for variant in &variants {
             // For DST, or when drop needs to copy things around, all
diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs
index ac1f2db848f..ef59df0dc88 100644
--- a/compiler/rustc_typeck/src/coherence/builtin.rs
+++ b/compiler/rustc_typeck/src/coherence/builtin.rs
@@ -154,8 +154,8 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
                 if def_a.is_struct() && def_b.is_struct() =>
             {
                 if def_a != def_b {
-                    let source_path = tcx.def_path_str(def_a.did);
-                    let target_path = tcx.def_path_str(def_b.did);
+                    let source_path = tcx.def_path_str(def_a.did());
+                    let target_path = tcx.def_path_str(def_b.did());
 
                     create_err(&format!(
                         "the trait `DispatchFromDyn` may only be implemented \
@@ -168,7 +168,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
                     return;
                 }
 
-                if def_a.repr.c() || def_a.repr.packed() {
+                if def_a.repr().c() || def_a.repr().packed() {
                     create_err(
                         "structs implementing `DispatchFromDyn` may not have \
                              `#[repr(packed)]` or `#[repr(C)]`",
@@ -353,8 +353,8 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
                 if def_a.is_struct() && def_b.is_struct() =>
             {
                 if def_a != def_b {
-                    let source_path = tcx.def_path_str(def_a.did);
-                    let target_path = tcx.def_path_str(def_b.did);
+                    let source_path = tcx.def_path_str(def_a.did());
+                    let target_path = tcx.def_path_str(def_b.did());
                     struct_span_err!(
                         tcx.sess,
                         span,
diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
index 78e54997403..59c252dec05 100644
--- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
@@ -48,7 +48,7 @@ impl<'tcx> ItemLikeVisitor<'_> for InherentCollect<'tcx> {
         let lang_items = self.tcx.lang_items();
         match *self_ty.kind() {
             ty::Adt(def, _) => {
-                self.check_def_id(item, def.did);
+                self.check_def_id(item, def.did());
             }
             ty::Foreign(did) => {
                 self.check_def_id(item, did);
diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs
index 8ed47226d5f..a1bcd141e10 100644
--- a/compiler/rustc_typeck/src/coherence/orphan.rs
+++ b/compiler/rustc_typeck/src/coherence/orphan.rs
@@ -97,7 +97,7 @@ fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
     if tcx.trait_is_auto(trait_def_id) && !trait_def_id.is_local() {
         let self_ty = trait_ref.self_ty();
         let opt_self_def_id = match *self_ty.kind() {
-            ty::Adt(self_def, _) => Some(self_def.did),
+            ty::Adt(self_def, _) => Some(self_def.did()),
             ty::Foreign(did) => Some(did),
             _ => None,
         };
@@ -181,7 +181,7 @@ fn emit_orphan_check_error<'tcx>(
                     // That way if we had `Vec<MyType>`, we will properly attribute the
                     // problem to `Vec<T>` and avoid confusing the user if they were to see
                     // `MyType` in the error.
-                    ty::Adt(def, _) => tcx.mk_adt(def, ty::List::empty()),
+                    ty::Adt(def, _) => tcx.mk_adt(*def, ty::List::empty()),
                     _ => ty,
                 };
                 let this = "this".to_string();
@@ -340,7 +340,7 @@ fn lint_auto_trait_impls(tcx: TyCtxt<'_>, trait_def_id: DefId, impls: &[LocalDef
         assert_eq!(trait_ref.substs.len(), 1);
         let self_ty = trait_ref.self_ty();
         let (self_type_did, substs) = match self_ty.kind() {
-            ty::Adt(def, substs) => (def.did, substs),
+            ty::Adt(def, substs) => (def.did(), substs),
             _ => {
                 // FIXME: should also lint for stuff like `&i32` but
                 // considering that auto traits are unstable, that
@@ -443,7 +443,7 @@ fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty:
                     // by only visiting each `DefId` once.
                     //
                     // This will be is incorrect in subtle cases, but I don't care :)
-                    if self.seen.insert(def.did) {
+                    if self.seen.insert(def.did()) {
                         for ty in def.all_fields().map(|field| field.ty(tcx, substs)) {
                             ty.visit_with(self)?;
                         }
@@ -457,7 +457,7 @@ fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty:
     }
 
     let self_ty_root = match self_ty.kind() {
-        ty::Adt(def, _) => tcx.mk_adt(def, InternalSubsts::identity_for_item(tcx, def.did)),
+        ty::Adt(def, _) => tcx.mk_adt(*def, InternalSubsts::identity_for_item(tcx, def.did())),
         _ => unimplemented!("unexpected self ty {:?}", self_ty),
     };
 
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 8229f4a80e1..cabdcdc214b 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -917,7 +917,7 @@ fn convert_variant_ctor(tcx: TyCtxt<'_>, ctor_id: hir::HirId) {
 
 fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId, variants: &[hir::Variant<'_>]) {
     let def = tcx.adt_def(def_id);
-    let repr_type = def.repr.discr_type();
+    let repr_type = def.repr().discr_type();
     let initial = repr_type.initial_discriminant(tcx);
     let mut prev_discr = None::<Discr<'_>>;
 
@@ -1012,7 +1012,7 @@ fn convert_variant(
     )
 }
 
-fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef {
+fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> {
     use rustc_hir::*;
 
     let def_id = def_id.expect_local();
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 2867574e656..3247a292242 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -464,7 +464,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
 
                 Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => tcx
                     .adt_def(tcx.hir().get_parent_item(hir_id))
-                    .repr
+                    .repr()
                     .discr_type()
                     .to_ty(tcx),
 
diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index 62598d23bd6..be4958ea062 100644
--- a/compiler/rustc_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
@@ -855,7 +855,7 @@ fn is_multivariant_adt(ty: Ty<'_>) -> bool {
             }
             AdtKind::Enum => def.is_variant_list_non_exhaustive(),
         };
-        def.variants.len() > 1 || (!def.did.is_local() && is_non_exhaustive)
+        def.variants().len() > 1 || (!def.did().is_local() && is_non_exhaustive)
     } else {
         false
     }
diff --git a/compiler/rustc_typeck/src/mem_categorization.rs b/compiler/rustc_typeck/src/mem_categorization.rs
index 876b1ae72ad..1464420090b 100644
--- a/compiler/rustc_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_typeck/src/mem_categorization.rs
@@ -576,7 +576,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     ) -> McResult<usize> {
         let ty = self.typeck_results.node_type(pat_hir_id);
         match ty.kind() {
-            ty::Adt(adt_def, _) => Ok(adt_def.variants[variant_index].fields.len()),
+            ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
             _ => {
                 self.tcx()
                     .sess
diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs
index 61ca09f6b98..00163c72974 100644
--- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs
@@ -157,7 +157,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
                 // `['b => 'a, U => T]` and thus get the requirement that `T:
                 // 'a` holds for `Foo`.
                 debug!("Adt");
-                if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did) {
+                if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did()) {
                     for (unsubstituted_predicate, &span) in unsubstituted_predicates {
                         // `unsubstituted_predicate` is `U: 'b` in the
                         // example above.  So apply the substitution to
@@ -178,7 +178,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
                 // let _: () = substs.region_at(0);
                 check_explicit_predicates(
                     tcx,
-                    def.did,
+                    def.did(),
                     substs,
                     required_predicates,
                     explicit_map,
diff --git a/compiler/rustc_typeck/src/variance/constraints.rs b/compiler/rustc_typeck/src/variance/constraints.rs
index 196e476b0e3..76755de4964 100644
--- a/compiler/rustc_typeck/src/variance/constraints.rs
+++ b/compiler/rustc_typeck/src/variance/constraints.rs
@@ -283,7 +283,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
             }
 
             ty::Adt(def, substs) => {
-                self.add_constraints_from_substs(current, def.did, substs, variance);
+                self.add_constraints_from_substs(current, def.did(), substs, variance);
             }
 
             ty::Projection(ref data) => {
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 2e66db425d6..353df68443f 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -244,7 +244,7 @@ fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
     clean::Enum {
         generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
         variants_stripped: false,
-        variants: cx.tcx.adt_def(did).variants.iter().map(|v| v.clean(cx)).collect(),
+        variants: cx.tcx.adt_def(did).variants().iter().map(|v| v.clean(cx)).collect(),
     }
 }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 29c11c7b28a..a58af4f44e2 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1551,7 +1551,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                 })
             }
             ty::Adt(def, substs) => {
-                let did = def.did;
+                let did = def.did();
                 let kind = match def.adt_kind() {
                     AdtKind::Struct => ItemType::Struct,
                     AdtKind::Union => ItemType::Union,
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 68644a017a4..e6c7745c6e1 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1765,7 +1765,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
                     };
 
                     for (index, layout) in variants.iter_enumerated() {
-                        let name = adt.variants[index].name;
+                        let name = adt.variant(index).name;
                         write!(w, "<li><code>{name}</code>: ", name = name);
                         write_size_of_layout(w, *layout, tag_size);
                         writeln!(w, "</li>");
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index aa771a06f9c..e1ae0a19ef9 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -2,7 +2,7 @@
 //!
 //! [RFC 1946]: https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md
 
-use rustc_data_structures::{fx::FxHashMap, stable_set::FxHashSet};
+use rustc_data_structures::{fx::FxHashMap, intern::Interned, stable_set::FxHashSet};
 use rustc_errors::{Applicability, Diagnostic};
 use rustc_hir::def::{
     DefKind,
@@ -439,7 +439,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                             Err(ResolutionFailure::NotResolved {
                                 item_id,
                                 module_id,
-                                partial_res: Some(Res::Def(DefKind::Enum, def.did)),
+                                partial_res: Some(Res::Def(DefKind::Enum, def.did())),
                                 unresolved: variant_field_name.to_string().into(),
                             }
                             .into())
@@ -686,7 +686,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
             ty::FnDef(..) => panic!("type alias to a function definition"),
             ty::FnPtr(_) => Res::Primitive(Fn),
             ty::Never => Res::Primitive(Never),
-            ty::Adt(&ty::AdtDef { did, .. }, _) | ty::Foreign(did) => {
+            ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) | ty::Foreign(did) => {
                 Res::Def(self.cx.tcx.def_kind(did), did)
             }
             ty::Projection(_)
@@ -779,7 +779,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                 if ns == TypeNS && def_kind == DefKind::Enum {
                     match tcx.type_of(did).kind() {
                         ty::Adt(adt_def, _) => {
-                            for variant in &adt_def.variants {
+                            for variant in adt_def.variants() {
                                 if variant.name == item_name {
                                     return Some((
                                         root_res,
@@ -1002,8 +1002,8 @@ fn trait_impls_for<'a>(
             let saw_impl = impl_type == ty
                 || match (impl_type.kind(), ty.kind()) {
                     (ty::Adt(impl_def, _), ty::Adt(ty_def, _)) => {
-                        debug!("impl def_id: {:?}, ty def_id: {:?}", impl_def.did, ty_def.did);
-                        impl_def.did == ty_def.did
+                        debug!("impl def_id: {:?}, ty def_id: {:?}", impl_def.did(), ty_def.did());
+                        impl_def.did() == ty_def.did()
                     }
                     _ => false,
                 };
diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
index f0979840ff8..4592ca72748 100644
--- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
+++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
@@ -149,7 +149,7 @@ impl LateLintPass<'_> for AwaitHolding {
 fn check_interior_types(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorTypeCause<'_>], span: Span) {
     for ty_cause in ty_causes {
         if let rustc_middle::ty::Adt(adt, _) = ty_cause.ty.kind() {
-            if is_mutex_guard(cx, adt.did) {
+            if is_mutex_guard(cx, adt.did()) {
                 span_lint_and_then(
                     cx,
                     AWAIT_HOLDING_LOCK,
@@ -167,7 +167,7 @@ fn check_interior_types(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorType
                     },
                 );
             }
-            if is_refcell_ref(cx, adt.did) {
+            if is_refcell_ref(cx, adt.did()) {
                 span_lint_and_then(
                     cx,
                     AWAIT_HOLDING_REFCELL_REF,
diff --git a/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs
index 7637666d059..df780747a0c 100644
--- a/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
+use rustc_data_structures::intern::Interned;
 use rustc_hir::{Expr, ExprKind, PathSegment};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
@@ -55,7 +56,7 @@ fn check_case_sensitive_file_extension_comparison(ctx: &LateContext<'_>, expr: &
                 ty::Str => {
                     return Some(span);
                 },
-                ty::Adt(&ty::AdtDef { did, .. }, _) => {
+                ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) => {
                     if ctx.tcx.is_diagnostic_item(sym::String, did) {
                         return Some(span);
                     }
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index 9b189ea1ef8..421bd6f53f7 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -116,15 +116,15 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
                 && let Res::Def(DefKind::Ctor(..), id) = cx.qpath_res(p, cast_expr.hir_id)
             {
                 let i = def.variant_index_with_ctor_id(id);
-                let variant = &def.variants[i];
-                let nbits = utils::enum_value_nbits(get_discriminant_value(cx.tcx, def, i));
+                let variant = def.variant(i);
+                let nbits = utils::enum_value_nbits(get_discriminant_value(cx.tcx, *def, i));
                 (nbits, Some(variant))
             } else {
-                (utils::enum_ty_to_nbits(def, cx.tcx), None)
+                (utils::enum_ty_to_nbits(*def, cx.tcx), None)
             };
             let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx);
 
-            let cast_from_ptr_size = def.repr.int.map_or(true, |ty| {
+            let cast_from_ptr_size = def.repr().int.map_or(true, |ty| {
                 matches!(
                     ty,
                     IntType::SignedInt(ast::IntTy::Isize) | IntType::UnsignedInt(ast::UintTy::Usize)
diff --git a/src/tools/clippy/clippy_lints/src/casts/utils.rs b/src/tools/clippy/clippy_lints/src/casts/utils.rs
index bbed766c47a..5a4f20f0990 100644
--- a/src/tools/clippy/clippy_lints/src/casts/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/utils.rs
@@ -34,10 +34,10 @@ pub(super) fn enum_value_nbits(value: EnumValue) -> u64 {
     .into()
 }
 
-pub(super) fn enum_ty_to_nbits(adt: &AdtDef, tcx: TyCtxt<'_>) -> u64 {
+pub(super) fn enum_ty_to_nbits(adt: AdtDef<'_>, tcx: TyCtxt<'_>) -> u64 {
     let mut explicit = 0i128;
     let (start, end) = adt
-        .variants
+        .variants()
         .iter()
         .fold((0, i128::MIN), |(start, end), variant| match variant.discr {
             VariantDiscr::Relative(x) => match explicit.checked_add(i128::from(x)) {
diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs
index 06e6bf986c2..f7e4bc24321 100644
--- a/src/tools/clippy/clippy_lints/src/default.rs
+++ b/src/tools/clippy/clippy_lints/src/default.rs
@@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
             then {
                 // TODO: Work out a way to put "whatever the imported way of referencing
                 // this type in this file" rather than a fully-qualified type.
-                let replacement = format!("{}::default()", cx.tcx.def_path_str(def.did));
+                let replacement = format!("{}::default()", cx.tcx.def_path_str(def.did()));
                 span_lint_and_sugg(
                     cx,
                     DEFAULT_TRAIT_ACCESS,
@@ -137,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
                 if let Some(adt) = binding_type.ty_adt_def();
                 if adt.is_struct();
                 let variant = adt.non_enum_variant();
-                if adt.did.is_local() || !variant.is_field_list_non_exhaustive();
+                if adt.did().is_local() || !variant.is_field_list_non_exhaustive();
                 let module_did = cx.tcx.parent_module(stmt.hir_id).to_def_id();
                 if variant
                     .fields
@@ -216,7 +216,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
                     if let ty::Adt(adt_def, substs) = binding_type.kind();
                     if !substs.is_empty();
                     then {
-                        let adt_def_ty_name = cx.tcx.item_name(adt_def.did);
+                        let adt_def_ty_name = cx.tcx.item_name(adt_def.did());
                         let generic_args = substs.iter().collect::<Vec<_>>();
                         let tys_str = generic_args
                             .iter()
diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
index b80d55dd192..f3996e5b44d 100644
--- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
+++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
@@ -148,7 +148,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
                 if_chain! {
                     if let Some(adt_def) = ty.ty_adt_def();
                     if adt_def.is_struct();
-                    if let Some(variant) = adt_def.variants.iter().next();
+                    if let Some(variant) = adt_def.variants().iter().next();
                     then {
                         let fields_def = &variant.fields;
 
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index eccb18982f3..14098340745 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
                     _ => false,
                 };
                 if should_emit {
-                    let path_string = cx.tcx.def_path_str(adt_def.did);
+                    let path_string = cx.tcx.def_path_str(adt_def.did());
                     span_lint_and_help(
                         cx,
                         DERIVABLE_IMPLS,
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 7277e4080c5..557e101494e 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -315,7 +315,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &T
             let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).map_or(false, |impls| {
                 impls
                     .iter()
-                    .any(|&id| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did == adt.did))
+                    .any(|&id| matches!(cx.tcx.type_of(id).kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did()))
             });
             if !has_copy_impl {
                 return;
@@ -357,10 +357,10 @@ fn check_unsafe_derive_deserialize<'tcx>(
         if let Some(trait_def_id) = trait_ref.trait_def_id();
         if match_def_path(cx, trait_def_id, &paths::SERDE_DESERIALIZE);
         if let ty::Adt(def, _) = ty.kind();
-        if let Some(local_def_id) = def.did.as_local();
+        if let Some(local_def_id) = def.did().as_local();
         let adt_hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_def_id);
         if !is_lint_allowed(cx, UNSAFE_DERIVE_DESERIALIZE, adt_hir_id);
-        if cx.tcx.inherent_impls(def.did)
+        if cx.tcx.inherent_impls(def.did())
             .iter()
             .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
             .any(|imp| has_unsafe(cx, imp));
diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs
index af9e65e6361..b5d6b3c7524 100644
--- a/src/tools/clippy/clippy_lints/src/empty_enum.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs
@@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for EmptyEnum {
         if let ItemKind::Enum(..) = item.kind {
             let ty = cx.tcx.type_of(item.def_id);
             let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
-            if adt.variants.is_empty() {
+            if adt.variants().is_empty() {
                 span_lint_and_help(
                     cx,
                     EMPTY_ENUM,
diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs
index 3b6661c817b..e2a5430da08 100644
--- a/src/tools/clippy/clippy_lints/src/enum_clike.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs
@@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant {
                     if let Some(Constant::Int(val)) = constant.and_then(miri_to_const) {
                         if let ty::Adt(adt, _) = ty.kind() {
                             if adt.is_enum() {
-                                ty = adt.repr.discr_type().to_ty(cx.tcx);
+                                ty = adt.repr().discr_type().to_ty(cx.tcx);
                             }
                         }
                         match ty.kind() {
diff --git a/src/tools/clippy/clippy_lints/src/eq_op.rs b/src/tools/clippy/clippy_lints/src/eq_op.rs
index 6490231fed8..51c811b304c 100644
--- a/src/tools/clippy/clippy_lints/src/eq_op.rs
+++ b/src/tools/clippy/clippy_lints/src/eq_op.rs
@@ -306,7 +306,7 @@ fn in_impl<'tcx>(
 fn are_equal<'tcx>(cx: &LateContext<'tcx>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool {
     if_chain! {
         if let ty::Adt(adt_def, _) = middle_ty.kind();
-        if let Some(local_did) = adt_def.did.as_local();
+        if let Some(local_did) = adt_def.did().as_local();
         let item = cx.tcx.hir().expect_item(local_did);
         let middle_ty_id = item.def_id.to_def_id();
         if let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind;
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index d23c0c225e1..845863bd209 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -224,7 +224,7 @@ fn get_ufcs_type_name(cx: &LateContext<'_>, method_def_id: DefId) -> String {
         ty::ImplContainer(def_id) => {
             let ty = cx.tcx.type_of(def_id);
             match ty.kind() {
-                ty::Adt(adt, _) => cx.tcx.def_path_str(adt.did),
+                ty::Adt(adt, _) => cx.tcx.def_path_str(adt.did()),
                 _ => ty.to_string(),
             }
         },
diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs
index 395c920c997..64c41b56587 100644
--- a/src/tools/clippy/clippy_lints/src/format.rs
+++ b/src/tools/clippy/clippy_lints/src/format.rs
@@ -72,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
             if_chain! {
                 if format_args.format_string_parts == [kw::Empty];
                 if match cx.typeck_results().expr_ty(value).peel_refs().kind() {
-                    ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did),
+                    ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did()),
                     ty::Str => true,
                     _ => false,
                 };
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index ea9b68d1a40..0709580c8ad 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -189,8 +189,8 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, tys: &m
         // primitive types are never mutable
         ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
         ty::Adt(adt, substs) => {
-            tys.insert(adt.did) && !ty.is_freeze(cx.tcx.at(span), cx.param_env)
-                || KNOWN_WRAPPER_TYS.iter().any(|path| match_def_path(cx, adt.did, path))
+            tys.insert(adt.did()) && !ty.is_freeze(cx.tcx.at(span), cx.param_env)
+                || KNOWN_WRAPPER_TYS.iter().any(|path| match_def_path(cx, adt.did(), path))
                     && substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys))
         },
         ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, span, tys)),
diff --git a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs
index 3d44a669d8f..c8ec2f45137 100644
--- a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs
+++ b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs
@@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for InconsistentStructConstructor {
             let ty = cx.typeck_results().expr_ty(expr);
             if let Some(adt_def) = ty.ty_adt_def();
             if adt_def.is_struct();
-            if let Some(variant) = adt_def.variants.iter().next();
+            if let Some(variant) = adt_def.variants().iter().next();
             if fields.iter().all(|f| f.is_shorthand);
             then {
                 let mut def_order_map = FxHashMap::default();
diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
index d1dc6b775c5..0f3889a2936 100644
--- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
+++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
@@ -81,11 +81,11 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
         if let ItemKind::Enum(ref def, _) = item.kind {
             let ty = cx.tcx.type_of(item.def_id);
             let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
-            if adt.variants.len() <= 1 {
+            if adt.variants().len() <= 1 {
                 return;
             }
             let mut variants_size: Vec<VariantInfo> = Vec::new();
-            for (i, variant) in adt.variants.iter().enumerate() {
+            for (i, variant) in adt.variants().iter().enumerate() {
                 let mut fields_size = Vec::new();
                 for (i, f) in variant.fields.iter().enumerate() {
                     let ty = cx.tcx.type_of(f.did);
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 35d10d53112..dabbb8375f0 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -248,13 +248,13 @@ enum LenOutput<'tcx> {
 fn parse_len_output<'tcx>(cx: &LateContext<'_>, sig: FnSig<'tcx>) -> Option<LenOutput<'tcx>> {
     match *sig.output().kind() {
         ty::Int(_) | ty::Uint(_) => Some(LenOutput::Integral),
-        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Option, adt.did) => {
-            subs.type_at(0).is_integral().then(|| LenOutput::Option(adt.did))
+        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) => {
+            subs.type_at(0).is_integral().then(|| LenOutput::Option(adt.did()))
         },
-        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Result, adt.did) => subs
+        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => subs
             .type_at(0)
             .is_integral()
-            .then(|| LenOutput::Result(adt.did, subs.type_at(1))),
+            .then(|| LenOutput::Result(adt.did(), subs.type_at(1))),
         _ => None,
     }
 }
@@ -263,8 +263,8 @@ impl LenOutput<'_> {
     fn matches_is_empty_output(self, ty: Ty<'_>) -> bool {
         match (self, ty.kind()) {
             (_, &ty::Bool) => true,
-            (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did => subs.type_at(0).is_bool(),
-            (Self::Result(id, err_ty), &ty::Adt(adt, subs)) if id == adt.did => {
+            (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(),
+            (Self::Result(id, err_ty), &ty::Adt(adt, subs)) if id == adt.did() => {
                 subs.type_at(0).is_bool() && subs.type_at(1) == err_ty
             },
             _ => false,
@@ -488,7 +488,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
                 .any(|item| is_is_empty(cx, item))
         }),
         ty::Projection(ref proj) => has_is_empty_impl(cx, proj.item_def_id),
-        ty::Adt(id, _) => has_is_empty_impl(cx, id.did),
+        ty::Adt(id, _) => has_is_empty_impl(cx, id.did()),
         ty::Array(..) | ty::Slice(..) | ty::Str => true,
         _ => false,
     }
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
index f6ef87264c0..b31015d195b 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
@@ -334,7 +334,7 @@ struct Start<'hir> {
 
 fn get_slice_like_element_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
     match ty.kind() {
-        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Vec, adt.did) => Some(subs.type_at(0)),
+        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Vec, adt.did()) => Some(subs.type_at(0)),
         ty::Ref(_, subty, _) => get_slice_like_element_ty(cx, *subty),
         ty::Slice(ty) | ty::Array(ty, _) => Some(*ty),
         _ => None,
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs
index 3515286d5b4..93bf0dc62e0 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs
@@ -45,8 +45,8 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
 
     // Accumulate the variants which should be put in place of the wildcard because they're not
     // already covered.
-    let has_hidden = adt_def.variants.iter().any(|x| is_hidden(cx, x));
-    let mut missing_variants: Vec<_> = adt_def.variants.iter().filter(|x| !is_hidden(cx, x)).collect();
+    let has_hidden = adt_def.variants().iter().any(|x| is_hidden(cx, x));
+    let mut missing_variants: Vec<_> = adt_def.variants().iter().filter(|x| !is_hidden(cx, x)).collect();
 
     let mut path_prefix = CommonPrefixSearcher::None;
     for arm in arms {
@@ -118,7 +118,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
                 }
                 s
             } else {
-                let mut s = cx.tcx.def_path_str(adt_def.did);
+                let mut s = cx.tcx.def_path_str(adt_def.did());
                 s.push_str("::");
                 s
             },
diff --git a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
index ce958b8ac9f..eec232e6d09 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
@@ -145,7 +145,7 @@ pub(crate) trait BindInsteadOfMap {
         if_chain! {
             if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def();
             if let Ok(vid) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM);
-            if Some(adt.did) == cx.tcx.parent(vid);
+            if Some(adt.did()) == cx.tcx.parent(vid);
             then {} else { return false; }
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs b/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
index 67a585edc25..6d30bb5a278 100644
--- a/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
@@ -15,7 +15,7 @@ pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span,
     let inner_ty = match recv_ty.kind() {
         // `Option<T>` -> `T`
         ty::Adt(adt, subst)
-            if cx.tcx.is_diagnostic_item(sym::Option, adt.did) && meets_msrv(msrv, &msrvs::OPTION_COPIED) =>
+            if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && meets_msrv(msrv, &msrvs::OPTION_COPIED) =>
         {
             subst.type_at(0)
         },
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
index 30c68186b3a..558cb6bd64e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
@@ -119,9 +119,9 @@ pub(super) fn check<'tcx>(
             if let PatKind::Binding(_, filter_param_id, _, None) = filter_pat.kind;
             if let ExprKind::MethodCall(path, [filter_arg], _) = filter_body.value.kind;
             if let Some(opt_ty) = cx.typeck_results().expr_ty(filter_arg).ty_adt_def();
-            if let Some(is_result) = if cx.tcx.is_diagnostic_item(sym::Option, opt_ty.did) {
+            if let Some(is_result) = if cx.tcx.is_diagnostic_item(sym::Option, opt_ty.did()) {
                 Some(false)
-            } else if cx.tcx.is_diagnostic_item(sym::Result, opt_ty.did) {
+            } else if cx.tcx.is_diagnostic_item(sym::Result, opt_ty.did()) {
                 Some(true)
             } else {
                 None
diff --git a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
index 7a255baffd7..6e64e7f6222 100644
--- a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
@@ -17,7 +17,7 @@ pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv
         let return_type = cx.typeck_results().expr_ty(expr);
         let input_type = cx.typeck_results().expr_ty(recv);
         let (input_type, ref_count) = peel_mid_ty_refs(input_type);
-        if let Some(ty_name) = input_type.ty_adt_def().map(|adt_def| cx.tcx.item_name(adt_def.did));
+        if let Some(ty_name) = input_type.ty_adt_def().map(|adt_def| cx.tcx.item_name(adt_def.did()));
         if return_type == input_type;
         then {
             let mut app = Applicability::MachineApplicable;
diff --git a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
index c0f66feb48a..06ead144afa 100644
--- a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
@@ -60,7 +60,7 @@ fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     }
 
     if let ty::Adt(adt, substs) = ty.kind() {
-        match_def_path(cx, adt.did, &paths::COW) && substs.type_at(1).is_str()
+        match_def_path(cx, adt.did(), &paths::COW) && substs.type_at(1).is_str()
     } else {
         false
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
index 6782f64f2ca..e1212c31cfb 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
@@ -55,9 +55,9 @@ pub(super) fn check<'tcx>(
     // lint if caller of `.map().flatten()` is an Option or Result
     let caller_type = match cx.typeck_results().expr_ty(recv).kind() {
         ty::Adt(adt, _) => {
-            if cx.tcx.is_diagnostic_item(sym::Option, adt.did) {
+            if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) {
                 "Option"
-            } else if cx.tcx.is_diagnostic_item(sym::Result, adt.did) {
+            } else if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) {
                 "Result"
             } else {
                 return;
diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
index 926c25b4b40..8125930b304 100644
--- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
@@ -152,7 +152,7 @@ fn parse_iter_usage<'tcx>(
                     return if_chain! {
                         if match_def_path(cx, did, &paths::ITERTOOLS_NEXT_TUPLE);
                         if let ty::Adt(adt_def, subs) = cx.typeck_results().expr_ty(e).kind();
-                        if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did);
+                        if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did());
                         if let ty::Tuple(subs) = subs.type_at(0).kind();
                         if subs.len() == 2;
                         then {
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
index 12ad3d8d690..a307e33875e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -33,7 +33,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
         } else if !found_mapping && !mutates_arg {
             let in_ty = cx.typeck_results().node_type(body.params[0].hir_id);
             match cx.typeck_results().expr_ty(&body.value).kind() {
-                ty::Adt(adt, subst) if cx.tcx.is_diagnostic_item(sym::Option, adt.did) && in_ty == subst.type_at(0) => {
+                ty::Adt(adt, subst) if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && in_ty == subst.type_at(0) => {
                     "filter"
                 },
                 _ => return,
diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs
index ce9ca15430e..cba54e14212 100644
--- a/src/tools/clippy/clippy_lints/src/mut_key.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_key.rs
@@ -125,7 +125,7 @@ fn check_ty<'tcx>(cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
     if let Adt(def, substs) = ty.kind() {
         let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet]
             .iter()
-            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did));
+            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
         if is_keyed_type && is_interior_mutable_type(cx, substs.type_at(0), span) {
             span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type");
         }
@@ -159,8 +159,8 @@ fn is_interior_mutable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Sp
                 sym::Arc,
             ]
             .iter()
-            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did));
-            let is_box = Some(def.did) == cx.tcx.lang_items().owned_box();
+            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
+            let is_box = Some(def.did()) == cx.tcx.lang_items().owned_box();
             if is_std_collection || is_box {
                 // The type is mutable if any of its type parameters are
                 substs.types().any(|ty| is_interior_mutable_type(cx, ty, span))
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index ebfd908a6fb..a57dc2b2798 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -198,7 +198,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                     // Dereference suggestion
                     let sugg = |diag: &mut Diagnostic| {
                         if let ty::Adt(def, ..) = ty.kind() {
-                            if let Some(span) = cx.tcx.hir().span_if_local(def.did) {
+                            if let Some(span) = cx.tcx.hir().span_if_local(def.did()) {
                                 if can_type_implement_copy(cx.tcx, cx.param_env, ty, traits::ObligationCause::dummy_with_span(span)).is_ok() {
                                     diag.span_help(span, "consider marking this type as `Copy`");
                                 }
diff --git a/src/tools/clippy/clippy_lints/src/needless_update.rs b/src/tools/clippy/clippy_lints/src/needless_update.rs
index ed315efaa2f..c87c174ef73 100644
--- a/src/tools/clippy/clippy_lints/src/needless_update.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_update.rs
@@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessUpdate {
             let ty = cx.typeck_results().expr_ty(expr);
             if let ty::Adt(def, _) = ty.kind() {
                 if fields.len() == def.non_enum_variant().fields.len()
-                    && !def.variants[0_usize.into()].is_field_list_non_exhaustive()
+                    && !def.variant(0_usize.into()).is_field_list_non_exhaustive()
                 {
                     span_lint(
                         cx,
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index 6c68c1bc48d..9419056be14 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -113,7 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                                     let mut impls = HirIdSet::default();
                                     cx.tcx.for_each_impl(default_trait_id, |d| {
                                         if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() {
-                                            if let Some(local_def_id) = ty_def.did.as_local() {
+                                            if let Some(local_def_id) = ty_def.did().as_local() {
                                                 impls.insert(cx.tcx.hir().local_def_id_to_hir_id(local_def_id));
                                             }
                                         }
@@ -126,7 +126,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                                 if_chain! {
                                     if let Some(ref impling_types) = self.impling_types;
                                     if let Some(self_def) = cx.tcx.type_of(self_def_id).ty_adt_def();
-                                    if let Some(self_local_did) = self_def.did.as_local();
+                                    if let Some(self_local_did) = self_def.did().as_local();
                                     let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did);
                                     if impling_types.contains(&self_id);
                                     then {
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 3ba99403f06..8db41ba6ee2 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -140,7 +140,7 @@ fn is_value_unfrozen_raw<'tcx>(
         match val.ty().kind() {
             // the fact that we have to dig into every structs to search enums
             // leads us to the point checking `UnsafeCell` directly is the only option.
-            ty::Adt(ty_def, ..) if Some(ty_def.did) == cx.tcx.lang_items().unsafe_cell_type() => true,
+            ty::Adt(ty_def, ..) if Some(ty_def.did()) == cx.tcx.lang_items().unsafe_cell_type() => true,
             ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => {
                 let val = cx.tcx.destructure_const(cx.param_env.and(val));
                 val.fields.iter().any(|field| inner(cx, *field))
diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
index 5168ca67b6a..ddef7352de8 100644
--- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
+++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
@@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
                 let mut non_send_fields = Vec::new();
 
                 let hir_map = cx.tcx.hir();
-                for variant in &adt_def.variants {
+                for variant in adt_def.variants() {
                     for field in &variant.fields {
                         if_chain! {
                             if let Some(field_hir_id) = field
@@ -233,7 +233,7 @@ fn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> b
                     return true;
                 },
                 ty::Adt(adt_def, _) => {
-                    if match_def_path(cx, adt_def.did, &paths::PTR_NON_NULL) {
+                    if match_def_path(cx, adt_def.did(), &paths::PTR_NON_NULL) {
                         return true;
                     }
                 },
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 2c328195f24..9c776437d7f 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -405,13 +405,13 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
                 // Check that the name as typed matches the actual name of the type.
                 // e.g. `fn foo(_: &Foo)` shouldn't trigger the lint when `Foo` is an alias for `Vec`
                 if let [.., name] = path.segments;
-                if cx.tcx.item_name(adt.did) == name.ident.name;
+                if cx.tcx.item_name(adt.did()) == name.ident.name;
 
                 if !is_lint_allowed(cx, PTR_ARG, hir_ty.hir_id);
                 if params.get(i).map_or(true, |p| !is_lint_allowed(cx, PTR_ARG, p.hir_id));
 
                 then {
-                    let (method_renames, deref_ty, deref_impl_id) = match cx.tcx.get_diagnostic_name(adt.did) {
+                    let (method_renames, deref_ty, deref_impl_id) = match cx.tcx.get_diagnostic_name(adt.did()) {
                         Some(sym::Vec) => (
                             [("clone", ".to_owned()")].as_slice(),
                             DerefTy::Slice(
@@ -462,7 +462,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
                     return Some(PtrArg {
                         idx: i,
                         span: hir_ty.span,
-                        ty_did: adt.did,
+                        ty_did: adt.did(),
                         ty_name: name.ident.name,
                         method_renames,
                         ref_prefix: RefPrefix {
@@ -570,7 +570,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
                             .map(|sig| sig.input(i).skip_binder().peel_refs())
                             .map_or(true, |ty| match *ty.kind() {
                                 ty::Param(_) => true,
-                                ty::Adt(def, _) => def.did == args.ty_did,
+                                ty::Adt(def, _) => def.did() == args.ty_did,
                                 _ => false,
                             })
                         {
@@ -607,7 +607,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
                             // If the types match check for methods which exist on both types. e.g. `Vec::len` and
                             // `slice::len`
                             ty::Adt(def, _)
-                                if def.did == args.ty_did
+                                if def.did() == args.ty_did
                                     && (i != 0
                                         || self.cx.tcx.trait_of_item(id).is_some()
                                         || !args.deref_assoc_items.map_or(false, |(id, items)| {
diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
index 123d0ad0457..d07c26d7c89 100644
--- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
+++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
@@ -72,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
 
         if_chain! {
             if let Some(self_def) = self_ty.ty_adt_def();
-            if let Some(self_local_did) = self_def.did.as_local();
+            if let Some(self_local_did) = self_def.did().as_local();
             let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did);
             if let Some(Node::Item(x)) = cx.tcx.hir().find(self_id);
             let type_name = x.ident.name.as_str().to_lowercase();
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
index 81076776ed3..6edff224092 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
@@ -141,7 +141,7 @@ pub(super) fn check<'tcx>(
                                 then {
                                     diag.note(&format!(
                                         "two instances of the same generic type (`{}`) may have different layouts",
-                                        cx.tcx.item_name(from_def.did)
+                                        cx.tcx.item_name(from_def.did())
                                     ));
                                 } else {
                                     if from_ty_orig.peel_refs() != from_ty {
@@ -304,13 +304,13 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
                     ty = sized_ty;
                     continue;
                 }
-                if def.repr.inhibit_struct_field_reordering_opt() {
+                if def.repr().inhibit_struct_field_reordering_opt() {
                     ReducedTy::OrderedFields(ty)
                 } else {
                     ReducedTy::UnorderedFields(ty)
                 }
             },
-            ty::Adt(def, _) if def.is_enum() && (def.variants.is_empty() || is_c_void(cx, ty)) => {
+            ty::Adt(def, _) if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) => {
                 ReducedTy::TypeErasure
             },
             ty::Foreign(_) => ReducedTy::TypeErasure,
diff --git a/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
index 2d67401a15f..831b0d450d2 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
@@ -11,11 +11,11 @@ use rustc_span::symbol::sym;
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
     match (&from_ty.kind(), &to_ty.kind()) {
         (ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => {
-            if from_adt.did != to_adt.did {
+            if from_adt.did() != to_adt.did() {
                 return false;
             }
             if !matches!(
-                cx.tcx.get_diagnostic_name(to_adt.did),
+                cx.tcx.get_diagnostic_name(to_adt.did()),
                 Some(
                     sym::BTreeMap
                         | sym::BTreeSet
diff --git a/src/tools/clippy/clippy_lints/src/try_err.rs b/src/tools/clippy/clippy_lints/src/try_err.rs
index 4da32c52e75..80d6f3c6336 100644
--- a/src/tools/clippy/clippy_lints/src/try_err.rs
+++ b/src/tools/clippy/clippy_lints/src/try_err.rs
@@ -151,11 +151,11 @@ fn result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
 fn poll_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
     if_chain! {
         if let ty::Adt(def, subst) = ty.kind();
-        if match_def_path(cx, def.did, &paths::POLL);
+        if match_def_path(cx, def.did(), &paths::POLL);
         let ready_ty = subst.type_at(0);
 
         if let ty::Adt(ready_def, ready_subst) = ready_ty.kind();
-        if cx.tcx.is_diagnostic_item(sym::Result, ready_def.did);
+        if cx.tcx.is_diagnostic_item(sym::Result, ready_def.did());
         then {
             Some(ready_subst.type_at(1))
         } else {
@@ -168,15 +168,15 @@ fn poll_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<
 fn poll_option_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
     if_chain! {
         if let ty::Adt(def, subst) = ty.kind();
-        if match_def_path(cx, def.did, &paths::POLL);
+        if match_def_path(cx, def.did(), &paths::POLL);
         let ready_ty = subst.type_at(0);
 
         if let ty::Adt(ready_def, ready_subst) = ready_ty.kind();
-        if cx.tcx.is_diagnostic_item(sym::Option, ready_def.did);
+        if cx.tcx.is_diagnostic_item(sym::Option, ready_def.did());
         let some_ty = ready_subst.type_at(0);
 
         if let ty::Adt(some_def, some_subst) = some_ty.kind();
-        if cx.tcx.is_diagnostic_item(sym::Result, some_def.did);
+        if cx.tcx.is_diagnostic_item(sym::Result, some_def.did());
         then {
             Some(some_subst.type_at(1))
         } else {
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
index 1728533f18b..f4f5a4336a3 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
@@ -102,9 +102,9 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
 
         // Get the wrapper and inner types, if can't, abort.
         let (return_type_label, lang_item, inner_type) = if let ty::Adt(adt_def, subst) = return_ty(cx, hir_id).kind() {
-            if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did) {
+            if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did()) {
                 ("Option", OptionSome, subst.type_at(0))
-            } else if cx.tcx.is_diagnostic_item(sym::Result, adt_def.did) {
+            } else if cx.tcx.is_diagnostic_item(sym::Result, adt_def.did()) {
                 ("Result", ResultOk, subst.type_at(0))
             } else {
                 return;
diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
index eb9efec3f16..a6ef6d79fc0 100644
--- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
+++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
@@ -73,7 +73,7 @@ fn fn_eagerness<'tcx>(
         // than marker traits.
         // Due to the limited operations on these types functions should be fairly cheap.
         if def
-            .variants
+            .variants()
             .iter()
             .flat_map(|v| v.fields.iter())
             .any(|x| matches!(cx.tcx.type_of(x.did).peel_refs().kind(), ty::Param(_)))
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 8c14f0dd761..cd20abd94ed 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -268,7 +268,7 @@ pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str])
 pub fn is_diag_item_method(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool {
     if let Some(impl_did) = cx.tcx.impl_of_method(def_id) {
         if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() {
-            return cx.tcx.is_diagnostic_item(diag_item, adt.did);
+            return cx.tcx.is_diagnostic_item(diag_item, adt.did());
         }
     }
     false
@@ -657,7 +657,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<
                 if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() {
                     return std_types_symbols
                         .iter()
-                        .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did));
+                        .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did()));
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 0646d1524a7..3645a9a5228 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -51,7 +51,7 @@ pub fn contains_ty(ty: Ty<'_>, other_ty: Ty<'_>) -> bool {
 
 /// Walks into `ty` and returns `true` if any inner type is an instance of the given adt
 /// constructor.
-pub fn contains_adt_constructor(ty: Ty<'_>, adt: &AdtDef) -> bool {
+pub fn contains_adt_constructor(ty: Ty<'_>, adt: AdtDef<'_>) -> bool {
     ty.walk().any(|inner| match inner.unpack() {
         GenericArgKind::Type(inner_ty) => inner_ty.ty_adt_def() == Some(adt),
         GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
@@ -112,7 +112,7 @@ pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<
     let def_id = match ty_to_check.kind() {
         ty::Array(..) => return Some(sym::array),
         ty::Slice(..) => return Some(sym::slice),
-        ty::Adt(adt, _) => adt.did,
+        ty::Adt(adt, _) => adt.did(),
         _ => return None,
     };
 
@@ -164,7 +164,7 @@ pub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
 // Returns whether the type has #[must_use] attribute
 pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
     match ty.kind() {
-        ty::Adt(adt, _) => must_use_attr(cx.tcx.get_attrs(adt.did)).is_some(),
+        ty::Adt(adt, _) => must_use_attr(cx.tcx.get_attrs(adt.did())).is_some(),
         ty::Foreign(ref did) => must_use_attr(cx.tcx.get_attrs(*did)).is_some(),
         ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => {
             // for the Array case we don't need to care for the len == 0 case
@@ -220,7 +220,7 @@ fn is_normalizable_helper<'tcx>(
         let cause = rustc_middle::traits::ObligationCause::dummy();
         if infcx.at(&cause, param_env).normalize(ty).is_ok() {
             match ty.kind() {
-                ty::Adt(def, substs) => def.variants.iter().all(|variant| {
+                ty::Adt(def, substs) => def.variants().iter().all(|variant| {
                     variant
                         .fields
                         .iter()
@@ -264,7 +264,7 @@ pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool {
 pub fn is_type_ref_to_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symbol) -> bool {
     match ty.kind() {
         ty::Ref(_, ref_ty, _) => match ref_ty.kind() {
-            ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did),
+            ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did()),
             _ => false,
         },
         _ => false,
@@ -284,7 +284,7 @@ pub fn is_type_ref_to_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_ite
 /// [Diagnostic Items]: https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-items.html
 pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symbol) -> bool {
     match ty.kind() {
-        ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did),
+        ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did()),
         _ => false,
     }
 }
@@ -294,7 +294,7 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symb
 /// Returns `false` if the `LangItem` is not defined.
 pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool {
     match ty.kind() {
-        ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).map_or(false, |li| li == adt.did),
+        ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).map_or(false, |li| li == adt.did()),
         _ => false,
     }
 }
@@ -310,7 +310,7 @@ pub fn is_isize_or_usize(typ: Ty<'_>) -> bool {
 /// If you change the signature, remember to update the internal lint `MatchTypeOnDiagItem`
 pub fn match_type(cx: &LateContext<'_>, ty: Ty<'_>, path: &[&str]) -> bool {
     match ty.kind() {
-        ty::Adt(adt, _) => match_def_path(cx, adt.did, path),
+        ty::Adt(adt, _) => match_def_path(cx, adt.did(), path),
         _ => false,
     }
 }
@@ -398,7 +398,7 @@ pub fn is_uninit_value_valid_for_ty(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     match *ty.kind() {
         ty::Array(component, _) => is_uninit_value_valid_for_ty(cx, component),
         ty::Tuple(types) => types.iter().all(|ty| is_uninit_value_valid_for_ty(cx, ty)),
-        ty::Adt(adt, _) => cx.tcx.lang_items().maybe_uninit() == Some(adt.did),
+        ty::Adt(adt, _) => cx.tcx.lang_items().maybe_uninit() == Some(adt.did()),
         _ => false,
     }
 }
@@ -562,11 +562,11 @@ pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option<EnumValue>
 }
 
 /// Gets the value of the given variant.
-pub fn get_discriminant_value(tcx: TyCtxt<'_>, adt: &'_ AdtDef, i: VariantIdx) -> EnumValue {
-    let variant = &adt.variants[i];
+pub fn get_discriminant_value(tcx: TyCtxt<'_>, adt: AdtDef<'_>, i: VariantIdx) -> EnumValue {
+    let variant = &adt.variant(i);
     match variant.discr {
         VariantDiscr::Explicit(id) => read_explicit_enum_value(tcx, id).unwrap(),
-        VariantDiscr::Relative(x) => match adt.variants[(i.as_usize() - x as usize).into()].discr {
+        VariantDiscr::Relative(x) => match adt.variant((i.as_usize() - x as usize).into()).discr {
             VariantDiscr::Explicit(id) => read_explicit_enum_value(tcx, id).unwrap() + x,
             VariantDiscr::Relative(_) => EnumValue::Unsigned(x.into()),
         },
@@ -577,7 +577,7 @@ pub fn get_discriminant_value(tcx: TyCtxt<'_>, adt: &'_ AdtDef, i: VariantIdx) -
 /// platform specific `libc::<platform>::c_void` types in libc.
 pub fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     if let ty::Adt(adt, _) = ty.kind()
-        && let &[krate, .., name] = &*cx.get_def_path(adt.did)
+        && let &[krate, .., name] = &*cx.get_def_path(adt.did())
         && let sym::libc | sym::core | sym::std = krate
         && name.as_str() == "c_void"
     {