Skip to content

Commit 6c0ef5a

Browse files
rustc_abi::Abi to IrForm in const_eval
1 parent fc90f6e commit 6c0ef5a

File tree

12 files changed

+68
-61
lines changed

12 files changed

+68
-61
lines changed

compiler/rustc_const_eval/src/const_eval/dummy_machine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
131131
interp_ok(match bin_op {
132132
Eq | Ne | Lt | Le | Gt | Ge => {
133133
// Types can differ, e.g. fn ptrs with different `for`.
134-
assert_eq!(left.layout.abi, right.layout.abi);
134+
assert_eq!(left.layout.ir_form, right.layout.ir_form);
135135
let size = ecx.pointer_size();
136136
// Just compare the bits. ScalarPairs are compared lexicographically.
137137
// We thus always compare pairs and simply fill scalars up with 0.

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::sync::atomic::Ordering::Relaxed;
22

33
use either::{Left, Right};
4+
use rustc_abi::{self as abi, IrForm};
45
use rustc_hir::def::DefKind;
56
use rustc_middle::bug;
67
use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo};
@@ -12,7 +13,6 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
1213
use rustc_middle::ty::{self, Ty, TyCtxt};
1314
use rustc_span::def_id::LocalDefId;
1415
use rustc_span::{DUMMY_SP, Span};
15-
use rustc_target::abi::{self, Abi};
1616
use tracing::{debug, instrument, trace};
1717

1818
use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
@@ -174,8 +174,8 @@ pub(super) fn op_to_const<'tcx>(
174174
// type (it's used throughout the compiler and having it work just on literals is not enough)
175175
// and we want it to be fast (i.e., don't go to an `Allocation` and reconstruct the `Scalar`
176176
// from its byte-serialized form).
177-
let force_as_immediate = match op.layout.abi {
178-
Abi::Scalar(abi::Scalar::Initialized { .. }) => true,
177+
let force_as_immediate = match op.layout.ir_form {
178+
IrForm::Scalar(abi::Scalar::Initialized { .. }) => true,
179179
// We don't *force* `ConstValue::Slice` for `ScalarPair`. This has the advantage that if the
180180
// input `op` is a place, then turning it into a `ConstValue` and back into a `OpTy` will
181181
// not have to generate any duplicate allocations (we preserve the original `AllocId` in

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
use rustc_abi::{IrForm, VariantIdx};
12
use rustc_data_structures::stack::ensure_sufficient_stack;
23
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
34
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
45
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
56
use rustc_middle::{bug, mir};
67
use rustc_span::DUMMY_SP;
7-
use rustc_target::abi::{Abi, VariantIdx};
88
use tracing::{debug, instrument, trace};
99

1010
use super::eval_queries::{mk_eval_cx_to_read_const_val, op_to_const};
@@ -117,7 +117,7 @@ fn const_to_valtree_inner<'tcx>(
117117
let val = ecx.read_immediate(place).unwrap();
118118
// We could allow wide raw pointers where both sides are integers in the future,
119119
// but for now we reject them.
120-
if matches!(val.layout.abi, Abi::ScalarPair(..)) {
120+
if matches!(val.layout.ir_form, IrForm::ScalarPair(..)) {
121121
return Err(ValTreeCreationError::NonSupportedType(ty));
122122
}
123123
let val = val.to_scalar();
@@ -311,7 +311,7 @@ pub fn valtree_to_const_value<'tcx>(
311311
// Fast path to avoid some allocations.
312312
return mir::ConstValue::ZeroSized;
313313
}
314-
if layout.abi.is_scalar()
314+
if layout.ir_form.is_scalar()
315315
&& (matches!(ty.kind(), ty::Tuple(_))
316316
|| matches!(ty.kind(), ty::Adt(def, _) if def.is_struct()))
317317
{

compiler/rustc_const_eval/src/interpret/call.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
172172
// must be compatible. So we just accept everything with Pointer ABI as compatible,
173173
// even if this will accept some code that is not stably guaranteed to work.
174174
// This also handles function pointers.
175-
let thin_pointer = |layout: TyAndLayout<'tcx>| match layout.abi {
176-
abi::Abi::Scalar(s) => match s.primitive() {
175+
let thin_pointer = |layout: TyAndLayout<'tcx>| match layout.ir_form {
176+
abi::IrForm::Scalar(s) => match s.primitive() {
177177
abi::Primitive::Pointer(addr_space) => Some(addr_space),
178178
_ => None,
179179
},

compiler/rustc_const_eval/src/interpret/cast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
274274
cast_ty: Ty<'tcx>,
275275
) -> InterpResult<'tcx, Scalar<M::Provenance>> {
276276
// Let's make sure v is sign-extended *if* it has a signed type.
277-
let signed = src_layout.abi.is_signed(); // Also asserts that abi is `Scalar`.
277+
let signed = src_layout.ir_form.is_signed(); // Also asserts that abi is `Scalar`.
278278

279279
let v = match src_layout.ty.kind() {
280280
Uint(_) | RawPtr(..) | FnPtr(..) => scalar.to_uint(src_layout.size)?,

compiler/rustc_const_eval/src/interpret/discriminant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
112112
// Read tag and sanity-check `tag_layout`.
113113
let tag_val = self.read_immediate(&self.project_field(op, tag_field)?)?;
114114
assert_eq!(tag_layout.size, tag_val.layout.size);
115-
assert_eq!(tag_layout.abi.is_signed(), tag_val.layout.abi.is_signed());
115+
assert_eq!(tag_layout.ir_form.is_signed(), tag_val.layout.ir_form.is_signed());
116116
trace!("tag value: {}", tag_val);
117117

118118
// Figure out which discriminant and variant this corresponds to.

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
563563
self.binary_op(mir_op.wrapping_to_overflowing().unwrap(), l, r)?.to_scalar_pair();
564564
interp_ok(if overflowed.to_bool()? {
565565
let size = l.layout.size;
566-
if l.layout.abi.is_signed() {
566+
if l.layout.ir_form.is_signed() {
567567
// For signed ints the saturated value depends on the sign of the first
568568
// term since the sign of the second term can be inferred from this and
569569
// the fact that the operation has overflowed (if either is 0 no

compiler/rustc_const_eval/src/interpret/operand.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::assert_matches::assert_matches;
55

66
use either::{Either, Left, Right};
77
use rustc_abi as abi;
8-
use rustc_abi::{Abi, HasDataLayout, Size};
8+
use rustc_abi::{HasDataLayout, IrForm, Size};
99
use rustc_hir::def::Namespace;
1010
use rustc_middle::mir::interpret::ScalarSizeMismatch;
1111
use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutOf, TyAndLayout};
@@ -114,9 +114,9 @@ impl<Prov: Provenance> Immediate<Prov> {
114114
}
115115

116116
/// Assert that this immediate is a valid value for the given ABI.
117-
pub fn assert_matches_abi(self, abi: Abi, msg: &str, cx: &impl HasDataLayout) {
117+
pub fn assert_matches_abi(self, abi: IrForm, msg: &str, cx: &impl HasDataLayout) {
118118
match (self, abi) {
119-
(Immediate::Scalar(scalar), Abi::Scalar(s)) => {
119+
(Immediate::Scalar(scalar), IrForm::Scalar(s)) => {
120120
assert_eq!(scalar.size(), s.size(cx), "{msg}: scalar value has wrong size");
121121
if !matches!(s.primitive(), abi::Primitive::Pointer(..)) {
122122
// This is not a pointer, it should not carry provenance.
@@ -126,7 +126,7 @@ impl<Prov: Provenance> Immediate<Prov> {
126126
);
127127
}
128128
}
129-
(Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => {
129+
(Immediate::ScalarPair(a_val, b_val), IrForm::ScalarPair(a, b)) => {
130130
assert_eq!(
131131
a_val.size(),
132132
a.size(cx),
@@ -244,15 +244,15 @@ impl<'tcx, Prov: Provenance> std::ops::Deref for ImmTy<'tcx, Prov> {
244244
impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
245245
#[inline]
246246
pub fn from_scalar(val: Scalar<Prov>, layout: TyAndLayout<'tcx>) -> Self {
247-
debug_assert!(layout.abi.is_scalar(), "`ImmTy::from_scalar` on non-scalar layout");
247+
debug_assert!(layout.ir_form.is_scalar(), "`ImmTy::from_scalar` on non-scalar layout");
248248
debug_assert_eq!(val.size(), layout.size);
249249
ImmTy { imm: val.into(), layout }
250250
}
251251

252252
#[inline]
253253
pub fn from_scalar_pair(a: Scalar<Prov>, b: Scalar<Prov>, layout: TyAndLayout<'tcx>) -> Self {
254254
debug_assert!(
255-
matches!(layout.abi, Abi::ScalarPair(..)),
255+
matches!(layout.ir_form, IrForm::ScalarPair(..)),
256256
"`ImmTy::from_scalar_pair` on non-scalar-pair layout"
257257
);
258258
let imm = Immediate::ScalarPair(a, b);
@@ -263,9 +263,9 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
263263
pub fn from_immediate(imm: Immediate<Prov>, layout: TyAndLayout<'tcx>) -> Self {
264264
// Without a `cx` we cannot call `assert_matches_abi`.
265265
debug_assert!(
266-
match (imm, layout.abi) {
267-
(Immediate::Scalar(..), Abi::Scalar(..)) => true,
268-
(Immediate::ScalarPair(..), Abi::ScalarPair(..)) => true,
266+
match (imm, layout.ir_form) {
267+
(Immediate::Scalar(..), IrForm::Scalar(..)) => true,
268+
(Immediate::ScalarPair(..), IrForm::ScalarPair(..)) => true,
269269
(Immediate::Uninit, _) if layout.is_sized() => true,
270270
_ => false,
271271
},
@@ -356,7 +356,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
356356
fn offset_(&self, offset: Size, layout: TyAndLayout<'tcx>, cx: &impl HasDataLayout) -> Self {
357357
// Verify that the input matches its type.
358358
if cfg!(debug_assertions) {
359-
self.assert_matches_abi(self.layout.abi, "invalid input to Immediate::offset", cx);
359+
self.assert_matches_abi(self.layout.ir_form, "invalid input to Immediate::offset", cx);
360360
}
361361
// `ImmTy` have already been checked to be in-bounds, so we can just check directly if this
362362
// remains in-bounds. This cannot actually be violated since projections are type-checked
@@ -370,19 +370,19 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
370370
);
371371
// This makes several assumptions about what layouts we will encounter; we match what
372372
// codegen does as good as we can (see `extract_field` in `rustc_codegen_ssa/src/mir/operand.rs`).
373-
let inner_val: Immediate<_> = match (**self, self.layout.abi) {
373+
let inner_val: Immediate<_> = match (**self, self.layout.ir_form) {
374374
// If the entire value is uninit, then so is the field (can happen in ConstProp).
375375
(Immediate::Uninit, _) => Immediate::Uninit,
376376
// If the field is uninhabited, we can forget the data (can happen in ConstProp).
377377
// `enum S { A(!), B, C }` is an example of an enum with Scalar layout that
378378
// has an `Uninhabited` variant, which means this case is possible.
379-
_ if layout.abi.is_uninhabited() => Immediate::Uninit,
379+
_ if layout.is_uninhabited() => Immediate::Uninit,
380380
// the field contains no information, can be left uninit
381381
// (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST)
382382
_ if layout.is_zst() => Immediate::Uninit,
383383
// some fieldless enum variants can have non-zero size but still `Aggregate` ABI... try
384384
// to detect those here and also give them no data
385-
_ if matches!(layout.abi, Abi::Aggregate { .. })
385+
_ if matches!(layout.ir_form, IrForm::Memory { .. })
386386
&& matches!(layout.variants, abi::Variants::Single { .. })
387387
&& matches!(&layout.fields, abi::FieldsShape::Arbitrary { offsets, .. } if offsets.len() == 0) =>
388388
{
@@ -394,7 +394,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
394394
**self
395395
}
396396
// extract fields from types with `ScalarPair` ABI
397-
(Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => {
397+
(Immediate::ScalarPair(a_val, b_val), IrForm::ScalarPair(a, b)) => {
398398
Immediate::from(if offset.bytes() == 0 {
399399
a_val
400400
} else {
@@ -411,7 +411,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
411411
),
412412
};
413413
// Ensure the new layout matches the new value.
414-
inner_val.assert_matches_abi(layout.abi, "invalid field type in Immediate::offset", cx);
414+
inner_val.assert_matches_abi(layout.ir_form, "invalid field type in Immediate::offset", cx);
415415

416416
ImmTy::from_immediate(inner_val, layout)
417417
}
@@ -567,8 +567,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
567567
// case where some of the bytes are initialized and others are not. So, we need an extra
568568
// check that walks over the type of `mplace` to make sure it is truly correct to treat this
569569
// like a `Scalar` (or `ScalarPair`).
570-
interp_ok(match mplace.layout.abi {
571-
Abi::Scalar(abi::Scalar::Initialized { value: s, .. }) => {
570+
interp_ok(match mplace.layout.ir_form {
571+
IrForm::Scalar(abi::Scalar::Initialized { value: s, .. }) => {
572572
let size = s.size(self);
573573
assert_eq!(size, mplace.layout.size, "abi::Scalar size does not match layout size");
574574
let scalar = alloc.read_scalar(
@@ -577,7 +577,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
577577
)?;
578578
Some(ImmTy::from_scalar(scalar, mplace.layout))
579579
}
580-
Abi::ScalarPair(
580+
IrForm::ScalarPair(
581581
abi::Scalar::Initialized { value: a, .. },
582582
abi::Scalar::Initialized { value: b, .. },
583583
) => {
@@ -637,9 +637,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
637637
op: &impl Projectable<'tcx, M::Provenance>,
638638
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
639639
if !matches!(
640-
op.layout().abi,
641-
Abi::Scalar(abi::Scalar::Initialized { .. })
642-
| Abi::ScalarPair(abi::Scalar::Initialized { .. }, abi::Scalar::Initialized { .. })
640+
op.layout().ir_form,
641+
IrForm::Scalar(abi::Scalar::Initialized { .. })
642+
| IrForm::ScalarPair(
643+
abi::Scalar::Initialized { .. },
644+
abi::Scalar::Initialized { .. }
645+
)
643646
) {
644647
span_bug!(self.cur_span(), "primitive read not possible for type: {}", op.layout().ty);
645648
}

compiler/rustc_const_eval/src/interpret/operator.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
114114
let l_bits = left.layout.size.bits();
115115
// Compute the equivalent shift modulo `size` that is in the range `0..size`. (This is
116116
// the one MIR operator that does *not* directly map to a single LLVM operation.)
117-
let (shift_amount, overflow) = if right.layout.abi.is_signed() {
117+
let (shift_amount, overflow) = if right.layout.ir_form.is_signed() {
118118
let shift_amount = r_signed();
119119
let rem = shift_amount.rem_euclid(l_bits.into());
120120
// `rem` is guaranteed positive, so the `unwrap` cannot fail
@@ -126,7 +126,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
126126
};
127127
let shift_amount = u32::try_from(shift_amount).unwrap(); // we brought this in the range `0..size` so this will always fit
128128
// Compute the shifted result.
129-
let result = if left.layout.abi.is_signed() {
129+
let result = if left.layout.ir_form.is_signed() {
130130
let l = l_signed();
131131
let result = match bin_op {
132132
Shl | ShlUnchecked => l.checked_shl(shift_amount).unwrap(),
@@ -147,7 +147,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
147147
if overflow && let Some(intrinsic) = throw_ub_on_overflow {
148148
throw_ub!(ShiftOverflow {
149149
intrinsic,
150-
shift_amount: if right.layout.abi.is_signed() {
150+
shift_amount: if right.layout.ir_form.is_signed() {
151151
Either::Right(r_signed())
152152
} else {
153153
Either::Left(r_unsigned())
@@ -171,7 +171,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
171171
let size = left.layout.size;
172172

173173
// Operations that need special treatment for signed integers
174-
if left.layout.abi.is_signed() {
174+
if left.layout.ir_form.is_signed() {
175175
let op: Option<fn(&i128, &i128) -> bool> = match bin_op {
176176
Lt => Some(i128::lt),
177177
Le => Some(i128::le),
@@ -250,7 +250,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
250250
BitXor => ImmTy::from_uint(l ^ r, left.layout),
251251

252252
_ => {
253-
assert!(!left.layout.abi.is_signed());
253+
assert!(!left.layout.ir_form.is_signed());
254254
let op: fn(u128, u128) -> (u128, bool) = match bin_op {
255255
Add | AddUnchecked | AddWithOverflow => u128::overflowing_add,
256256
Sub | SubUnchecked | SubWithOverflow => u128::overflowing_sub,
@@ -332,7 +332,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
332332
}
333333

334334
let offset_bytes = val.to_target_isize(self)?;
335-
if !right.layout.abi.is_signed() && offset_bytes < 0 {
335+
if !right.layout.ir_form.is_signed() && offset_bytes < 0 {
336336
// We were supposed to do an unsigned offset but the result is negative -- this
337337
// can only mean that the cast wrapped around.
338338
throw_ub!(PointerArithOverflow)

compiler/rustc_const_eval/src/interpret/place.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
use std::assert_matches::assert_matches;
66

77
use either::{Either, Left, Right};
8+
use rustc_abi::{Align, HasDataLayout, IrForm, Size};
89
use rustc_ast::Mutability;
910
use rustc_middle::ty::Ty;
1011
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
1112
use rustc_middle::{bug, mir, span_bug};
12-
use rustc_target::abi::{Abi, Align, HasDataLayout, Size};
1313
use tracing::{instrument, trace};
1414

1515
use super::{
@@ -659,7 +659,7 @@ where
659659
// Unfortunately this is too expensive to do in release builds.
660660
if cfg!(debug_assertions) {
661661
src.assert_matches_abi(
662-
local_layout.abi,
662+
local_layout.ir_form,
663663
"invalid immediate for given destination place",
664664
self,
665665
);
@@ -683,7 +683,11 @@ where
683683
) -> InterpResult<'tcx> {
684684
// We use the sizes from `value` below.
685685
// Ensure that matches the type of the place it is written to.
686-
value.assert_matches_abi(layout.abi, "invalid immediate for given destination place", self);
686+
value.assert_matches_abi(
687+
layout.ir_form,
688+
"invalid immediate for given destination place",
689+
self,
690+
);
687691
// Note that it is really important that the type here is the right one, and matches the
688692
// type things are read at. In case `value` is a `ScalarPair`, we don't do any magic here
689693
// to handle padding properly, which is only correct if we never look at this data with the
@@ -700,7 +704,7 @@ where
700704
alloc.write_scalar(alloc_range(Size::ZERO, scalar.size()), scalar)
701705
}
702706
Immediate::ScalarPair(a_val, b_val) => {
703-
let Abi::ScalarPair(a, b) = layout.abi else {
707+
let IrForm::ScalarPair(a, b) = layout.ir_form else {
704708
span_bug!(
705709
self.cur_span(),
706710
"write_immediate_to_mplace: invalid ScalarPair layout: {:#?}",

0 commit comments

Comments
 (0)