Use FieldIdx
in various things related to aggregates
Shrank `AggregateKind` by 8 bytes on x64, since the active field of a union is tracked as an `Option<FieldIdx>` instead of `Option<usize>`.
This commit is contained in:
parent
480068c235
commit
b5b6def021
@ -6,6 +6,7 @@
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, Namespace};
|
||||
use rustc_hir::GeneratorKind;
|
||||
use rustc_index::vec::IndexSlice;
|
||||
use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt};
|
||||
use rustc_middle::mir::tcx::PlaceTy;
|
||||
use rustc_middle::mir::{
|
||||
@ -825,7 +826,7 @@ pub(super) fn move_spans(
|
||||
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place);
|
||||
let places = &[Operand::Move(place)];
|
||||
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
||||
self.closure_span(closure_def_id, moved_place, places)
|
||||
self.closure_span(closure_def_id, moved_place, IndexSlice::from_raw(places))
|
||||
{
|
||||
return ClosureUse {
|
||||
generator_kind,
|
||||
@ -975,7 +976,7 @@ fn closure_span(
|
||||
&self,
|
||||
def_id: LocalDefId,
|
||||
target_place: PlaceRef<'tcx>,
|
||||
places: &[Operand<'tcx>],
|
||||
places: &IndexSlice<FieldIdx, Operand<'tcx>>,
|
||||
) -> Option<(Span, Option<GeneratorKind>, Span, Span)> {
|
||||
debug!(
|
||||
"closure_span: def_id={:?} target_place={:?} places={:?}",
|
||||
|
@ -1343,7 +1343,7 @@ fn consume_rvalue(
|
||||
self.infcx.tcx.mir_borrowck(def_id);
|
||||
debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars);
|
||||
for field in used_mut_upvars {
|
||||
self.propagate_closure_used_mut_upvar(&operands[field.index()]);
|
||||
self.propagate_closure_used_mut_upvar(&operands[*field]);
|
||||
}
|
||||
}
|
||||
AggregateKind::Adt(..)
|
||||
|
@ -14,7 +14,7 @@
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_index::vec::{IndexSlice, IndexVec};
|
||||
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
||||
use rustc_infer::infer::outlives::env::RegionBoundPairs;
|
||||
use rustc_infer::infer::region_constraints::RegionConstraintData;
|
||||
@ -1716,7 +1716,7 @@ fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
|
||||
fn aggregate_field_ty(
|
||||
&mut self,
|
||||
ak: &AggregateKind<'tcx>,
|
||||
field_index: usize,
|
||||
field_index: FieldIdx,
|
||||
location: Location,
|
||||
) -> Result<Ty<'tcx>, FieldAccessError> {
|
||||
let tcx = self.tcx();
|
||||
@ -1725,8 +1725,7 @@ 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 =
|
||||
FieldIdx::from_usize(active_field_index.unwrap_or(field_index));
|
||||
let adj_field_index = 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 {
|
||||
@ -1734,7 +1733,7 @@ fn aggregate_field_ty(
|
||||
}
|
||||
}
|
||||
AggregateKind::Closure(_, substs) => {
|
||||
match substs.as_closure().upvar_tys().nth(field_index) {
|
||||
match substs.as_closure().upvar_tys().nth(field_index.as_usize()) {
|
||||
Some(ty) => Ok(ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: substs.as_closure().upvar_tys().count(),
|
||||
@ -1745,7 +1744,7 @@ fn aggregate_field_ty(
|
||||
// It doesn't make sense to look at a field beyond the prefix;
|
||||
// these require a variant index, and are not initialized in
|
||||
// aggregate rvalues.
|
||||
match substs.as_generator().prefix_tys().nth(field_index) {
|
||||
match substs.as_generator().prefix_tys().nth(field_index.as_usize()) {
|
||||
Some(ty) => Ok(ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: substs.as_generator().prefix_tys().count(),
|
||||
@ -2350,7 +2349,7 @@ fn check_aggregate_rvalue(
|
||||
body: &Body<'tcx>,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
aggregate_kind: &AggregateKind<'tcx>,
|
||||
operands: &[Operand<'tcx>],
|
||||
operands: &IndexSlice<FieldIdx, Operand<'tcx>>,
|
||||
location: Location,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
@ -2362,7 +2361,7 @@ fn check_aggregate_rvalue(
|
||||
return;
|
||||
}
|
||||
|
||||
for (i, operand) in operands.iter().enumerate() {
|
||||
for (i, operand) in operands.iter_enumerated() {
|
||||
let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
|
||||
Ok(field_ty) => field_ty,
|
||||
Err(FieldAccessError::OutOfRange { field_count }) => {
|
||||
@ -2370,8 +2369,8 @@ fn check_aggregate_rvalue(
|
||||
self,
|
||||
rvalue,
|
||||
"accessed field #{} but variant only has {}",
|
||||
i,
|
||||
field_count
|
||||
i.as_u32(),
|
||||
field_count,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
@ -802,14 +802,15 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
if active_field_index.is_some() {
|
||||
assert_eq!(operands.len(), 1);
|
||||
}
|
||||
for (i, operand) in operands.iter().enumerate() {
|
||||
for (i, operand) in operands.iter_enumerated() {
|
||||
let operand = codegen_operand(fx, operand);
|
||||
let field_index = active_field_index.unwrap_or(i);
|
||||
let to = if let mir::AggregateKind::Array(_) = **kind {
|
||||
let index = fx.bcx.ins().iconst(fx.pointer_type, field_index as i64);
|
||||
let array_index = i64::from(field_index.as_u32());
|
||||
let index = fx.bcx.ins().iconst(fx.pointer_type, array_index);
|
||||
variant_dest.place_index(fx, index)
|
||||
} else {
|
||||
variant_dest.place_field(fx, FieldIdx::new(field_index))
|
||||
variant_dest.place_field(fx, field_index)
|
||||
};
|
||||
to.write_cvalue(fx, operand);
|
||||
}
|
||||
|
@ -306,9 +306,9 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
|
||||
assert_eq!(def_a, def_b);
|
||||
|
||||
for i in 0..def_a.variant(FIRST_VARIANT).fields.len() {
|
||||
let src_f = src.project_field(bx, i);
|
||||
let dst_f = dst.project_field(bx, i);
|
||||
for i in def_a.variant(FIRST_VARIANT).fields.indices() {
|
||||
let src_f = src.project_field(bx, i.as_usize());
|
||||
let dst_f = dst.project_field(bx, i.as_usize());
|
||||
|
||||
if dst_f.layout.is_zst() {
|
||||
continue;
|
||||
|
@ -123,16 +123,16 @@ pub fn codegen_rvalue(
|
||||
if active_field_index.is_some() {
|
||||
assert_eq!(operands.len(), 1);
|
||||
}
|
||||
for (i, operand) in operands.iter().enumerate() {
|
||||
for (i, operand) in operands.iter_enumerated() {
|
||||
let op = self.codegen_operand(bx, operand);
|
||||
// Do not generate stores and GEPis for zero-sized fields.
|
||||
if !op.layout.is_zst() {
|
||||
let field_index = active_field_index.unwrap_or(i);
|
||||
let field = if let mir::AggregateKind::Array(_) = **kind {
|
||||
let llindex = bx.cx().const_usize(field_index as u64);
|
||||
let llindex = bx.cx().const_usize(field_index.as_u32().into());
|
||||
variant_dest.project_index(bx, llindex)
|
||||
} else {
|
||||
variant_dest.project_field(bx, field_index)
|
||||
variant_dest.project_field(bx, field_index.as_usize())
|
||||
};
|
||||
op.val.store(bx, field);
|
||||
}
|
||||
|
@ -5,10 +5,11 @@
|
||||
use either::{Either, Left, Right};
|
||||
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_index::vec::IndexSlice;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, FIRST_VARIANT};
|
||||
use rustc_target::abi::{self, Abi, Align, FieldIdx, HasDataLayout, Size, FIRST_VARIANT};
|
||||
|
||||
use super::{
|
||||
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg,
|
||||
@ -787,7 +788,7 @@ pub fn allocate_str(
|
||||
pub fn write_aggregate(
|
||||
&mut self,
|
||||
kind: &mir::AggregateKind<'tcx>,
|
||||
operands: &[mir::Operand<'tcx>],
|
||||
operands: &IndexSlice<FieldIdx, mir::Operand<'tcx>>,
|
||||
dest: &PlaceTy<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
self.write_uninit(&dest)?;
|
||||
@ -801,9 +802,9 @@ pub fn write_aggregate(
|
||||
if active_field_index.is_some() {
|
||||
assert_eq!(operands.len(), 1);
|
||||
}
|
||||
for (field_index, operand) in operands.iter().enumerate() {
|
||||
for (field_index, operand) in operands.iter_enumerated() {
|
||||
let field_index = active_field_index.unwrap_or(field_index);
|
||||
let field_dest = self.place_field(&variant_dest, field_index)?;
|
||||
let field_dest = self.place_field(&variant_dest, field_index.as_usize())?;
|
||||
let op = self.eval_operand(operand, Some(field_dest.layout))?;
|
||||
self.copy_op(&op, &field_dest, /*allow_transmute*/ false)?;
|
||||
}
|
||||
|
@ -93,6 +93,12 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Debug::fmt(&self.raw, fmt)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Idx, T> IndexVec<I, T> {
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
|
@ -16,6 +16,7 @@
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{self as hir};
|
||||
use rustc_hir::{self, GeneratorKind};
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_target::abi::{FieldIdx, VariantIdx};
|
||||
|
||||
use rustc_ast::Mutability;
|
||||
@ -1125,7 +1126,7 @@ pub enum Rvalue<'tcx> {
|
||||
///
|
||||
/// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
|
||||
/// generator lowering, `Generator` aggregate kinds are disallowed too.
|
||||
Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
|
||||
Aggregate(Box<AggregateKind<'tcx>>, IndexVec<FieldIdx, Operand<'tcx>>),
|
||||
|
||||
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
|
||||
///
|
||||
@ -1186,7 +1187,7 @@ pub enum AggregateKind<'tcx> {
|
||||
/// active field number and is present only for union expressions
|
||||
/// -- e.g., for a union expression `SomeUnion { c: .. }`, the
|
||||
/// active field index would identity the field `c`
|
||||
Adt(DefId, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<usize>),
|
||||
Adt(DefId, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
|
||||
|
||||
Closure(DefId, SubstsRef<'tcx>),
|
||||
Generator(DefId, SubstsRef<'tcx>, hir::Movability),
|
||||
@ -1263,7 +1264,7 @@ pub enum BinOp {
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
// tidy-alphabetical-start
|
||||
static_assert_size!(AggregateKind<'_>, 40);
|
||||
static_assert_size!(AggregateKind<'_>, 32);
|
||||
static_assert_size!(Operand<'_>, 24);
|
||||
static_assert_size!(Place<'_>, 16);
|
||||
static_assert_size!(PlaceElem<'_>, 24);
|
||||
|
@ -185,7 +185,7 @@ fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
|
||||
},
|
||||
ExprKind::Adt(box AdtExpr{ adt_def, variant_index, substs, fields, .. }) => {
|
||||
let is_union = adt_def.is_union();
|
||||
let active_field_index = is_union.then(|| fields[0].name.index());
|
||||
let active_field_index = is_union.then(|| fields[0].name);
|
||||
|
||||
Ok(Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Adt(adt_def.did(), *variant_index, substs, None, active_field_index)),
|
||||
|
@ -1,8 +1,8 @@
|
||||
//! See docs in `build/expr/mod.rs`.
|
||||
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_target::abi::{Abi, Primitive};
|
||||
use rustc_target::abi::{Abi, FieldIdx, Primitive};
|
||||
|
||||
use crate::build::expr::as_place::PlaceBase;
|
||||
use crate::build::expr::category::{Category, RvalueFunc};
|
||||
@ -17,7 +17,6 @@
|
||||
use rustc_middle::ty::cast::{mir_cast_kind, CastTy};
|
||||
use rustc_middle::ty::{self, Ty, UpvarSubsts};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::FieldIdx;
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
/// Returns an rvalue suitable for use until the end of the current
|
||||
@ -327,7 +326,7 @@ pub(crate) fn as_rvalue(
|
||||
|
||||
// first process the set of fields
|
||||
let el_ty = expr.ty.sequence_element_type(this.tcx);
|
||||
let fields: Vec<_> = fields
|
||||
let fields: IndexVec<FieldIdx, _> = fields
|
||||
.into_iter()
|
||||
.copied()
|
||||
.map(|f| {
|
||||
@ -348,7 +347,7 @@ pub(crate) fn as_rvalue(
|
||||
ExprKind::Tuple { ref fields } => {
|
||||
// see (*) above
|
||||
// first process the set of fields
|
||||
let fields: Vec<_> = fields
|
||||
let fields: IndexVec<FieldIdx, _> = fields
|
||||
.into_iter()
|
||||
.copied()
|
||||
.map(|f| {
|
||||
@ -402,7 +401,7 @@ pub(crate) fn as_rvalue(
|
||||
}
|
||||
|
||||
// see (*) above
|
||||
let operands: Vec<_> = upvars
|
||||
let operands: IndexVec<FieldIdx, _> = upvars
|
||||
.into_iter()
|
||||
.copied()
|
||||
.map(|upvar| {
|
||||
@ -710,7 +709,7 @@ fn build_zero_repeat(
|
||||
}
|
||||
this.record_operands_moved(&[value_operand]);
|
||||
}
|
||||
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), Vec::new()))
|
||||
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), IndexVec::new()))
|
||||
}
|
||||
|
||||
fn limit_capture_mutability(
|
||||
|
@ -6,11 +6,9 @@
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir as hir;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::thir::*;
|
||||
use rustc_middle::ty::CanonicalUserTypeAnnotation;
|
||||
use rustc_target::abi::FieldIdx;
|
||||
use std::iter;
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
@ -320,7 +318,7 @@ pub(crate) fn expr_into_dest(
|
||||
// See the notes for `ExprKind::Array` in `as_rvalue` and for
|
||||
// `ExprKind::Borrow` above.
|
||||
let is_union = adt_def.is_union();
|
||||
let active_field_index = is_union.then(|| fields[0].name.index());
|
||||
let active_field_index = is_union.then(|| fields[0].name);
|
||||
|
||||
let scope = this.local_scope();
|
||||
|
||||
@ -344,10 +342,9 @@ pub(crate) fn expr_into_dest(
|
||||
})
|
||||
.collect();
|
||||
|
||||
let field_names: Vec<_> =
|
||||
(0..adt_def.variant(variant_index).fields.len()).map(FieldIdx::new).collect();
|
||||
let field_names = adt_def.variant(variant_index).fields.indices();
|
||||
|
||||
let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base {
|
||||
let fields = if let Some(FruInfo { base, field_types }) = base {
|
||||
let place_builder =
|
||||
unpack!(block = this.as_place_builder(block, &this.thir[*base]));
|
||||
|
||||
@ -364,7 +361,7 @@ pub(crate) fn expr_into_dest(
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
field_names.iter().filter_map(|n| fields_map.get(n).cloned()).collect()
|
||||
field_names.filter_map(|n| fields_map.get(&n).cloned()).collect()
|
||||
};
|
||||
|
||||
let inferred_ty = expr.ty;
|
||||
|
@ -274,7 +274,7 @@ fn make_state(
|
||||
statements.push(Statement {
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
Place::return_place(),
|
||||
Rvalue::Aggregate(Box::new(kind), vec![]),
|
||||
Rvalue::Aggregate(Box::new(kind), IndexVec::new()),
|
||||
))),
|
||||
source_info,
|
||||
});
|
||||
@ -287,7 +287,7 @@ fn make_state(
|
||||
statements.push(Statement {
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
Place::return_place(),
|
||||
Rvalue::Aggregate(Box::new(kind), vec![val]),
|
||||
Rvalue::Aggregate(Box::new(kind), IndexVec::from_iter([val])),
|
||||
))),
|
||||
source_info,
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user