Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b541f1b
resolve: Disable an assert that no longer holds
petrochenkov Feb 16, 2026
e8b0e6b
add regression test
Kivooeo Feb 13, 2026
52b19f7
compiler: Don't mark `SingleUseConsts` MIR pass as "required for soun…
Enselic Feb 16, 2026
cbfa215
fix ICE in suggest_param_env_shadowing with incompatible args
TaKO8Ki Feb 17, 2026
e0d9d47
Fix invalid `mut T` suggestion for `&mut T` in missing lifetime error
reddevilmidzy Feb 17, 2026
6d4b1b3
Remove ShallowInitBox.
cjgillot Oct 15, 2025
28c8d71
Implement opt-bisect-limit for mir
sgasho Feb 11, 2026
f542160
Miri: recursive validity: also recurse into Boxes
RalfJung Feb 17, 2026
195b849
remove the explicit error for old `rental` versions
cyrgani Feb 17, 2026
83ef505
make `rustc_allow_const_fn_unstable` an actual `rustc_attrs` attribute
cyrgani Feb 17, 2026
626de86
carryless_mul: mention the base
RalfJung Feb 17, 2026
ad5108e
tail calls: fix copying non-scalar arguments to callee
RalfJung Dec 28, 2025
9ba2d45
Rollup merge of #150473 - RalfJung:interpret-tail-call, r=WaffleLapkin
jhpratt Feb 18, 2026
7f8c8e9
Rollup merge of #152729 - Enselic:single_use_consts-not-required, r=c…
jhpratt Feb 18, 2026
737ed6f
Rollup merge of #152753 - cyrgani:remove-hack, r=petrochenkov
jhpratt Feb 18, 2026
871b2f9
Rollup merge of #152758 - cjgillot:noinit-box, r=RalfJung
jhpratt Feb 18, 2026
03abac8
Rollup merge of #151530 - reddevilmidzy:e0106, r=fee1-dead
jhpratt Feb 18, 2026
4e90469
Rollup merge of #152474 - sgasho:opt-bisect-limit-mir, r=saethlin
jhpratt Feb 18, 2026
b5c3035
Rollup merge of #152711 - petrochenkov:globass, r=Kivooeo
jhpratt Feb 18, 2026
bc61bd2
Rollup merge of #152732 - Kivooeo:add-regression-test-1, r=TaKO8Ki
jhpratt Feb 18, 2026
155c527
Rollup merge of #152745 - TaKO8Ki:fix-ice-suggest-param-env-shadowing…
jhpratt Feb 18, 2026
06afc4a
Rollup merge of #152749 - cyrgani:rustc-allow-const, r=jdonszelmann
jhpratt Feb 18, 2026
7a54bb3
Rollup merge of #152756 - RalfJung:miri-recursive-box, r=Kivooeo
jhpratt Feb 18, 2026
3d83dbe
Rollup merge of #152770 - RalfJung:carryless-mul-base, r=scottmcm
jhpratt Feb 18, 2026
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
3 changes: 1 addition & 2 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1544,8 +1544,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
Rvalue::Use(operand)
| Rvalue::Repeat(operand, _)
| Rvalue::UnaryOp(_ /*un_op*/, operand)
| Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
| Rvalue::ShallowInitBox(operand, _ /*ty*/) => {
| Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/) => {
self.consume_operand(location, (operand, span), state)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,9 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
Rvalue::Use(operand)
| Rvalue::Repeat(operand, _)
| Rvalue::UnaryOp(_ /*un_op*/, operand)
| Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
| Rvalue::ShallowInitBox(operand, _ /*ty*/) => self.consume_operand(location, operand),
| Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/) => {
self.consume_operand(location, operand)
}

&Rvalue::Discriminant(place) => {
self.access_place(
Expand Down
12 changes: 0 additions & 12 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1004,17 +1004,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}

Rvalue::ShallowInitBox(_operand, ty) => {
let trait_ref =
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [*ty]);

self.prove_trait_ref(
trait_ref,
location.to_locations(),
ConstraintCategory::SizedBound,
);
}

Rvalue::Cast(cast_kind, op, ty) => {
match *cast_kind {
CastKind::PointerCoercion(
Expand Down Expand Up @@ -2231,7 +2220,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
| Rvalue::Ref(..)
| Rvalue::RawPtr(..)
| Rvalue::Cast(..)
| Rvalue::ShallowInitBox(..)
| Rvalue::BinaryOp(..)
| Rvalue::CopyForDeref(..)
| Rvalue::UnaryOp(..)
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
lval.write_cvalue_transmute(fx, operand);
}
Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"),
Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in codegen"),
}
}
StatementKind::StorageLive(_)
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
OperandRef { val: operand.val, layout, move_annotation: None }
}
mir::Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"),
mir::Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in codegen"),
}
}

Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,8 +646,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {

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

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

Rvalue::UnaryOp(op, operand) => {
let ty = operand.ty(self.body, self.tcx);
match op {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_const_eval/src/check_consts/qualifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,7 @@ where
Rvalue::Use(operand)
| Rvalue::Repeat(operand, _)
| Rvalue::UnaryOp(_, operand)
| Rvalue::Cast(_, operand, _)
| Rvalue::ShallowInitBox(operand, _) => in_operand::<Q, _>(cx, in_local, operand),
| Rvalue::Cast(_, operand, _) => in_operand::<Q, _>(cx, in_local, operand),

Rvalue::BinaryOp(_, box (lhs, rhs)) => {
in_operand::<Q, _>(cx, in_local, lhs) || in_operand::<Q, _>(cx, in_local, rhs)
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 @@ -192,7 +192,6 @@ where
}

mir::Rvalue::Cast(..)
| mir::Rvalue::ShallowInitBox(..)
| mir::Rvalue::Use(..)
| mir::Rvalue::CopyForDeref(..)
| mir::Rvalue::ThreadLocalRef(..)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
if self.tcx.is_lang_item(def_id, LangItem::PanicDisplay)
|| self.tcx.is_lang_item(def_id, LangItem::BeginPanic)
{
let args = self.copy_fn_args(args);
let args = Self::copy_fn_args(args);
// &str or &&str
assert!(args.len() == 1);

Expand Down
92 changes: 51 additions & 41 deletions compiler/rustc_const_eval/src/interpret/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use tracing::{info, instrument, trace};

use super::{
CtfeProvenance, FnVal, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, PlaceTy,
Projectable, Provenance, ReturnAction, ReturnContinuation, Scalar, StackPopInfo, interp_ok,
throw_ub, throw_ub_custom,
Projectable, Provenance, ReturnAction, ReturnContinuation, Scalar, interp_ok, throw_ub,
throw_ub_custom,
};
use crate::enter_trace_span;
use crate::interpret::EnteredTraceSpan;
Expand All @@ -43,25 +43,22 @@ impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> {
FnArg::InPlace(mplace) => &mplace.layout,
}
}
}

impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the
/// original memory occurs.
pub fn copy_fn_arg(&self, arg: &FnArg<'tcx, M::Provenance>) -> OpTy<'tcx, M::Provenance> {
match arg {
pub fn copy_fn_arg(&self) -> OpTy<'tcx, Prov> {
match self {
FnArg::Copy(op) => op.clone(),
FnArg::InPlace(mplace) => mplace.clone().into(),
}
}
}

impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Make a copy of the given fn_args. Any `InPlace` are degenerated to copies, no protection of the
/// original memory occurs.
pub fn copy_fn_args(
&self,
args: &[FnArg<'tcx, M::Provenance>],
) -> Vec<OpTy<'tcx, M::Provenance>> {
args.iter().map(|fn_arg| self.copy_fn_arg(fn_arg)).collect()
pub fn copy_fn_args(args: &[FnArg<'tcx, M::Provenance>]) -> Vec<OpTy<'tcx, M::Provenance>> {
args.iter().map(|fn_arg| fn_arg.copy_fn_arg()).collect()
}

/// Helper function for argument untupling.
Expand Down Expand Up @@ -319,7 +316,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// We work with a copy of the argument for now; if this is in-place argument passing, we
// will later protect the source it comes from. This means the callee cannot observe if we
// did in-place of by-copy argument passing, except for pointer equality tests.
let caller_arg_copy = self.copy_fn_arg(caller_arg);
let caller_arg_copy = caller_arg.copy_fn_arg();
if !already_live {
let local = callee_arg.as_local().unwrap();
let meta = caller_arg_copy.meta();
Expand Down Expand Up @@ -616,7 +613,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
if let Some(fallback) = M::call_intrinsic(
self,
instance,
&self.copy_fn_args(args),
&Self::copy_fn_args(args),
destination,
target,
unwind,
Expand Down Expand Up @@ -703,7 +700,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// An `InPlace` does nothing here, we keep the original receiver intact. We can't
// really pass the argument in-place anyway, and we are constructing a new
// `Immediate` receiver.
let mut receiver = self.copy_fn_arg(&args[0]);
let mut receiver = args[0].copy_fn_arg();
let receiver_place = loop {
match receiver.layout.ty.kind() {
ty::Ref(..) | ty::RawPtr(..) => {
Expand Down Expand Up @@ -824,41 +821,50 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
with_caller_location: bool,
) -> InterpResult<'tcx> {
trace!("init_fn_tail_call: {:#?}", fn_val);

// This is the "canonical" implementation of tails calls,
// a pop of the current stack frame, followed by a normal call
// which pushes a new stack frame, with the return address from
// the popped stack frame.
//
// Note that we are using `pop_stack_frame_raw` and not `return_from_current_stack_frame`,
// as the latter "executes" the goto to the return block, but we don't want to,
// Note that we cannot use `return_from_current_stack_frame`,
// as that "executes" the goto to the return block, but we don't want to,
// only the tail called function should return to the current return block.
let StackPopInfo { return_action, return_cont, return_place } =
self.pop_stack_frame_raw(false, |_this, _return_place| {
// This function's return value is just discarded, the tail-callee will fill in the return place instead.
interp_ok(())
})?;

assert_eq!(return_action, ReturnAction::Normal);

// Take the "stack pop cleanup" info, and use that to initiate the next call.
let ReturnContinuation::Goto { ret, unwind } = return_cont else {
bug!("can't tailcall as root");
// The arguments need to all be copied since the current stack frame will be removed
// before the callee even starts executing.
// FIXME(explicit_tail_calls,#144855): does this match what codegen does?
let args = args.iter().map(|fn_arg| FnArg::Copy(fn_arg.copy_fn_arg())).collect::<Vec<_>>();
// Remove the frame from the stack.
let frame = self.pop_stack_frame_raw()?;
// Remember where this frame would have returned to.
let ReturnContinuation::Goto { ret, unwind } = frame.return_cont() else {
bug!("can't tailcall as root of the stack");
};

// There's no return value to deal with! Instead, we forward the old return place
// to the new function.
// FIXME(explicit_tail_calls):
// we should check if both caller&callee can/n't unwind,
// see <https://github.com/rust-lang/rust/pull/113128#issuecomment-1614979803>

// Now push the new stack frame.
self.init_fn_call(
fn_val,
(caller_abi, caller_fn_abi),
args,
&*args,
with_caller_location,
&return_place,
frame.return_place(),
ret,
unwind,
)
)?;

// Finally, clear the local variables. Has to be done after pushing to support
// non-scalar arguments.
// FIXME(explicit_tail_calls,#144855): revisit this once codegen supports indirect
// arguments, to ensure the semantics are compatible.
let return_action = self.cleanup_stack_frame(/* unwinding */ false, frame)?;
assert_eq!(return_action, ReturnAction::Normal);

interp_ok(())
}

pub(super) fn init_drop_in_place_call(
Expand Down Expand Up @@ -953,14 +959,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// local's value out.
let return_op =
self.local_to_op(mir::RETURN_PLACE, None).expect("return place should always be live");
// Do the actual pop + copy.
let stack_pop_info = self.pop_stack_frame_raw(unwinding, |this, return_place| {
this.copy_op_allow_transmute(&return_op, return_place)?;
trace!("return value: {:?}", this.dump_place(return_place));
interp_ok(())
})?;

match stack_pop_info.return_action {
// Remove the frame from the stack.
let frame = self.pop_stack_frame_raw()?;
// Copy the return value and remember the return continuation.
if !unwinding {
self.copy_op_allow_transmute(&return_op, frame.return_place())?;
trace!("return value: {:?}", self.dump_place(frame.return_place()));
}
let return_cont = frame.return_cont();
// Finish popping the stack frame.
let return_action = self.cleanup_stack_frame(unwinding, frame)?;
// Jump to the next block.
match return_action {
ReturnAction::Normal => {}
ReturnAction::NoJump => {
// The hook already did everything.
Expand All @@ -978,7 +988,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// Normal return, figure out where to jump.
if unwinding {
// Follow the unwind edge.
match stack_pop_info.return_cont {
match return_cont {
ReturnContinuation::Goto { unwind, .. } => {
// This must be the very last thing that happens, since it can in fact push a new stack frame.
self.unwind_to_block(unwind)
Expand All @@ -989,7 +999,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
} else {
// Follow the normal return edge.
match stack_pop_info.return_cont {
match return_cont {
ReturnContinuation::Goto { ret, .. } => self.return_to_block(ret),
ReturnContinuation::Stop { .. } => {
assert!(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub use self::operand::{ImmTy, Immediate, OpTy};
pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable};
use self::place::{MemPlace, Place};
pub use self::projection::{OffsetMode, Projectable};
pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation, StackPopInfo};
pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation};
pub use self::util::EnteredTraceSpan;
pub(crate) use self::util::create_static_alloc;
pub use self::validity::{CtfeValidationMode, RangeSet, RefTracking};
Expand Down
Loading
Loading