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:
commit
eb3e9c1f45
47 changed files with 127 additions and 104 deletions
|
@ -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
|
||||
|
|
|
@ -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()],
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue