From b5b6def021d37c5f1cb7e06c1cf6915bcbcd53b1 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 1 Apr 2023 20:11:38 -0700 Subject: [PATCH] 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` instead of `Option`. --- .../rustc_borrowck/src/diagnostics/mod.rs | 5 +++-- compiler/rustc_borrowck/src/lib.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 19 +++++++++---------- compiler/rustc_codegen_cranelift/src/base.rs | 7 ++++--- compiler/rustc_codegen_ssa/src/base.rs | 6 +++--- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 6 +++--- .../rustc_const_eval/src/interpret/place.rs | 9 +++++---- compiler/rustc_index/src/vec.rs | 6 ++++++ compiler/rustc_middle/src/mir/syntax.rs | 7 ++++--- .../src/build/custom/parse/instruction.rs | 2 +- .../src/build/expr/as_rvalue.rs | 13 ++++++------- .../rustc_mir_build/src/build/expr/into.rs | 11 ++++------- compiler/rustc_mir_transform/src/generator.rs | 4 ++-- 13 files changed, 51 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index da0456856ac63..7bd4331c5ed92 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -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::{ @@ -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, @@ -975,7 +976,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self, def_id: LocalDefId, target_place: PlaceRef<'tcx>, - places: &[Operand<'tcx>], + places: &IndexSlice>, ) -> Option<(Span, Option, Span, Span)> { debug!( "closure_span: def_id={:?} target_place={:?} places={:?}", diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8b463a018a8d4..ba322425089a3 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -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(..) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 10bbce3776069..f3fe5a6cada16 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -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; @@ -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, FieldAccessError> { let tcx = self.tcx(); @@ -1725,8 +1725,7 @@ 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 { @@ -1734,7 +1733,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } 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 @@ 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(), @@ -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>, location: Location, ) { let tcx = self.tcx(); @@ -2362,7 +2361,7 @@ 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 }) => { @@ -2370,8 +2369,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self, rvalue, "accessed field #{} but variant only has {}", - i, - field_count + i.as_u32(), + field_count, ); continue; } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 98112fe08305e..2630f02e6eb31 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -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); } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 6c4ca8f7fb12d..c5ca7936a2b45 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -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; diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 0a59fabdc17fe..d49d23afe5134 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -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); } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index a95bcaa3f9988..03b09cf830b71 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -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 @@ where pub fn write_aggregate( &mut self, kind: &mir::AggregateKind<'tcx>, - operands: &[mir::Operand<'tcx>], + operands: &IndexSlice>, dest: &PlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { self.write_uninit(&dest)?; @@ -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)?; } diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 596849bd45682..6caae059f4ad6 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -93,6 +93,12 @@ impl fmt::Debug for IndexVec { } } +impl fmt::Debug for IndexSlice { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.raw, fmt) + } +} + impl IndexVec { #[inline] pub fn new() -> Self { diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 413a7629b9a11..cc35e6106e294 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -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; @@ -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>, Vec>), + Aggregate(Box>, IndexVec>), /// Transmutes a `*mut u8` into shallow-initialized `Box`. /// @@ -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, Option), + Adt(DefId, VariantIdx, SubstsRef<'tcx>, Option, Option), 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); diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 77a5017b3630f..33b73928704a0 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -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)), diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index d1878bf77ef1e..baa12ec11c321 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -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::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 @@ -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 = fields .into_iter() .copied() .map(|f| { @@ -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 = fields .into_iter() .copied() .map(|f| { @@ -402,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } // see (*) above - let operands: Vec<_> = upvars + let operands: IndexVec = upvars .into_iter() .copied() .map(|upvar| { @@ -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( diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index b8260c719c89a..8efaba1f602e0 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -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> { @@ -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(); @@ -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])); @@ -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; diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 50538248d91ee..af6422c724647 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -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, }); @@ -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, });