1
Fork 0

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

@ -2,7 +2,7 @@ use crate::ty;
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 @@ impl<'tcx> PlaceTy<'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 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
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 as hir;
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 @@ impl<'tcx> CapturedPlace<'tcx> {
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 crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt};
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 @@ impl<'tcx> SizeSkeleton<'tcx> {
// 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 @@ where
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 @@ pub use rustc_session::lint::RegisteredTools;
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 @@ impl VariantDef {
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 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
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_index::vec::Idx;
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 @@ impl<'tcx> 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_macros::HashStable;
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 @@ impl<'tcx> TypeckResults<'tcx> {
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 @@ impl<'tcx> TyCtxt<'tcx> {
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 @@ impl<'tcx> TyCtxt<'tcx> {
(&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 {