1
Fork 0

Auto merge of #109849 - scottmcm:more-fieldidx-rebase, r=oli-obk

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 https://github.com/rust-lang/compiler-team/issues/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 https://github.com/rust-lang/rust/pull/109787
This commit is contained in:
bors 2023-04-02 21:40:29 +00:00
commit a93bcdc307
13 changed files with 51 additions and 46 deletions

View file

@ -6,6 +6,7 @@ use rustc_errors::{Applicability, Diagnostic};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::GeneratorKind; use rustc_hir::GeneratorKind;
use rustc_index::vec::IndexSlice;
use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt}; use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt};
use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::{ use rustc_middle::mir::{
@ -825,7 +826,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place); debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place);
let places = &[Operand::Move(place)]; let places = &[Operand::Move(place)];
if let Some((args_span, generator_kind, capture_kind_span, path_span)) = 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 { return ClosureUse {
generator_kind, generator_kind,
@ -975,7 +976,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&self, &self,
def_id: LocalDefId, def_id: LocalDefId,
target_place: PlaceRef<'tcx>, target_place: PlaceRef<'tcx>,
places: &[Operand<'tcx>], places: &IndexSlice<FieldIdx, Operand<'tcx>>,
) -> Option<(Span, Option<GeneratorKind>, Span, Span)> { ) -> Option<(Span, Option<GeneratorKind>, Span, Span)> {
debug!( debug!(
"closure_span: def_id={:?} target_place={:?} places={:?}", "closure_span: def_id={:?} target_place={:?} places={:?}",

View file

@ -1343,7 +1343,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
self.infcx.tcx.mir_borrowck(def_id); self.infcx.tcx.mir_borrowck(def_id);
debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars); debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars);
for field in 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(..) AggregateKind::Adt(..)

View file

@ -14,7 +14,7 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_hir::lang_items::LangItem; 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::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::region_constraints::RegionConstraintData;
@ -1716,7 +1716,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
fn aggregate_field_ty( fn aggregate_field_ty(
&mut self, &mut self,
ak: &AggregateKind<'tcx>, ak: &AggregateKind<'tcx>,
field_index: usize, field_index: FieldIdx,
location: Location, location: Location,
) -> Result<Ty<'tcx>, FieldAccessError> { ) -> Result<Ty<'tcx>, FieldAccessError> {
let tcx = self.tcx(); let tcx = self.tcx();
@ -1725,8 +1725,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => { AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => {
let def = tcx.adt_def(adt_did); let def = tcx.adt_def(adt_did);
let variant = &def.variant(variant_index); let variant = &def.variant(variant_index);
let adj_field_index = let adj_field_index = active_field_index.unwrap_or(field_index);
FieldIdx::from_usize(active_field_index.unwrap_or(field_index));
if let Some(field) = variant.fields.get(adj_field_index) { if let Some(field) = variant.fields.get(adj_field_index) {
Ok(self.normalize(field.ty(tcx, substs), location)) Ok(self.normalize(field.ty(tcx, substs), location))
} else { } else {
@ -1734,7 +1733,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
} }
AggregateKind::Closure(_, substs) => { 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), Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange { None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_closure().upvar_tys().count(), 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; // It doesn't make sense to look at a field beyond the prefix;
// these require a variant index, and are not initialized in // these require a variant index, and are not initialized in
// aggregate rvalues. // 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), Some(ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange { None => Err(FieldAccessError::OutOfRange {
field_count: substs.as_generator().prefix_tys().count(), field_count: substs.as_generator().prefix_tys().count(),
@ -2350,7 +2349,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
body: &Body<'tcx>, body: &Body<'tcx>,
rvalue: &Rvalue<'tcx>, rvalue: &Rvalue<'tcx>,
aggregate_kind: &AggregateKind<'tcx>, aggregate_kind: &AggregateKind<'tcx>,
operands: &[Operand<'tcx>], operands: &IndexSlice<FieldIdx, Operand<'tcx>>,
location: Location, location: Location,
) { ) {
let tcx = self.tcx(); let tcx = self.tcx();
@ -2362,7 +2361,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
return; 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) { let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
Ok(field_ty) => field_ty, Ok(field_ty) => field_ty,
Err(FieldAccessError::OutOfRange { field_count }) => { Err(FieldAccessError::OutOfRange { field_count }) => {
@ -2370,8 +2369,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self, self,
rvalue, rvalue,
"accessed field #{} but variant only has {}", "accessed field #{} but variant only has {}",
i, i.as_u32(),
field_count field_count,
); );
continue; continue;
} }

View file

@ -802,14 +802,15 @@ fn codegen_stmt<'tcx>(
if active_field_index.is_some() { if active_field_index.is_some() {
assert_eq!(operands.len(), 1); 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 operand = codegen_operand(fx, operand);
let field_index = active_field_index.unwrap_or(i); let field_index = active_field_index.unwrap_or(i);
let to = if let mir::AggregateKind::Array(_) = **kind { 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) variant_dest.place_index(fx, index)
} else { } else {
variant_dest.place_field(fx, FieldIdx::new(field_index)) variant_dest.place_field(fx, field_index)
}; };
to.write_cvalue(fx, operand); to.write_cvalue(fx, operand);
} }

View file

@ -306,9 +306,9 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
assert_eq!(def_a, def_b); assert_eq!(def_a, def_b);
for i in 0..def_a.variant(FIRST_VARIANT).fields.len() { for i in def_a.variant(FIRST_VARIANT).fields.indices() {
let src_f = src.project_field(bx, i); let src_f = src.project_field(bx, i.as_usize());
let dst_f = dst.project_field(bx, i); let dst_f = dst.project_field(bx, i.as_usize());
if dst_f.layout.is_zst() { if dst_f.layout.is_zst() {
continue; continue;

View file

@ -123,16 +123,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if active_field_index.is_some() { if active_field_index.is_some() {
assert_eq!(operands.len(), 1); 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); let op = self.codegen_operand(bx, operand);
// Do not generate stores and GEPis for zero-sized fields. // Do not generate stores and GEPis for zero-sized fields.
if !op.layout.is_zst() { if !op.layout.is_zst() {
let field_index = active_field_index.unwrap_or(i); let field_index = active_field_index.unwrap_or(i);
let field = if let mir::AggregateKind::Array(_) = **kind { 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) variant_dest.project_index(bx, llindex)
} else { } else {
variant_dest.project_field(bx, field_index) variant_dest.project_field(bx, field_index.as_usize())
}; };
op.val.store(bx, field); op.val.store(bx, field);
} }

View file

@ -5,10 +5,11 @@
use either::{Either, Left, Right}; use either::{Either, Left, Right};
use rustc_ast::Mutability; use rustc_ast::Mutability;
use rustc_index::vec::IndexSlice;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; 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::{ use super::{
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg,
@ -787,7 +788,7 @@ where
pub fn write_aggregate( pub fn write_aggregate(
&mut self, &mut self,
kind: &mir::AggregateKind<'tcx>, kind: &mir::AggregateKind<'tcx>,
operands: &[mir::Operand<'tcx>], operands: &IndexSlice<FieldIdx, mir::Operand<'tcx>>,
dest: &PlaceTy<'tcx, M::Provenance>, dest: &PlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
self.write_uninit(&dest)?; self.write_uninit(&dest)?;
@ -801,9 +802,9 @@ where
if active_field_index.is_some() { if active_field_index.is_some() {
assert_eq!(operands.len(), 1); 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_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))?; let op = self.eval_operand(operand, Some(field_dest.layout))?;
self.copy_op(&op, &field_dest, /*allow_transmute*/ false)?; self.copy_op(&op, &field_dest, /*allow_transmute*/ false)?;
} }

View file

@ -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> { impl<I: Idx, T> IndexVec<I, T> {
#[inline] #[inline]
pub fn new() -> Self { pub fn new() -> Self {

View file

@ -16,6 +16,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir}; use rustc_hir::{self as hir};
use rustc_hir::{self, GeneratorKind}; use rustc_hir::{self, GeneratorKind};
use rustc_index::vec::IndexVec;
use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_ast::Mutability; use rustc_ast::Mutability;
@ -1125,7 +1126,7 @@ pub enum Rvalue<'tcx> {
/// ///
/// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
/// generator lowering, `Generator` aggregate kinds are disallowed too. /// 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>`. /// 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 /// active field number and is present only for union expressions
/// -- e.g., for a union expression `SomeUnion { c: .. }`, the /// -- e.g., for a union expression `SomeUnion { c: .. }`, the
/// active field index would identity the field `c` /// 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>), Closure(DefId, SubstsRef<'tcx>),
Generator(DefId, SubstsRef<'tcx>, hir::Movability), Generator(DefId, SubstsRef<'tcx>, hir::Movability),
@ -1263,7 +1264,7 @@ pub enum BinOp {
mod size_asserts { mod size_asserts {
use super::*; use super::*;
// tidy-alphabetical-start // tidy-alphabetical-start
static_assert_size!(AggregateKind<'_>, 40); static_assert_size!(AggregateKind<'_>, 32);
static_assert_size!(Operand<'_>, 24); static_assert_size!(Operand<'_>, 24);
static_assert_size!(Place<'_>, 16); static_assert_size!(Place<'_>, 16);
static_assert_size!(PlaceElem<'_>, 24); static_assert_size!(PlaceElem<'_>, 24);

View file

@ -185,7 +185,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
}, },
ExprKind::Adt(box AdtExpr{ adt_def, variant_index, substs, fields, .. }) => { ExprKind::Adt(box AdtExpr{ adt_def, variant_index, substs, fields, .. }) => {
let is_union = adt_def.is_union(); 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( Ok(Rvalue::Aggregate(
Box::new(AggregateKind::Adt(adt_def.did(), *variant_index, substs, None, active_field_index)), Box::new(AggregateKind::Adt(adt_def.did(), *variant_index, substs, None, active_field_index)),

View file

@ -1,8 +1,8 @@
//! See docs in `build/expr/mod.rs`. //! 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_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::as_place::PlaceBase;
use crate::build::expr::category::{Category, RvalueFunc}; 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::cast::{mir_cast_kind, CastTy};
use rustc_middle::ty::{self, Ty, UpvarSubsts}; use rustc_middle::ty::{self, Ty, UpvarSubsts};
use rustc_span::Span; use rustc_span::Span;
use rustc_target::abi::FieldIdx;
impl<'a, 'tcx> Builder<'a, 'tcx> { impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Returns an rvalue suitable for use until the end of the current /// 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 // first process the set of fields
let el_ty = expr.ty.sequence_element_type(this.tcx); let el_ty = expr.ty.sequence_element_type(this.tcx);
let fields: Vec<_> = fields let fields: IndexVec<FieldIdx, _> = fields
.into_iter() .into_iter()
.copied() .copied()
.map(|f| { .map(|f| {
@ -348,7 +347,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ExprKind::Tuple { ref fields } => { ExprKind::Tuple { ref fields } => {
// see (*) above // see (*) above
// first process the set of fields // first process the set of fields
let fields: Vec<_> = fields let fields: IndexVec<FieldIdx, _> = fields
.into_iter() .into_iter()
.copied() .copied()
.map(|f| { .map(|f| {
@ -402,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
// see (*) above // see (*) above
let operands: Vec<_> = upvars let operands: IndexVec<FieldIdx, _> = upvars
.into_iter() .into_iter()
.copied() .copied()
.map(|upvar| { .map(|upvar| {
@ -710,7 +709,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
this.record_operands_moved(&[value_operand]); 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( fn limit_capture_mutability(

View file

@ -6,11 +6,9 @@ use rustc_ast::InlineAsmOptions;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_index::vec::Idx;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::thir::*; use rustc_middle::thir::*;
use rustc_middle::ty::CanonicalUserTypeAnnotation; use rustc_middle::ty::CanonicalUserTypeAnnotation;
use rustc_target::abi::FieldIdx;
use std::iter; use std::iter;
impl<'a, 'tcx> Builder<'a, 'tcx> { 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 // See the notes for `ExprKind::Array` in `as_rvalue` and for
// `ExprKind::Borrow` above. // `ExprKind::Borrow` above.
let is_union = adt_def.is_union(); 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(); let scope = this.local_scope();
@ -344,10 +342,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}) })
.collect(); .collect();
let field_names: Vec<_> = let field_names = adt_def.variant(variant_index).fields.indices();
(0..adt_def.variant(variant_index).fields.len()).map(FieldIdx::new).collect();
let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base { let fields = if let Some(FruInfo { base, field_types }) = base {
let place_builder = let place_builder =
unpack!(block = this.as_place_builder(block, &this.thir[*base])); unpack!(block = this.as_place_builder(block, &this.thir[*base]));
@ -364,7 +361,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}) })
.collect() .collect()
} else { } 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; let inferred_ty = expr.ty;

View file

@ -274,7 +274,7 @@ impl<'tcx> TransformVisitor<'tcx> {
statements.push(Statement { statements.push(Statement {
kind: StatementKind::Assign(Box::new(( kind: StatementKind::Assign(Box::new((
Place::return_place(), Place::return_place(),
Rvalue::Aggregate(Box::new(kind), vec![]), Rvalue::Aggregate(Box::new(kind), IndexVec::new()),
))), ))),
source_info, source_info,
}); });
@ -287,7 +287,7 @@ impl<'tcx> TransformVisitor<'tcx> {
statements.push(Statement { statements.push(Statement {
kind: StatementKind::Assign(Box::new(( kind: StatementKind::Assign(Box::new((
Place::return_place(), Place::return_place(),
Rvalue::Aggregate(Box::new(kind), vec![val]), Rvalue::Aggregate(Box::new(kind), IndexVec::from_iter([val])),
))), ))),
source_info, source_info,
}); });