Skip to content

Commit 3a6f1b0

Browse files
Rollup merge of #142103 - scottmcm:fieldidx-in-interp, r=oli-obk
Update `InterpCx::project_field` to take `FieldIdx` As suggested by Ralf in #142005 (comment)
2 parents 2946ce2 + f9cf096 commit 3a6f1b0

File tree

26 files changed

+102
-80
lines changed

26 files changed

+102
-80
lines changed

compiler/rustc_abi/src/layout/ty.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ rustc_index::newtype_index! {
3939
pub struct FieldIdx {}
4040
}
4141

42+
impl FieldIdx {
43+
/// The second field, at index 1.
44+
///
45+
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.
46+
pub const ONE: FieldIdx = FieldIdx::from_u32(1);
47+
}
48+
4249
rustc_index::newtype_index! {
4350
/// The *source-order* index of a variant in a type.
4451
///
@@ -274,7 +281,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
274281

275282
/// Finds the one field that is not a 1-ZST.
276283
/// Returns `None` if there are multiple non-1-ZST fields or only 1-ZST-fields.
277-
pub fn non_1zst_field<C>(&self, cx: &C) -> Option<(usize, Self)>
284+
pub fn non_1zst_field<C>(&self, cx: &C) -> Option<(FieldIdx, Self)>
278285
where
279286
Ty: TyAbiInterface<'a, C> + Copy,
280287
{
@@ -288,7 +295,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
288295
// More than one non-1-ZST field.
289296
return None;
290297
}
291-
found = Some((field_idx, field));
298+
found = Some((FieldIdx::from_usize(field_idx), field));
292299
}
293300
found
294301
}

compiler/rustc_codegen_cranelift/src/inline_asm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option<ty
850850
// Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151
851851
ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => {
852852
let fields = &adt.non_enum_variant().fields;
853-
let ty = fields[FieldIdx::from_u32(1)].ty(fx.tcx, args);
853+
let ty = fields[FieldIdx::ONE].ty(fx.tcx, args);
854854
let ty::Adt(ty, args) = ty.kind() else {
855855
unreachable!("expected first field of `MaybeUninit` to be an ADT")
856856
};

compiler/rustc_codegen_cranelift/src/vtable.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
5353
.layout()
5454
.non_1zst_field(fx)
5555
.expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type");
56-
arg = arg.value_field(fx, FieldIdx::new(idx));
56+
arg = arg.value_field(fx, idx);
5757
}
5858
}
5959

@@ -62,8 +62,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
6262
let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap());
6363
let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout);
6464
let ptr = dyn_star.place_field(fx, FieldIdx::ZERO).to_ptr();
65-
let vtable =
66-
dyn_star.place_field(fx, FieldIdx::new(1)).to_cvalue(fx).load_scalar(fx);
65+
let vtable = dyn_star.place_field(fx, FieldIdx::ONE).to_cvalue(fx).load_scalar(fx);
6766
break 'block (ptr, vtable);
6867
}
6968
}

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10771077
let (idx, _) = op.layout.non_1zst_field(bx).expect(
10781078
"not exactly one non-1-ZST field in a `DispatchFromDyn` type",
10791079
);
1080-
op = op.extract_field(self, bx, idx);
1080+
op = op.extract_field(self, bx, idx.as_usize());
10811081
}
10821082

10831083
// Now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
@@ -1109,7 +1109,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11091109
let (idx, _) = op.layout.non_1zst_field(bx).expect(
11101110
"not exactly one non-1-ZST field in a `DispatchFromDyn` type",
11111111
);
1112-
op = op.extract_field(self, bx, idx);
1112+
op = op.extract_field(self, bx, idx.as_usize());
11131113
}
11141114

11151115
// Make sure that we've actually unwrapped the rcvr down

compiler/rustc_const_eval/src/const_eval/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Not in interpret to make sure we do not use private implementation details
22

3-
use rustc_abi::VariantIdx;
3+
use rustc_abi::{FieldIdx, VariantIdx};
44
use rustc_middle::query::Key;
55
use rustc_middle::ty::layout::LayoutOf;
66
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -60,7 +60,7 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
6060

6161
let fields_iter = (0..field_count)
6262
.map(|i| {
63-
let field_op = ecx.project_field(&down, i).discard_err()?;
63+
let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?;
6464
let val = op_to_const(&ecx, &field_op, /* for diagnostics */ true);
6565
Some((val, field_op.layout.ty))
6666
})

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_abi::{BackendRepr, VariantIdx};
1+
use rustc_abi::{BackendRepr, FieldIdx, VariantIdx};
22
use rustc_data_structures::stack::ensure_sufficient_stack;
33
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ReportedErrorInfo};
44
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
@@ -40,7 +40,7 @@ fn branches<'tcx>(
4040
}
4141

4242
for i in 0..field_count {
43-
let field = ecx.project_field(&place, i).unwrap();
43+
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();
4444
let valtree = const_to_valtree_inner(ecx, &field, num_nodes)?;
4545
branches.push(valtree);
4646
}
@@ -437,7 +437,7 @@ fn valtree_into_mplace<'tcx>(
437437
ty::Str | ty::Slice(_) | ty::Array(..) => {
438438
ecx.project_index(place, i as u64).unwrap()
439439
}
440-
_ => ecx.project_field(&place_adjusted, i).unwrap(),
440+
_ => ecx.project_field(&place_adjusted, FieldIdx::from_usize(i)).unwrap(),
441441
};
442442

443443
debug!(?place_inner);

compiler/rustc_const_eval/src/interpret/call.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
6262
pub(super) fn fn_arg_field(
6363
&self,
6464
arg: &FnArg<'tcx, M::Provenance>,
65-
field: usize,
65+
field: FieldIdx,
6666
) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> {
6767
interp_ok(match arg {
6868
FnArg::Copy(op) => FnArg::Copy(self.project_field(op, field)?),
@@ -600,10 +600,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
600600
Cow::from(
601601
args.iter()
602602
.map(|a| interp_ok(a.clone()))
603-
.chain(
604-
(0..untuple_arg.layout().fields.count())
605-
.map(|i| self.fn_arg_field(untuple_arg, i)),
606-
)
603+
.chain((0..untuple_arg.layout().fields.count()).map(|i| {
604+
self.fn_arg_field(untuple_arg, FieldIdx::from_usize(i))
605+
}))
607606
.collect::<InterpResult<'_, Vec<_>>>()?,
608607
)
609608
} else {

compiler/rustc_const_eval/src/interpret/cast.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::assert_matches::assert_matches;
22

3-
use rustc_abi::Integer;
3+
use rustc_abi::{FieldIdx, Integer};
44
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
55
use rustc_apfloat::{Float, FloatConvert};
66
use rustc_middle::mir::CastKind;
@@ -484,6 +484,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
484484
let mut found_cast_field = false;
485485
for i in 0..src.layout.fields.count() {
486486
let cast_ty_field = cast_ty.field(self, i);
487+
let i = FieldIdx::from_usize(i);
487488
let src_field = self.project_field(src, i)?;
488489
let dst_field = self.project_field(dest, i)?;
489490
if src_field.layout.is_1zst() && cast_ty_field.is_1zst() {

compiler/rustc_const_eval/src/interpret/discriminant.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
2626
// No need to validate that the discriminant here because the
2727
// `TyAndLayout::for_variant()` call earlier already checks the
2828
// variant is valid.
29-
let tag_dest = self.project_field(dest, tag_field.as_usize())?;
29+
let tag_dest = self.project_field(dest, tag_field)?;
3030
self.write_scalar(tag, &tag_dest)
3131
}
3232
None => {
@@ -96,7 +96,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
9696
let tag_layout = self.layout_of(tag_scalar_layout.primitive().to_int_ty(*self.tcx))?;
9797

9898
// Read tag and sanity-check `tag_layout`.
99-
let tag_val = self.read_immediate(&self.project_field(op, tag_field.as_usize())?)?;
99+
let tag_val = self.read_immediate(&self.project_field(op, tag_field)?)?;
100100
assert_eq!(tag_layout.size, tag_val.layout.size);
101101
assert_eq!(tag_layout.backend_repr.is_signed(), tag_val.layout.backend_repr.is_signed());
102102
trace!("tag value: {}", tag_val);

compiler/rustc_const_eval/src/interpret/projection.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use std::marker::PhantomData;
1111
use std::ops::Range;
1212

13-
use rustc_abi::{self as abi, Size, VariantIdx};
13+
use rustc_abi::{self as abi, FieldIdx, Size, VariantIdx};
1414
use rustc_middle::ty::Ty;
1515
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
1616
use rustc_middle::{bug, mir, span_bug, ty};
@@ -144,22 +144,22 @@ where
144144
/// always possible without allocating, so it can take `&self`. Also return the field's layout.
145145
/// This supports both struct and array fields, but not slices!
146146
///
147-
/// This also works for arrays, but then the `usize` index type is restricting.
148-
/// For indexing into arrays, use `mplace_index`.
147+
/// This also works for arrays, but then the `FieldIdx` index type is restricting.
148+
/// For indexing into arrays, use [`Self::project_index`].
149149
pub fn project_field<P: Projectable<'tcx, M::Provenance>>(
150150
&self,
151151
base: &P,
152-
field: usize,
152+
field: FieldIdx,
153153
) -> InterpResult<'tcx, P> {
154154
// Slices nominally have length 0, so they will panic somewhere in `fields.offset`.
155155
debug_assert!(
156156
!matches!(base.layout().ty.kind(), ty::Slice(..)),
157157
"`field` projection called on a slice -- call `index` projection instead"
158158
);
159-
let offset = base.layout().fields.offset(field);
159+
let offset = base.layout().fields.offset(field.as_usize());
160160
// Computing the layout does normalization, so we get a normalized type out of this
161161
// even if the field type is non-normalized (possible e.g. via associated types).
162-
let field_layout = base.layout().field(self, field);
162+
let field_layout = base.layout().field(self, field.as_usize());
163163

164164
// Offset may need adjustment for unsized fields.
165165
let (meta, offset) = if field_layout.is_unsized() {
@@ -244,7 +244,7 @@ where
244244
}
245245
_ => span_bug!(
246246
self.cur_span(),
247-
"`mplace_index` called on non-array type {:?}",
247+
"`project_index` called on non-array type {:?}",
248248
base.layout().ty
249249
),
250250
};
@@ -260,7 +260,7 @@ where
260260
) -> InterpResult<'tcx, (P, u64)> {
261261
assert!(base.layout().ty.ty_adt_def().unwrap().repr().simd());
262262
// SIMD types must be newtypes around arrays, so all we have to do is project to their only field.
263-
let array = self.project_field(base, 0)?;
263+
let array = self.project_field(base, FieldIdx::ZERO)?;
264264
let len = array.len(self)?;
265265
interp_ok((array, len))
266266
}
@@ -384,7 +384,7 @@ where
384384
UnwrapUnsafeBinder(target) => base.transmute(self.layout_of(target)?, self)?,
385385
// We don't want anything happening here, this is here as a dummy.
386386
Subtype(_) => base.transmute(base.layout(), self)?,
387-
Field(field, _) => self.project_field(base, field.index())?,
387+
Field(field, _) => self.project_field(base, field)?,
388388
Downcast(_, variant) => self.project_downcast(base, variant)?,
389389
Deref => self.deref_pointer(&base.to_op(self)?)?.into(),
390390
Index(local) => {

0 commit comments

Comments
 (0)