Skip to content

Commit

Permalink
Update ty::VariantDef to use IndexVec<FieldIdx, FieldDef>
Browse files Browse the repository at this point in the history
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 rust-lang/compiler-team#606
  • Loading branch information
scottmcm committed Mar 30, 2023
1 parent 1033857 commit 4abb455
Show file tree
Hide file tree
Showing 47 changed files with 127 additions and 104 deletions.
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));
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));
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

0 comments on commit 4abb455

Please sign in to comment.