1
Fork 0

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`.
This commit is contained in:
Nicholas Nethercote 2022-03-05 07:28:41 +11:00
parent 5f4e067719
commit ca5525d564
169 changed files with 702 additions and 687 deletions

View file

@ -138,7 +138,7 @@ impl BorrowExplanation {
let mut ty = local_decl.ty; let mut ty = local_decl.ty;
if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) { if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
if let ty::Adt(adt, substs) = local_decl.ty.kind() { 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 // in for loop desugaring, only look at the `Some(..)` inner type
ty = substs.type_at(0); ty = substs.type_at(0);
} }
@ -148,7 +148,7 @@ impl BorrowExplanation {
// If type is an ADT that implements Drop, then // If type is an ADT that implements Drop, then
// simplify output by reporting just the ADT name. // simplify output by reporting just the ADT name.
ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => { 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 // Otherwise, just report the whole type (and use

View file

@ -370,7 +370,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
ty::Adt(def, _) => { ty::Adt(def, _) => {
let variant = if let Some(idx) = variant_index { let variant = if let Some(idx) = variant_index {
assert!(def.is_enum()); assert!(def.is_enum());
&def.variants[idx] &def.variant(idx)
} else { } else {
def.non_enum_variant() def.non_enum_variant()
}; };
@ -701,7 +701,7 @@ impl<'tcx> BorrowedContentSource<'tcx> {
BorrowedContentSource::DerefMutableRef => "a mutable reference".to_string(), BorrowedContentSource::DerefMutableRef => "a mutable reference".to_string(),
BorrowedContentSource::OverloadedDeref(ty) => ty BorrowedContentSource::OverloadedDeref(ty) => ty
.ty_adt_def() .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)), name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
_ => None, _ => None,
}) })
@ -731,7 +731,7 @@ impl<'tcx> BorrowedContentSource<'tcx> {
} }
BorrowedContentSource::OverloadedDeref(ty) => ty BorrowedContentSource::OverloadedDeref(ty) => ty
.ty_adt_def() .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)), name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
_ => None, _ => None,
}) })

View file

@ -388,7 +388,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}; };
let ty = move_place.ty(self.body, self.infcx.tcx).ty; let ty = move_place.ty(self.body, self.infcx.tcx).ty;
let def_id = match *ty.kind() { 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::Foreign(def_id)
| ty::FnDef(def_id, _) | ty::FnDef(def_id, _)
| ty::Closure(def_id, _) | ty::Closure(def_id, _)

View file

@ -345,8 +345,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
ty::Adt(adt, substs) => { ty::Adt(adt, substs) => {
let generic_arg = substs[param_index as usize]; let generic_arg = substs[param_index as usize];
let identity_substs = let identity_substs =
InternalSubsts::identity_for_item(self.infcx.tcx, adt.did); InternalSubsts::identity_for_item(self.infcx.tcx, adt.did());
let base_ty = self.infcx.tcx.mk_adt(adt, identity_substs); let base_ty = self.infcx.tcx.mk_adt(*adt, identity_substs);
let base_generic_arg = identity_substs[param_index as usize]; let base_generic_arg = identity_substs[param_index as usize];
let adt_desc = adt.descr(); 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 \ "returns a closure that contains a reference to a captured variable, which then \
escapes the closure body" 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 \ "returns an `async` block that contains a reference to a captured variable, which then \
escapes the closure body" escapes the closure body"
} }

View file

@ -736,13 +736,13 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
} }
ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() { ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() {
ty::Adt(adt_def, _substs) if adt_def.is_enum() => { 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!( PlaceTy::from_ty(span_mirbug_and_err!(
self, self,
place, place,
"cast to variant #{:?} but enum only has {:?}", "cast to variant #{:?} but enum only has {:?}",
index, index,
adt_def.variants.len() adt_def.variants().len()
)) ))
} else { } else {
PlaceTy { ty: base_ty, variant_index: Some(index) } 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 { let (variant, substs) = match base_ty {
PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() { 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, _) => { ty::Generator(def_id, substs, _) => {
let mut variants = substs.as_generator().state_tys(def_id, tcx); let mut variants = substs.as_generator().state_tys(def_id, tcx);
let Some(mut variant) = variants.nth(variant_index.into()) else { 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() { PlaceTy { ty, variant_index: None } => match *ty.kind() {
ty::Adt(adt_def, substs) if !adt_def.is_enum() => { 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) => { ty::Closure(_, substs) => {
return match 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!( span_bug!(
stmt.source_info.span, stmt.source_info.span,
"bad set discriminant ({:?} = {:?}): value of of range", "bad set discriminant ({:?} = {:?}): value of of range",
@ -1928,7 +1928,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
match *ak { match *ak {
AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => { AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => {
let def = tcx.adt_def(adt_did); 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); let adj_field_index = active_field_index.unwrap_or(field_index);
if let Some(field) = variant.fields.get(adj_field_index) { if let Some(field) = variant.fields.get(adj_field_index) {
Ok(self.normalize(field.ty(tcx, substs), location)) Ok(self.normalize(field.ty(tcx, substs), location))

View file

@ -67,7 +67,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
pointer_ty(tcx) 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 let (element, count) = match &tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().abi
{ {
Abi::Vector { element, count } => (element.clone(), *count), Abi::Vector { element, count } => (element.clone(), *count),

View file

@ -127,7 +127,7 @@ pub(crate) fn coerce_unsized_into<'tcx>(
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
assert_eq!(def_a, 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 src_f = src.value_field(fx, mir::Field::new(i));
let dst_f = dst.place_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. // Packed types ignore the alignment of their fields.
if let ty::Adt(def, _) = layout.ty.kind() { if let ty::Adt(def, _) = layout.ty.kind() {
if def.repr.packed() { if def.repr().packed() {
unsized_align = sized_align; unsized_align = sized_align;
} }
} }

View file

@ -24,7 +24,7 @@ fn codegen_field<'tcx>(
} }
match field_layout.ty.kind() { match field_layout.ty.kind() {
ty::Slice(..) | ty::Str | ty::Foreign(..) => simple(fx), 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); assert_eq!(layout.align.abi.bytes(), 1);
simple(fx) simple(fx)
} }
@ -816,7 +816,7 @@ pub(crate) fn assert_assignable<'tcx>(
// dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
} }
(&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b)) (&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_a = substs_a.types();
let mut types_b = substs_b.types(); let mut types_b = substs_b.types();

View file

@ -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 }) = if let (&ty::Adt(def, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants) (layout.ty.kind(), &layout.variants)
{ {
if def.is_enum() && !def.variants.is_empty() { if def.is_enum() && !def.variants().is_empty() {
write!(&mut name, "::{}", def.variants[index].name).unwrap(); write!(&mut name, "::{}", def.variant(index).name).unwrap();
} }
} }
if let (&ty::Generator(_, _, _), &Variants::Single { index }) = if let (&ty::Generator(_, _, _), &Variants::Single { index }) =

View file

@ -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::Struct => prepare_struct_metadata(cx, t, unique_type_id).finalize(cx),
AdtKind::Union => prepare_union_metadata(cx, t, unique_type_id).finalize(cx), AdtKind::Union => prepare_union_metadata(cx, t, unique_type_id).finalize(cx),
AdtKind::Enum => { 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) => { 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_name = compute_debuginfo_type_name(cx.tcx, struct_type, false);
let (struct_def_id, variant) = match struct_type.kind() { 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"), _ => 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_name = compute_debuginfo_type_name(cx.tcx, union_type, false);
let (union_def_id, variant) = match union_type.kind() { 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"), _ => 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() { 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, _, _) => { ty::Generator(def_id, _, _) => {
let (generator_layout, generator_saved_local_names) = let (generator_layout, generator_saved_local_names) =
generator_variant_info_data.as_ref().unwrap(); generator_variant_info_data.as_ref().unwrap();
@ -1490,7 +1490,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
match self.layout.variants { match self.layout.variants {
Variants::Single { index } => { Variants::Single { index } => {
if let ty::Adt(adt, _) = self.enum_type.kind() { if let ty::Adt(adt, _) = self.enum_type.kind() {
if adt.variants.is_empty() { if adt.variants().is_empty() {
return vec![]; return vec![];
} }
} }
@ -1940,7 +1940,7 @@ fn prepare_enum_metadata<'ll, 'tcx>(
let discriminant_type_metadata = |discr: Primitive| { let discriminant_type_metadata = |discr: Primitive| {
let enumerators_metadata: Vec<_> = match enum_type.kind() { 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)| { .map(|((_, discr), v)| {
let name = v.name.as_str(); let name = v.name.as_str();
let is_unsigned = match discr.ty.kind() { 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 { fn compute_type_parameters<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> &'ll DIArray {
if let ty::Adt(def, substs) = *ty.kind() { if let ty::Adt(def, substs) = *ty.kind() {
if substs.types().next().is_some() { 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 names = get_parameter_names(cx, generics);
let template_params: Vec<_> = iter::zip(substs, names) let template_params: Vec<_> = iter::zip(substs, names)
.filter_map(|(kind, name)| { .filter_map(|(kind, name)| {

View file

@ -524,7 +524,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
{ {
Some(type_metadata(cx, impl_self_ty)) Some(type_metadata(cx, impl_self_ty))
} else { } else {
Some(namespace::item_namespace(cx, def.did)) Some(namespace::item_namespace(cx, def.did()))
} }
} }
_ => None, _ => None,

View file

@ -53,8 +53,8 @@ fn uncached_llvm_type<'a, 'tcx>(
if let (&ty::Adt(def, _), &Variants::Single { index }) = if let (&ty::Adt(def, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants) (layout.ty.kind(), &layout.variants)
{ {
if def.is_enum() && !def.variants.is_empty() { if def.is_enum() && !def.variants().is_empty() {
write!(&mut name, "::{}", def.variants[index].name).unwrap(); write!(&mut name, "::{}", def.variant(index).name).unwrap();
} }
} }
if let (&ty::Generator(_, _, _), &Variants::Single { index }) = if let (&ty::Generator(_, _, _), &Variants::Single { index }) =

View file

@ -255,7 +255,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
assert_eq!(def_a, 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 src_f = src.project_field(bx, i);
let dst_f = dst.project_field(bx, i); let dst_f = dst.project_field(bx, i);

View file

@ -74,7 +74,7 @@ fn push_debuginfo_type_name<'tcx>(
if def.is_enum() && cpp_like_debuginfo { if def.is_enum() && cpp_like_debuginfo {
msvc_enum_fallback(tcx, t, def, substs, output, visited); msvc_enum_fallback(tcx, t, def, substs, output, visited);
} else { } 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); push_generic_params_internal(tcx, substs, output, visited);
} }
} }
@ -405,15 +405,15 @@ fn push_debuginfo_type_name<'tcx>(
fn msvc_enum_fallback<'tcx>( fn msvc_enum_fallback<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
def: &AdtDef, def: AdtDef<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
output: &mut String, output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>, 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$<"); 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); push_generic_params_internal(tcx, substs, output, visited);
if let Variants::Multiple { if let Variants::Multiple {
@ -435,14 +435,14 @@ fn push_debuginfo_type_name<'tcx>(
let max = dataful_discriminant_range.end; let max = dataful_discriminant_range.end;
let max = tag.value.size(&tcx).truncate(max); 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)); output.push_str(&format!(", {}, {}, {}", min, max, dataful_variant_name));
} else if let Variants::Single { index: variant_idx } = &layout.variants { } else if let Variants::Single { index: variant_idx } = &layout.variants {
// Uninhabited enums can't be constructed and should never need to be visualized so // Uninhabited enums can't be constructed and should never need to be visualized so
// skip this step for them. // skip this step for them.
if def.variants.len() != 0 { if def.variants().len() != 0 {
let variant = def.variants[*variant_idx].name.as_str(); let variant = def.variant(*variant_idx).name.as_str();
output.push_str(&format!(", {}", variant)); output.push_str(&format!(", {}", variant));
} }

View file

@ -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. // Packed types ignore the alignment of their fields.
if let ty::Adt(def, _) = t.kind() { if let ty::Adt(def, _) = t.kind() {
if def.repr.packed() { if def.repr().packed() {
unsized_align = sized_align; unsized_align = sized_align;
} }
} }

View file

@ -149,7 +149,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
_ if !field.is_unsized() => return simple(), _ if !field.is_unsized() => return simple(),
ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(), ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(),
ty::Adt(def, _) => { ty::Adt(def, _) => {
if def.repr.packed() { if def.repr().packed() {
// FIXME(eddyb) generalize the adjustment when we // FIXME(eddyb) generalize the adjustment when we
// start supporting packing to larger alignments. // start supporting packing to larger alignments.
assert_eq!(self.layout.align.abi.bytes(), 1); assert_eq!(self.layout.align.abi.bytes(), 1);

View file

@ -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::Array(_, len) => branches(usize::try_from(len.eval_usize(ecx.tcx.tcx, ecx.param_env)).unwrap(), None),
ty::Adt(def, _) => { 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") bug!("uninhabited types should have errored and never gotten converted to valtree")
} }
let variant = ecx.read_discriminant(&place.into()).unwrap().1; 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 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 // 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 // there are no variants `read_discriminant` successfully returns a non-existing variant
// index). // 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, _) => { ty::Adt(def, _) => {
let variant = ecx.read_discriminant(&op)?.1; let variant = ecx.read_discriminant(&op)?.1;
let down = ecx.operand_downcast(&op, variant)?; 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), ty::Tuple(substs) => (substs.len(), None, op),
_ => bug!("cannot destructure constant {:?}", val), _ => bug!("cannot destructure constant {:?}", val),

View file

@ -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 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 // We are crossing over an `UnsafeCell`, we can mutate again. This means that
// References we encounter inside here are interned as pointing to mutable // References we encounter inside here are interned as pointing to mutable
// allocations. // allocations.

View file

@ -73,7 +73,9 @@ crate fn eval_nullary_intrinsic<'tcx>(
} }
sym::variant_count => match tp_ty.kind() { sym::variant_count => match tp_ty.kind() {
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. // 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::Projection(_)
| ty::Opaque(_, _) | ty::Opaque(_, _)
| ty::Param(_) | ty::Param(_)

View file

@ -1,3 +1,4 @@
use rustc_data_structures::intern::Interned;
use rustc_hir::def_id::CrateNum; use rustc_hir::def_id::CrateNum;
use rustc_hir::definitions::DisambiguatedDefPathData; use rustc_hir::definitions::DisambiguatedDefPathData;
use rustc_middle::mir::interpret::{Allocation, ConstAllocation}; 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). // 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::FnDef(def_id, substs)
| ty::Opaque(def_id, substs) | ty::Opaque(def_id, substs)
| ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })

View file

@ -759,7 +759,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
.ty .ty
.ty_adt_def() .ty_adt_def()
.expect("tagged layout for non adt") .expect("tagged layout for non adt")
.variants .variants()
.len(); .len();
assert!(usize::try_from(variant_index).unwrap() < variants_len); assert!(usize::try_from(variant_index).unwrap() < variants_len);
VariantIdx::from_u32(variant_index) VariantIdx::from_u32(variant_index)

View file

@ -267,7 +267,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
match layout.variants { match layout.variants {
Variants::Single { index } => { Variants::Single { index } => {
// Inside a variant // 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"), 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>, new_op: &OpTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
let name = match old_op.layout.ty.kind() { 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 // Generators also have variants
ty::Generator(..) => PathElem::GeneratorState(variant_id), ty::Generator(..) => PathElem::GeneratorState(variant_id),
_ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty), _ => 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 // Special check preventing `UnsafeCell` in the inner part of constants
if let Some(def) = op.layout.ty.ty_adt_def() { if let Some(def) = op.layout.ty.ty_adt_def() {
if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { inner: true, .. })) 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`" }); throw_validation_failure!(self.path, { "`UnsafeCell` in a `const`" });
} }

View file

@ -71,7 +71,7 @@ pub trait Qualif {
/// Returning `true` for `in_adt_inherently` but `false` for `in_any_value_of_ty` is unsound. /// Returning `true` for `in_adt_inherently` but `false` for `in_any_value_of_ty` is unsound.
fn in_adt_inherently<'tcx>( fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>, cx: &ConstCx<'_, 'tcx>,
adt: &'tcx AdtDef, adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
) -> bool; ) -> bool;
} }
@ -96,12 +96,12 @@ impl Qualif for HasMutInterior {
fn in_adt_inherently<'tcx>( fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>, cx: &ConstCx<'_, 'tcx>,
adt: &'tcx AdtDef, adt: AdtDef<'tcx>,
_: SubstsRef<'tcx>, _: SubstsRef<'tcx>,
) -> bool { ) -> bool {
// Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently. // Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
// It arises structurally for all other types. // 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>( fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>, cx: &ConstCx<'_, 'tcx>,
adt: &'tcx AdtDef, adt: AdtDef<'tcx>,
_: SubstsRef<'tcx>, _: SubstsRef<'tcx>,
) -> bool { ) -> bool {
adt.has_dtor(cx.tcx) adt.has_dtor(cx.tcx)
@ -205,7 +205,7 @@ impl Qualif for NeedsNonConstDrop {
fn in_adt_inherently<'tcx>( fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>, cx: &ConstCx<'_, 'tcx>,
adt: &'tcx AdtDef, adt: AdtDef<'tcx>,
_: SubstsRef<'tcx>, _: SubstsRef<'tcx>,
) -> bool { ) -> bool {
adt.has_non_const_dtor(cx.tcx) adt.has_non_const_dtor(cx.tcx)
@ -233,7 +233,7 @@ impl Qualif for CustomEq {
fn in_adt_inherently<'tcx>( fn in_adt_inherently<'tcx>(
cx: &ConstCx<'_, 'tcx>, cx: &ConstCx<'_, 'tcx>,
adt: &'tcx AdtDef, adt: AdtDef<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
) -> bool { ) -> bool {
let ty = cx.tcx.mk_ty(ty::Adt(adt, substs)); let ty = cx.tcx.mk_ty(ty::Adt(adt, substs));

View file

@ -55,7 +55,7 @@ where
ProjectionElem::Field(..) => { ProjectionElem::Field(..) => {
let ty = place_base.ty(local_decls, tcx).ty; let ty = place_base.ty(local_decls, tcx).ty;
match ty.kind() { match ty.kind() {
ty::Adt(def, _) => return def.repr.pack, ty::Adt(def, _) => return def.repr().pack,
_ => {} _ => {}
} }
} }

View file

@ -132,7 +132,7 @@ pub fn call_kind<'tcx>(
.parent(method_did) .parent(method_did)
.filter(|did| tcx.def_kind(*did) == rustc_hir::def::DefKind::Impl) .filter(|did| tcx.def_kind(*did) == rustc_hir::def::DefKind::Impl)
.and_then(|did| match tcx.type_of(did).kind() { .and_then(|did| match tcx.type_of(did).kind() {
ty::Adt(def, ..) => Some(def.did), ty::Adt(def, ..) => Some(def.did()),
_ => None, _ => None,
}); });
let is_option_or_result = parent_self_ty.map_or(false, |def_id| { let is_option_or_result = parent_self_ty.map_or(false, |def_id| {

View file

@ -582,7 +582,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) = if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) =
(exp_found.expected.kind(), exp_found.found.kind()) (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) => { TypeError::Traits(ref exp_found) => {
@ -914,7 +914,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
return Some(()); return Some(());
} }
if let ty::Adt(def, _) = ta.kind() { 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 { if path_ == other_path {
self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty); self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty);
return Some(()); return Some(());
@ -1126,12 +1126,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// process starts here // process starts here
match (t1.kind(), t2.kind()) { match (t1.kind(), t2.kind()) {
(&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => { (&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => {
let sub_no_defaults_1 = self.strip_generic_default_params(def1.did, sub1); let did1 = def1.did();
let sub_no_defaults_2 = self.strip_generic_default_params(def2.did, sub2); 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 mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
let path1 = self.tcx.def_path_str(def1.did); let path1 = self.tcx.def_path_str(did1);
let path2 = self.tcx.def_path_str(def2.did); let path2 = self.tcx.def_path_str(did2);
if def1.did == def2.did { if did1 == did2 {
// Easy case. Replace same types with `_` to shorten the output and highlight // Easy case. Replace same types with `_` to shorten the output and highlight
// the differing ones. // the differing ones.
// let x: Foo<Bar, Qux> = y::<Foo<Quz, Qux>>(); // let x: Foo<Bar, Qux> = y::<Foo<Quz, Qux>>();

View file

@ -958,7 +958,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
let t = match t.kind() { let t = match t.kind() {
// We'll hide this type only if all its type params are hidden as well. // We'll hide this type only if all its type params are hidden as well.
ty::Adt(def, substs) => { 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 // Account for params with default values, like `Vec`, where we
// want to show `Vec<T>`, not `Vec<T, _>`. If we replaced that // want to show `Vec<T>`, not `Vec<T, _>`. If we replaced that
// subst, then we'd get the incorrect output, so we passthrough. // 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) { if self.level == 1 || substs.iter().any(should_keep) {
let substs = self.tcx().intern_substs(&substs[..]); let substs = self.tcx().intern_substs(&substs[..]);
self.tcx().mk_ty(ty::Adt(def, substs)) self.tcx().mk_ty(ty::Adt(*def, substs))
} else { } else {
self.tcx().ty_error() self.tcx().ty_error()
} }

View file

@ -658,7 +658,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()); let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id());
let impl_ty = cx.tcx.type_of(parent); let impl_ty = cx.tcx.type_of(parent);
let outerdef = match impl_ty.kind() { 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), ty::Foreign(def_id) => Some(*def_id),
_ => None, _ => None,
}; };
@ -841,7 +841,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
let mut impls = LocalDefIdSet::default(); let mut impls = LocalDefIdSet::default();
cx.tcx.for_each_impl(debug, |d| { cx.tcx.for_each_impl(debug, |d| {
if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() { 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); impls.insert(def_id);
} }
} }
@ -2535,9 +2535,9 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
/// Test if this enum has several actually "existing" variants. /// 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". /// 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. // 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 existing_variants > 1
} }
@ -2571,7 +2571,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
Adt(adt_def, substs) if !adt_def.is_union() => { Adt(adt_def, substs) if !adt_def.is_union() => {
// First check if this ADT has a layout attribute (like `NonNull` and friends). // First check if this ADT has a layout attribute (like `NonNull` and friends).
use std::ops::Bound; 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 // We exploit here that `layout_scalar_valid_range` will never
// return `Bound::Excluded`. (And we have tests checking that we // return `Bound::Excluded`. (And we have tests checking that we
// handle the attribute correctly.) // handle the attribute correctly.)
@ -2592,12 +2592,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
_ => {} _ => {}
} }
// Now, recurse. // 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)), 0 => Some(("enums with no variants have no valid value".to_string(), None)),
1 => { 1 => {
// Struct, or enum with exactly one variant. // Struct, or enum with exactly one variant.
// Proceed recursively, check all fields. // 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| { variant.fields.iter().find_map(|field| {
ty_find_init_error(tcx, field.ty(tcx, substs), init).map( ty_find_init_error(tcx, field.ty(tcx, substs), init).map(
|(mut msg, span)| { |(mut msg, span)| {
@ -2622,8 +2622,8 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
} }
// Multi-variant enum. // Multi-variant enum.
_ => { _ => {
if init == InitKind::Uninit && is_multi_variant(adt_def) { if init == InitKind::Uninit && is_multi_variant(*adt_def) {
let span = tcx.def_span(adt_def.did); let span = tcx.def_span(adt_def.did());
Some(( Some((
"enums have to be initialized to a variant".to_string(), "enums have to be initialized to a variant".to_string(),
Some(span), Some(span),
@ -2819,15 +2819,15 @@ impl ClashingExternDeclarations {
let mut ty = ty; let mut ty = ty;
loop { loop {
if let ty::Adt(def, substs) = *ty.kind() { if let ty::Adt(def, substs) = *ty.kind() {
let is_transparent = def.subst(tcx, substs).repr.transparent(); let is_transparent = def.subst(tcx, substs).repr().transparent();
let is_non_null = crate::types::nonnull_optimization_guaranteed(tcx, &def); let is_non_null = crate::types::nonnull_optimization_guaranteed(tcx, def);
debug!( debug!(
"non_transparent_ty({:?}) -- type is transparent? {}, type is non-null? {}", "non_transparent_ty({:?}) -- type is transparent? {}, type is non-null? {}",
ty, is_transparent, is_non_null ty, is_transparent, is_non_null
); );
if is_transparent && !is_non_null { if is_transparent && !is_non_null {
debug_assert!(def.variants.len() == 1); debug_assert!(def.variants().len() == 1);
let v = &def.variants[VariantIdx::new(0)]; let v = &def.variant(VariantIdx::new(0));
ty = transparent_newtype_field(tcx, v) ty = transparent_newtype_field(tcx, v)
.expect( .expect(
"single-variant transparent structure with zero-sized field", "single-variant transparent structure with zero-sized field",
@ -2892,8 +2892,8 @@ impl ClashingExternDeclarations {
} }
// Grab a flattened representation of all fields. // Grab a flattened representation of all fields.
let a_fields = a_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()); let b_fields = b_def.variants().iter().flat_map(|v| v.fields.iter());
// Perform a structural comparison for each field. // Perform a structural comparison for each field.
a_fields.eq_by( a_fields.eq_by(

View file

@ -1050,7 +1050,7 @@ impl<'tcx> LateContext<'tcx> {
) -> Result<Self::Path, Self::Error> { ) -> Result<Self::Path, Self::Error> {
if trait_ref.is_none() { if trait_ref.is_none() {
if let ty::Adt(def, substs) = self_ty.kind() { 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);
} }
} }

View file

@ -202,7 +202,7 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, ty: &Ty<'_>) -> Option<String> {
Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => { Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => {
if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() { if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
if let Some(name @ (sym::Ty | sym::TyCtxt)) = 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 // NOTE: This path is currently unreachable as `Ty<'tcx>` is
// defined as a type alias meaning that `impl<'tcx> Ty<'tcx>` // defined as a type alias meaning that `impl<'tcx> Ty<'tcx>`

View file

@ -84,9 +84,9 @@ fn lint_cstring_as_ptr(
) { ) {
let source_type = cx.typeck_results().expr_ty(source); let source_type = cx.typeck_results().expr_ty(source);
if let ty::Adt(def, substs) = source_type.kind() { 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 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| { cx.struct_span_lint(TEMPORARY_CSTRING_AS_PTR, as_ptr_span, |diag| {
let mut diag = diag let mut diag = diag
.build("getting the inner pointer of a temporary `CString`"); .build("getting the inner pointer of a temporary `CString`");

View file

@ -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, ty::Ref(_, r, _) if *r.kind() == ty::Str,
) || matches!( ) || matches!(
ty.ty_adt_def(), 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| { let (suggest_display, suggest_debug) = cx.tcx.infer_ctxt().enter(|infcx| {

View file

@ -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, _)) } => { Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => {
if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() { if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
if cx.tcx.has_attr(adt.did, sym::rustc_pass_by_value) { if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) {
return Some(cx.tcx.def_path_str_with_substs(adt.did, substs)); return Some(cx.tcx.def_path_str_with_substs(adt.did(), substs));
} }
} }
} }

View file

@ -667,8 +667,8 @@ enum FfiResult<'tcx> {
FfiUnsafe { ty: Ty<'tcx>, reason: String, help: Option<String> }, FfiUnsafe { ty: Ty<'tcx>, reason: String, help: Option<String> },
} }
crate fn nonnull_optimization_guaranteed<'tcx>(tcx: TyCtxt<'tcx>, def: &ty::AdtDef) -> bool { 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)) 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 /// `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::FnPtr(_) => true,
ty::Ref(..) => true, ty::Ref(..) => true,
ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true, ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true,
ty::Adt(def, substs) if def.repr.transparent() && !def.is_union() => { ty::Adt(def, substs) if def.repr().transparent() && !def.is_union() => {
let marked_non_null = nonnull_optimization_guaranteed(tcx, &def); let marked_non_null = nonnull_optimization_guaranteed(tcx, *def);
if marked_non_null { if marked_non_null {
return true; 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. // 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). // 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; return false;
} }
def.variants def.variants()
.iter() .iter()
.filter_map(|variant| transparent_newtype_field(cx.tcx, variant)) .filter_map(|variant| transparent_newtype_field(cx.tcx, variant))
.any(|field| ty_is_known_nonnull(cx, field.ty(tcx, substs), mode)) .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() { Some(match *ty.kind() {
ty::Adt(field_def, field_substs) => { ty::Adt(field_def, field_substs) => {
let inner_field_ty = { let inner_field_ty = {
let first_non_zst_ty = let first_non_zst_ty = field_def
field_def.variants.iter().filter_map(|v| transparent_newtype_field(cx.tcx, v)); .variants()
.iter()
.filter_map(|v| transparent_newtype_field(cx.tcx, v));
debug_assert_eq!( debug_assert_eq!(
first_non_zst_ty.clone().count(), first_non_zst_ty.clone().count(),
1, 1,
@ -771,7 +773,7 @@ crate fn repr_nullable_ptr<'tcx>(
) -> Option<Ty<'tcx>> { ) -> Option<Ty<'tcx>> {
debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty); debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty);
if let ty::Adt(ty_def, substs) = ty.kind() { 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[..]) { [var_one, var_two] => match (&var_one.fields[..], &var_two.fields[..]) {
([], [field]) | ([field], []) => field.ty(cx.tcx, substs), ([], [field]) | ([field], []) => field.ty(cx.tcx, substs),
_ => return None, _ => return None,
@ -845,13 +847,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
&self, &self,
cache: &mut FxHashSet<Ty<'tcx>>, cache: &mut FxHashSet<Ty<'tcx>>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
def: &ty::AdtDef, def: ty::AdtDef<'tcx>,
variant: &ty::VariantDef, variant: &ty::VariantDef,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
) -> FfiResult<'tcx> { ) -> FfiResult<'tcx> {
use FfiResult::*; use FfiResult::*;
if def.repr.transparent() { if def.repr().transparent() {
// Can assume that at most one field is not a ZST, so only check // Can assume that at most one field is not a ZST, so only check
// that field's type for FFI-safety. // that field's type for FFI-safety.
if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) { 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 => { AdtKind::Struct | AdtKind::Union => {
let kind = if def.is_struct() { "struct" } else { "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 { return FfiUnsafe {
ty, ty,
reason: format!("this {} has unspecified layout", kind), reason: format!("this {} has unspecified layout", kind),
@ -939,7 +941,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
let is_non_exhaustive = let is_non_exhaustive =
def.non_enum_variant().is_field_list_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 { return FfiUnsafe {
ty, ty,
reason: format!("this {} is non-exhaustive", kind), 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) self.check_variant_for_ffi(cache, ty, def, def.non_enum_variant(), substs)
} }
AdtKind::Enum => { AdtKind::Enum => {
if def.variants.is_empty() { if def.variants().is_empty() {
// Empty enums are okay... although sort of useless. // Empty enums are okay... although sort of useless.
return FfiSafe; return FfiSafe;
} }
// Check for a repr() attribute to specify the size of the // Check for a repr() attribute to specify the size of the
// discriminant. // 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()>`. // Special-case types like `Option<extern fn()>`.
if repr_nullable_ptr(self.cx, ty, self.mode).is_none() { if repr_nullable_ptr(self.cx, ty, self.mode).is_none() {
return FfiUnsafe { 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 { return FfiUnsafe {
ty, ty,
reason: "this enum is non-exhaustive".into(), reason: "this enum is non-exhaustive".into(),
@ -990,7 +993,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
} }
// Check the contained variants. // Check the contained variants.
for variant in &def.variants { for variant in def.variants() {
let is_non_exhaustive = variant.is_field_list_non_exhaustive(); let is_non_exhaustive = variant.is_field_list_non_exhaustive();
if is_non_exhaustive && !variant.def_id.is_local() { if is_non_exhaustive && !variant.def_id.is_local() {
return FfiUnsafe { return FfiUnsafe {
@ -1161,7 +1164,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
} }
diag.note(note); diag.note(note);
if let ty::Adt(def, _) = ty.kind() { 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"); 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() && let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def()
// skip extension traits, only lint functions from the standard library // skip extension traits, only lint functions from the standard library
&& cx.tcx.trait_id_of_impl(impl_did).is_none() && 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) && 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)); return Some((method_path.ident.name, args));
} }

View file

@ -202,7 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
let descr_pre = &format!("{}boxed ", descr_pre); let descr_pre = &format!("{}boxed ", descr_pre);
check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len) 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, _) => { ty::Opaque(def, _) => {
let mut has_emitted = false; let mut has_emitted = false;
for &(predicate, _) in cx.tcx.explicit_item_bounds(def) { for &(predicate, _) in cx.tcx.explicit_item_bounds(def) {

View file

@ -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 kind = self.kind(item_id);
let did = self.local_def_id(item_id); let did = self.local_def_id(item_id);

View file

@ -1029,9 +1029,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id)); 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 tcx = self.tcx;
let variant = &def.variants[index]; let variant = &def.variant(index);
let def_id = variant.def_id; let def_id = variant.def_id;
debug!("EncodeContext::encode_enum_variant_info({:?})", 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 tcx = self.tcx;
let variant = &def.variants[index]; let variant = &def.variant(index);
let def_id = variant.ctor_def_id.unwrap(); let def_id = variant.ctor_def_id.unwrap();
debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id); debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
@ -1122,11 +1122,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_field( fn encode_field(
&mut self, &mut self,
adt_def: &ty::AdtDef, adt_def: ty::AdtDef<'tcx>,
variant_index: VariantIdx, variant_index: VariantIdx,
field_index: usize, field_index: usize,
) { ) {
let variant = &adt_def.variants[variant_index]; let variant = &adt_def.variant(variant_index);
let field = &variant.fields[field_index]; let field = &variant.fields[field_index];
let def_id = field.did; let def_id = field.did;
@ -1137,7 +1137,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.encode_item_type(def_id); 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); debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
let tcx = self.tcx; let tcx = self.tcx;
let variant = adt_def.non_enum_variant(); 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(), 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); self.encode_item_type(def_id);
if variant.ctor_kind == CtorKind::Fn { if variant.ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); 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); self.encode_explicit_item_bounds(def_id);
EntryKind::OpaqueTy 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, _) => { hir::ItemKind::Struct(ref struct_def, _) => {
let adt_def = self.tcx.adt_def(def_id); let adt_def = self.tcx.adt_def(def_id);
let variant = adt_def.non_enum_variant(); let variant = adt_def.non_enum_variant();
@ -1433,7 +1433,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
ctor, ctor,
is_non_exhaustive: variant.is_field_list_non_exhaustive(), is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}), }),
adt_def.repr, adt_def.repr(),
) )
} }
hir::ItemKind::Union(..) => { hir::ItemKind::Union(..) => {
@ -1447,7 +1447,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
ctor: None, ctor: None,
is_non_exhaustive: variant.is_field_list_non_exhaustive(), is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}), }),
adt_def.repr, adt_def.repr(),
) )
} }
hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => { 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. // FIXME(eddyb) there should be a nicer way to do this.
match item.kind { match item.kind {
hir::ItemKind::Enum(..) => record!(self.tables.children[def_id] <- 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()); assert!(v.def_id.is_local());
v.def_id.index v.def_id.index
}) })
@ -1926,8 +1926,8 @@ impl<'a, 'tcx> Visitor<'tcx> for EncodeContext<'a, 'tcx> {
} }
impl<'a, 'tcx> EncodeContext<'a, 'tcx> { impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_fields(&mut self, adt_def: &ty::AdtDef) { fn encode_fields(&mut self, adt_def: ty::AdtDef<'tcx>) {
for (variant_index, variant) in adt_def.variants.iter_enumerated() { for (variant_index, variant) in adt_def.variants().iter_enumerated() {
for (field_index, _field) in variant.fields.iter().enumerate() { for (field_index, _field) in variant.fields.iter().enumerate() {
self.encode_field(adt_def, variant_index, field_index); 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()); let def = self.tcx.adt_def(item.def_id.to_def_id());
self.encode_fields(def); 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); self.encode_enum_variant_info(def, i);
if let Some(_ctor_def_id) = variant.ctor_def_id { if let Some(_ctor_def_id) = variant.ctor_def_id {

View file

@ -9,7 +9,7 @@ macro_rules! arena_types {
[] layout: rustc_target::abi::LayoutS<'tcx>, [] layout: rustc_target::abi::LayoutS<'tcx>,
[] fn_abi: rustc_target::abi::call::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>, [] fn_abi: rustc_target::abi::call::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>,
// AdtDef are interned and compared by address // 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_thir: rustc_data_structures::steal::Steal<rustc_middle::thir::Thir<'tcx>>,
[] steal_mir: rustc_data_structures::steal::Steal<rustc_middle::mir::Body<'tcx>>, [] steal_mir: rustc_data_structures::steal::Steal<rustc_middle::mir::Body<'tcx>>,
[decode] mir: rustc_middle::mir::Body<'tcx>, [decode] mir: rustc_middle::mir::Body<'tcx>,

View file

@ -2425,7 +2425,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
AggregateKind::Adt(adt_did, variant, substs, _user_ty, _) => { AggregateKind::Adt(adt_did, variant, substs, _user_ty, _) => {
ty::tls::with(|tcx| { 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 substs = tcx.lift(substs).expect("could not lift for printing");
let name = FmtPrinter::new(tcx, Namespace::ValueNS) let name = FmtPrinter::new(tcx, Namespace::ValueNS)
.print_def_path(variant_def.def_id, substs)? .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)) 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)) 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( pub(crate) fn variant(
mut self, mut self,
adt_def: &AdtDef, adt_def: AdtDef<'_>,
variant_index: VariantIdx, variant_index: VariantIdx,
field: Field, field: Field,
) -> Self { ) -> Self {
self.projs.push(ProjectionElem::Downcast( self.projs.push(ProjectionElem::Downcast(
Some(adt_def.variants[variant_index].name), Some(adt_def.variant(variant_index).name),
variant_index, variant_index,
)); ));
self.projs.push(ProjectionElem::Field(field, ())); self.projs.push(ProjectionElem::Field(field, ()));

View file

@ -40,7 +40,7 @@ impl<'tcx> PlaceTy<'tcx> {
None => adt_def.non_enum_variant(), None => adt_def.non_enum_variant(),
Some(variant_index) => { Some(variant_index) => {
assert!(adt_def.is_enum()); assert!(adt_def.is_enum());
&adt_def.variants[variant_index] &adt_def.variant(variant_index)
} }
}; };
let field_def = &variant_def.fields[f.index()]; let field_def = &variant_def.fields[f.index()];

View file

@ -523,7 +523,7 @@ rustc_queries! {
storage(ArenaCacheSelector<'tcx>) storage(ArenaCacheSelector<'tcx>)
separate_provide_extern 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) } desc { |tcx| "computing ADT definition for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }
separate_provide_extern separate_provide_extern

View file

@ -128,7 +128,7 @@ pub struct Block {
#[derive(Debug, HashStable)] #[derive(Debug, HashStable)]
pub struct Adt<'tcx> { pub struct Adt<'tcx> {
/// The ADT we're constructing. /// The ADT we're constructing.
pub adt_def: &'tcx AdtDef, pub adt_def: AdtDef<'tcx>,
/// The variant of the ADT. /// The variant of the ADT.
pub variant_index: VariantIdx, pub variant_index: VariantIdx,
pub substs: SubstsRef<'tcx>, 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 /// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with
/// multiple variants. /// multiple variants.
Variant { Variant {
adt_def: &'tcx AdtDef, adt_def: AdtDef<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
variant_index: VariantIdx, variant_index: VariantIdx,
subpatterns: Vec<FieldPat<'tcx>>, subpatterns: Vec<FieldPat<'tcx>>,
@ -714,7 +714,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
PatKind::Variant { ref subpatterns, .. } | PatKind::Leaf { ref subpatterns } => { PatKind::Variant { ref subpatterns, .. } | PatKind::Leaf { ref subpatterns } => {
let variant = match *self.kind { let variant = match *self.kind {
PatKind::Variant { adt_def, variant_index, .. } => { 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| { _ => self.ty.ty_adt_def().and_then(|adt| {
if !adt.is_enum() { Some(adt.non_enum_variant()) } else { None } if !adt.is_enum() { Some(adt.non_enum_variant()) } else { None }

View file

@ -75,7 +75,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
type InternedVariances = Vec<chalk_ir::Variance>; type InternedVariances = Vec<chalk_ir::Variance>;
type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>; type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
type DefId = DefId; type DefId = DefId;
type InternedAdtId = &'tcx AdtDef; type InternedAdtId = AdtDef<'tcx>;
type Identifier = (); type Identifier = ();
type FnAbi = Abi; type FnAbi = Abi;

View file

@ -4,6 +4,7 @@ use crate::ty::util::{Discr, IntTypeExt};
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap; 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::HashingControls;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
@ -89,62 +90,62 @@ bitflags! {
/// where `x` here represents the `DefId` of `S.x`. Then, the `DefId` /// 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. /// can be used with [`TyCtxt::type_of()`] to get the type of the field.
#[derive(TyEncodable, TyDecodable)] #[derive(TyEncodable, TyDecodable)]
pub struct AdtDef { pub struct AdtDefData {
/// The `DefId` of the struct, enum or union item. /// The `DefId` of the struct, enum or union item.
pub did: DefId, pub did: DefId,
/// Variants of the ADT. If this is a struct or union, then there will be a single variant. /// 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 of the ADT (e.g., is this a struct? is this non-exhaustive?).
flags: AdtFlags, flags: AdtFlags,
/// Repr options provided by the user. /// Repr options provided by the user.
pub repr: ReprOptions, repr: ReprOptions,
} }
impl PartialOrd for AdtDef { impl PartialOrd for AdtDefData {
fn partial_cmp(&self, other: &AdtDef) -> Option<Ordering> { fn partial_cmp(&self, other: &AdtDefData) -> Option<Ordering> {
Some(self.cmp(&other)) Some(self.cmp(&other))
} }
} }
/// There should be only one AdtDef for each `did`, therefore /// There should be only one AdtDef for each `did`, therefore
/// it is fine to implement `Ord` only based on `did`. /// it is fine to implement `Ord` only based on `did`.
impl Ord for AdtDef { impl Ord for AdtDefData {
fn cmp(&self, other: &AdtDef) -> Ordering { fn cmp(&self, other: &AdtDefData) -> Ordering {
self.did.cmp(&other.did) self.did.cmp(&other.did)
} }
} }
/// There should be only one AdtDef for each `did`, therefore /// There should be only one AdtDef for each `did`, therefore
/// it is fine to implement `PartialEq` only based on `did`. /// it is fine to implement `PartialEq` only based on `did`.
impl PartialEq for AdtDef { impl PartialEq for AdtDefData {
#[inline] #[inline]
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.did == other.did self.did == other.did
} }
} }
impl Eq for AdtDef {} impl Eq for AdtDefData {}
/// There should be only one AdtDef for each `did`, therefore /// There should be only one AdtDef for each `did`, therefore
/// it is fine to implement `Hash` only based on `did`. /// it is fine to implement `Hash` only based on `did`.
impl Hash for AdtDef { impl Hash for AdtDefData {
#[inline] #[inline]
fn hash<H: Hasher>(&self, s: &mut H) { fn hash<H: Hasher>(&self, s: &mut H) {
self.did.hash(s) 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) { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
thread_local! { thread_local! {
static CACHE: RefCell<FxHashMap<(usize, HashingControls), Fingerprint>> = Default::default(); static CACHE: RefCell<FxHashMap<(usize, HashingControls), Fingerprint>> = Default::default();
} }
let hash: Fingerprint = CACHE.with(|cache| { 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(); let hashing_controls = hcx.hashing_controls();
*cache.borrow_mut().entry((addr, hashing_controls)).or_insert_with(|| { *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(); let mut hasher = StableHasher::new();
did.hash_stable(hcx, &mut hasher); 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)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, TyEncodable, TyDecodable)]
pub enum AdtKind { pub enum AdtKind {
Struct, Struct,
@ -177,8 +204,8 @@ impl Into<DataTypeKind> for AdtKind {
} }
} }
impl<'tcx> AdtDef { impl AdtDefData {
/// Creates a new `AdtDef`. /// Creates a new `AdtDefData`.
pub(super) fn new( pub(super) fn new(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
did: DefId, did: DefId,
@ -218,36 +245,38 @@ impl<'tcx> AdtDef {
flags |= AdtFlags::IS_MANUALLY_DROP; 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. /// Returns `true` if this is a struct.
#[inline] #[inline]
pub fn is_struct(&self) -> bool { pub fn is_struct(self) -> bool {
self.flags.contains(AdtFlags::IS_STRUCT) self.flags().contains(AdtFlags::IS_STRUCT)
} }
/// Returns `true` if this is a union. /// Returns `true` if this is a union.
#[inline] #[inline]
pub fn is_union(&self) -> bool { pub fn is_union(self) -> bool {
self.flags.contains(AdtFlags::IS_UNION) self.flags().contains(AdtFlags::IS_UNION)
} }
/// Returns `true` if this is an enum. /// Returns `true` if this is an enum.
#[inline] #[inline]
pub fn is_enum(&self) -> bool { pub fn is_enum(self) -> bool {
self.flags.contains(AdtFlags::IS_ENUM) self.flags().contains(AdtFlags::IS_ENUM)
} }
/// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`. /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`.
#[inline] #[inline]
pub fn is_variant_list_non_exhaustive(&self) -> bool { pub fn is_variant_list_non_exhaustive(self) -> bool {
self.flags.contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE) self.flags().contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
} }
/// Returns the kind of the ADT. /// Returns the kind of the ADT.
#[inline] #[inline]
pub fn adt_kind(&self) -> AdtKind { pub fn adt_kind(self) -> AdtKind {
if self.is_enum() { if self.is_enum() {
AdtKind::Enum AdtKind::Enum
} else if self.is_union() { } else if self.is_union() {
@ -258,7 +287,7 @@ impl<'tcx> AdtDef {
} }
/// Returns a description of this abstract data type. /// Returns a description of this abstract data type.
pub fn descr(&self) -> &'static str { pub fn descr(self) -> &'static str {
match self.adt_kind() { match self.adt_kind() {
AdtKind::Struct => "struct", AdtKind::Struct => "struct",
AdtKind::Union => "union", AdtKind::Union => "union",
@ -268,7 +297,7 @@ impl<'tcx> AdtDef {
/// Returns a description of a variant of this abstract data type. /// Returns a description of a variant of this abstract data type.
#[inline] #[inline]
pub fn variant_descr(&self) -> &'static str { pub fn variant_descr(self) -> &'static str {
match self.adt_kind() { match self.adt_kind() {
AdtKind::Struct => "struct", AdtKind::Struct => "struct",
AdtKind::Union => "union", AdtKind::Union => "union",
@ -278,65 +307,65 @@ impl<'tcx> AdtDef {
/// If this function returns `true`, it implies that `is_struct` must return `true`. /// If this function returns `true`, it implies that `is_struct` must return `true`.
#[inline] #[inline]
pub fn has_ctor(&self) -> bool { pub fn has_ctor(self) -> bool {
self.flags.contains(AdtFlags::HAS_CTOR) self.flags().contains(AdtFlags::HAS_CTOR)
} }
/// Returns `true` if this type is `#[fundamental]` for the purposes /// Returns `true` if this type is `#[fundamental]` for the purposes
/// of coherence checking. /// of coherence checking.
#[inline] #[inline]
pub fn is_fundamental(&self) -> bool { pub fn is_fundamental(self) -> bool {
self.flags.contains(AdtFlags::IS_FUNDAMENTAL) self.flags().contains(AdtFlags::IS_FUNDAMENTAL)
} }
/// Returns `true` if this is `PhantomData<T>`. /// Returns `true` if this is `PhantomData<T>`.
#[inline] #[inline]
pub fn is_phantom_data(&self) -> bool { pub fn is_phantom_data(self) -> bool {
self.flags.contains(AdtFlags::IS_PHANTOM_DATA) self.flags().contains(AdtFlags::IS_PHANTOM_DATA)
} }
/// Returns `true` if this is Box<T>. /// Returns `true` if this is Box<T>.
#[inline] #[inline]
pub fn is_box(&self) -> bool { pub fn is_box(self) -> bool {
self.flags.contains(AdtFlags::IS_BOX) self.flags().contains(AdtFlags::IS_BOX)
} }
/// Returns `true` if this is `ManuallyDrop<T>`. /// Returns `true` if this is `ManuallyDrop<T>`.
#[inline] #[inline]
pub fn is_manually_drop(&self) -> bool { pub fn is_manually_drop(self) -> bool {
self.flags.contains(AdtFlags::IS_MANUALLY_DROP) self.flags().contains(AdtFlags::IS_MANUALLY_DROP)
} }
/// Returns `true` if this type has a destructor. /// 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() 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, .. })) matches!(self.destructor(tcx), Some(Destructor { constness: hir::Constness::NotConst, .. }))
} }
/// Asserts this is a struct or union and returns its unique variant. /// 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()); assert!(self.is_struct() || self.is_union());
&self.variants[VariantIdx::new(0)] &self.variant(VariantIdx::new(0))
} }
#[inline] #[inline]
pub fn predicates(&self, tcx: TyCtxt<'tcx>) -> GenericPredicates<'tcx> { pub fn predicates(self, tcx: TyCtxt<'tcx>) -> GenericPredicates<'tcx> {
tcx.predicates_of(self.did) tcx.predicates_of(self.did())
} }
/// Returns an iterator over all fields contained /// Returns an iterator over all fields contained
/// by this ADT. /// by this ADT.
#[inline] #[inline]
pub fn all_fields(&self) -> impl Iterator<Item = &FieldDef> + Clone { pub fn all_fields(self) -> impl Iterator<Item = &'tcx FieldDef> + Clone {
self.variants.iter().flat_map(|v| v.fields.iter()) self.variants().iter().flat_map(|v| v.fields.iter())
} }
/// Whether the ADT lacks fields. Note that this includes uninhabited enums, /// Whether the ADT lacks fields. Note that this includes uninhabited enums,
/// e.g., `enum Void {}` is considered payload free as well. /// 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). // 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. // This would disallow the following kind of enum from being casted into integer.
// ``` // ```
@ -347,31 +376,31 @@ impl<'tcx> AdtDef {
// } // }
// ``` // ```
if self if self
.variants .variants()
.iter() .iter()
.any(|v| matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind != CtorKind::Const) .any(|v| matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind != CtorKind::Const)
{ {
return false; 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. /// Return a `VariantDef` given a variant id.
pub fn variant_with_id(&self, vid: DefId) -> &VariantDef { 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") self.variants().iter().find(|v| v.def_id == vid).expect("variant_with_id: unknown variant")
} }
/// Return a `VariantDef` given a constructor id. /// Return a `VariantDef` given a constructor id.
pub fn variant_with_ctor_id(&self, cid: DefId) -> &VariantDef { pub fn variant_with_ctor_id(self, cid: DefId) -> &'tcx VariantDef {
self.variants self.variants()
.iter() .iter()
.find(|v| v.ctor_def_id == Some(cid)) .find(|v| v.ctor_def_id == Some(cid))
.expect("variant_with_ctor_id: unknown variant") .expect("variant_with_ctor_id: unknown variant")
} }
/// Return the index of `VariantDef` given a variant id. /// Return the index of `VariantDef` given a variant id.
pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx { pub fn variant_index_with_id(self, vid: DefId) -> VariantIdx {
self.variants self.variants()
.iter_enumerated() .iter_enumerated()
.find(|(_, v)| v.def_id == vid) .find(|(_, v)| v.def_id == vid)
.expect("variant_index_with_id: unknown variant") .expect("variant_index_with_id: unknown variant")
@ -379,15 +408,15 @@ impl<'tcx> AdtDef {
} }
/// Return the index of `VariantDef` given a constructor id. /// Return the index of `VariantDef` given a constructor id.
pub fn variant_index_with_ctor_id(&self, cid: DefId) -> VariantIdx { pub fn variant_index_with_ctor_id(self, cid: DefId) -> VariantIdx {
self.variants self.variants()
.iter_enumerated() .iter_enumerated()
.find(|(_, v)| v.ctor_def_id == Some(cid)) .find(|(_, v)| v.ctor_def_id == Some(cid))
.expect("variant_index_with_ctor_id: unknown variant") .expect("variant_index_with_ctor_id: unknown variant")
.0 .0
} }
pub fn variant_of_res(&self, res: Res) -> &VariantDef { pub fn variant_of_res(self, res: Res) -> &'tcx VariantDef {
match res { match res {
Res::Def(DefKind::Variant, vid) => self.variant_with_id(vid), Res::Def(DefKind::Variant, vid) => self.variant_with_id(vid),
Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid), Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
@ -402,10 +431,10 @@ impl<'tcx> AdtDef {
} }
#[inline] #[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()); assert!(self.is_enum());
let param_env = tcx.param_env(expr_did); 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) { match tcx.const_eval_poly(expr_did) {
Ok(val) => { Ok(val) => {
let ty = repr_type.to_ty(tcx); let ty = repr_type.to_ty(tcx);
@ -437,14 +466,14 @@ impl<'tcx> AdtDef {
#[inline] #[inline]
pub fn discriminants( pub fn discriminants(
&'tcx self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> { ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
assert!(self.is_enum()); 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 initial = repr_type.initial_discriminant(tcx);
let mut prev_discr = None::<Discr<'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)); let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
if let VariantDiscr::Explicit(expr_did) = v.discr { if let VariantDiscr::Explicit(expr_did) = v.discr {
if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) { if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
@ -458,8 +487,8 @@ impl<'tcx> AdtDef {
} }
#[inline] #[inline]
pub fn variant_range(&self) -> Range<VariantIdx> { pub fn variant_range(self) -> Range<VariantIdx> {
VariantIdx::new(0)..VariantIdx::new(self.variants.len()) VariantIdx::new(0)..VariantIdx::new(self.variants().len())
} }
/// Computes the discriminant value used by a specific variant. /// Computes the discriminant value used by a specific variant.
@ -469,7 +498,7 @@ impl<'tcx> AdtDef {
/// assuming there are no constant-evaluation errors there. /// assuming there are no constant-evaluation errors there.
#[inline] #[inline]
pub fn discriminant_for_variant( pub fn discriminant_for_variant(
&self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
variant_index: VariantIdx, variant_index: VariantIdx,
) -> Discr<'tcx> { ) -> Discr<'tcx> {
@ -477,19 +506,19 @@ impl<'tcx> AdtDef {
let (val, offset) = self.discriminant_def_for_variant(variant_index); let (val, offset) = self.discriminant_def_for_variant(variant_index);
let explicit_value = val let explicit_value = val
.and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did)) .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 explicit_value.checked_add(tcx, offset as u128).0
} }
/// Yields a `DefId` for the discriminant and an offset to add to it /// Yields a `DefId` for the discriminant and an offset to add to it
/// Alternatively, if there is no explicit discriminant, returns the /// Alternatively, if there is no explicit discriminant, returns the
/// inferred discriminant directly. /// inferred discriminant directly.
pub fn discriminant_def_for_variant(&self, variant_index: VariantIdx) -> (Option<DefId>, u32) { pub fn discriminant_def_for_variant(self, variant_index: VariantIdx) -> (Option<DefId>, u32) {
assert!(!self.variants.is_empty()); assert!(!self.variants().is_empty());
let mut explicit_index = variant_index.as_u32(); let mut explicit_index = variant_index.as_u32();
let expr_did; let expr_did;
loop { loop {
match self.variants[VariantIdx::from_u32(explicit_index)].discr { match self.variant(VariantIdx::from_u32(explicit_index)).discr {
ty::VariantDiscr::Relative(0) => { ty::VariantDiscr::Relative(0) => {
expr_did = None; expr_did = None;
break; break;
@ -506,8 +535,8 @@ impl<'tcx> AdtDef {
(expr_did, variant_index.as_u32() - explicit_index) (expr_did, variant_index.as_u32() - explicit_index)
} }
pub fn destructor(&self, tcx: TyCtxt<'tcx>) -> Option<Destructor> { pub fn destructor(self, tcx: TyCtxt<'tcx>) -> Option<Destructor> {
tcx.adt_destructor(self.did) tcx.adt_destructor(self.did())
} }
/// Returns a list of types such that `Self: Sized` if and only /// 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 /// Due to normalization being eager, this applies even if
/// the associated type is behind a pointer (e.g., issue #31299). /// the associated type is behind a pointer (e.g., issue #31299).
pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] { pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] {
tcx.adt_sized_constraint(self.did).0 tcx.adt_sized_constraint(self.did()).0
} }
} }

View file

@ -164,7 +164,7 @@ impl<'tcx> CapturedPlace<'tcx> {
write!( write!(
&mut symbol, &mut symbol,
"__{}", "__{}",
def.variants[variant].fields[idx as usize].name.as_str(), def.variant(variant).fields[idx as usize].name.as_str(),
) )
.unwrap(); .unwrap();
} }
@ -330,7 +330,7 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc
curr_string = format!( curr_string = format!(
"{}.{}", "{}.{}",
curr_string, curr_string,
def.variants[variant].fields[idx as usize].name.as_str() def.variant(variant).fields[idx as usize].name.as_str()
); );
} }
ty::Tuple(_) => { ty::Tuple(_) => {

View file

@ -15,7 +15,7 @@ use crate::mir::{
use crate::thir; use crate::thir;
use crate::traits; use crate::traits;
use crate::ty::subst::SubstsRef; 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_data_structures::fx::FxHashMap;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::Span; 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 { impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
fn encode(&self, e: &mut E) -> Result<(), E::Error> { fn encode(&self, e: &mut E) -> Result<(), E::Error> {
e.encode_alloc_id(self) e.encode_alloc_id(self)
@ -178,8 +184,7 @@ encodable_via_deref! {
&'tcx mir::Body<'tcx>, &'tcx mir::Body<'tcx>,
&'tcx mir::UnsafetyCheckResult, &'tcx mir::UnsafetyCheckResult,
&'tcx mir::BorrowCheckResult<'tcx>, &'tcx mir::BorrowCheckResult<'tcx>,
&'tcx mir::coverage::CodeRegion, &'tcx mir::coverage::CodeRegion
&'tcx ty::AdtDef
} }
pub trait TyDecoder<'tcx>: Decoder { 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)] { impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, Span)] {
fn decode(decoder: &mut D) -> &'tcx Self { fn decode(decoder: &mut D) -> &'tcx Self {
decoder.tcx().arena.alloc_from_iter( decoder.tcx().arena.alloc_from_iter(
@ -409,8 +420,7 @@ impl_decodable_via_ref! {
&'tcx mir::UnsafetyCheckResult, &'tcx mir::UnsafetyCheckResult,
&'tcx mir::BorrowCheckResult<'tcx>, &'tcx mir::BorrowCheckResult<'tcx>,
&'tcx mir::coverage::CodeRegion, &'tcx mir::coverage::CodeRegion,
&'tcx ty::List<ty::BoundVariableKind>, &'tcx ty::List<ty::BoundVariableKind>
&'tcx ty::AdtDef
} }
#[macro_export] #[macro_export]

View file

@ -17,7 +17,7 @@ use crate::ty::query::{self, TyCtxtAt};
use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts}; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
use crate::ty::TyKind::*; use crate::ty::TyKind::*;
use crate::ty::{ 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, ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy,
FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
@ -115,7 +115,7 @@ pub struct CtxtInterners<'tcx> {
const_allocation: InternedSet<'tcx, Allocation>, const_allocation: InternedSet<'tcx, Allocation>,
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>, bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
layout: InternedSet<'tcx, LayoutS<'tcx>>, layout: InternedSet<'tcx, LayoutS<'tcx>>,
adt_def: InternedSet<'tcx, AdtDef>, adt_def: InternedSet<'tcx, AdtDefData>,
} }
impl<'tcx> CtxtInterners<'tcx> { impl<'tcx> CtxtInterners<'tcx> {
@ -1123,8 +1123,8 @@ impl<'tcx> TyCtxt<'tcx> {
kind: AdtKind, kind: AdtKind,
variants: IndexVec<VariantIdx, ty::VariantDef>, variants: IndexVec<VariantIdx, ty::VariantDef>,
repr: ReprOptions, repr: ReprOptions,
) -> &'tcx ty::AdtDef { ) -> ty::AdtDef<'tcx> {
self.intern_adt_def(ty::AdtDef::new(self, did, kind, variants, repr)) self.intern_adt_def(ty::AdtDefData::new(self, did, kind, variants, repr))
} }
/// Allocates a read-only byte or string literal for `mir::interpret`. /// 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_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>, layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>,
} adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'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),
} }
macro_rules! slice_interners { macro_rules! slice_interners {
@ -2341,7 +2301,7 @@ impl<'tcx> TyCtxt<'tcx> {
} }
#[inline] #[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. // Take a copy of substs so that we own the vectors inside.
self.mk_ty(Adt(def, substs)) self.mk_ty(Adt(def, substs))
} }
@ -2563,12 +2523,12 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn mk_place_downcast( pub fn mk_place_downcast(
self, self,
place: Place<'tcx>, place: Place<'tcx>,
adt_def: &'tcx AdtDef, adt_def: AdtDef<'tcx>,
variant_index: VariantIdx, variant_index: VariantIdx,
) -> Place<'tcx> { ) -> Place<'tcx> {
self.mk_place_elem( self.mk_place_elem(
place, place,
PlaceElem::Downcast(Some(adt_def.variants[variant_index].name), variant_index), PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
) )
} }

View file

@ -247,7 +247,7 @@ impl<'tcx> Ty<'tcx> {
} }
ty::Tuple(ref tys) if tys.is_empty() => format!("`{}`", self).into(), 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::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
ty::Array(t, n) => { ty::Array(t, n) => {
if t.is_simple_ty() { if t.is_simple_ty() {

View file

@ -86,7 +86,7 @@ pub fn simplify_type<'tcx>(
ty::Int(int_type) => Some(IntSimplifiedType(int_type)), ty::Int(int_type) => Some(IntSimplifiedType(int_type)),
ty::Uint(uint_type) => Some(UintSimplifiedType(uint_type)), ty::Uint(uint_type) => Some(UintSimplifiedType(uint_type)),
ty::Float(float_type) => Some(FloatSimplifiedType(float_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::Str => Some(StrSimplifiedType),
ty::Array(..) => Some(ArraySimplifiedType), ty::Array(..) => Some(ArraySimplifiedType),
ty::Slice(..) => Some(SliceSimplifiedType), ty::Slice(..) => Some(SliceSimplifiedType),

View file

@ -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. /// Calculates the forest of `DefId`s from which this ADT is visibly uninhabited.
fn uninhabited_from( fn uninhabited_from(
&self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> DefIdForest<'tcx> { ) -> DefIdForest<'tcx> {
// Non-exhaustive ADTs from other crates are always considered inhabited. // 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() DefIdForest::empty()
} else { } else {
DefIdForest::intersection( DefIdForest::intersection(
tcx, tcx,
self.variants self.variants()
.iter() .iter()
.map(|v| v.uninhabited_from(tcx, substs, self.adt_kind(), param_env)), .map(|v| v.uninhabited_from(tcx, substs, self.adt_kind(), param_env)),
) )

View file

@ -733,7 +733,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
} }
// SIMD vector types. // SIMD vector types.
ty::Adt(def, substs) if def.repr.simd() => { ty::Adt(def, substs) if def.repr().simd() => {
if !def.is_struct() { if !def.is_struct() {
// Should have yielded E0517 by now. // Should have yielded E0517 by now.
tcx.sess.delay_span_bug( tcx.sess.delay_span_bug(
@ -853,7 +853,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
// Cache the field layouts. // Cache the field layouts.
let variants = def let variants = def
.variants .variants()
.iter() .iter()
.map(|v| { .map(|v| {
v.fields v.fields
@ -864,22 +864,22 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
.collect::<Result<IndexVec<VariantIdx, _>, _>>()?; .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
if def.is_union() { 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( self.tcx.sess.delay_span_bug(
tcx.def_span(def.did), tcx.def_span(def.did()),
"union cannot be packed and aligned", "union cannot be packed and aligned",
); );
return Err(LayoutError::Unknown(ty)); return Err(LayoutError::Unknown(ty));
} }
let mut align = 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)); 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 size = Size::ZERO;
let mut abi = Abi::Aggregate { sized: true }; let mut abi = Abi::Aggregate { sized: true };
let index = VariantIdx::new(0); let index = VariantIdx::new(0);
@ -915,7 +915,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
size = cmp::max(size, field.size); 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)); align = align.min(AbiAndPrefAlign::new(pack));
} }
@ -963,7 +963,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
// Only one variant is present. // Only one variant is present.
(present_second.is_none() && (present_second.is_none() &&
// Representation optimizations are allowed. // Representation optimizations are allowed.
!def.repr.inhibit_enum_layout_opt()); !def.repr().inhibit_enum_layout_opt());
if is_struct { if is_struct {
// Struct, or univariant enum equivalent to a struct. // Struct, or univariant enum equivalent to a struct.
// (Typechecking will reject discriminant-sizing attrs.) // (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() { let kind = if def.is_enum() || variants[v].is_empty() {
StructKind::AlwaysSized StructKind::AlwaysSized
} else { } else {
let param_env = tcx.param_env(def.did); let param_env = tcx.param_env(def.did());
let last_field = def.variants[v].fields.last().unwrap(); let last_field = def.variant(v).fields.last().unwrap();
let always_sized = let always_sized =
tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env); tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env);
if !always_sized { 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 }; 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 { match st.abi {
Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => { Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => {
// the asserts ensure that we are not using the // 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. // 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 None
} else { } else {
Niche::from_scalar(dl, Size::ZERO, *scalar) 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 // instead of actual discriminants, so dataful enums with
// explicit discriminants (RFC #2363) would misbehave. // explicit discriminants (RFC #2363) would misbehave.
let no_explicit_discriminants = def let no_explicit_discriminants = def
.variants .variants()
.iter_enumerated() .iter_enumerated()
.all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32())); .all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));
let mut niche_filling_layout = None; let mut niche_filling_layout = None;
// Niche-filling enum optimization. // 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 dataful_variant = None;
let mut niche_variants = VariantIdx::MAX..=VariantIdx::new(0); 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( let mut st = self.univariant_uninterned(
ty, ty,
v, v,
&def.repr, &def.repr(),
StructKind::AlwaysSized, StructKind::AlwaysSized,
)?; )?;
st.variants = Variants::Single { index: j }; 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 (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(); let bits = Integer::from_attr(self, discr_type).size().bits();
for (i, discr) in def.discriminants(tcx) { for (i, discr) in def.discriminants(tcx) {
if variants[i].iter().any(|f| f.abi.is_uninhabited()) { if variants[i].iter().any(|f| f.abi.is_uninhabited()) {
@ -1193,7 +1193,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
max = 0; max = 0;
} }
assert!(min <= max, "discriminant range is {}...{}", min, max); 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 align = dl.aggregate_align;
let mut size = Size::ZERO; 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 overall enum, and the
// determining the alignment of the payload after the tag.) // determining the alignment of the payload after the tag.)
let mut prefix_align = min_ity.align(dl).abi; let mut prefix_align = min_ity.align(dl).abi;
if def.repr.c() { if def.repr().c() {
for fields in &variants { for fields in &variants {
for field in fields { for field in fields {
prefix_align = prefix_align.max(field.align.abi); prefix_align = prefix_align.max(field.align.abi);
@ -1223,7 +1223,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
let mut st = self.univariant_uninterned( let mut st = self.univariant_uninterned(
ty, ty,
&field_layouts, &field_layouts,
&def.repr, &def.repr(),
StructKind::Prefixed(min_ity.size(), prefix_align), StructKind::Prefixed(min_ity.size(), prefix_align),
)?; )?;
st.variants = Variants::Single { index: i }; st.variants = Variants::Single { index: i };
@ -1250,7 +1250,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
return Err(LayoutError::SizeOverflow(ty)); 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 { if typeck_ity < min_ity {
// It is a bug if Layout decided on a greater discriminant size than typeck for // 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 // 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. // won't be so conservative.
// Use the initial field alignment // 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 min_ity
} else { } else {
Integer::for_align(dl, start_align).unwrap_or(min_ity) 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_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 build_variant_info = |n: Option<Symbol>, flds: &[Symbol], layout: TyAndLayout<'tcx>| {
let mut min_size = Size::ZERO; let mut min_size = Size::ZERO;
@ -1855,12 +1855,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
match layout.variants { match layout.variants {
Variants::Single { index } => { Variants::Single { index } => {
if !adt_def.variants.is_empty() && layout.fields != FieldsShape::Primitive { if !adt_def.variants().is_empty() && layout.fields != FieldsShape::Primitive {
debug!( debug!(
"print-type-size `{:#?}` variant {}", "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(); let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
record( record(
adt_kind.into(), adt_kind.into(),
@ -1879,10 +1880,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
debug!( debug!(
"print-type-size `{:#?}` adt general variants def {}", "print-type-size `{:#?}` adt general variants def {}",
layout.ty, layout.ty,
adt_def.variants.len() adt_def.variants().len()
); );
let variant_infos: Vec<_> = adt_def let variant_infos: Vec<_> = adt_def
.variants .variants()
.iter_enumerated() .iter_enumerated()
.map(|(i, variant_def)| { .map(|(i, variant_def)| {
let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect(); let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
@ -1964,17 +1965,17 @@ impl<'tcx> SizeSkeleton<'tcx> {
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
// Only newtypes and enums w/ nullable pointer optimization. // 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); return Err(err);
} }
// Get a zero-sized variant or a pointer newtype. // Get a zero-sized variant or a pointer newtype.
let zero_or_ptr_variant = |i| { let zero_or_ptr_variant = |i| {
let i = VariantIdx::new(i); let i = VariantIdx::new(i);
let fields = def.variants[i] let fields =
.fields def.variant(i).fields.iter().map(|field| {
.iter() SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env)
.map(|field| SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env)); });
let mut ptr = None; let mut ptr = None;
for field in fields { for field in fields {
let field = field?; let field = field?;
@ -1997,11 +1998,11 @@ impl<'tcx> SizeSkeleton<'tcx> {
let v0 = zero_or_ptr_variant(0)?; let v0 = zero_or_ptr_variant(0)?;
// Newtype. // Newtype.
if def.variants.len() == 1 { if def.variants().len() == 1 {
if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 { if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 {
return Ok(SizeSkeleton::Pointer { return Ok(SizeSkeleton::Pointer {
non_zero: non_zero 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::Unbounded) => start > 0,
(Bound::Included(start), Bound::Included(end)) => { (Bound::Included(start), Bound::Included(end)) => {
0 < start && start < end 0 < start && start < end
@ -2262,9 +2263,9 @@ where
} }
let fields = match this.ty.kind() { 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"), 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!(), _ => bug!(),
}; };
tcx.intern_layout(LayoutS { tcx.intern_layout(LayoutS {
@ -2405,7 +2406,7 @@ where
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
match this.variants { match this.variants {
Variants::Single { index } => { 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). // Discriminant field for enums (where applicable).

View file

@ -274,7 +274,7 @@ fn characteristic_def_id_of_type_cached<'a>(
visited: &mut SsoHashSet<Ty<'a>>, visited: &mut SsoHashSet<Ty<'a>>,
) -> Option<DefId> { ) -> Option<DefId> {
match *ty.kind() { 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(), ty::Dynamic(data, ..) => data.principal_def_id(),

View file

@ -618,7 +618,7 @@ pub trait PrettyPrinter<'tcx>:
ty::BoundTyKind::Param(p) => p!(write("{}", p)), ty::BoundTyKind::Param(p) => p!(write("{}", p)),
}, },
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
p!(print_def_path(def.did, substs)); p!(print_def_path(def.did(), substs));
} }
ty::Dynamic(data, r) => { ty::Dynamic(data, r) => {
let print_r = self.should_print_region(r); let print_r = self.should_print_region(r);
@ -1487,7 +1487,7 @@ pub trait PrettyPrinter<'tcx>:
} }
p!(")"); p!(")");
} }
ty::Adt(def, _) if def.variants.is_empty() => { ty::Adt(def, _) if def.variants().is_empty() => {
self = self.typed_value( self = self.typed_value(
|mut this| { |mut this| {
write!(this, "unreachable()")?; write!(this, "unreachable()")?;
@ -1500,7 +1500,7 @@ pub trait PrettyPrinter<'tcx>:
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
let variant_idx = let variant_idx =
contents.variant.expect("destructed const of adt without 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)); p!(print_value_path(variant_def.def_id, substs));
match variant_def.ctor_kind { match variant_def.ctor_kind {

View file

@ -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::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 => { (&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)) Ok(tcx.mk_adt(a_def, substs))
} }

View file

@ -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 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ty::tls::with(|tcx| { ty::tls::with(|tcx| {
with_no_trimmed_paths!({ with_no_trimmed_paths!({
f.write_str( f.write_str(
&FmtPrinter::new(tcx, Namespace::TypeNS) &FmtPrinter::new(tcx, Namespace::TypeNS)
.print_def_path(self.did, &[])? .print_def_path(self.did(), &[])?
.into_buffer(), .into_buffer(),
) )
}) })
@ -672,7 +672,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
// TypeFoldable implementations. // TypeFoldable implementations.
/// AdtDefs are basically the same as a DefId. /// 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>>( fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self, self,
_folder: &mut F, _folder: &mut F,

View file

@ -109,7 +109,7 @@ pub enum TyKind<'tcx> {
/// ///
/// Note that generic parameters in fields only get lazily substituted /// Note that generic parameters in fields only get lazily substituted
/// by using something like `adt_def.all_fields().map(|field| field.ty(tcx, substs))`. /// 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`. /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
Foreign(DefId), Foreign(DefId),
@ -1903,7 +1903,7 @@ impl<'tcx> Ty<'tcx> {
#[inline] #[inline]
pub fn is_simd(self) -> bool { pub fn is_simd(self) -> bool {
match self.kind() { match self.kind() {
Adt(def, _) => def.repr.simd(), Adt(def, _) => def.repr().simd(),
_ => false, _ => false,
} }
} }
@ -1919,7 +1919,7 @@ impl<'tcx> Ty<'tcx> {
pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) { pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
match self.kind() { match self.kind() {
Adt(def, substs) => { 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 variant = def.non_enum_variant();
let f0_ty = variant.fields[0].ty(tcx, substs); let f0_ty = variant.fields[0].ty(tcx, substs);
@ -2153,9 +2153,9 @@ impl<'tcx> Ty<'tcx> {
} }
#[inline] #[inline]
pub fn ty_adt_def(self) -> Option<&'tcx AdtDef> { pub fn ty_adt_def(self) -> Option<AdtDef<'tcx>> {
match self.kind() { match self.kind() {
Adt(adt, _) => Some(adt), Adt(adt, _) => Some(*adt),
_ => None, _ => None,
} }
} }
@ -2194,7 +2194,7 @@ impl<'tcx> Ty<'tcx> {
variant_index: VariantIdx, variant_index: VariantIdx,
) -> Option<Discr<'tcx>> { ) -> Option<Discr<'tcx>> {
match self.kind() { 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 // This can actually happen during CTFE, see
// https://github.com/rust-lang/rust/issues/89765. // https://github.com/rust-lang/rust/issues/89765.
None None
@ -2212,7 +2212,7 @@ impl<'tcx> Ty<'tcx> {
/// Returns the type of the discriminant of this type. /// Returns the type of the discriminant of this type.
pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match self.kind() { 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::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
ty::Param(_) | ty::Projection(_) | ty::Opaque(..) | ty::Infer(ty::TyVar(_)) => { ty::Param(_) | ty::Projection(_) | ty::Opaque(..) | ty::Infer(ty::TyVar(_)) => {

View file

@ -377,10 +377,10 @@ impl<'tcx> TyCtxt<'tcx> {
/// Note that this returns only the constraints for the /// Note that this returns only the constraints for the
/// destructor of `def` itself. For the destructors of the /// destructor of `def` itself. For the destructors of the
/// contents, you need `adt_dtorck_constraint`. /// 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) { let dtor = match def.destructor(self) {
None => { None => {
debug!("destructor_constraints({:?}) - no dtor", def.did); debug!("destructor_constraints({:?}) - no dtor", def.did());
return vec![]; return vec![];
} }
Some(dtor) => dtor.did, Some(dtor) => dtor.did,
@ -415,7 +415,7 @@ impl<'tcx> TyCtxt<'tcx> {
_ => bug!(), _ => 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, ty::Adt(def_, substs) if def_ == def => substs,
_ => bug!(), _ => bug!(),
}; };
@ -445,7 +445,7 @@ impl<'tcx> TyCtxt<'tcx> {
}) })
.map(|(item_param, _)| item_param) .map(|(item_param, _)| item_param)
.collect(); .collect();
debug!("destructor_constraint({:?}) = {:?}", def.did, result); debug!("destructor_constraint({:?}) = {:?}", def.did(), result);
result result
} }

View file

@ -334,8 +334,8 @@ impl<'tcx> PlaceBuilder<'tcx> {
self.project(PlaceElem::Deref) self.project(PlaceElem::Deref)
} }
crate fn downcast(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx) -> Self { crate fn downcast(self, adt_def: AdtDef<'tcx>, variant_index: VariantIdx) -> Self {
self.project(PlaceElem::Downcast(Some(adt_def.variants[variant_index].name), variant_index)) self.project(PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index))
} }
fn index(self, index: Local) -> Self { fn index(self, index: Local) -> Self {

View file

@ -332,7 +332,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.collect(); .collect();
let field_names: Vec<_> = 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 fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base {
let place_builder = let place_builder =
@ -367,7 +367,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}) })
}); });
let adt = Box::new(AggregateKind::Adt( let adt = Box::new(AggregateKind::Adt(
adt_def.did, adt_def.did(),
variant_index, variant_index,
substs, substs,
user_ty, user_ty,

View file

@ -946,7 +946,7 @@ enum TestKind<'tcx> {
/// Test what enum variant a value is. /// Test what enum variant a value is.
Switch { Switch {
/// The enum type being tested. /// 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 /// The set of variants that we should create a branch for. We also
/// create an additional "otherwise" case. /// create an additional "otherwise" case.
variants: BitSet<VariantIdx>, variants: BitSet<VariantIdx>,

View file

@ -264,7 +264,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => { 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 || { i == variant_index || {
self.tcx.features().exhaustive_patterns self.tcx.features().exhaustive_patterns
&& !v && !v
@ -276,7 +276,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
) )
.is_empty() .is_empty()
} }
}) && (adt_def.did.is_local() }) && (adt_def.did().is_local()
|| !adt_def.is_variant_list_non_exhaustive()); || !adt_def.is_variant_list_non_exhaustive());
if irrefutable { if irrefutable {
let place_builder = match_pair.place.downcast(adt_def, variant_index); let place_builder = match_pair.place.downcast(adt_def, variant_index);

View file

@ -30,11 +30,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// It is a bug to call this with a not-fully-simplified pattern. /// 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> { pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> {
match *match_pair.pattern.kind { 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, span: match_pair.pattern.span,
kind: TestKind::Switch { kind: TestKind::Switch {
adt_def, 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 } => { TestKind::Switch { adt_def, ref variants } => {
let target_blocks = make_target_blocks(self); let target_blocks = make_target_blocks(self);
// Variants is a BitVec of indexes into adt_def.variants. // 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); debug_assert_eq!(target_blocks.len(), num_enum_variants + 1);
let otherwise_block = *target_blocks.last().unwrap(); let otherwise_block = *target_blocks.last().unwrap();
let tcx = self.tcx; let tcx = self.tcx;
@ -201,7 +201,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
otherwise_block, otherwise_block,
); );
debug!("num_enum_variants: {}, variants: {:?}", num_enum_variants, variants); 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); let discr = self.temp(discr_ty, test.span);
self.cfg.push_assign( self.cfg.push_assign(
block, block,
@ -733,7 +733,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn candidate_after_variant_switch<'pat>( fn candidate_after_variant_switch<'pat>(
&mut self, &mut self,
match_pair_index: usize, match_pair_index: usize,
adt_def: &'tcx ty::AdtDef, adt_def: ty::AdtDef<'tcx>,
variant_index: VariantIdx, variant_index: VariantIdx,
subpatterns: &'pat [FieldPat<'tcx>], subpatterns: &'pat [FieldPat<'tcx>],
candidate: &mut Candidate<'pat, '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 // we want to create a set of derived match-patterns like
// `(x as Variant).0 @ P1` and `(x as Variant).1 @ P1`. // `(x as Variant).0 @ P1` and `(x as Variant).1 @ P1`.
let elem = 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 downcast_place = match_pair.place.project(elem); // `(x as Variant)`
let consequent_match_pairs = subpatterns.iter().map(|subpattern| { let consequent_match_pairs = subpatterns.iter().map(|subpattern| {
// e.g., `(x as Variant).0` // e.g., `(x as Variant).0`
@ -798,7 +798,7 @@ impl Test<'_> {
// variants, we have a target for each variant and the // variants, we have a target for each variant and the
// otherwise case, and we make sure that all of the cases not // otherwise case, and we make sure that all of the cases not
// specified have the same block. // specified have the same block.
adt_def.variants.len() + 1 adt_def.variants().len() + 1
} }
TestKind::SwitchInt { switch_ty, ref options, .. } => { TestKind::SwitchInt { switch_ty, ref options, .. } => {
if switch_ty.is_bool() { if switch_ty.is_bool() {

View file

@ -162,7 +162,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for LayoutConstrainedPlaceVisitor<'a, 'tcx> {
ExprKind::Field { lhs, .. } => { ExprKind::Field { lhs, .. } => {
if let ty::Adt(adt_def, _) = self.thir[lhs].ty.kind() { if let ty::Adt(adt_def, _) = self.thir[lhs].ty.kind() {
if (Bound::Unbounded, Bound::Unbounded) 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; self.found = true;
} }
@ -242,7 +242,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
visit::walk_pat(self, pat); visit::walk_pat(self, pat);
self.in_union_destructure = old_in_union_destructure; self.in_union_destructure = old_in_union_destructure;
} else if (Bound::Unbounded, Bound::Unbounded) } 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); let old_inside_adt = std::mem::replace(&mut self.inside_adt, true);
visit::walk_pat(self, pat); visit::walk_pat(self, pat);
@ -386,7 +386,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
user_ty: _, user_ty: _,
fields: _, fields: _,
base: _, 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) => {} (Bound::Unbounded, Bound::Unbounded) => {}
_ => self.requires_unsafe(expr.span, InitializingTypeWith), _ => self.requires_unsafe(expr.span, InitializingTypeWith),
}, },

View file

@ -228,7 +228,7 @@ impl<'tcx> Cx<'tcx> {
let user_ty = let user_ty =
user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| { user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
if let UserType::TypeOf(ref mut did, _) = &mut u_ty.value { if let UserType::TypeOf(ref mut did, _) = &mut u_ty.value {
*did = adt_def.did; *did = adt_def.did();
} }
u_ty u_ty
}); });
@ -376,7 +376,7 @@ impl<'tcx> Cx<'tcx> {
let user_ty = user_provided_types.get(expr.hir_id).copied(); let user_ty = user_provided_types.get(expr.hir_id).copied();
debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty); debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
ExprKind::Adt(Box::new(Adt { ExprKind::Adt(Box::new(Adt {
adt_def: adt, adt_def: *adt,
variant_index: VariantIdx::new(0), variant_index: VariantIdx::new(0),
substs, substs,
user_ty, user_ty,
@ -402,7 +402,7 @@ impl<'tcx> Cx<'tcx> {
let user_ty = user_provided_types.get(expr.hir_id).copied(); let user_ty = user_provided_types.get(expr.hir_id).copied();
debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty); debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
ExprKind::Adt(Box::new(Adt { ExprKind::Adt(Box::new(Adt {
adt_def: adt, adt_def: *adt,
variant_index: index, variant_index: index,
substs, substs,
user_ty, user_ty,
@ -680,7 +680,7 @@ impl<'tcx> Cx<'tcx> {
let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id); let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
let (d, o) = adt_def.discriminant_def_for_variant(idx); let (d, o) = adt_def.discriminant_def_for_variant(idx);
use rustc_middle::ty::util::IntTypeExt; 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()); let ty = ty.to_ty(self.tcx());
Some((d, o, ty)) Some((d, o, ty))
} }
@ -924,7 +924,7 @@ impl<'tcx> Cx<'tcx> {
// A unit struct/variant which is used as a value. // A unit struct/variant which is used as a value.
// We return a completely different ExprKind here to account for this special case. // We return a completely different ExprKind here to account for this special case.
ty::Adt(adt_def, substs) => ExprKind::Adt(Box::new(Adt { 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), variant_index: adt_def.variant_index_with_ctor_id(def_id),
substs, substs,
user_ty: user_provided_type, user_ty: user_provided_type,

View file

@ -395,17 +395,17 @@ fn check_for_bindings_named_same_as_variants(
&& let pat_ty = cx.typeck_results.pat_ty(p).peel_refs() && let pat_ty = cx.typeck_results.pat_ty(p).peel_refs()
&& let ty::Adt(edef, _) = pat_ty.kind() && let ty::Adt(edef, _) = pat_ty.kind()
&& edef.is_enum() && edef.is_enum()
&& edef.variants.iter().any(|variant| { && edef.variants().iter().any(|variant| {
variant.ident(cx.tcx) == ident && variant.ctor_kind == CtorKind::Const 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( cx.tcx.struct_span_lint_hir(
BINDINGS_WITH_VARIANT_NAME, BINDINGS_WITH_VARIANT_NAME,
p.hir_id, p.hir_id,
p.span, p.span,
|lint| { |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!( let mut err = lint.build(&format!(
"pattern binding `{}` is named the same as one \ "pattern binding `{}` is named the same as one \
of the variants of the type `{}`", of the variants of the type `{}`",
@ -573,7 +573,7 @@ fn non_exhaustive_match<'p, 'tcx>(
) { ) {
let is_empty_match = arms.is_empty(); let is_empty_match = arms.is_empty();
let non_empty_enum = match scrut_ty.kind() { 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, _ => false,
}; };
// In the case of an empty match, replace the '`_` not covered' diagnostic with something more // 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() { 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, _ => false,
}; };
@ -762,17 +762,17 @@ fn adt_defined_here<'p, 'tcx>(
if let ty::Adt(def, _) = ty.kind() { if let ty::Adt(def, _) = ty.kind() {
let mut spans = vec![]; let mut spans = vec![];
if witnesses.len() < 5 { 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); spans.push(sp);
} }
} }
let def_span = cx let def_span = cx
.tcx .tcx
.hir() .hir()
.get_if_local(def.did) .get_if_local(def.did())
.and_then(|node| node.ident()) .and_then(|node| node.ident())
.map(|ident| ident.span) .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 = let mut span: MultiSpan =
if spans.is_empty() { def_span.into() } else { spans.clone().into() }; 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>( fn maybe_point_at_variant<'a, 'p: 'a, 'tcx: 'a>(
cx: &MatchCheckCtxt<'p, 'tcx>, cx: &MatchCheckCtxt<'p, 'tcx>,
def: &AdtDef, def: AdtDef<'tcx>,
patterns: impl Iterator<Item = &'a DeconstructedPat<'p, 'tcx>>, patterns: impl Iterator<Item = &'a DeconstructedPat<'p, 'tcx>>,
) -> Vec<Span> { ) -> Vec<Span> {
use Constructor::*; use Constructor::*;
let mut covered = vec![]; let mut covered = vec![];
for pattern in patterns { for pattern in patterns {
if let Variant(variant_index) = pattern.ctor() { 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; 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) { if covered.contains(&sp) {
// Don't point at variants that have already been covered due to other patterns to avoid // Don't point at variants that have already been covered due to other patterns to avoid
// visual clutter. // visual clutter.

View file

@ -110,8 +110,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
self.infcx.tcx self.infcx.tcx
} }
fn adt_derive_msg(&self, adt_def: &AdtDef) -> String { fn adt_derive_msg(&self, adt_def: AdtDef<'tcx>) -> String {
let path = self.tcx().def_path_str(adt_def.did); let path = self.tcx().def_path_str(adt_def.did());
format!( format!(
"to use a constant of type `{}` in a pattern, \ "to use a constant of type `{}` in a pattern, \
`{}` must be annotated with `#[derive(PartialEq, Eq)]`", `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
@ -346,7 +346,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
adt_def, adt_def,
cv.ty() cv.ty()
); );
let path = tcx.def_path_str(adt_def.did); let path = tcx.def_path_str(adt_def.did());
let msg = format!( let msg = format!(
"to use a constant of type `{}` in a pattern, \ "to use a constant of type `{}` in a pattern, \
`{}` must be annotated with `#[derive(PartialEq, Eq)]`", `{}` 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() => { ty::Adt(adt_def, substs) if adt_def.is_enum() => {
let destructured = tcx.destructure_const(param_env.and(cv)); let destructured = tcx.destructure_const(param_env.and(cv));
PatKind::Variant { PatKind::Variant {
adt_def, adt_def: *adt_def,
substs, substs,
variant_index: destructured variant_index: destructured
.variant .variant

View file

@ -681,7 +681,7 @@ impl<'tcx> Constructor<'tcx> {
/// This means that the variant has a stdlib unstable feature marking it. /// This means that the variant has a stdlib unstable feature marking it.
pub(super) fn is_unstable_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool { pub(super) fn is_unstable_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool {
if let Constructor::Variant(idx) = self && let ty::Adt(adt, _) = pcx.ty.kind() { 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. // Filter variants that depend on a disabled unstable feature.
return matches!( return matches!(
pcx.cx.tcx.eval_stability(variant_def_id, None, DUMMY_SP, None), pcx.cx.tcx.eval_stability(variant_def_id, None, DUMMY_SP, None),
@ -695,13 +695,13 @@ impl<'tcx> Constructor<'tcx> {
/// attribute. /// attribute.
pub(super) fn is_doc_hidden_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool { 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() { 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); return pcx.cx.tcx.is_doc_hidden(variant_def_id);
} }
false 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 { match *self {
Variant(idx) => idx, Variant(idx) => idx,
Single => { Single => {
@ -725,7 +725,7 @@ impl<'tcx> Constructor<'tcx> {
// patterns. If we're here we can assume this is a box pattern. // patterns. If we're here we can assume this is a box pattern.
1 1
} else { } 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() 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 // exception is if the pattern is at the top level, because we want empty matches to be
// considered exhaustive. // considered exhaustive.
let is_secretly_empty = 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 let mut ctors: SmallVec<[_; 1]> = def
.variants .variants()
.iter_enumerated() .iter_enumerated()
.filter(|(_, v)| { .filter(|(_, v)| {
// If `exhaustive_patterns` is enabled, we exclude variants known to be // 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> { ) -> impl Iterator<Item = (Field, Ty<'tcx>)> + Captures<'a> + Captures<'p> {
let ty::Adt(adt, substs) = ty.kind() else { bug!() }; let ty::Adt(adt, substs) = ty.kind() else { bug!() };
// Whether we must not match the fields of this variant exhaustively. // 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)| { variant.fields.iter().enumerate().filter_map(move |(i, field)| {
let ty = field.ty(cx.tcx, substs); 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. // patterns. If we're here we can assume this is a box pattern.
Fields::wildcards_from_tys(cx, once(substs.type_at(0))) Fields::wildcards_from_tys(cx, once(substs.type_at(0)))
} else { } 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) let tys = Fields::list_variant_nonhidden_fields(cx, ty, variant)
.map(|(_, ty)| ty); .map(|(_, ty)| ty);
Fields::wildcards_from_tys(cx, tys) Fields::wildcards_from_tys(cx, tys)
@ -1346,7 +1346,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
PatKind::Variant { variant_index, .. } => Variant(*variant_index), PatKind::Variant { variant_index, .. } => Variant(*variant_index),
_ => bug!(), _ => 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. // 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>> = let mut field_id_to_id: Vec<Option<usize>> =
(0..variant.fields.len()).map(|_| None).collect(); (0..variant.fields.len()).map(|_| None).collect();
@ -1459,15 +1459,15 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
PatKind::Deref { subpattern: subpatterns.next().unwrap() } PatKind::Deref { subpattern: subpatterns.next().unwrap() }
} }
ty::Adt(adt_def, substs) => { ty::Adt(adt_def, substs) => {
let variant_index = self.ctor.variant_index_for_adt(adt_def); let variant_index = self.ctor.variant_index_for_adt(*adt_def);
let variant = &adt_def.variants[variant_index]; let variant = &adt_def.variant(variant_index);
let subpatterns = Fields::list_variant_nonhidden_fields(cx, self.ty, variant) let subpatterns = Fields::list_variant_nonhidden_fields(cx, self.ty, variant)
.zip(subpatterns) .zip(subpatterns)
.map(|((field, _ty), pattern)| FieldPat { field, pattern }) .map(|((field, _ty), pattern)| FieldPat { field, pattern })
.collect(); .collect();
if adt_def.is_enum() { if adt_def.is_enum() {
PatKind::Variant { adt_def, substs, variant_index, subpatterns } PatKind::Variant { adt_def: *adt_def, substs, variant_index, subpatterns }
} else { } else {
PatKind::Leaf { subpatterns } PatKind::Leaf { subpatterns }
} }
@ -1640,9 +1640,7 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
} }
ty::Adt(..) | ty::Tuple(..) => { ty::Adt(..) | ty::Tuple(..) => {
let variant = match self.ty.kind() { let variant = match self.ty.kind() {
ty::Adt(adt, _) => { ty::Adt(adt, _) => Some(adt.variant(self.ctor.variant_index_for_adt(*adt))),
Some(&adt.variants[self.ctor.variant_index_for_adt(adt)])
}
ty::Tuple(_) => None, ty::Tuple(_) => None,
_ => unreachable!(), _ => unreachable!(),
}; };

View file

@ -653,7 +653,7 @@ macro_rules! CloneImpls {
CloneImpls! { <'tcx> CloneImpls! { <'tcx>
Span, Field, Mutability, Symbol, hir::HirId, usize, ty::Const<'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>, SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>,
UserTypeProjection, PatTyProj<'tcx> UserTypeProjection, PatTyProj<'tcx>
} }

View file

@ -325,7 +325,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
pub(super) fn is_foreign_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool { pub(super) fn is_foreign_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool {
match ty.kind() { match ty.kind() {
ty::Adt(def, ..) => { 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, _ => false,
} }

View file

@ -20,7 +20,7 @@ crate trait UserAnnotatedTyHelpers<'tcx> {
match ty.kind() { match ty.kind() {
ty::Adt(adt_def, ..) => { ty::Adt(adt_def, ..) => {
if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value { if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value {
*did = adt_def.did; *did = adt_def.did();
} }
Some(user_ty) Some(user_ty)
} }

View file

@ -407,7 +407,7 @@ where
self.drop_ladder(fields, succ, unwind).0 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); debug!("open_drop_for_box({:?}, {:?}, {:?})", self, adt, substs);
let interior = self.tcx().mk_place_deref(self.place); let interior = self.tcx().mk_place_deref(self.place);
@ -420,9 +420,9 @@ where
self.drop_subpath(interior, interior_path, succ, unwind_succ) 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); 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 { return self.elaborator.patch().new_block(BasicBlockData {
statements: vec![], statements: vec![],
terminator: Some(Terminator { terminator: Some(Terminator {
@ -434,7 +434,7 @@ where
} }
let skip_contents = 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 { let contents_drop = if skip_contents {
(self.succ, self.unwind) (self.succ, self.unwind)
} else { } else {
@ -450,7 +450,7 @@ where
fn open_drop_for_adt_contents( fn open_drop_for_adt_contents(
&mut self, &mut self,
adt: &'tcx ty::AdtDef, adt: ty::AdtDef<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
) -> (BasicBlock, Unwind) { ) -> (BasicBlock, Unwind) {
let (succ, unwind) = self.drop_ladder_bottom(); let (succ, unwind) = self.drop_ladder_bottom();
@ -458,7 +458,7 @@ where
let fields = self.move_paths_for_fields( let fields = self.move_paths_for_fields(
self.place, self.place,
self.path, self.path,
&adt.variants[VariantIdx::new(0)], &adt.variant(VariantIdx::new(0)),
substs, substs,
); );
self.drop_ladder(fields, succ, unwind) self.drop_ladder(fields, succ, unwind)
@ -469,22 +469,22 @@ where
fn open_drop_for_multivariant( fn open_drop_for_multivariant(
&mut self, &mut self,
adt: &'tcx ty::AdtDef, adt: ty::AdtDef<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
succ: BasicBlock, succ: BasicBlock,
unwind: Unwind, unwind: Unwind,
) -> (BasicBlock, Unwind) { ) -> (BasicBlock, Unwind) {
let mut values = 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 normal_blocks = Vec::with_capacity(adt.variants().len());
let mut unwind_blocks = 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_with_drop_glue = false;
let mut have_otherwise = false; let mut have_otherwise = false;
let tcx = self.tcx(); let tcx = self.tcx();
for (variant_index, discr) in adt.discriminants(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); let subpath = self.elaborator.downcast_subpath(self.path, variant_index);
if let Some(variant_path) = subpath { if let Some(variant_path) = subpath {
@ -564,7 +564,7 @@ where
fn adt_switch_block( fn adt_switch_block(
&mut self, &mut self,
adt: &'tcx ty::AdtDef, adt: ty::AdtDef<'tcx>,
blocks: Vec<BasicBlock>, blocks: Vec<BasicBlock>,
values: &[u128], values: &[u128],
succ: BasicBlock, succ: BasicBlock,
@ -577,7 +577,7 @@ where
// Additionally, we do not want to switch on the // Additionally, we do not want to switch on the
// discriminant after it is free-ed, because that // discriminant after it is free-ed, because that
// way lies only trouble. // 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 = Place::from(self.new_temp(discr_ty));
let discr_rv = Rvalue::Discriminant(self.place); let discr_rv = Rvalue::Discriminant(self.place);
let switch_block = BasicBlockData { let switch_block = BasicBlockData {
@ -869,9 +869,9 @@ where
ty::Tuple(fields) => self.open_drop_for_tuple(fields), ty::Tuple(fields) => self.open_drop_for_tuple(fields),
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
if def.is_box() { if def.is_box() {
self.open_drop_for_box(def, substs) self.open_drop_for_box(*def, substs)
} else { } else {
self.open_drop_for_adt(def, substs) self.open_drop_for_adt(*def, substs)
} }
} }
ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind), ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
@ -927,7 +927,7 @@ where
/// The contained value will not be dropped. /// The contained value will not be dropped.
fn box_free_block( fn box_free_block(
&mut self, &mut self,
adt: &'tcx ty::AdtDef, adt: ty::AdtDef<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
target: BasicBlock, target: BasicBlock,
unwind: Unwind, unwind: Unwind,
@ -940,7 +940,7 @@ where
/// value). /// value).
fn unelaborated_free_block( fn unelaborated_free_block(
&mut self, &mut self,
adt: &'tcx ty::AdtDef, adt: ty::AdtDef<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
target: BasicBlock, target: BasicBlock,
unwind: Unwind, unwind: Unwind,
@ -948,7 +948,8 @@ where
let tcx = self.tcx(); let tcx = self.tcx();
let unit_temp = Place::from(self.new_temp(tcx.mk_unit())); 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 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 .fields
.iter() .iter()
.enumerate() .enumerate()

View file

@ -705,14 +705,14 @@ fn switch_on_enum_discriminant<'mir, 'tcx>(
body: &'mir mir::Body<'tcx>, body: &'mir mir::Body<'tcx>,
block: &'mir mir::BasicBlockData<'tcx>, block: &'mir mir::BasicBlockData<'tcx>,
switch_on: mir::Place<'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() { for statement in block.statements.iter().rev() {
match &statement.kind { match &statement.kind {
mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated))) mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated)))
if *lhs == switch_on => if *lhs == switch_on =>
{ {
match &discriminated.ty(body, tcx).ty.kind() { match discriminated.ty(body, tcx).ty.kind() {
ty::Adt(def, _) => return Some((*discriminated, def)), ty::Adt(def, _) => return Some((*discriminated, *def)),
// `Rvalue::Discriminant` is also used to get the active yield point for a // `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 // generator, but we do not need edge-specific effects in that case. This may

View file

@ -336,7 +336,7 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
ProjectionElem::Field(..) => { ProjectionElem::Field(..) => {
let ty = place_base.ty(&self.body.local_decls, self.tcx).ty; let ty = place_base.ty(&self.body.local_decls, self.tcx).ty;
if let ty::Adt(def, _) = ty.kind() { 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) != (Bound::Unbounded, Bound::Unbounded)
{ {
let details = if is_mut_use { let details = if is_mut_use {

View file

@ -210,7 +210,7 @@ struct SuspensionPoint<'tcx> {
struct TransformVisitor<'tcx> { struct TransformVisitor<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
state_adt_ref: &'tcx AdtDef, state_adt_ref: AdtDef<'tcx>,
state_substs: SubstsRef<'tcx>, state_substs: SubstsRef<'tcx>,
// The type of the discriminant in the generator struct // The type of the discriminant in the generator struct
@ -243,11 +243,11 @@ impl<'tcx> TransformVisitor<'tcx> {
val: Operand<'tcx>, val: Operand<'tcx>,
source_info: SourceInfo, source_info: SourceInfo,
) -> impl Iterator<Item = Statement<'tcx>> { ) -> impl Iterator<Item = Statement<'tcx>> {
let kind = AggregateKind::Adt(self.state_adt_ref.did, idx, self.state_substs, None, None); 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); assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 1);
let ty = self let ty = self
.tcx .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); .subst(self.tcx, self.state_substs);
expand_aggregate( expand_aggregate(
Place::return_place(), Place::return_place(),

View file

@ -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 // If its projection *is* present in `MoveData`, then the field may have been moved
// from separate from its parent. Recurse. // 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. // Enums have multiple variants, which are discriminated with a `Downcast` projection.
// Structs have a single variant, and don't use a `Downcast` projection. // Structs have a single variant, and don't use a `Downcast` projection.
let mpi = if adt.is_enum() { let mpi = if adt.is_enum() {

View file

@ -760,10 +760,10 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
let statements = expand_aggregate( let statements = expand_aggregate(
Place::return_place(), 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)) (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, source_info,
tcx, tcx,
) )

View file

@ -726,7 +726,7 @@ impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> {
); );
return StatementEquality::NotEqual; 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 { if !variant_is_fieldless {
trace!("NO: variant {:?} was not fieldless", variant_index); trace!("NO: variant {:?} was not fieldless", variant_index);
return StatementEquality::NotEqual; return StatementEquality::NotEqual;

View file

@ -259,7 +259,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
if self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads) { if self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads) {
let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap(); let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap();
if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() { 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 self.ignored_derived_traits
.entry(adt_def_id) .entry(adt_def_id)
.or_default() .or_default()
@ -297,7 +297,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
match item.kind { match item.kind {
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
let def = self.tcx.adt_def(item.def_id); 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); intravisit::walk_item(self, &item);
} }
@ -328,8 +328,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
self.repr_has_repr_c = had_repr_c; self.repr_has_repr_c = had_repr_c;
} }
fn mark_as_used_if_union(&mut self, adt: &ty::AdtDef, fields: &[hir::ExprField<'_>]) { 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() { if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did().is_local() {
for field in fields { for field in fields {
let index = self.tcx.field_index(field.hir_id, self.typeck_results()); let index = self.tcx.field_index(field.hir_id, self.typeck_results());
self.insert_def_id(adt.non_enum_variant().fields[index].did); 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, _) => { hir::ExprKind::Struct(ref qpath, ref fields, _) => {
let res = self.typeck_results().qpath_res(qpath, expr.hir_id); let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
self.handle_res(res); self.handle_res(res);
if let ty::Adt(ref adt, _) = self.typeck_results().expr_ty(expr).kind() { if let ty::Adt(adt, _) = self.typeck_results().expr_ty(expr).kind() {
self.mark_as_used_if_union(adt, fields); self.mark_as_used_if_union(*adt, fields);
} }
} }
_ => (), _ => (),

View file

@ -38,22 +38,22 @@ struct ExprVisitor<'tcx> {
fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
let ty::Adt(def, substs) = *ty.kind() else { return ty }; 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 data_idx;
let one = VariantIdx::new(1); let one = VariantIdx::new(1);
let zero = VariantIdx::new(0); let zero = VariantIdx::new(0);
if def.variants[zero].fields.is_empty() { if def.variant(zero).fields.is_empty() {
data_idx = one; data_idx = one;
} else if def.variants[one].fields.is_empty() { } else if def.variant(one).fields.is_empty() {
data_idx = zero; data_idx = zero;
} else { } else {
return ty; return ty;
} }
if def.variants[data_idx].fields.len() == 1 { if def.variant(data_idx).fields.len() == 1 {
return def.variants[data_idx].fields[0].ty(tcx, substs); 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) => { ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => {
Some(asm_ty_isize) 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 fields = &adt.non_enum_variant().fields;
let elem_ty = fields[0].ty(self.tcx, substs); let elem_ty = fields[0].ty(self.tcx, substs);
match elem_ty.kind() { match elem_ty.kind() {

View file

@ -9,6 +9,7 @@
use rustc_ast::MacroDef; use rustc_ast::MacroDef;
use rustc_attr as attr; use rustc_attr as attr;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::intern::Interned;
use rustc_errors::struct_span_err; use rustc_errors::struct_span_err;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
@ -182,7 +183,7 @@ where
let tcx = self.def_id_visitor.tcx(); let tcx = self.def_id_visitor.tcx();
// InternalSubsts are not visited here because they are visited below in `super_visit_with`. // InternalSubsts are not visited here because they are visited below in `super_visit_with`.
match *ty.kind() { 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::Foreign(def_id)
| ty::FnDef(def_id, ..) | ty::FnDef(def_id, ..)
| ty::Closure(def_id, ..) | ty::Closure(def_id, ..)
@ -930,7 +931,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
&mut self, &mut self,
use_ctxt: Span, // syntax context of the field name at the use site use_ctxt: Span, // syntax context of the field name at the use site
span: Span, // span of the field pattern, e.g., `x: 0` 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, field: &'tcx ty::FieldDef,
in_update_syntax: bool, in_update_syntax: bool,
) { ) {
@ -941,7 +942,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
// definition of the field // definition of the field
let ident = Ident::new(kw::Empty, use_ctxt); let ident = Ident::new(kw::Empty, use_ctxt);
let hir_id = self.tcx.hir().local_def_id_to_hir_id(self.current_item); 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) { if !field.vis.is_accessible_from(def_id, self.tcx) {
let label = if in_update_syntax { let label = if in_update_syntax {
format!("field `{}` is private", field.name) format!("field `{}` is private", field.name)
@ -956,7 +957,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
"field `{}` of {} `{}` is private", "field `{}` of {} `{}` is private",
field.name, field.name,
def.variant_descr(), def.variant_descr(),
self.tcx.def_path_str(def.did) self.tcx.def_path_str(def.did())
) )
.span_label(span, label) .span_label(span, label)
.emit(); .emit();

View file

@ -554,7 +554,7 @@ impl<'tcx> SaveContext<'tcx> {
Some(Data::RefData(Ref { Some(Data::RefData(Ref {
kind: RefKind::Type, kind: RefKind::Type,
span, span,
ref_id: id_from_def_id(def.did), ref_id: id_from_def_id(def.did()),
})) }))
} }
_ => { _ => {

View file

@ -1,5 +1,6 @@
use rustc_data_structures::base_n; use rustc_data_structures::base_n;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::intern::Interned;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::CtorKind; use rustc_hir::def::CtorKind;
use rustc_hir::def_id::{CrateNum, DefId}; 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. // 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::FnDef(def_id, substs)
| ty::Opaque(def_id, substs) | ty::Opaque(def_id, substs)
| ty::Projection(ty::ProjectionTy { item_def_id: 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) => { ty::Adt(def, substs) => {
let variant_idx = let variant_idx =
contents.variant.expect("destructed const of adt without 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.push("V");
self = self.print_def_path(variant_def.def_id, substs)?; self = self.print_def_path(variant_def.def_id, substs)?;

View file

@ -676,7 +676,7 @@ fn fundamental_ty_inner_tys<'tcx>(
match types.next() { match types.next() {
None => { None => {
tcx.sess.span_err( tcx.sess.span_err(
tcx.def_span(def.did), tcx.def_span(def.did()),
"`#[fundamental]` requires at least one type parameter", "`#[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, 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::Foreign(did) => def_id_is_local(did, in_crate),
ty::Opaque(..) => { ty::Opaque(..) => {
// This merits some explanation. // This merits some explanation.

View file

@ -813,7 +813,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
| ty::Foreign(did) | ty::Foreign(did)
| ty::FnDef(did, _) | ty::FnDef(did, _)
| ty::Generator(did, ..) => Some(did), | ty::Generator(did, ..) => Some(did),
ty::Adt(def, _) => Some(def.did), ty::Adt(def, _) => Some(def.did()),
_ => None, _ => None,
}; };
@ -1467,7 +1467,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
ty::Bool => Some(0), ty::Bool => Some(0),
ty::Char => Some(1), ty::Char => Some(1),
ty::Str => Some(2), 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::Int(..)
| ty::Uint(..) | ty::Uint(..)
| ty::Float(..) | ty::Float(..)

View file

@ -172,7 +172,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
if let Some(def) = self_ty.ty_adt_def() { if let Some(def) = self_ty.ty_adt_def() {
// We also want to be able to select self's original // We also want to be able to select self's original
// signature with no type arguments resolved // 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() { 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() { if let Some(def) = param_ty.ty_adt_def() {
// We also want to be able to select the parameter's // We also want to be able to select the parameter's
// original signature with no type arguments resolved // 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)); 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() { if let Some(def) = aty.ty_adt_def() {
// We also want to be able to select the array's type's original // We also want to be able to select the array's type's original
// signature with no type arguments resolved // 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)))); flags.push((sym::_Self, Some(format!("[{}]", type_string))));
let len = let len =

View file

@ -2129,7 +2129,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
if !is_upvar_tys_infer_tuple { if !is_upvar_tys_infer_tuple {
let msg = format!("required because it appears within the type `{}`", ty); let msg = format!("required because it appears within the type `{}`", ty);
match ty.kind() { 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), Some(ident) => err.span_note(ident.span, &msg),
None => err.note(&msg), None => err.note(&msg),
}, },

View file

@ -43,7 +43,7 @@ pub fn can_type_implement_copy<'tcx>(
}; };
let mut infringing = Vec::new(); let mut infringing = Vec::new();
for variant in &adt.variants { for variant in adt.variants() {
for field in &variant.fields { for field in &variant.fields {
let ty = field.ty(tcx, substs); let ty = field.ty(tcx, substs);
if ty.references_error() { 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 // If it does not, then this field probably doesn't normalize
// to begin with, and point to the bad field's span instead. // to begin with, and point to the bad field's span instead.
let cause = if field 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() .has_param_types_or_consts()
{ {
cause.clone() cause.clone()

View file

@ -112,7 +112,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
} }
ty::Adt(def, _) => { 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. // `ManuallyDrop` never has a dtor.
true true
} else { } else {

View file

@ -12,7 +12,7 @@ use std::ops::ControlFlow;
#[derive(Debug)] #[derive(Debug)]
pub enum NonStructuralMatchTy<'tcx> { pub enum NonStructuralMatchTy<'tcx> {
Adt(&'tcx AdtDef), Adt(AdtDef<'tcx>),
Param, Param,
Dynamic, Dynamic,
Foreign, 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); debug!("Search already seen adt_def: {:?}", adt_def);
return ControlFlow::CONTINUE; return ControlFlow::CONTINUE;
} }
if !self.type_marked_structural(ty) { if !self.type_marked_structural(ty) {
debug!("Search found ty: {:?}", 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 // structural-match does not care about the

View file

@ -540,7 +540,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
// WfNominalType // WfNominalType
let obligations = self.nominal_obligations(def.did, substs); let obligations = self.nominal_obligations(def.did(), substs);
self.out.extend(obligations); self.out.extend(obligations);
} }

View file

@ -166,13 +166,13 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
) -> Arc<chalk_solve::rust_ir::AdtDatum<RustInterner<'tcx>>> { ) -> Arc<chalk_solve::rust_ir::AdtDatum<RustInterner<'tcx>>> {
let adt_def = adt_id.0; 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 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 let variants: Vec<_> = adt_def
.variants .variants()
.iter() .iter()
.map(|variant| chalk_solve::rust_ir::AdtVariantDatum { .map(|variant| chalk_solve::rust_ir::AdtVariantDatum {
fields: variant fields: variant
@ -189,7 +189,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
chalk_solve::rust_ir::AdtDatumBound { variants, where_clauses }, chalk_solve::rust_ir::AdtDatumBound { variants, where_clauses },
), ),
flags: chalk_solve::rust_ir::AdtFlags { flags: chalk_solve::rust_ir::AdtFlags {
upstream: !adt_def.did.is_local(), upstream: !adt_def.did().is_local(),
fundamental: adt_def.is_fundamental(), fundamental: adt_def.is_fundamental(),
phantom_data: adt_def.is_phantom_data(), 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 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); let uint = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(i)).intern(self.interner);
Arc::new(chalk_solve::rust_ir::AdtRepr { Arc::new(chalk_solve::rust_ir::AdtRepr {
c: adt_def.repr.c(), c: adt_def.repr().c(),
packed: adt_def.repr.packed(), packed: adt_def.repr().packed(),
int: adt_def.repr.int.map(|i| match i { int: adt_def.repr().int.map(|i| match i {
attr::IntType::SignedInt(ty) => match ty { attr::IntType::SignedInt(ty) => match ty {
ast::IntTy::Isize => int(chalk_ir::IntTy::Isize), ast::IntTy::Isize => int(chalk_ir::IntTy::Isize),
ast::IntTy::I8 => int(chalk_ir::IntTy::I8), 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 trait_ref = self.interner.tcx.impl_trait_ref(impl_def_id).unwrap();
let self_ty = trait_ref.self_ty(); let self_ty = trait_ref.self_ty();
let provides = match (self_ty.kind(), chalk_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, ..)) => { (_, AssociatedType(_ty_id, ..)) => {
// FIXME(chalk): See https://github.com/rust-lang/rust/pull/77152#discussion_r494484774 // FIXME(chalk): See https://github.com/rust-lang/rust/pull/77152#discussion_r494484774
false false
@ -671,7 +671,7 @@ impl<'tcx> chalk_ir::UnificationDatabase<RustInterner<'tcx>> for RustIrDatabase<
&self, &self,
adt_id: chalk_ir::AdtId<RustInterner<'tcx>>, adt_id: chalk_ir::AdtId<RustInterner<'tcx>>,
) -> chalk_ir::Variances<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( chalk_ir::Variances::from_iter(
self.interner, self.interner,
variances.iter().map(|v| v.lower_into(self.interner)), variances.iter().map(|v| v.lower_into(self.interner)),

View file

@ -268,7 +268,7 @@ fn dtorck_constraint_for_ty<'tcx>(
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
let DtorckConstraint { dtorck_types, outlives, overflows } = 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` // FIXME: we can try to recursively `dtorck_constraint_on_ty`
// there, but that needs some way to handle cycles. // there, but that needs some way to handle cycles.
constraints.dtorck_types.extend(dtorck_types.iter().map(|t| t.subst(tcx, substs))); constraints.dtorck_types.extend(dtorck_types.iter().map(|t| t.subst(tcx, substs)));

View file

@ -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 // parameter without a `Copy` bound, then we conservatively return that it
// needs drop. // needs drop.
let adt_has_dtor = 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 = let res =
drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor, false).next().is_some(); 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> impl<'tcx, F, I> Iterator for NeedsDropTypes<'tcx, F>
where where
F: Fn(&ty::AdtDef, SubstsRef<'tcx>) -> NeedsDropResult<I>, F: Fn(ty::AdtDef<'tcx>, SubstsRef<'tcx>) -> NeedsDropResult<I>,
I: Iterator<Item = Ty<'tcx>>, I: Iterator<Item = Ty<'tcx>>,
{ {
type Item = NeedsDropResult<Ty<'tcx>>; type Item = NeedsDropResult<Ty<'tcx>>;
@ -193,7 +193,7 @@ fn drop_tys_helper<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
param_env: rustc_middle::ty::ParamEnv<'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, only_significant: bool,
) -> impl Iterator<Item = NeedsDropResult<Ty<'tcx>>> { ) -> impl Iterator<Item = NeedsDropResult<Ty<'tcx>>> {
fn with_query_cache<'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| { iter.into_iter().try_fold(Vec::new(), |mut vec, subty| {
match subty.kind() { match subty.kind() {
ty::Adt(adt_id, subst) => { 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)); 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() { if adt_def.is_manually_drop() {
debug!("drop_tys_helper: `{:?}` is manually drop", adt_def); debug!("drop_tys_helper: `{:?}` is manually drop", adt_def);
Ok(Vec::new()) Ok(Vec::new())
@ -260,9 +260,9 @@ fn drop_tys_helper<'tcx>(
fn adt_consider_insignificant_dtor<'tcx>( fn adt_consider_insignificant_dtor<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
) -> impl Fn(&ty::AdtDef) -> Option<DtorType> + 'tcx { ) -> impl Fn(ty::AdtDef<'tcx>) -> Option<DtorType> + 'tcx {
move |adt_def: &ty::AdtDef| { move |adt_def: ty::AdtDef<'tcx>| {
let is_marked_insig = tcx.has_attr(adt_def.did, sym::rustc_insignificant_dtor); let is_marked_insig = tcx.has_attr(adt_def.did(), sym::rustc_insignificant_dtor);
if is_marked_insig { if is_marked_insig {
// In some cases like `std::collections::HashMap` where the struct is a wrapper around // 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 // 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 // This is for the "adt_drop_tys" query, that considers all `Drop` impls, therefore all dtors are
// significant. // significant.
let adt_has_dtor = 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)` // `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) drop_tys_helper(tcx, tcx.type_of(def_id), tcx.param_env(def_id), adt_has_dtor, false)
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()

View file

@ -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 // 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). // can catch cases of mutual recursion where A also contains B).
let mut seen: Vec<Ty<'_>> = Vec::new(); 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 representable_cache = FxHashMap::default();
let mut force_result = false; let mut force_result = false;
let r = is_type_structurally_recursive( let r = is_type_structurally_recursive(
@ -63,7 +63,7 @@ fn are_inner_types_recursive<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
sp: Span, sp: Span,
seen: &mut Vec<Ty<'tcx>>, 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>, representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
force_result: &mut bool, force_result: &mut bool,
@ -150,7 +150,7 @@ fn are_inner_types_recursive<'tcx>(
.take(shadow_seen.len() - 1) .take(shadow_seen.len() - 1)
.any(|seen_def| seen_def == def) .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); let raw_adt_ty = tcx.type_of(adt_def_id);
debug!("are_inner_types_recursive: checking nested type: {:?}", raw_adt_ty); 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() { match *ty.kind() {
ty::Adt(ty_def, _) => ty_def == def, ty::Adt(ty_def, _) => ty_def == def,
_ => false, _ => false,
@ -249,7 +249,7 @@ fn is_type_structurally_recursive<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
sp: Span, sp: Span,
seen: &mut Vec<Ty<'tcx>>, 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>, representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
force_result: &mut bool, force_result: &mut bool,
@ -281,7 +281,7 @@ fn is_type_structurally_recursive_inner<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
sp: Span, sp: Span,
seen: &mut Vec<Ty<'tcx>>, 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>, representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
force_result: &mut bool, 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 // For structs and enums, track all previously seen types by pushing them
// onto the 'seen' stack. // onto the 'seen' stack.
seen.push(ty); seen.push(ty);
shadow_seen.push(def); shadow_seen.push(*def);
let out = are_inner_types_recursive( let out = are_inner_types_recursive(
tcx, tcx,
sp, sp,

View file

@ -8,7 +8,7 @@ use rustc_trait_selection::traits;
fn sized_constraint_for_ty<'tcx>( fn sized_constraint_for_ty<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
adtdef: &ty::AdtDef, adtdef: ty::AdtDef<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Vec<Ty<'tcx>> { ) -> Vec<Ty<'tcx>> {
use ty::TyKind::*; use ty::TyKind::*;
@ -56,7 +56,7 @@ fn sized_constraint_for_ty<'tcx>(
}) })
.without_const() .without_const()
.to_predicate(tcx); .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] } 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 def = tcx.adt_def(def_id);
let result = tcx.mk_type_list( let result = tcx.mk_type_list(
def.variants def.variants()
.iter() .iter()
.flat_map(|v| v.fields.last()) .flat_map(|v| v.fields.last())
.flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did))), .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`); // (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 // (b) Each of its variants (a single one in the case of a `struct`) has at least
// one uninhabited field. // one uninhabited field.
def.variants.iter().all(|var| { def.variants().iter().all(|var| {
var.fields.iter().any(|field| { var.fields.iter().any(|field| {
let ty = tcx.type_of(field.did).subst(tcx, substs); let ty = tcx.type_of(field.did).subst(tcx, substs);
tcx.conservative_is_privately_uninhabited(param_env.and(ty)) tcx.conservative_is_privately_uninhabited(param_env.and(ty))

View file

@ -1788,9 +1788,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if let ty::Adt(adt_def, _) = qself_ty.kind() { if let ty::Adt(adt_def, _) = qself_ty.kind() {
if adt_def.is_enum() { if adt_def.is_enum() {
let variant_def = adt_def let variant_def = adt_def
.variants .variants()
.iter() .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 let Some(variant_def) = variant_def {
if permit_variants { if permit_variants {
tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None); 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"); let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT");
if let Some(suggested_name) = find_best_match_for_name( if let Some(suggested_name) = find_best_match_for_name(
&adt_def &adt_def
.variants .variants()
.iter() .iter()
.map(|variant| variant.name) .map(|variant| variant.name)
.collect::<Vec<Symbol>>(), .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); let sp = tcx.sess.source_map().guess_head_span(sp);
err.span_label(sp, format!("variant `{}` not found here", assoc_ident)); 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 adt_def = self_ty.map(|t| t.ty_adt_def().unwrap());
let (generics_def_id, index) = if let Some(adt_def) = adt_def { let (generics_def_id, index) = if let Some(adt_def) = adt_def {
debug_assert!(adt_def.is_enum()); debug_assert!(adt_def.is_enum());
(adt_def.did, last) (adt_def.did(), last)
} else if last >= 1 && segments[last - 1].args.is_some() { } else if last >= 1 && segments[last - 1].args.is_some() {
// Everything but the penultimate segment should have no // Everything but the penultimate segment should have no
// parameters at all. // parameters at all.

View file

@ -269,7 +269,7 @@ pub(super) fn check_fn<'a, 'tcx>(
let arg_is_panic_info = match *inputs[0].kind() { let arg_is_panic_info = match *inputs[0].kind() {
ty::Ref(region, ty, mutbl) => match *ty.kind() { ty::Ref(region, ty, mutbl) => match *ty.kind() {
ty::Adt(ref adt, _) => { ty::Adt(ref adt, _) => {
adt.did == panic_info_did adt.did() == panic_info_did
&& mutbl == hir::Mutability::Not && mutbl == hir::Mutability::Not
&& !region.is_static() && !region.is_static()
} }
@ -310,7 +310,7 @@ pub(super) fn check_fn<'a, 'tcx>(
let span = hir.span(fn_id); let span = hir.span(fn_id);
if inputs.len() == 1 { if inputs.len() == 1 {
let arg_is_alloc_layout = match inputs[0].kind() { 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, _ => false,
}; };
@ -345,7 +345,7 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) {
def.destructor(tcx); // force the destructor to be evaluated def.destructor(tcx); // force the destructor to be evaluated
check_representable(tcx, span, def_id); check_representable(tcx, span, def_id);
if def.repr.simd() { if def.repr().simd() {
check_simd(tcx, span, def_id); 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() { 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 { } else {
Some(fields.len() as u64) 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) { pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
let repr = def.repr; let repr = def.repr();
if repr.packed() { 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) { for r in attr::find_repr_attrs(&tcx.sess, attr) {
if let attr::ReprPacked(pack) = r if let attr::ReprPacked(pack) = r
&& let Some(repr_pack) = repr.pack && let Some(repr_pack) = repr.pack
@ -1165,7 +1165,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
) )
.emit(); .emit();
} else { } 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!( let mut err = struct_span_err!(
tcx.sess, tcx.sess,
sp, sp,
@ -1190,7 +1190,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
&if first { &if first {
format!( format!(
"`{}` contains a field of type `{}`", "`{}` contains a field of type `{}`",
tcx.type_of(def.did), tcx.type_of(def.did()),
ident ident
) )
} else { } else {
@ -1214,16 +1214,16 @@ pub(super) fn check_packed_inner(
) -> Option<Vec<(DefId, Span)>> { ) -> Option<Vec<(DefId, Span)>> {
if let ty::Adt(def, substs) = tcx.type_of(def_id).kind() { if let ty::Adt(def, substs) = tcx.type_of(def_id).kind() {
if def.is_struct() || def.is_union() { if def.is_struct() || def.is_union() {
if def.repr.align.is_some() { if def.repr().align.is_some() {
return Some(vec![(def.did, DUMMY_SP)]); return Some(vec![(def.did(), DUMMY_SP)]);
} }
stack.push(def_id); stack.push(def_id);
for field in &def.non_enum_variant().fields { for field in &def.non_enum_variant().fields {
if let ty::Adt(def, _) = field.ty(tcx, substs).kind() { if let ty::Adt(def, _) = field.ty(tcx, substs).kind() {
if !stack.contains(&def.did) { if !stack.contains(&def.did()) {
if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) { if let Some(mut defs) = check_packed_inner(tcx, def.did(), stack) {
defs.push((def.did, field.ident(tcx).span)); defs.push((def.did(), field.ident(tcx).span));
return Some(defs); return Some(defs);
} }
} }
@ -1236,8 +1236,8 @@ pub(super) fn check_packed_inner(
None None
} }
pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) { pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtDef<'tcx>) {
if !adt.repr.transparent() { if !adt.repr().transparent() {
return; return;
} }
let sp = tcx.sess.source_map().guess_head_span(sp); 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(); .emit();
} }
if adt.variants.len() != 1 { if adt.variants().len() != 1 {
bad_variant_count(tcx, adt, sp, adt.did); bad_variant_count(tcx, adt, sp, adt.did());
if adt.variants.is_empty() { if adt.variants().is_empty() {
// Don't bother checking the fields. No variants (and thus no fields) exist. // Don't bother checking the fields. No variants (and thus no fields) exist.
return; 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 repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
if !tcx.features().repr128 { if !tcx.features().repr128 {
feature_err( 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 is_unit = |var: &hir::Variant<'_>| matches!(var.data, hir::VariantData::Unit(..));
let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some(); 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) { for ((_, discr), v) in iter::zip(def.discriminants(tcx), vs) {
// Check for duplicate discriminant values // Check for duplicate discriminant values
if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) { 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_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 variant_i = tcx.hir().expect_variant(variant_i_hir_id);
let i_span = match variant_i.disr_expr { let i_span = match variant_i.disr_expr {

View file

@ -299,15 +299,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{ {
if e.hir_id == id { if e.hir_id == id {
if let Some(span) = expr.span.find_ancestor_inside(block_span) { if let Some(span) = expr.span.find_ancestor_inside(block_span) {
let return_suggestions = let return_suggestions = if self
if self.tcx.is_diagnostic_item(sym::Result, expected_adt.did) { .tcx
vec!["Ok(())".to_string()] .is_diagnostic_item(sym::Result, expected_adt.did())
} else if self.tcx.is_diagnostic_item(sym::Option, expected_adt.did) {
{ vec!["Ok(())".to_string()]
vec!["None".to_string(), "Some(())".to_string()] } else if self.tcx.is_diagnostic_item(sym::Option, expected_adt.did()) {
} else { vec!["None".to_string(), "Some(())".to_string()]
return; } else {
}; return;
};
if let Some(indent) = if let Some(indent) =
self.tcx.sess.source_map().indentation_before(span.shrink_to_lo()) 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 let compatible_variants: Vec<String> = expected_adt
.variants .variants()
.iter() .iter()
.filter(|variant| variant.fields.len() == 1) .filter(|variant| variant.fields.len() == 1)
.filter_map(|variant| { .filter_map(|variant| {
@ -378,7 +379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.multipart_suggestions( err.multipart_suggestions(
&format!( &format!(
"try wrapping the expression in a variant of `{}`", "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| { compatible_variants.into_iter().map(|variant| {
vec![ vec![

View file

@ -40,13 +40,13 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
tcx, tcx,
drop_impl_did.expect_local(), drop_impl_did.expect_local(),
dtor_self_type, dtor_self_type,
adt_def.did, adt_def.did(),
)?; )?;
ensure_drop_predicates_are_implied_by_item_defn( ensure_drop_predicates_are_implied_by_item_defn(
tcx, tcx,
dtor_predicates, dtor_predicates,
adt_def.did.expect_local(), adt_def.did().expect_local(),
self_to_impl_substs, self_to_impl_substs,
) )
} }

View file

@ -1333,7 +1333,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Prohibit struct expressions when non-exhaustive flag is set. // Prohibit struct expressions when non-exhaustive flag is set.
let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type"); 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 self.tcx
.sess .sess
.emit_err(StructExprNonExhaustive { span: expr.span, what: adt.variant_descr() }); .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() => { ty::Adt(base_def, substs) if !base_def.is_enum() => {
debug!("struct named {:?}", base_t); debug!("struct named {:?}", base_t);
let (ident, def_scope) = 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; let fields = &base_def.non_enum_variant().fields;
if let Some(index) = fields if let Some(index) = fields
.iter() .iter()
@ -1882,7 +1882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None); self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
return field_ty; return field_ty;
} }
private_candidate = Some((adjustments, base_def.did, field_ty)); private_candidate = Some((adjustments, base_def.did(), field_ty));
} }
} }
ty::Tuple(tys) => { 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::RawPtr(ty_and_mut) = expr_t.kind() {
if let ty::Adt(adt_def, _) = ty_and_mut.ty.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 && adt_def
.variants .variants()
.iter() .iter()
.next() .next()
.unwrap() .unwrap()
@ -2154,7 +2154,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_fields_on_recordish( fn suggest_fields_on_recordish(
&self, &self,
err: &mut Diagnostic, err: &mut Diagnostic,
def: &'tcx ty::AdtDef, def: ty::AdtDef<'tcx>,
field: Ident, field: Ident,
access_span: Span, access_span: Span,
) { ) {

Some files were not shown because too many files have changed in this diff Show more