Skip to content

Commit

Permalink
Auto merge of #109849 - scottmcm:more-fieldidx-rebase, r=oli-obk
Browse files Browse the repository at this point in the history
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>`.

Part 3/? of rust-lang/compiler-team#606

[`IndexSlice`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_index/vec/struct.IndexVec.html#deref-methods-IndexSlice%3CI,+T%3E) was added in #109787
  • Loading branch information
bors committed Apr 2, 2023
2 parents 3a8a131 + b5b6def commit a93bcdc
Show file tree
Hide file tree
Showing 13 changed files with 51 additions and 46 deletions.
5 changes: 3 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_errors::{Applicability, Diagnostic};
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::{
Expand Down Expand Up @@ -825,7 +826,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
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,
Expand Down Expand Up @@ -975,7 +976,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&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={:?}",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
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(..)
Expand Down
19 changes: 9 additions & 10 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_hir as hir;
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;
Expand Down Expand Up @@ -1716,7 +1716,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
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();
Expand All @@ -1725,16 +1725,15 @@ 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 =
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 {
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
}
}
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(),
Expand All @@ -1745,7 +1744,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// 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(),
Expand Down Expand Up @@ -2350,7 +2349,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
body: &Body<'tcx>,
rvalue: &Rvalue<'tcx>,
aggregate_kind: &AggregateKind<'tcx>,
operands: &[Operand<'tcx>],
operands: &IndexSlice<FieldIdx, Operand<'tcx>>,
location: Location,
) {
let tcx = self.tcx();
Expand All @@ -2362,16 +2361,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
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 }) => {
span_mirbug!(
self,
rvalue,
"accessed field #{} but variant only has {}",
i,
field_count
i.as_u32(),
field_count,
);
continue;
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,14 +802,15 @@ fn codegen_stmt<'tcx>(
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);
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
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);
}
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -787,7 +788,7 @@ where
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)?;
Expand All @@ -801,9 +802,9 @@ where
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)?;
}
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_index/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> {
}
}

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 {
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
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;
Expand Down Expand Up @@ -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>`.
///
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
},
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)),
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -17,7 +17,6 @@ use rustc_middle::thir::*;
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
Expand Down Expand Up @@ -327,7 +326,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

// 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| {
Expand All @@ -348,7 +347,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
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| {
Expand Down Expand Up @@ -402,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}

// see (*) above
let operands: Vec<_> = upvars
let operands: IndexVec<FieldIdx, _> = upvars
.into_iter()
.copied()
.map(|upvar| {
Expand Down Expand Up @@ -710,7 +709,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
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(
Expand Down
11 changes: 4 additions & 7 deletions compiler/rustc_mir_build/src/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ use rustc_ast::InlineAsmOptions;
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> {
Expand Down Expand Up @@ -320,7 +318,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// 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();

Expand All @@ -344,10 +342,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
.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]));

Expand All @@ -364,7 +361,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
.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;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ impl<'tcx> TransformVisitor<'tcx> {
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,
});
Expand All @@ -287,7 +287,7 @@ impl<'tcx> TransformVisitor<'tcx> {
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,
});
Expand Down

0 comments on commit a93bcdc

Please sign in to comment.