Auto merge of #109762 - scottmcm:variantdef-indexvec, r=WaffleLapkin

Update `ty::VariantDef` to use `IndexVec<FieldIdx, FieldDef>`

And while doing the updates for that, also uses `FieldIdx` in `ProjectionKind::Field` and `TypeckResults::field_indices`.

There's more places that could use it (like `rustc_const_eval` and `LayoutS`), but I tried to keep this PR from exploding to *even more* places.

Part 2/? of https://github.com/rust-lang/compiler-team/issues/606
This commit is contained in:
bors 2023-03-31 03:36:18 +00:00
commit eb3e9c1f45
47 changed files with 127 additions and 104 deletions

View file

@ -350,7 +350,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if !including_tuple_field.0 && variant.ctor_kind() == Some(CtorKind::Fn) { if !including_tuple_field.0 && variant.ctor_kind() == Some(CtorKind::Fn) {
return None; return None;
} }
Some(variant.fields[field.index()].name.to_string()) Some(variant.fields[field].name.to_string())
} }
ty::Tuple(_) => Some(field.index().to_string()), ty::Tuple(_) => Some(field.index().to_string()),
ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => { ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {

View file

@ -854,7 +854,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
}, },
}; };
if let Some(field) = variant.fields.get(field.index()) { if let Some(field) = variant.fields.get(field) {
Ok(self.cx.normalize(field.ty(tcx, substs), location)) Ok(self.cx.normalize(field.ty(tcx, substs), location))
} else { } else {
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
@ -1725,7 +1725,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
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.variant(variant_index); let variant = &def.variant(variant_index);
let adj_field_index = active_field_index.unwrap_or(field_index); let adj_field_index =
FieldIdx::from_usize(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))
} else { } else {

View file

@ -701,7 +701,8 @@ impl<'tcx> CPlace<'tcx> {
}; };
} }
ty::Adt(adt_def, substs) if layout.ty.is_simd() => { ty::Adt(adt_def, substs) if layout.ty.is_simd() => {
let f0_ty = adt_def.non_enum_variant().fields[0].ty(fx.tcx, substs); let f0 = &adt_def.non_enum_variant().fields[FieldIdx::from_u32(0)];
let f0_ty = f0.ty(fx.tcx, substs);
match f0_ty.kind() { match f0_ty.kind() {
ty::Array(_, _) => { ty::Array(_, _) => {

View file

@ -274,7 +274,8 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
.map(|field_index| { .map(|field_index| {
let field_name = if variant_def.ctor_kind() != Some(CtorKind::Fn) { let field_name = if variant_def.ctor_kind() != Some(CtorKind::Fn) {
// Fields have names // Fields have names
Cow::from(variant_def.fields[field_index].name.as_str()) let field = &variant_def.fields[FieldIdx::from_usize(field_index)];
Cow::from(field.name.as_str())
} else { } else {
// Tuple-like // Tuple-like
super::tuple_field_name(field_index) super::tuple_field_name(field_index)

View file

@ -8,7 +8,7 @@ use crate::interpret::{
use crate::interpret::{MPlaceTy, Value}; use crate::interpret::{MPlaceTy, Value};
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
use rustc_span::source_map::DUMMY_SP; use rustc_span::source_map::DUMMY_SP;
use rustc_target::abi::{Align, VariantIdx, FIRST_VARIANT}; use rustc_target::abi::{Align, FieldIdx, VariantIdx, FIRST_VARIANT};
#[instrument(skip(ecx), level = "debug")] #[instrument(skip(ecx), level = "debug")]
fn branches<'tcx>( fn branches<'tcx>(
@ -412,6 +412,7 @@ fn valtree_into_mplace<'tcx>(
let inner_ty = match ty.kind() { let inner_ty = match ty.kind() {
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
let i = FieldIdx::from_usize(i);
def.variant(FIRST_VARIANT).fields[i].ty(tcx, substs) def.variant(FIRST_VARIANT).fields[i].ty(tcx, substs)
} }
ty::Tuple(inner_tys) => inner_tys[i], ty::Tuple(inner_tys) => inner_tys[i],

View file

@ -16,7 +16,9 @@ use rustc_middle::mir::interpret::InterpError;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::{Abi, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange}; use rustc_target::abi::{
Abi, FieldIdx, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange,
};
use std::hash::Hash; use std::hash::Hash;
@ -269,14 +271,16 @@ 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.variant(index).fields[field].name) PathElem::Field(def.variant(index).fields[FieldIdx::from_usize(field)].name)
} }
Variants::Multiple { .. } => bug!("we handled variants above"), Variants::Multiple { .. } => bug!("we handled variants above"),
} }
} }
// other ADTs // other ADTs
ty::Adt(def, _) => PathElem::Field(def.non_enum_variant().fields[field].name), ty::Adt(def, _) => {
PathElem::Field(def.non_enum_variant().fields[FieldIdx::from_usize(field)].name)
}
// arrays/slices // arrays/slices
ty::Array(..) | ty::Slice(..) => PathElem::ArrayElem(field), ty::Array(..) | ty::Slice(..) => PathElem::ArrayElem(field),

View file

@ -360,7 +360,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
} }
ty::Adt(adt_def, substs) => { ty::Adt(adt_def, substs) => {
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT); let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { let Some(field) = adt_def.variant(var).fields.get(f) else {
fail_out_of_bounds(self, location); fail_out_of_bounds(self, location);
return; return;
}; };

View file

@ -27,6 +27,7 @@ use rustc_middle::ty::{
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::{self, Span}; use rustc_span::{self, Span};
use rustc_target::abi::FieldIdx;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
@ -474,7 +475,7 @@ fn is_enum_of_nonnullable_ptr<'tcx>(
let [var_one, var_two] = &adt_def.variants().raw[..] else { let [var_one, var_two] = &adt_def.variants().raw[..] else {
return false; return false;
}; };
let (([], [field]) | ([field], [])) = (&var_one.fields[..], &var_two.fields[..]) else { let (([], [field]) | ([field], [])) = (&var_one.fields.raw[..], &var_two.fields.raw[..]) else {
return false; return false;
}; };
matches!(field.ty(tcx, substs).kind(), ty::FnPtr(..) | ty::Ref(..)) matches!(field.ty(tcx, substs).kind(), ty::FnPtr(..) | ty::Ref(..))
@ -893,7 +894,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit(); struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
return; return;
} }
let e = fields[0].ty(tcx, substs); let e = fields[FieldIdx::from_u32(0)].ty(tcx, substs);
if !fields.iter().all(|f| f.ty(tcx, substs) == e) { if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous") struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
.span_label(sp, "SIMD elements must have the same type") .span_label(sp, "SIMD elements must have the same type")

View file

@ -5,6 +5,7 @@ use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableE
use rustc_session::lint; use rustc_session::lint;
use rustc_span::def_id::LocalDefId; use rustc_span::def_id::LocalDefId;
use rustc_span::{Symbol, DUMMY_SP}; use rustc_span::{Symbol, DUMMY_SP};
use rustc_target::abi::FieldIdx;
use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType}; use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType};
pub struct InlineAsmCtxt<'a, 'tcx> { pub struct InlineAsmCtxt<'a, 'tcx> {
@ -82,7 +83,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
} }
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[FieldIdx::from_u32(0)].ty(self.tcx, substs);
match elem_ty.kind() { match elem_ty.kind() {
ty::Never | ty::Error(_) => return None, ty::Never | ty::Error(_) => return None,
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => { ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => {

View file

@ -1030,7 +1030,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
// intermediate types must be sized. // intermediate types must be sized.
let needs_drop_copy = || { let needs_drop_copy = || {
packed && { packed && {
let ty = tcx.type_of(variant.fields.last().unwrap().did).subst_identity(); let ty = tcx.type_of(variant.fields.raw.last().unwrap().did).subst_identity();
let ty = tcx.erase_regions(ty); let ty = tcx.erase_regions(ty);
if ty.needs_infer() { if ty.needs_infer() {
tcx.sess tcx.sess
@ -1046,7 +1046,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
let all_sized = all_sized || variant.fields.is_empty() || needs_drop_copy(); let all_sized = all_sized || variant.fields.is_empty() || needs_drop_copy();
let unsized_len = if all_sized { 0 } else { 1 }; let unsized_len = if all_sized { 0 } else { 1 };
for (idx, field) in for (idx, field) in
variant.fields[..variant.fields.len() - unsized_len].iter().enumerate() variant.fields.raw[..variant.fields.len() - unsized_len].iter().enumerate()
{ {
let last = idx == variant.fields.len() - 1; let last = idx == variant.fields.len() - 1;
let field_id = field.did.expect_local(); let field_id = field.did.expect_local();

View file

@ -486,8 +486,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
// U` can be coerced to `*mut V` if `U: Unsize<V>`. // U` can be coerced to `*mut V` if `U: Unsize<V>`.
let fields = &def_a.non_enum_variant().fields; let fields = &def_a.non_enum_variant().fields;
let diff_fields = fields let diff_fields = fields
.iter() .iter_enumerated()
.enumerate()
.filter_map(|(i, f)| { .filter_map(|(i, f)| {
let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b)); let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b));

View file

@ -103,13 +103,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Ok(match *t.kind() { Ok(match *t.kind() {
ty::Slice(_) | ty::Str => Some(PointerKind::Length), ty::Slice(_) | ty::Str => Some(PointerKind::Length),
ty::Dynamic(ref tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal_def_id())), ty::Dynamic(ref tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal_def_id())),
ty::Adt(def, substs) if def.is_struct() => match def.non_enum_variant().fields.last() { ty::Adt(def, substs) if def.is_struct() => {
None => Some(PointerKind::Thin), match def.non_enum_variant().fields.raw.last() {
Some(f) => { None => Some(PointerKind::Thin),
let field_ty = self.field_ty(span, f, substs); Some(f) => {
self.pointer_kind(field_ty, span)? let field_ty = self.field_ty(span, f, substs);
self.pointer_kind(field_ty, span)?
}
} }
}, }
ty::Tuple(fields) => match fields.last() { ty::Tuple(fields) => match fields.last() {
None => Some(PointerKind::Thin), None => Some(PointerKind::Thin),
Some(&f) => self.pointer_kind(f, span)?, Some(&f) => self.pointer_kind(f, span)?,

View file

@ -19,6 +19,7 @@ use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitableExt}; use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitableExt};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use rustc_span::{BytePos, Span}; use rustc_span::{BytePos, Span};
use rustc_target::abi::FieldIdx;
use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::method_chain::CollectAllMismatches; use rustc_trait_selection::traits::error_reporting::method_chain::CollectAllMismatches;
use rustc_trait_selection::traits::ObligationCause; use rustc_trait_selection::traits::ObligationCause;
@ -850,7 +851,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
variant.fields.len() == 1 variant.fields.len() == 1
}) })
.filter_map(|variant| { .filter_map(|variant| {
let sole_field = &variant.fields[0]; let sole_field = &variant.fields[FieldIdx::from_u32(0)];
let field_is_local = sole_field.did.is_local(); let field_is_local = sole_field.did.is_local();
let field_is_accessible = let field_is_accessible =

View file

@ -50,6 +50,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::hygiene::DesugaringKind; use rustc_span::hygiene::DesugaringKind;
use rustc_span::source_map::{Span, Spanned}; use rustc_span::source_map::{Span, Spanned};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_target::abi::FieldIdx;
use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_target::spec::abi::Abi::RustIntrinsic;
use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::{self, ObligationCauseCode}; use rustc_trait_selection::traits::{self, ObligationCauseCode};
@ -1561,8 +1562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut remaining_fields = variant let mut remaining_fields = variant
.fields .fields
.iter() .iter_enumerated()
.enumerate()
.map(|(i, field)| (field.ident(tcx).normalize_to_macros_2_0(), (i, field))) .map(|(i, field)| (field.ident(tcx).normalize_to_macros_2_0(), (i, field)))
.collect::<FxHashMap<_, _>>(); .collect::<FxHashMap<_, _>>();
@ -1815,7 +1815,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
adt_ty: Ty<'tcx>, adt_ty: Ty<'tcx>,
span: Span, span: Span,
remaining_fields: FxHashMap<Ident, (usize, &ty::FieldDef)>, remaining_fields: FxHashMap<Ident, (FieldIdx, &ty::FieldDef)>,
variant: &'tcx ty::VariantDef, variant: &'tcx ty::VariantDef,
ast_fields: &'tcx [hir::ExprField<'tcx>], ast_fields: &'tcx [hir::ExprField<'tcx>],
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
@ -2209,11 +2209,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (ident, def_scope) = let (ident, def_scope) =
self.tcx.adjust_ident_and_get_scope(field, base_def.did(), body_hir_id); self.tcx.adjust_ident_and_get_scope(field, base_def.did(), body_hir_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, field)) = fields
.iter() .iter_enumerated()
.position(|f| f.ident(self.tcx).normalize_to_macros_2_0() == ident) .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == ident)
{ {
let field = &fields[index];
let field_ty = self.field_ty(expr.span, field, substs); let field_ty = self.field_ty(expr.span, field, substs);
// Save the index of all fields regardless of their visibility in case // Save the index of all fields regardless of their visibility in case
// of error recovery. // of error recovery.
@ -2230,15 +2229,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
ty::Tuple(tys) => { ty::Tuple(tys) => {
let fstr = field.as_str(); if let Ok(index) = field.as_str().parse::<usize>() {
if let Ok(index) = fstr.parse::<usize>() { if field.name == sym::integer(index) {
if fstr == index.to_string() {
if let Some(&field_ty) = tys.get(index) { if let Some(&field_ty) = tys.get(index) {
let adjustments = self.adjust_steps(&autoderef); let adjustments = self.adjust_steps(&autoderef);
self.apply_adjustments(base, adjustments); self.apply_adjustments(base, adjustments);
self.register_predicates(autoderef.into_obligations()); self.register_predicates(autoderef.into_obligations());
self.write_field_index(expr.hir_id, index); self.write_field_index(expr.hir_id, FieldIdx::from_usize(index));
return field_ty; return field_ty;
} }
} }

View file

@ -539,7 +539,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
match with_place.place.ty().kind() { match with_place.place.ty().kind() {
ty::Adt(adt, substs) if adt.is_struct() => { ty::Adt(adt, substs) if adt.is_struct() => {
// Consume those fields of the with expression that are needed. // Consume those fields of the with expression that are needed.
for (f_index, with_field) in adt.non_enum_variant().fields.iter().enumerate() { for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() {
let is_mentioned = fields let is_mentioned = fields
.iter() .iter()
.any(|f| self.mc.typeck_results.opt_field_index(f.hir_id) == Some(f_index)); .any(|f| self.mc.typeck_results.opt_field_index(f.hir_id) == Some(f_index));
@ -548,7 +548,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
&*with_expr, &*with_expr,
with_place.clone(), with_place.clone(),
with_field.ty(self.tcx(), substs), with_field.ty(self.tcx(), substs),
ProjectionKind::Field(f_index as u32, FIRST_VARIANT), ProjectionKind::Field(f_index, FIRST_VARIANT),
); );
self.delegate_consume(&field_place, field_place.hir_id); self.delegate_consume(&field_place, field_place.hir_id);
} }

View file

@ -33,6 +33,7 @@ use rustc_span::def_id::LocalDefId;
use rustc_span::hygiene::DesugaringKind; use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span; use rustc_span::Span;
use rustc_target::abi::FieldIdx;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCauseCode, ObligationCtxt}; use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCauseCode, ObligationCtxt};
@ -147,7 +148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) { pub fn write_field_index(&self, hir_id: hir::HirId, index: FieldIdx) {
self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index); self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
} }

View file

@ -4,7 +4,7 @@ use rustc_hir as hir;
use rustc_index::vec::Idx; use rustc_index::vec::Idx;
use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_target::abi::{Pointer, VariantIdx}; use rustc_target::abi::{FieldIdx, Pointer, VariantIdx};
use super::FnCtxt; use super::FnCtxt;
@ -28,7 +28,7 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
} }
if def.variant(data_idx).fields.len() == 1 { if def.variant(data_idx).fields.len() == 1 {
return def.variant(data_idx).fields[0].ty(tcx, substs); return def.variant(data_idx).fields[FieldIdx::from_u32(0)].ty(tcx, substs);
} }
} }

View file

@ -61,7 +61,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
use rustc_hir::PatKind; use rustc_hir::PatKind;
use rustc_infer::infer::InferCtxt; use rustc_infer::infer::InferCtxt;
use rustc_span::Span; use rustc_span::Span;
use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::infer::InferCtxtExt;
pub(crate) trait HirNode { pub(crate) trait HirNode {
@ -330,7 +330,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
expr, expr,
base, base,
expr_ty, expr_ty,
ProjectionKind::Field(field_idx as u32, FIRST_VARIANT), ProjectionKind::Field(field_idx, FIRST_VARIANT),
)) ))
} }
@ -674,7 +674,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
let subpat_ty = self.pat_ty_adjusted(subpat)?; let subpat_ty = self.pat_ty_adjusted(subpat)?;
let projection_kind = ProjectionKind::Field(i as u32, FIRST_VARIANT); let projection_kind =
ProjectionKind::Field(FieldIdx::from_usize(i), FIRST_VARIANT);
let sub_place = let sub_place =
self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind); self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind);
self.cat_pattern_(sub_place, subpat, op)?; self.cat_pattern_(sub_place, subpat, op)?;
@ -689,7 +690,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
let subpat_ty = self.pat_ty_adjusted(subpat)?; let subpat_ty = self.pat_ty_adjusted(subpat)?;
let projection_kind = ProjectionKind::Field(i as u32, variant_index); let projection_kind =
ProjectionKind::Field(FieldIdx::from_usize(i), variant_index);
let sub_place = let sub_place =
self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind); self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind);
self.cat_pattern_(sub_place, subpat, op)?; self.cat_pattern_(sub_place, subpat, op)?;
@ -714,7 +716,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
pat, pat,
place_with_id.clone(), place_with_id.clone(),
field_ty, field_ty,
ProjectionKind::Field(field_index as u32, variant_index), ProjectionKind::Field(field_index, variant_index),
); );
self.cat_pattern_(field_place, fp.pat, op)?; self.cat_pattern_(field_place, fp.pat, op)?;
} }

View file

@ -1815,7 +1815,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.variants() .variants()
.iter() .iter()
.flat_map(|variant| { .flat_map(|variant| {
let [field] = &variant.fields[..] else { return None; }; let [field] = &variant.fields.raw[..] else { return None; };
let field_ty = field.ty(tcx, substs); let field_ty = field.ty(tcx, substs);
// Skip `_`, since that'll just lead to ambiguity. // Skip `_`, since that'll just lead to ambiguity.

View file

@ -19,6 +19,7 @@ use rustc_span::hygiene::DesugaringKind;
use rustc_span::source_map::{Span, Spanned}; use rustc_span::source_map::{Span, Spanned};
use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, DUMMY_SP}; use rustc_span::{BytePos, DUMMY_SP};
use rustc_target::abi::FieldIdx;
use rustc_trait_selection::traits::{ObligationCause, Pattern}; use rustc_trait_selection::traits::{ObligationCause, Pattern};
use ty::VariantDef; use ty::VariantDef;
@ -1091,11 +1092,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
bug!("unexpected pattern type {:?}", pat_ty); bug!("unexpected pattern type {:?}", pat_ty);
}; };
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs); let field = &variant.fields[FieldIdx::from_usize(i)];
let field_ty = self.field_ty(subpat.span, field, substs);
self.check_pat(subpat, field_ty, def_bm, ti); self.check_pat(subpat, field_ty, def_bm, ti);
self.tcx.check_stability( self.tcx.check_stability(
variant.fields[i].did, variant.fields[FieldIdx::from_usize(i)].did,
Some(pat.hir_id), Some(pat.hir_id),
subpat.span, subpat.span,
None, None,
@ -1103,7 +1105,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} else { } else {
// Pattern has wrong number of fields. // Pattern has wrong number of fields.
let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err); let e =
self.e0023(pat.span, res, qpath, subpats, &variant.fields.raw, expected, had_err);
on_error(e); on_error(e);
return tcx.ty_error(e); return tcx.ty_error(e);
} }
@ -1333,8 +1336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Index the struct fields' types. // Index the struct fields' types.
let field_map = variant let field_map = variant
.fields .fields
.iter() .iter_enumerated()
.enumerate()
.map(|(i, field)| (field.ident(self.tcx).normalize_to_macros_2_0(), (i, field))) .map(|(i, field)| (field.ident(self.tcx).normalize_to_macros_2_0(), (i, field)))
.collect::<FxHashMap<_, _>>(); .collect::<FxHashMap<_, _>>();

View file

@ -1405,7 +1405,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ProjectionKind::Field(..) ProjectionKind::Field(..)
)) ))
); );
def.variants().get(FIRST_VARIANT).unwrap().fields.iter().enumerate().any( def.variants().get(FIRST_VARIANT).unwrap().fields.iter_enumerated().any(
|(i, field)| { |(i, field)| {
let paths_using_field = captured_by_move_projs let paths_using_field = captured_by_move_projs
.iter() .iter()
@ -1413,7 +1413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let ProjectionKind::Field(field_idx, _) = if let ProjectionKind::Field(field_idx, _) =
projs.first().unwrap().kind projs.first().unwrap().kind
{ {
if (field_idx as usize) == i { Some(&projs[1..]) } else { None } if field_idx == i { Some(&projs[1..]) } else { None }
} else { } else {
unreachable!(); unreachable!();
} }
@ -1446,7 +1446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.filter_map(|projs| { .filter_map(|projs| {
if let ProjectionKind::Field(field_idx, _) = projs.first().unwrap().kind if let ProjectionKind::Field(field_idx, _) = projs.first().unwrap().kind
{ {
if (field_idx as usize) == i { Some(&projs[1..]) } else { None } if field_idx.index() == i { Some(&projs[1..]) } else { None }
} else { } else {
unreachable!(); unreachable!();
} }

View file

@ -10,6 +10,7 @@ use rustc_middle::traits::{
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitableExt}; use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitableExt};
use rustc_span::{sym, BytePos, Span}; use rustc_span::{sym, BytePos, Span};
use rustc_target::abi::FieldIdx;
use crate::errors::{ use crate::errors::{
ConsiderAddingAwait, SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding, ConsiderAddingAwait, SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding,
@ -109,7 +110,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn) variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn)
}) })
.filter_map(|variant| { .filter_map(|variant| {
let sole_field = &variant.fields[0]; let sole_field = &variant.fields[FieldIdx::from_u32(0)];
let sole_field_ty = sole_field.ty(self.tcx, substs); let sole_field_ty = sole_field.ty(self.tcx, substs);
if self.same_type_modulo_infer(sole_field_ty, exp_found.found) { if self.same_type_modulo_infer(sole_field_ty, exp_found.found) {
let variant_path = let variant_path =

View file

@ -770,7 +770,7 @@ pub(crate) fn repr_nullable_ptr<'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.raw[..], &var_two.fields.raw[..]) {
([], [field]) | ([field], []) => field.ty(cx.tcx, substs), ([], [field]) | ([field], []) => field.ty(cx.tcx, substs),
_ => return None, _ => return None,
}, },

View file

@ -2,7 +2,7 @@ use crate::ty;
use crate::ty::Ty; use crate::ty::Ty;
use rustc_hir::HirId; use rustc_hir::HirId;
use rustc_target::abi::VariantIdx; use rustc_target::abi::{FieldIdx, VariantIdx};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
#[derive(TypeFoldable, TypeVisitable)] #[derive(TypeFoldable, TypeVisitable)]
@ -27,7 +27,7 @@ pub enum ProjectionKind {
/// the field. The field is identified by which variant /// the field. The field is identified by which variant
/// it appears in along with a field index. The variant /// it appears in along with a field index. The variant
/// is used for enums. /// is used for enums.
Field(u32, VariantIdx), Field(FieldIdx, VariantIdx),
/// Some index like `B[x]`, where `B` is the base /// Some index like `B[x]`, where `B` is the base
/// expression. We don't preserve the index `x` because /// expression. We don't preserve the index `x` because

View file

@ -43,7 +43,7 @@ impl<'tcx> PlaceTy<'tcx> {
&adt_def.variant(variant_index) &adt_def.variant(variant_index)
} }
}; };
let field_def = &variant_def.fields[f.index()]; let field_def = &variant_def.fields[f];
field_def.ty(tcx, substs) field_def.ty(tcx, substs)
} }
ty::Tuple(tys) => tys[f.index()], ty::Tuple(tys) => tys[f.index()],

View file

@ -784,7 +784,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
if let PatKind::Wild = p.pattern.kind { if let PatKind::Wild = p.pattern.kind {
continue; continue;
} }
let name = variant.fields[p.field.index()].name; let name = variant.fields[p.field].name;
write!(f, "{}{}: {}", start_or_comma(), name, p.pattern)?; write!(f, "{}{}: {}", start_or_comma(), name, p.pattern)?;
printed += 1; printed += 1;
} }

View file

@ -3,6 +3,7 @@ use rustc_hir as hir;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_span::Span; use rustc_span::Span;
use rustc_target::abi::FieldIdx;
#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
pub enum PointerCast { pub enum PointerCast {
@ -208,5 +209,5 @@ pub struct CoerceUnsizedInfo {
#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, HashStable)] #[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, HashStable)]
pub enum CustomCoerceUnsized { pub enum CustomCoerceUnsized {
/// Records the index of the field being coerced. /// Records the index of the field being coerced.
Struct(usize), Struct(FieldIdx),
} }

View file

@ -158,12 +158,12 @@ impl<'tcx> CapturedPlace<'tcx> {
for proj in self.place.projections.iter() { for proj in self.place.projections.iter() {
match proj.kind { match proj.kind {
HirProjectionKind::Field(idx, variant) => match ty.kind() { HirProjectionKind::Field(idx, variant) => match ty.kind() {
ty::Tuple(_) => write!(&mut symbol, "__{}", idx).unwrap(), ty::Tuple(_) => write!(&mut symbol, "__{}", idx.index()).unwrap(),
ty::Adt(def, ..) => { ty::Adt(def, ..) => {
write!( write!(
&mut symbol, &mut symbol,
"__{}", "__{}",
def.variant(variant).fields[idx as usize].name.as_str(), def.variant(variant).fields[idx].name.as_str(),
) )
.unwrap(); .unwrap();
} }
@ -356,11 +356,11 @@ 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.variant(variant).fields[idx as usize].name.as_str() def.variant(variant).fields[idx].name.as_str()
); );
} }
ty::Tuple(_) => { ty::Tuple(_) => {
curr_string = format!("{}.{}", curr_string, idx); curr_string = format!("{}.{}", curr_string, idx.index());
} }
_ => { _ => {
bug!( bug!(

View file

@ -5,7 +5,6 @@ use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt};
use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic}; use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_index::vec::Idx;
use rustc_session::config::OptLevel; use rustc_session::config::OptLevel;
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -335,7 +334,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
// 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::from_usize(i);
let fields = let fields =
def.variant(i).fields.iter().map(|field| { def.variant(i).fields.iter().map(|field| {
SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env) SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env)
@ -798,7 +797,8 @@ where
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
match this.variants { match this.variants {
Variants::Single { index } => { Variants::Single { index } => {
TyMaybeWithLayout::Ty(def.variant(index).fields[i].ty(tcx, substs)) let field = &def.variant(index).fields[FieldIdx::from_usize(i)];
TyMaybeWithLayout::Ty(field.ty(tcx, substs))
} }
// Discriminant field for enums (where applicable). // Discriminant field for enums (where applicable).

View file

@ -50,7 +50,7 @@ pub use rustc_session::lint::RegisteredTools;
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{ExpnId, ExpnKind, Span}; use rustc_span::{ExpnId, ExpnKind, Span};
use rustc_target::abi::{Align, Integer, IntegerType, VariantIdx}; use rustc_target::abi::{Align, FieldIdx, Integer, IntegerType, VariantIdx};
pub use rustc_target::abi::{ReprFlags, ReprOptions}; pub use rustc_target::abi::{ReprFlags, ReprOptions};
use rustc_type_ir::WithCachedTypeInfo; use rustc_type_ir::WithCachedTypeInfo;
pub use subst::*; pub use subst::*;
@ -1891,7 +1891,7 @@ pub struct VariantDef {
/// Discriminant of this variant. /// Discriminant of this variant.
pub discr: VariantDiscr, pub discr: VariantDiscr,
/// Fields of this variant. /// Fields of this variant.
pub fields: Vec<FieldDef>, pub fields: IndexVec<FieldIdx, FieldDef>,
/// Flags of the variant (e.g. is field list non-exhaustive)? /// Flags of the variant (e.g. is field list non-exhaustive)?
flags: VariantFlags, flags: VariantFlags,
} }
@ -1918,7 +1918,7 @@ impl VariantDef {
variant_did: Option<DefId>, variant_did: Option<DefId>,
ctor: Option<(CtorKind, DefId)>, ctor: Option<(CtorKind, DefId)>,
discr: VariantDiscr, discr: VariantDiscr,
fields: Vec<FieldDef>, fields: IndexVec<FieldIdx, FieldDef>,
adt_kind: AdtKind, adt_kind: AdtKind,
parent_did: DefId, parent_did: DefId,
recovered: bool, recovered: bool,
@ -2270,11 +2270,10 @@ impl<'tcx> TyCtxt<'tcx> {
} }
} }
pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> { pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<FieldIdx> {
variant variant.fields.iter_enumerated().find_map(|(i, field)| {
.fields self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i)
.iter() })
.position(|field| self.hygienic_eq(ident, field.ident(self), variant.def_id))
} }
/// Returns `true` if the impls are the same polarity and the trait either /// Returns `true` if the impls are the same polarity and the trait either

View file

@ -22,7 +22,7 @@ use rustc_index::vec::Idx;
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span; use rustc_span::Span;
use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
use rustc_target::spec::abi::{self, Abi}; use rustc_target::spec::abi::{self, Abi};
use std::borrow::Cow; use std::borrow::Cow;
use std::cmp::Ordering; use std::cmp::Ordering;
@ -1903,7 +1903,7 @@ impl<'tcx> Ty<'tcx> {
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[FieldIdx::from_u32(0)].ty(tcx, substs);
match f0_ty.kind() { match f0_ty.kind() {
// If the first field is an array, we assume it is the only field and its // If the first field is an array, we assume it is the only field and its

View file

@ -25,6 +25,7 @@ use rustc_macros::HashStable;
use rustc_middle::mir::FakeReadCause; use rustc_middle::mir::FakeReadCause;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::Span; use rustc_span::Span;
use rustc_target::abi::FieldIdx;
use std::{collections::hash_map::Entry, hash::Hash, iter}; use std::{collections::hash_map::Entry, hash::Hash, iter};
use super::RvalueScopes; use super::RvalueScopes;
@ -42,7 +43,7 @@ pub struct TypeckResults<'tcx> {
/// or patterns (`S { field }`). The index is often useful by itself, but to learn more /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
/// about the field you also need definition of the variant to which the field /// about the field you also need definition of the variant to which the field
/// belongs, but it may not exist if it's a tuple field (`tuple.0`). /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
field_indices: ItemLocalMap<usize>, field_indices: ItemLocalMap<FieldIdx>,
/// Stores the types for various nodes in the AST. Note that this table /// Stores the types for various nodes in the AST. Note that this table
/// is not guaranteed to be populated outside inference. See /// is not guaranteed to be populated outside inference. See
@ -313,19 +314,19 @@ impl<'tcx> TypeckResults<'tcx> {
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs } LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs }
} }
pub fn field_indices(&self) -> LocalTableInContext<'_, usize> { pub fn field_indices(&self) -> LocalTableInContext<'_, FieldIdx> {
LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices } LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices }
} }
pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, usize> { pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, FieldIdx> {
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices } LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
} }
pub fn field_index(&self, id: hir::HirId) -> usize { pub fn field_index(&self, id: hir::HirId) -> FieldIdx {
self.field_indices().get(id).cloned().expect("no index for a field") self.field_indices().get(id).cloned().expect("no index for a field")
} }
pub fn opt_field_index(&self, id: hir::HirId) -> Option<usize> { pub fn opt_field_index(&self, id: hir::HirId) -> Option<FieldIdx> {
self.field_indices().get(id).cloned() self.field_indices().get(id).cloned()
} }

View file

@ -235,7 +235,7 @@ impl<'tcx> TyCtxt<'tcx> {
if !def.is_struct() { if !def.is_struct() {
break; break;
} }
match def.non_enum_variant().fields.last() { match def.non_enum_variant().fields.raw.last() {
Some(field) => { Some(field) => {
f(); f();
ty = field.ty(self, substs); ty = field.ty(self, substs);
@ -309,7 +309,7 @@ impl<'tcx> TyCtxt<'tcx> {
(&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs)) (&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs))
if a_def == b_def && a_def.is_struct() => if a_def == b_def && a_def.is_struct() =>
{ {
if let Some(f) = a_def.non_enum_variant().fields.last() { if let Some(f) = a_def.non_enum_variant().fields.raw.last() {
a = f.ty(self, a_substs); a = f.ty(self, a_substs);
b = f.ty(self, b_substs); b = f.ty(self, b_substs);
} else { } else {

View file

@ -90,7 +90,7 @@ fn convert_to_hir_projections_and_truncate_for_capture(
ProjectionElem::Deref => HirProjectionKind::Deref, ProjectionElem::Deref => HirProjectionKind::Deref,
ProjectionElem::Field(field, _) => { ProjectionElem::Field(field, _) => {
let variant = variant.unwrap_or(FIRST_VARIANT); let variant = variant.unwrap_or(FIRST_VARIANT);
HirProjectionKind::Field(field.index() as u32, variant) HirProjectionKind::Field(*field, variant)
} }
ProjectionElem::Downcast(.., idx) => { ProjectionElem::Downcast(.., idx) => {
// We don't expect to see multi-variant enums here, as earlier // We don't expect to see multi-variant enums here, as earlier

View file

@ -733,7 +733,7 @@ impl<'tcx> Cx<'tcx> {
hir::ExprKind::Field(ref source, ..) => ExprKind::Field { hir::ExprKind::Field(ref source, ..) => ExprKind::Field {
lhs: self.mirror_expr(source), lhs: self.mirror_expr(source),
variant_index: FIRST_VARIANT, variant_index: FIRST_VARIANT,
name: FieldIdx::new(self.typeck_results.field_index(expr.hir_id)), name: self.typeck_results.field_index(expr.hir_id),
}, },
hir::ExprKind::Cast(ref source, ref cast_ty) => { hir::ExprKind::Cast(ref source, ref cast_ty) => {
// Check for a user-given type annotation on this `cast` // Check for a user-given type annotation on this `cast`
@ -1053,7 +1053,7 @@ impl<'tcx> Cx<'tcx> {
HirProjectionKind::Field(field, variant_index) => ExprKind::Field { HirProjectionKind::Field(field, variant_index) => ExprKind::Field {
lhs: self.thir.exprs.push(captured_place_expr), lhs: self.thir.exprs.push(captured_place_expr),
variant_index, variant_index,
name: FieldIdx::new(field as usize), name: field,
}, },
HirProjectionKind::Index | HirProjectionKind::Subslice => { HirProjectionKind::Index | HirProjectionKind::Subslice => {
// We don't capture these projections, so we can ignore them here // We don't capture these projections, so we can ignore them here
@ -1107,7 +1107,7 @@ impl<'tcx> Cx<'tcx> {
fields fields
.iter() .iter()
.map(|field| FieldExpr { .map(|field| FieldExpr {
name: FieldIdx::new(self.typeck_results.field_index(field.hir_id)), name: self.typeck_results.field_index(field.hir_id),
expr: self.mirror_expr(field.expr), expr: self.mirror_expr(field.expr),
}) })
.collect() .collect()

View file

@ -357,7 +357,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let subpatterns = fields let subpatterns = fields
.iter() .iter()
.map(|field| FieldPat { .map(|field| FieldPat {
field: FieldIdx::new(self.typeck_results.field_index(field.hir_id)), field: self.typeck_results.field_index(field.hir_id),
pattern: self.lower_pattern(&field.pat), pattern: self.lower_pattern(&field.pat),
}) })
.collect(); .collect();

View file

@ -411,9 +411,9 @@ where
fn open_drop_for_box(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock { fn open_drop_for_box(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock {
// drop glue is sent straight to codegen // drop glue is sent straight to codegen
// box cannot be directly dereferenced // box cannot be directly dereferenced
let unique_ty = adt.non_enum_variant().fields[0].ty(self.tcx(), substs); let unique_ty = adt.non_enum_variant().fields[FieldIdx::new(0)].ty(self.tcx(), substs);
let nonnull_ty = let unique_variant = unique_ty.ty_adt_def().unwrap().non_enum_variant();
unique_ty.ty_adt_def().unwrap().non_enum_variant().fields[0].ty(self.tcx(), substs); let nonnull_ty = unique_variant.fields[FieldIdx::from_u32(0)].ty(self.tcx(), substs);
let ptr_ty = self.tcx().mk_imm_ptr(substs[0].expect_ty()); let ptr_ty = self.tcx().mk_imm_ptr(substs[0].expect_ty());
let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::new(0), unique_ty); let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::new(0), unique_ty);

View file

@ -92,13 +92,14 @@ pub struct ElaborateBoxDerefs;
impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs { impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if let Some(def_id) = tcx.lang_items().owned_box() { if let Some(def_id) = tcx.lang_items().owned_box() {
let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[0].did; let unique_did =
tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::from_u32(0)].did;
let Some(nonnull_def) = tcx.type_of(unique_did).subst_identity().ty_adt_def() else { let Some(nonnull_def) = tcx.type_of(unique_did).subst_identity().ty_adt_def() else {
span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique") span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique")
}; };
let nonnull_did = nonnull_def.non_enum_variant().fields[0].did; let nonnull_did = nonnull_def.non_enum_variant().fields[FieldIdx::from_u32(0)].did;
let patch = MirPatch::new(body); let patch = MirPatch::new(body);

View file

@ -907,7 +907,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
} }
ty::Adt(adt_def, substs) => { ty::Adt(adt_def, substs) => {
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT); let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { let Some(field) = adt_def.variant(var).fields.get(f) else {
self.validation = Err("malformed MIR"); self.validation = Err("malformed MIR");
return; return;
}; };

View file

@ -1119,7 +1119,8 @@ fn find_vtable_types_for_unsizing<'tcx>(
let target_fields = &target_adt_def.non_enum_variant().fields; let target_fields = &target_adt_def.non_enum_variant().fields;
assert!( assert!(
coerce_index < source_fields.len() && source_fields.len() == target_fields.len() coerce_index.index() < source_fields.len()
&& source_fields.len() == target_fields.len()
); );
find_vtable_types_for_unsizing( find_vtable_types_for_unsizing(

View file

@ -16,6 +16,7 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::FieldIdx;
use std::mem; use std::mem;
use crate::errors::{ use crate::errors::{
@ -232,7 +233,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
if let PatKind::Wild = pat.kind { if let PatKind::Wild = pat.kind {
continue; continue;
} }
self.insert_def_id(variant.fields[idx].did); self.insert_def_id(variant.fields[FieldIdx::from_usize(idx)].did);
} }
} }

View file

@ -1082,7 +1082,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
// If the expression uses FRU we need to make sure all the unmentioned fields // If the expression uses FRU we need to make sure all the unmentioned fields
// are checked for privacy (RFC 736). Rather than computing the set of // are checked for privacy (RFC 736). Rather than computing the set of
// unmentioned fields, just check them all. // unmentioned fields, just check them all.
for (vf_index, variant_field) in variant.fields.iter().enumerate() { for (vf_index, variant_field) in variant.fields.iter_enumerated() {
let field = fields let field = fields
.iter() .iter()
.find(|f| self.typeck_results().field_index(f.hir_id) == vf_index); .find(|f| self.typeck_results().field_index(f.hir_id) == vf_index);

View file

@ -340,7 +340,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
} }
ty::Adt(def, substs) if def.is_struct() => { ty::Adt(def, substs) if def.is_struct() => {
match def.non_enum_variant().fields.last() { match def.non_enum_variant().fields.raw.last() {
None => tcx.types.unit, None => tcx.types.unit,
Some(field_def) => { Some(field_def) => {
let self_ty = field_def.ty(tcx, substs); let self_ty = field_def.ty(tcx, substs);

View file

@ -407,6 +407,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
let tail_field = a_def let tail_field = a_def
.non_enum_variant() .non_enum_variant()
.fields .fields
.raw
.last() .last()
.expect("expected unsized ADT to have a tail field"); .expect("expected unsized ADT to have a tail field");
let tail_field_ty = tcx.type_of(tail_field.did); let tail_field_ty = tcx.type_of(tail_field.did);

View file

@ -1078,6 +1078,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let tail_field = def let tail_field = def
.non_enum_variant() .non_enum_variant()
.fields .fields
.raw
.last() .last()
.expect("expected unsized ADT to have a tail field"); .expect("expected unsized ADT to have a tail field");
let tail_field_ty = tcx.type_of(tail_field.did); let tail_field_ty = tcx.type_of(tail_field.did);

View file

@ -320,7 +320,7 @@ fn layout_of_uncached<'tcx>(
} }
// Type of the first ADT field: // Type of the first ADT field:
let f0_ty = def.non_enum_variant().fields[0].ty(tcx, substs); let f0_ty = def.non_enum_variant().fields[FieldIdx::from_u32(0)].ty(tcx, substs);
// Heterogeneous SIMD vectors are not supported: // Heterogeneous SIMD vectors are not supported:
// (should be caught by typeck) // (should be caught by typeck)
@ -456,7 +456,8 @@ fn layout_of_uncached<'tcx>(
{ {
let param_env = tcx.param_env(def.did()); let param_env = tcx.param_env(def.did());
def.is_struct() def.is_struct()
&& match def.variants().iter().next().and_then(|x| x.fields.last()) { && match def.variants().iter().next().and_then(|x| x.fields.raw.last())
{
Some(last_field) => tcx Some(last_field) => tcx
.type_of(last_field.did) .type_of(last_field.did)
.subst_identity() .subst_identity()

View file

@ -107,7 +107,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
let result = tcx.mk_type_list_from_iter( let result = tcx.mk_type_list_from_iter(
def.variants() def.variants()
.iter() .iter()
.flat_map(|v| v.fields.last()) .filter_map(|v| v.fields.raw.last())
.flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did).subst_identity())), .flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did).subst_identity())),
); );
@ -542,7 +542,7 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet<u32
// The last field of the structure has to exist and contain type/const parameters. // The last field of the structure has to exist and contain type/const parameters.
let Some((tail_field, prefix_fields)) = let Some((tail_field, prefix_fields)) =
def.non_enum_variant().fields.split_last() else def.non_enum_variant().fields.raw.split_last() else
{ {
return BitSet::new_empty(num_params); return BitSet::new_empty(num_params);
}; };