Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
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, .. }) => {
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
} else {
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
Expand Down Expand Up @@ -1725,7 +1725,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
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));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the kind of place that will hopefully be temporary -- changing AggregateKind::Adt to hold a FieldIdx and the function to use field_index: FieldIdx instead of field_index: usize should get rid of this in an upcoming PR in this series, but I needed to stop the tendrils somewhere 🙃

if let Some(field) = variant.fields.get(adj_field_index) {
Ok(self.normalize(field.ty(tcx, substs), location))
} else {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_cranelift/src/value_and_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,8 @@ impl<'tcx> CPlace<'tcx> {
};
}
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(_, _) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::interpret::{
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>(
Expand Down Expand Up @@ -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],
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ use rustc_middle::mir::interpret::InterpError;
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;

Expand Down Expand Up @@ -269,14 +271,16 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
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),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
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;
};
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use rustc_middle::ty::{
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 _;
Expand Down Expand Up @@ -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(..))
Expand Down Expand Up @@ -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")
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/check/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableE
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> {
Expand Down Expand Up @@ -82,7 +83,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
}
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) => {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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();
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
14 changes: 8 additions & 6 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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)?,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustc_middle::ty::relate::TypeRelation;
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;
Expand Down Expand Up @@ -850,7 +851,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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 =
Expand Down
20 changes: 9 additions & 11 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
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};
Expand Down Expand Up @@ -1561,8 +1562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

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<_, _>>();

Expand Down Expand Up @@ -1815,7 +1815,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&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>,
Expand Down Expand Up @@ -2209,11 +2209,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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.
Expand All @@ -2230,15 +2229,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
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));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes me wonder why do we need such cruel string manipulation few lines above O_o

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it's because field is an Ident. So I guess the fstr == index.to_string() is basically just checking that it's not tup.0001? (It has an as_u32, but that's the index in the string interner, so would be very, very wrong here.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha, found a little tweak that should be clearer and avoid the String for every .0, .1, through .9:

field.name == sym::integer(index) 

return field_ty;
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
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));
Expand All @@ -548,7 +548,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
&*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);
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use rustc_span::def_id::LocalDefId;
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};

Expand Down Expand Up @@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_hir as hir;
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;

Expand All @@ -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);
}
}

Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_hir_typeck/src/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
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 {
Expand Down Expand Up @@ -330,7 +330,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
expr,
base,
expr_ty,
ProjectionKind::Field(field_idx as u32, FIRST_VARIANT),
ProjectionKind::Field(field_idx, FIRST_VARIANT),
))
}

Expand Down Expand Up @@ -674,7 +674,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {

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)?;
Expand All @@ -689,7 +690,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {

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)?;
Expand All @@ -714,7 +716,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
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)?;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1815,7 +1815,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.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.
Expand Down
Loading