Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
{
// Just point to the function, to reduce the chance of overlapping spans.
let function_span = match func {
Operand::RuntimeChecks(_) => span,
Operand::Constant(c) => c.span,
Operand::Copy(place) | Operand::Move(place) => {
if let Some(l) = place.as_local() {
Expand Down Expand Up @@ -808,6 +809,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
{
// Just point to the function, to reduce the chance of overlapping spans.
let function_span = match func {
Operand::RuntimeChecks(_) => span,
Operand::Constant(c) => c.span,
Operand::Copy(place) | Operand::Move(place) => {
if let Some(l) = place.as_local() {
Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1559,10 +1559,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
self.consume_operand(location, (operand2, span), state);
}

Rvalue::NullaryOp(_op) => {
// nullary ops take no dynamic input; no borrowck effect.
}

Rvalue::Aggregate(aggregate_kind, operands) => {
// We need to report back the list of mutable upvars that were
// moved into the closure and subsequently used by the closure,
Expand Down Expand Up @@ -1699,7 +1695,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
_ => propagate_closure_used_mut_place(self, place),
}
}
Operand::Constant(..) => {}
Operand::Constant(..) | Operand::RuntimeChecks(_) => {}
}
}

Expand Down Expand Up @@ -1750,7 +1746,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
state,
);
}
Operand::Constant(_) => {}
Operand::Constant(_) | Operand::RuntimeChecks(_) => {}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
LocalMutationIsAllowed::Yes,
);
}
Operand::Constant(_) => {}
Operand::Constant(_) | Operand::RuntimeChecks(_) => {}
}
}

Expand Down Expand Up @@ -314,8 +314,6 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
self.consume_operand(location, operand2);
}

Rvalue::NullaryOp(_op) => {}

Rvalue::Aggregate(_, operands) => {
for operand in operands {
self.consume_operand(location, operand);
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
// element, so we require the `Copy` trait.
if len.try_to_target_usize(tcx).is_none_or(|len| len > 1) {
match operand {
Operand::Copy(..) | Operand::Constant(..) => {
Operand::Copy(..) | Operand::Constant(..) | Operand::RuntimeChecks(_) => {
// These are always okay: direct use of a const, or a value that can
// evidently be copied.
}
Expand All @@ -1046,8 +1046,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}

&Rvalue::NullaryOp(NullOp::RuntimeChecks(_)) => {}

Rvalue::ShallowInitBox(_operand, ty) => {
let trait_ref =
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [*ty]);
Expand Down Expand Up @@ -2201,7 +2199,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
| Rvalue::Cast(..)
| Rvalue::ShallowInitBox(..)
| Rvalue::BinaryOp(..)
| Rvalue::NullaryOp(..)
| Rvalue::CopyForDeref(..)
| Rvalue::UnaryOp(..)
| Rvalue::Discriminant(..)
Expand Down
21 changes: 8 additions & 13 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use rustc_ast::InlineAsmOptions;
use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_index::IndexVec;
use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{ScalarInt, TypeVisitableExt};
use rustc_session::config::OutputFilenames;
use rustc_span::Symbol;

Expand Down Expand Up @@ -853,17 +853,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
fx.bcx.ins().nop();
}
}
Rvalue::NullaryOp(ref null_op) => {
assert!(lval.layout().ty.is_sized(fx.tcx, fx.typing_env()));
let val = match null_op {
NullOp::RuntimeChecks(kind) => kind.value(fx.tcx.sess),
};
let val = CValue::by_val(
fx.bcx.ins().iconst(types::I8, i64::from(val)),
fx.layout_of(fx.tcx.types.bool),
);
lval.write_cvalue(fx, val);
}
Rvalue::Aggregate(ref kind, ref operands)
if matches!(**kind, AggregateKind::RawPtr(..)) =>
{
Expand Down Expand Up @@ -1050,6 +1039,12 @@ pub(crate) fn codegen_operand<'tcx>(
cplace.to_cvalue(fx)
}
Operand::Constant(const_) => crate::constant::codegen_constant_operand(fx, const_),
Operand::RuntimeChecks(checks) => {
let int = checks.value(fx.tcx.sess);
let int = ScalarInt::try_from_uint(int, Size::from_bits(1)).unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ScalarInt implements From<bool> -- please use that instead of effectively inlining it. (Also, int is a confusing name for a boolean variable.)

let layout = fx.layout_of(fx.tcx.types.bool);
return CValue::const_val(fx, layout, int);
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,10 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
operand: &Operand<'tcx>,
) -> Option<ScalarInt> {
match operand {
Operand::RuntimeChecks(checks) => {
let int = checks.value(fx.tcx.sess);
ScalarInt::try_from_uint(int, Size::from_bits(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another place where the From<bool> impl could be used. (Also, int is a confusing name for a boolean variable.)

}
Operand::Constant(const_) => eval_mir_constant(fx, const_).0.try_to_scalar_int(),
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
// inside a temporary before being passed to the intrinsic requiring the const argument.
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_codegen_ssa/src/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
OperandRef { move_annotation, ..self.codegen_consume(bx, place.as_ref()) }
}

mir::Operand::RuntimeChecks(checks) => {
let layout = bx.layout_of(bx.tcx().types.bool);
let BackendRepr::Scalar(scalar) = layout.backend_repr else {
bug!("from_const: invalid ByVal layout: {:#?}", layout);
};
let x = Scalar::from_bool(checks.value(bx.tcx().sess));
let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout));
let val = OperandValue::Immediate(llval);
OperandRef { val, layout, move_annotation: None }
}

mir::Operand::Constant(ref constant) => {
let constant_ty = self.monomorphize(constant.ty());
// Most SIMD vector constants should be passed as immediates.
Expand Down
15 changes: 0 additions & 15 deletions compiler/rustc_codegen_ssa/src/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,21 +619,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}

mir::Rvalue::NullaryOp(ref null_op) => {
let val = match null_op {
mir::NullOp::RuntimeChecks(kind) => {
let val = kind.value(bx.tcx().sess);
bx.cx().const_bool(val)
}
};
let tcx = self.cx.tcx();
OperandRef {
val: OperandValue::Immediate(val),
layout: self.cx.layout_of(null_op.ty(tcx)),
move_annotation: None,
}
}

mir::Rvalue::ThreadLocalRef(def_id) => {
assert!(bx.cx().tcx().is_static(def_id));
let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id, bx.typing_env()));
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {

Rvalue::Cast(_, _, _) => {}

Rvalue::NullaryOp(NullOp::RuntimeChecks(_)) => {}
Rvalue::ShallowInitBox(_, _) => {}

Rvalue::UnaryOp(op, operand) => {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_const_eval/src/check_consts/qualifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,7 @@ where
F: FnMut(Local) -> bool,
{
match rvalue {
Rvalue::ThreadLocalRef(_) | Rvalue::NullaryOp(..) => {
Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx))
}
Rvalue::ThreadLocalRef(_) => Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)),

Rvalue::Discriminant(place) => in_place::<Q, _>(cx, in_local, place.as_ref()),

Expand Down Expand Up @@ -340,6 +338,7 @@ where
Operand::Copy(place) | Operand::Move(place) => {
return in_place::<Q, _>(cx, in_local, place.as_ref());
}
Operand::RuntimeChecks(_) => return Q::in_any_value_of_ty(cx, cx.tcx.types.bool),

Operand::Constant(c) => c,
};
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_const_eval/src/check_consts/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ where
| mir::Rvalue::ThreadLocalRef(..)
| mir::Rvalue::Repeat(..)
| mir::Rvalue::BinaryOp(..)
| mir::Rvalue::NullaryOp(..)
| mir::Rvalue::UnaryOp(..)
| mir::Rvalue::Discriminant(..)
| mir::Rvalue::Aggregate(..)
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_const_eval/src/const_eval/dummy_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
unimplemented!()
}

#[inline(always)]
fn runtime_checks(_ecx: &InterpCx<'tcx, Self>, r: RuntimeChecks) -> InterpResult<'tcx, bool> {
// Runtime checks have different value depending on the crate they are codegenned in.
// Verify we aren't trying to evaluate them in mir-optimizations.
panic!("compiletime machine evaluated {r:?}")
}

fn binary_ptr_op(
ecx: &InterpCx<'tcx, Self>,
bin_op: BinOp,
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,16 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
Err(ConstEvalErrKind::AssertFailure(err)).into()
}

#[inline(always)]
fn runtime_checks(
_ecx: &InterpCx<'tcx, Self>,
_r: mir::RuntimeChecks,
) -> InterpResult<'tcx, bool> {
// We can't look at `tcx.sess` here as that can differ across crates, which can lead to
// unsound differences in evaluating the same constant at different instantiation sites.
interp_ok(true)
}

fn binary_ptr_op(
_ecx: &InterpCx<'tcx, Self>,
_bin_op: mir::BinOp,
Expand Down
12 changes: 1 addition & 11 deletions compiler/rustc_const_eval/src/interpret/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ pub trait Machine<'tcx>: Sized {
interp_ok(())
}

/// Determines the result of a `NullaryOp::RuntimeChecks` invocation.
/// Determines the result of a `Operand::RuntimeChecks` invocation.
fn runtime_checks(
_ecx: &InterpCx<'tcx, Self>,
r: mir::RuntimeChecks,
Expand Down Expand Up @@ -680,16 +680,6 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
true
}

#[inline(always)]
fn runtime_checks(
_ecx: &InterpCx<$tcx, Self>,
_r: mir::RuntimeChecks,
) -> InterpResult<$tcx, bool> {
// We can't look at `tcx.sess` here as that can differ across crates, which can lead to
// unsound differences in evaluating the same constant at different instantiation sites.
interp_ok(true)
}

#[inline(always)]
fn adjust_global_allocation<'b>(
_ecx: &InterpCx<$tcx, Self>,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// FIXME: do some more logic on `move` to invalidate the old location
&Copy(place) | &Move(place) => self.eval_place_to_op(place, layout)?,

&RuntimeChecks(checks) => {
let val = M::runtime_checks(self, checks)?;
ImmTy::from_bool(val, self.tcx()).into()
}

Constant(constant) => {
let c = self.instantiate_from_current_frame_and_normalize_erasing_regions(
constant.const_,
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_const_eval/src/interpret/operator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use either::Either;
use rustc_abi::Size;
use rustc_apfloat::{Float, FloatConvert};
use rustc_middle::mir::NullOp;
use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, FloatTy, ScalarInt};
Expand Down Expand Up @@ -505,11 +504,4 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
}
}

pub fn nullary_op(&self, null_op: NullOp) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
use rustc_middle::mir::NullOp::*;
interp_ok(match null_op {
RuntimeChecks(r) => ImmTy::from_bool(M::runtime_checks(self, r)?, *self.tcx),
})
}
}
7 changes: 1 addition & 6 deletions compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_immediate(*result, &dest)?;
}

NullaryOp(null_op) => {
let val = self.nullary_op(null_op)?;
self.write_immediate(*val, &dest)?;
}

Aggregate(box ref kind, ref operands) => {
self.write_aggregate(kind, operands, &dest)?;
}
Expand Down Expand Up @@ -392,7 +387,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
move_definitely_disjoint: bool,
) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> {
interp_ok(match op {
mir::Operand::Copy(_) | mir::Operand::Constant(_) => {
mir::Operand::Copy(_) | mir::Operand::Constant(_) | mir::Operand::RuntimeChecks(_) => {
// Make a regular copy.
let op = self.eval_operand(op, None)?;
FnArg::Copy(op)
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,10 @@ impl<'tcx> Body<'tcx> {
let bits = eval_mono_const(constant)?;
return Some((bits, targets));
}
Operand::RuntimeChecks(check) => {
let bits = check.value(tcx.sess) as u128;
return Some((bits, targets));
}
Operand::Move(place) | Operand::Copy(place) => place,
};

Expand Down Expand Up @@ -649,9 +653,6 @@ impl<'tcx> Body<'tcx> {
}

match rvalue {
Rvalue::NullaryOp(NullOp::RuntimeChecks(kind)) => {
Some((kind.value(tcx.sess) as u128, targets))
}
Rvalue::Use(Operand::Constant(constant)) => {
let bits = eval_mono_const(constant)?;
Some((bits, targets))
Expand Down
10 changes: 1 addition & 9 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1097,15 +1097,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
BinaryOp(ref op, box (ref a, ref b)) => write!(fmt, "{op:?}({a:?}, {b:?})"),
UnaryOp(ref op, ref a) => write!(fmt, "{op:?}({a:?})"),
Discriminant(ref place) => write!(fmt, "discriminant({place:?})"),
NullaryOp(ref op) => match op {
NullOp::RuntimeChecks(RuntimeChecks::UbChecks) => write!(fmt, "UbChecks()"),
NullOp::RuntimeChecks(RuntimeChecks::ContractChecks) => {
write!(fmt, "ContractChecks()")
}
NullOp::RuntimeChecks(RuntimeChecks::OverflowChecks) => {
write!(fmt, "OverflowChecks()")
}
},
ThreadLocalRef(did) => ty::tls::with(|tcx| {
let muta = tcx.static_mutability(did).unwrap().prefix_str();
write!(fmt, "&/*tls*/ {}{}", muta, tcx.def_path_str(did))
Expand Down Expand Up @@ -1264,6 +1255,7 @@ impl<'tcx> Debug for Operand<'tcx> {
Constant(ref a) => write!(fmt, "{a:?}"),
Copy(ref place) => write!(fmt, "copy {place:?}"),
Move(ref place) => write!(fmt, "move {place:?}"),
RuntimeChecks(checks) => write!(fmt, "{checks:?}"),
}
}
}
Expand Down
Loading
Loading