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 @@ fn describe_field_from_ty(
if !including_tuple_field.0 && variant.ctor_kind() == Some(CtorKind::Fn) {
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::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {

View File

@ -854,7 +854,7 @@ fn field_ty(
},
};
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))
} else {
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
@ -1725,7 +1725,8 @@ fn aggregate_field_ty(
AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => {
let def = tcx.adt_def(adt_did);
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) {
Ok(self.normalize(field.ty(tcx, substs), location))
} else {

View File

@ -701,7 +701,8 @@ pub(crate) fn place_field(
};
}
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() {
ty::Array(_, _) => {

View File

@ -274,7 +274,8 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
.map(|field_index| {
let field_name = if variant_def.ctor_kind() != Some(CtorKind::Fn) {
// 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 {
// Tuple-like
super::tuple_field_name(field_index)

View File

@ -8,7 +8,7 @@
use crate::interpret::{MPlaceTy, Value};
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
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")]
fn branches<'tcx>(
@ -412,6 +412,7 @@ fn valtree_into_mplace<'tcx>(
let inner_ty = match ty.kind() {
ty::Adt(def, substs) => {
let i = FieldIdx::from_usize(i);
def.variant(FIRST_VARIANT).fields[i].ty(tcx, substs)
}
ty::Tuple(inner_tys) => inner_tys[i],

View File

@ -16,7 +16,9 @@
use rustc_middle::ty;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
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;
@ -269,14 +271,16 @@ fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize)
match layout.variants {
Variants::Single { index } => {
// 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"),
}
}
// 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
ty::Array(..) | ty::Slice(..) => PathElem::ArrayElem(field),

View File

@ -360,7 +360,7 @@ fn visit_projection_elem(
}
ty::Adt(adt_def, substs) => {
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);
return;
};

View File

@ -27,6 +27,7 @@
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
use rustc_span::symbol::sym;
use rustc_span::{self, Span};
use rustc_target::abi::FieldIdx;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective;
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 {
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;
};
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();
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) {
struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
.span_label(sp, "SIMD elements must have the same type")

View File

@ -5,6 +5,7 @@
use rustc_session::lint;
use rustc_span::def_id::LocalDefId;
use rustc_span::{Symbol, DUMMY_SP};
use rustc_target::abi::FieldIdx;
use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType};
pub struct InlineAsmCtxt<'a, 'tcx> {
@ -82,7 +83,7 @@ fn check_asm_operand_type(
}
ty::Adt(adt, substs) if adt.repr().simd() => {
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() {
ty::Never | ty::Error(_) => return None,
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.
let needs_drop_copy = || {
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);
if ty.needs_infer() {
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 unsized_len = if all_sized { 0 } else { 1 };
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 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>`.
let fields = &def_a.non_enum_variant().fields;
let diff_fields = fields
.iter()
.enumerate()
.iter_enumerated()
.filter_map(|(i, f)| {
let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b));

View File

@ -103,13 +103,15 @@ fn pointer_kind(
Ok(match *t.kind() {
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
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() {
None => Some(PointerKind::Thin),
Some(f) => {
let field_ty = self.field_ty(span, f, substs);
self.pointer_kind(field_ty, span)?
ty::Adt(def, substs) if def.is_struct() => {
match def.non_enum_variant().fields.raw.last() {
None => Some(PointerKind::Thin),
Some(f) => {
let field_ty = self.field_ty(span, f, substs);
self.pointer_kind(field_ty, span)?
}
}
},
}
ty::Tuple(fields) => match fields.last() {
None => Some(PointerKind::Thin),
Some(&f) => self.pointer_kind(f, span)?,

View File

@ -19,6 +19,7 @@
use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitableExt};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{BytePos, Span};
use rustc_target::abi::FieldIdx;
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::method_chain::CollectAllMismatches;
use rustc_trait_selection::traits::ObligationCause;
@ -850,7 +851,7 @@ fn suggest_compatible_variants(
variant.fields.len() == 1
})
.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_accessible =

View File

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

View File

@ -539,7 +539,7 @@ fn walk_struct_expr<'hir>(
match with_place.place.ty().kind() {
ty::Adt(adt, substs) if adt.is_struct() => {
// 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
.iter()
.any(|f| self.mc.typeck_results.opt_field_index(f.hir_id) == Some(f_index));
@ -548,7 +548,7 @@ fn walk_struct_expr<'hir>(
&*with_expr,
with_place.clone(),
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);
}

View File

@ -33,6 +33,7 @@
use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use rustc_target::abi::FieldIdx;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCauseCode, ObligationCtxt};
@ -147,7 +148,7 @@ pub fn write_ty(&self, id: hir::HirId, ty: Ty<'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);
}

View File

@ -4,7 +4,7 @@
use rustc_index::vec::Idx;
use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_target::abi::{Pointer, VariantIdx};
use rustc_target::abi::{FieldIdx, Pointer, VariantIdx};
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 {
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::PatKind;
use rustc_infer::infer::InferCtxt;
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;
pub(crate) trait HirNode {
@ -330,7 +330,7 @@ pub(crate) fn cat_expr_unadjusted(
expr,
base,
expr_ty,
ProjectionKind::Field(field_idx as u32, FIRST_VARIANT),
ProjectionKind::Field(field_idx, FIRST_VARIANT),
))
}
@ -674,7 +674,8 @@ fn cat_pattern_<F>(
for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
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 =
self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind);
self.cat_pattern_(sub_place, subpat, op)?;
@ -689,7 +690,8 @@ fn cat_pattern_<F>(
for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
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 =
self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind);
self.cat_pattern_(sub_place, subpat, op)?;
@ -714,7 +716,7 @@ fn cat_pattern_<F>(
pat,
place_with_id.clone(),
field_ty,
ProjectionKind::Field(field_index as u32, variant_index),
ProjectionKind::Field(field_index, variant_index),
);
self.cat_pattern_(field_place, fp.pat, op)?;
}

View File

@ -1815,7 +1815,7 @@ fn check_for_inner_self(
.variants()
.iter()
.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);
// Skip `_`, since that'll just lead to ambiguity.

View File

@ -19,6 +19,7 @@
use rustc_span::source_map::{Span, Spanned};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, DUMMY_SP};
use rustc_target::abi::FieldIdx;
use rustc_trait_selection::traits::{ObligationCause, Pattern};
use ty::VariantDef;
@ -1091,11 +1092,12 @@ fn check_pat_tuple_struct(
bug!("unexpected pattern type {:?}", pat_ty);
};
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.tcx.check_stability(
variant.fields[i].did,
variant.fields[FieldIdx::from_usize(i)].did,
Some(pat.hir_id),
subpat.span,
None,
@ -1103,7 +1105,8 @@ fn check_pat_tuple_struct(
}
} else {
// 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);
return tcx.ty_error(e);
}
@ -1333,8 +1336,7 @@ fn check_struct_pat_fields(
// Index the struct fields' types.
let field_map = variant
.fields
.iter()
.enumerate()
.iter_enumerated()
.map(|(i, field)| (field.ident(self.tcx).normalize_to_macros_2_0(), (i, field)))
.collect::<FxHashMap<_, _>>();

View File

@ -1405,7 +1405,7 @@ fn has_significant_drop_outside_of_captures(
ProjectionKind::Field(..)
))
);
def.variants().get(FIRST_VARIANT).unwrap().fields.iter().enumerate().any(
def.variants().get(FIRST_VARIANT).unwrap().fields.iter_enumerated().any(
|(i, field)| {
let paths_using_field = captured_by_move_projs
.iter()
@ -1413,7 +1413,7 @@ fn has_significant_drop_outside_of_captures(
if let ProjectionKind::Field(field_idx, _) =
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 {
unreachable!();
}
@ -1446,7 +1446,7 @@ fn has_significant_drop_outside_of_captures(
.filter_map(|projs| {
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 {
unreachable!();
}

View File

@ -10,6 +10,7 @@
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitableExt};
use rustc_span::{sym, BytePos, Span};
use rustc_target::abi::FieldIdx;
use crate::errors::{
ConsiderAddingAwait, SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding,
@ -109,7 +110,7 @@ pub(super) fn suggest_tuple_pattern(
variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn)
})
.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);
if self.same_type_modulo_infer(sole_field_ty, exp_found.found) {
let variant_path =

View File

@ -770,7 +770,7 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty);
if let ty::Adt(ty_def, substs) = ty.kind() {
let field_ty = match &ty_def.variants().raw[..] {
[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),
_ => return None,
},

View File

@ -2,7 +2,7 @@
use crate::ty::Ty;
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(TypeFoldable, TypeVisitable)]
@ -27,7 +27,7 @@ pub enum ProjectionKind {
/// the field. The field is identified by which variant
/// it appears in along with a field index. The variant
/// is used for enums.
Field(u32, VariantIdx),
Field(FieldIdx, VariantIdx),
/// Some index like `B[x]`, where `B` is the base
/// expression. We don't preserve the index `x` because

View File

@ -43,7 +43,7 @@ pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: FieldIdx) -> Ty<'tcx> {
&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)
}
ty::Tuple(tys) => tys[f.index()],

View File

@ -784,7 +784,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let PatKind::Wild = p.pattern.kind {
continue;
}
let name = variant.fields[p.field.index()].name;
let name = variant.fields[p.field].name;
write!(f, "{}{}: {}", start_or_comma(), name, p.pattern)?;
printed += 1;
}

View File

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

View File

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

View File

@ -5,7 +5,6 @@
use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_index::vec::Idx;
use rustc_session::config::OptLevel;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
@ -335,7 +334,7 @@ pub fn compute(
// Get a zero-sized variant or a pointer newtype.
let zero_or_ptr_variant = |i| {
let i = VariantIdx::new(i);
let i = VariantIdx::from_usize(i);
let fields =
def.variant(i).fields.iter().map(|field| {
SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env)
@ -798,7 +797,8 @@ fn field_ty_or_layout<'tcx>(
ty::Adt(def, substs) => {
match this.variants {
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).

View File

@ -50,7 +50,7 @@
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
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};
use rustc_type_ir::WithCachedTypeInfo;
pub use subst::*;
@ -1891,7 +1891,7 @@ pub struct VariantDef {
/// Discriminant of this variant.
pub discr: VariantDiscr,
/// 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: VariantFlags,
}
@ -1918,7 +1918,7 @@ pub fn new(
variant_did: Option<DefId>,
ctor: Option<(CtorKind, DefId)>,
discr: VariantDiscr,
fields: Vec<FieldDef>,
fields: IndexVec<FieldIdx, FieldDef>,
adt_kind: AdtKind,
parent_did: DefId,
recovered: bool,
@ -2270,11 +2270,10 @@ pub fn opt_rpitit_info(self, def_id: DefId) -> Option<ImplTraitInTraitData> {
}
}
pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> {
variant
.fields
.iter()
.position(|field| self.hygienic_eq(ident, field.ident(self), variant.def_id))
pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<FieldIdx> {
variant.fields.iter_enumerated().find_map(|(i, field)| {
self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i)
})
}
/// Returns `true` if the impls are the same polarity and the trait either

View File

@ -22,7 +22,7 @@
use rustc_macros::HashStable;
use rustc_span::symbol::{kw, sym, Symbol};
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 std::borrow::Cow;
use std::cmp::Ordering;
@ -1903,7 +1903,7 @@ pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
Adt(def, substs) => {
assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type");
let variant = def.non_enum_variant();
let f0_ty = variant.fields[0].ty(tcx, substs);
let f0_ty = variant.fields[FieldIdx::from_u32(0)].ty(tcx, substs);
match f0_ty.kind() {
// If the first field is an array, we assume it is the only field and its

View File

@ -25,6 +25,7 @@
use rustc_middle::mir::FakeReadCause;
use rustc_session::Session;
use rustc_span::Span;
use rustc_target::abi::FieldIdx;
use std::{collections::hash_map::Entry, hash::Hash, iter};
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
/// 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`).
field_indices: ItemLocalMap<usize>,
field_indices: ItemLocalMap<FieldIdx>,
/// Stores the types for various nodes in the AST. Note that this table
/// is not guaranteed to be populated outside inference. See
@ -313,19 +314,19 @@ pub fn type_dependent_defs_mut(
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 }
}
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 }
}
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")
}
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()
}

View File

@ -235,7 +235,7 @@ pub fn struct_tail_with_normalize(
if !def.is_struct() {
break;
}
match def.non_enum_variant().fields.last() {
match def.non_enum_variant().fields.raw.last() {
Some(field) => {
f();
ty = field.ty(self, substs);
@ -309,7 +309,7 @@ pub fn struct_lockstep_tails_with_normalize(
(&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs))
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);
b = f.ty(self, b_substs);
} else {

View File

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

View File

@ -733,7 +733,7 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx>
hir::ExprKind::Field(ref source, ..) => ExprKind::Field {
lhs: self.mirror_expr(source),
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) => {
// Check for a user-given type annotation on this `cast`
@ -1053,7 +1053,7 @@ fn convert_captured_hir_place(
HirProjectionKind::Field(field, variant_index) => ExprKind::Field {
lhs: self.thir.exprs.push(captured_place_expr),
variant_index,
name: FieldIdx::new(field as usize),
name: field,
},
HirProjectionKind::Index | HirProjectionKind::Subslice => {
// We don't capture these projections, so we can ignore them here
@ -1107,7 +1107,7 @@ fn field_refs(&mut self, fields: &'tcx [hir::ExprField<'tcx>]) -> Box<[FieldExpr
fields
.iter()
.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),
})
.collect()

View File

@ -357,7 +357,7 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tc
let subpatterns = fields
.iter()
.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),
})
.collect();

View File

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

View File

@ -92,13 +92,14 @@ fn visit_place(
impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
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 {
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);

View File

@ -907,7 +907,7 @@ fn visit_projection_elem(
}
ty::Adt(adt_def, substs) => {
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");
return;
};

View File

@ -1119,7 +1119,8 @@ fn find_vtable_types_for_unsizing<'tcx>(
let target_fields = &target_adt_def.non_enum_variant().fields;
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(

View File

@ -16,6 +16,7 @@
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint;
use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::FieldIdx;
use std::mem;
use crate::errors::{
@ -232,7 +233,7 @@ fn handle_tuple_field_pattern_match(
if let PatKind::Wild = pat.kind {
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 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
// 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
// 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
.iter()
.find(|f| self.typeck_results().field_index(f.hir_id) == vf_index);

View File

@ -340,7 +340,7 @@ fn consider_builtin_pointee_candidate(
}
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,
Some(field_def) => {
let self_ty = field_def.ty(tcx, substs);

View File

@ -407,6 +407,7 @@ fn consider_builtin_unsize_candidate(
let tail_field = a_def
.non_enum_variant()
.fields
.raw
.last()
.expect("expected unsized ADT to have a tail field");
let tail_field_ty = tcx.type_of(tail_field.did);

View File

@ -1078,6 +1078,7 @@ fn confirm_builtin_unsize_candidate(
let tail_field = def
.non_enum_variant()
.fields
.raw
.last()
.expect("expected unsized ADT to have a tail field");
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:
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:
// (should be caught by typeck)
@ -456,7 +456,8 @@ fn layout_of_uncached<'tcx>(
{
let param_env = tcx.param_env(def.did());
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
.type_of(last_field.did)
.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(
def.variants()
.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())),
);
@ -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.
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);
};