Skip to content

Commit c53698b

Browse files
authored
Rollup merge of #128697 - RalfJung:nullary-op, r=compiler-errors
interpret: move nullary-op evaluation into operator.rs We call it an operator, so we might as well treat it like one. :) Also use more consistent naming for the "evaluate intrinsic" functions. "emulate" is really the wrong term, this *is* a genuine implementation of the intrinsic semantics after all.
2 parents 77f57cb + 46896d6 commit c53698b

File tree

6 files changed

+49
-41
lines changed

6 files changed

+49
-41
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
458458
_unwind: mir::UnwindAction,
459459
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
460460
// Shared intrinsics.
461-
if ecx.emulate_intrinsic(instance, args, dest, target)? {
461+
if ecx.eval_intrinsic(instance, args, dest, target)? {
462462
return Ok(None);
463463
}
464464
let intrinsic_name = ecx.tcx.item_name(instance.def_id());

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
9797
/// Returns `true` if emulation happened.
9898
/// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
9999
/// intrinsic handling.
100-
pub fn emulate_intrinsic(
100+
pub fn eval_intrinsic(
101101
&mut self,
102102
instance: ty::Instance<'tcx>,
103103
args: &[OpTy<'tcx, M::Provenance>],
@@ -447,7 +447,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
447447
Ok(true)
448448
}
449449

450-
pub(super) fn emulate_nondiverging_intrinsic(
450+
pub(super) fn eval_nondiverging_intrinsic(
451451
&mut self,
452452
intrinsic: &NonDivergingIntrinsic<'tcx>,
453453
) -> InterpResult<'tcx> {

compiler/rustc_const_eval/src/interpret/operator.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use either::Either;
22
use rustc_apfloat::{Float, FloatConvert};
33
use rustc_middle::mir::interpret::{InterpResult, Scalar};
4+
use rustc_middle::mir::NullOp;
45
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
5-
use rustc_middle::ty::{self, FloatTy, ScalarInt};
6+
use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty};
67
use rustc_middle::{bug, mir, span_bug};
78
use rustc_span::symbol::sym;
89
use tracing::trace;
@@ -480,4 +481,38 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
480481
}
481482
}
482483
}
484+
485+
pub fn nullary_op(
486+
&self,
487+
null_op: NullOp<'tcx>,
488+
arg_ty: Ty<'tcx>,
489+
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
490+
use rustc_middle::mir::NullOp::*;
491+
492+
let layout = self.layout_of(arg_ty)?;
493+
let usize_layout = || self.layout_of(self.tcx.types.usize).unwrap();
494+
495+
Ok(match null_op {
496+
SizeOf => {
497+
if !layout.abi.is_sized() {
498+
span_bug!(self.cur_span(), "unsized type for `NullaryOp::SizeOf`");
499+
}
500+
let val = layout.size.bytes();
501+
ImmTy::from_uint(val, usize_layout())
502+
}
503+
AlignOf => {
504+
if !layout.abi.is_sized() {
505+
span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`");
506+
}
507+
let val = layout.align.abi.bytes();
508+
ImmTy::from_uint(val, usize_layout())
509+
}
510+
OffsetOf(fields) => {
511+
let val =
512+
self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes();
513+
ImmTy::from_uint(val, usize_layout())
514+
}
515+
UbChecks => ImmTy::from_bool(self.tcx.sess.ub_checks(), *self.tcx),
516+
})
517+
}
483518
}

compiler/rustc_const_eval/src/interpret/step.rs

+8-35
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
55
use either::Either;
66
use rustc_index::IndexSlice;
7-
use rustc_middle::ty::layout::LayoutOf;
8-
use rustc_middle::{bug, mir, span_bug};
7+
use rustc_middle::{bug, mir};
98
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
109
use tracing::{info, instrument, trace};
1110

@@ -94,7 +93,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
9493
M::retag_place_contents(self, *kind, &dest)?;
9594
}
9695

97-
Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
96+
Intrinsic(box intrinsic) => self.eval_nondiverging_intrinsic(intrinsic)?,
9897

9998
// Evaluate the place expression, without reading from it.
10099
PlaceMention(box place) => {
@@ -179,6 +178,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
179178
self.write_immediate(*result, &dest)?;
180179
}
181180

181+
NullaryOp(null_op, ty) => {
182+
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
183+
let val = self.nullary_op(null_op, ty)?;
184+
self.write_immediate(*val, &dest)?;
185+
}
186+
182187
Aggregate(box ref kind, ref operands) => {
183188
self.write_aggregate(kind, operands, &dest)?;
184189
}
@@ -230,38 +235,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
230235
self.write_immediate(*val, &dest)?;
231236
}
232237

233-
NullaryOp(ref null_op, ty) => {
234-
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
235-
let layout = self.layout_of(ty)?;
236-
if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op
237-
&& layout.is_unsized()
238-
{
239-
span_bug!(
240-
self.frame().current_span(),
241-
"{null_op:?} MIR operator called for unsized type {ty}",
242-
);
243-
}
244-
let val = match null_op {
245-
mir::NullOp::SizeOf => {
246-
let val = layout.size.bytes();
247-
Scalar::from_target_usize(val, self)
248-
}
249-
mir::NullOp::AlignOf => {
250-
let val = layout.align.abi.bytes();
251-
Scalar::from_target_usize(val, self)
252-
}
253-
mir::NullOp::OffsetOf(fields) => {
254-
let val = self
255-
.tcx
256-
.offset_of_subfield(self.param_env, layout, fields.iter())
257-
.bytes();
258-
Scalar::from_target_usize(val, self)
259-
}
260-
mir::NullOp::UbChecks => Scalar::from_bool(self.tcx.sess.ub_checks()),
261-
};
262-
self.write_scalar(val, &dest)?;
263-
}
264-
265238
ShallowInitBox(ref operand, _) => {
266239
let src = self.eval_operand(operand, None)?;
267240
let v = self.read_immediate(&src)?;

src/tools/miri/src/intrinsics/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
3333
let this = self.eval_context_mut();
3434

3535
// See if the core engine can handle this intrinsic.
36-
if this.emulate_intrinsic(instance, args, dest, ret)? {
36+
if this.eval_intrinsic(instance, args, dest, ret)? {
3737
return Ok(None);
3838
}
3939
let intrinsic_name = this.tcx.item_name(instance.def_id());

tests/ui/const-generics/generic_const_exprs/issue-80742.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:LL:CC: SizeOf MIR operator called for unsized type dyn Debug
1+
error: internal compiler error: compiler/rustc_const_eval/src/interpret/operator.rs:LL:CC: unsized type for `NullaryOp::SizeOf`
22
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
33

44
Box<dyn Any>

0 commit comments

Comments
 (0)