Remove ShallowInitBox.

This commit is contained in:
Camille Gillot 2025-10-15 23:08:15 +00:00
parent 1210e9fa3e
commit 6d4b1b38e7
27 changed files with 8 additions and 173 deletions

View file

@ -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)
}

View file

@ -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(

View file

@ -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(
@ -2231,7 +2220,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
| Rvalue::Ref(..)
| Rvalue::RawPtr(..)
| Rvalue::Cast(..)
| Rvalue::ShallowInitBox(..)
| Rvalue::BinaryOp(..)
| Rvalue::CopyForDeref(..)
| Rvalue::UnaryOp(..)

View file

@ -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(_)

View file

@ -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"),
}
}

View file

@ -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 {

View file

@ -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)

View file

@ -192,7 +192,6 @@ where
}
mir::Rvalue::Cast(..)
| mir::Rvalue::ShallowInitBox(..)
| mir::Rvalue::Use(..)
| mir::Rvalue::CopyForDeref(..)
| mir::Rvalue::ThreadLocalRef(..)

View file

@ -249,12 +249,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_immediate(*val, &dest)?;
}
ShallowInitBox(ref operand, _) => {
let src = self.eval_operand(operand, None)?;
let v = self.read_immediate(&src)?;
self.write_immediate(*v, &dest)?;
}
Cast(cast_kind, ref operand, cast_ty) => {
let src = self.eval_operand(operand, None)?;
let cast_ty =

View file

@ -1237,10 +1237,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
}
}
ShallowInitBox(ref place, ref ty) => {
with_no_trimmed_paths!(write!(fmt, "ShallowInitBox({place:?}, {ty})"))
}
WrapUnsafeBinder(ref op, ty) => {
with_no_trimmed_paths!(write!(fmt, "wrap_binder!({op:?}; {ty})"))
}

View file

@ -747,11 +747,6 @@ impl<'tcx> ConstOperand<'tcx> {
///////////////////////////////////////////////////////////////////////////
// Rvalues
pub enum RvalueInitializationState {
Shallow,
Deep,
}
impl<'tcx> Rvalue<'tcx> {
/// Returns true if rvalue can be safely removed when the result is unused.
#[inline]
@ -786,7 +781,6 @@ impl<'tcx> Rvalue<'tcx> {
| Rvalue::UnaryOp(_, _)
| Rvalue::Discriminant(_)
| Rvalue::Aggregate(_, _)
| Rvalue::ShallowInitBox(_, _)
| Rvalue::WrapUnsafeBinder(_, _) => true,
}
}
@ -833,21 +827,10 @@ impl<'tcx> Rvalue<'tcx> {
}
AggregateKind::RawPtr(ty, mutability) => Ty::new_ptr(tcx, ty, mutability),
},
Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),
Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty,
Rvalue::WrapUnsafeBinder(_, ty) => ty,
}
}
#[inline]
/// Returns `true` if this rvalue is deeply initialized (most rvalues) or
/// whether its only shallowly initialized (`Rvalue::Box`).
pub fn initialization_state(&self) -> RvalueInitializationState {
match *self {
Rvalue::ShallowInitBox(_, _) => RvalueInitializationState::Shallow,
_ => RvalueInitializationState::Deep,
}
}
}
impl BorrowKind {

View file

@ -1458,13 +1458,6 @@ pub enum Rvalue<'tcx> {
/// coroutine lowering, `Coroutine` aggregate kinds are disallowed too.
Aggregate(Box<AggregateKind<'tcx>>, IndexVec<FieldIdx, Operand<'tcx>>),
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
///
/// This is different from a normal transmute because dataflow analysis will treat the box as
/// initialized but its content as uninitialized. Like other pointer casts, this in general
/// affects alias analysis.
ShallowInitBox(Operand<'tcx>, Ty<'tcx>),
/// A CopyForDeref is equivalent to a read from a place at the
/// codegen level, but is treated specially by drop elaboration. When such a read happens, it
/// is guaranteed (via nature of the mir_opt `Derefer` in rustc_mir_transform/src/deref_separator)

View file

@ -810,11 +810,6 @@ macro_rules! make_mir_visitor {
}
}
Rvalue::ShallowInitBox(operand, ty) => {
self.visit_operand(operand, location);
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
}
Rvalue::WrapUnsafeBinder(op, ty) => {
self.visit_operand(op, location);
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));

View file

@ -86,7 +86,6 @@ where
Rvalue::Cast(..)
| Rvalue::Ref(_, BorrowKind::Fake(_), _)
| Rvalue::ShallowInitBox(..)
| Rvalue::Use(..)
| Rvalue::ThreadLocalRef(..)
| Rvalue::Repeat(..)

View file

@ -391,15 +391,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
}
StatementKind::Assign(box (place, rval)) => {
self.create_move_path(*place);
if let RvalueInitializationState::Shallow = rval.initialization_state() {
// Box starts out uninitialized - need to create a separate
// move-path for the interior so it will be separate from
// the exterior.
self.create_move_path(self.tcx.mk_place_deref(*place));
self.gather_init(place.as_ref(), InitKind::Shallow);
} else {
self.gather_init(place.as_ref(), InitKind::Deep);
}
self.gather_init(place.as_ref(), InitKind::Deep);
self.gather_rvalue(rval);
}
StatementKind::FakeRead(box (_, place)) => {
@ -435,7 +427,6 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
Rvalue::Use(ref operand)
| Rvalue::Repeat(ref operand, _)
| Rvalue::Cast(_, ref operand, _)
| Rvalue::ShallowInitBox(ref operand, _)
| Rvalue::UnaryOp(_, ref operand)
| Rvalue::WrapUnsafeBinder(ref operand, _) => self.gather_operand(operand),
Rvalue::BinaryOp(ref _binop, box (ref lhs, ref rhs)) => {

View file

@ -467,7 +467,6 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
Rvalue::Discriminant(place) => state.get_discr(place.as_ref(), &self.map),
Rvalue::Use(operand) => return self.handle_operand(operand, state),
Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in runtime MIR"),
Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in runtime MIR"),
Rvalue::Ref(..) | Rvalue::RawPtr(..) => {
// We don't track such places.
return ValueOrPlace::TOP;

View file

@ -1,12 +1,8 @@
//! This pass transforms derefs of Box into a deref of the pointer inside Box.
//!
//! Box is not actually a pointer so it is incorrect to dereference it directly.
//!
//! `ShallowInitBox` being a device for drop elaboration to understand deferred assignment to box
//! contents, we do not need this any more on runtime MIR.
use rustc_abi::{FieldIdx, VariantIdx};
use rustc_index::{IndexVec, indexvec};
use rustc_abi::FieldIdx;
use rustc_middle::mir::visit::MutVisitor;
use rustc_middle::mir::*;
use rustc_middle::span_bug;
@ -89,68 +85,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'a, 'tcx> {
self.super_place(place, context, location);
}
fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, location: Location) {
self.super_statement(stmt, location);
let tcx = self.tcx;
let source_info = stmt.source_info;
if let StatementKind::Assign(box (_, ref mut rvalue)) = stmt.kind
&& let Rvalue::ShallowInitBox(ref mut mutptr_to_u8, pointee) = *rvalue
&& let ty::Adt(box_adt, box_args) = Ty::new_box(tcx, pointee).kind()
{
let args = tcx.mk_args(&[pointee.into()]);
let (unique_ty, nonnull_ty, ptr_ty) =
build_ptr_tys(tcx, pointee, self.unique_def, self.nonnull_def);
let adt_kind = |def: ty::AdtDef<'tcx>, args| {
Box::new(AggregateKind::Adt(def.did(), VariantIdx::ZERO, args, None, None))
};
let zst = |ty| {
Operand::Constant(Box::new(ConstOperand {
span: source_info.span,
user_ty: None,
const_: Const::zero_sized(ty),
}))
};
let constptr = self.patch.new_temp(ptr_ty, source_info.span);
self.patch.add_assign(
location,
constptr.into(),
Rvalue::Cast(CastKind::Transmute, mutptr_to_u8.clone(), ptr_ty),
);
let nonnull = self.patch.new_temp(nonnull_ty, source_info.span);
self.patch.add_assign(
location,
nonnull.into(),
Rvalue::Aggregate(
adt_kind(self.nonnull_def, args),
indexvec![Operand::Move(constptr.into())],
),
);
let unique = self.patch.new_temp(unique_ty, source_info.span);
let phantomdata_ty =
self.unique_def.non_enum_variant().fields[FieldIdx::ONE].ty(tcx, args);
self.patch.add_assign(
location,
unique.into(),
Rvalue::Aggregate(
adt_kind(self.unique_def, args),
indexvec![Operand::Move(nonnull.into()), zst(phantomdata_ty)],
),
);
let global_alloc_ty =
box_adt.non_enum_variant().fields[FieldIdx::ONE].ty(tcx, box_args);
*rvalue = Rvalue::Aggregate(
adt_kind(*box_adt, box_args),
indexvec![Operand::Move(unique.into()), zst(global_alloc_ty)],
);
}
}
}
pub(super) struct ElaborateBoxDerefs;

View file

@ -1069,7 +1069,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
// Unsupported values.
Rvalue::ThreadLocalRef(..) => return None,
Rvalue::CopyForDeref(_) | Rvalue::ShallowInitBox(..) => {
Rvalue::CopyForDeref(_) => {
bug!("forbidden in runtime MIR: {rvalue:?}")
}
};

View file

@ -443,7 +443,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
| Rvalue::CopyForDeref(..)
| Rvalue::Repeat(..)
| Rvalue::Cast(..)
| Rvalue::ShallowInitBox(..)
| Rvalue::Discriminant(..)
| Rvalue::WrapUnsafeBinder(..) => {}
}
@ -605,8 +604,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
Ref(..) | RawPtr(..) => return None,
ShallowInitBox(..) => return None,
Cast(ref kind, ref value, to) => match kind {
CastKind::IntToInt | CastKind::IntToFloat => {
let value = self.eval_operand(value)?;

View file

@ -85,7 +85,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
| Rvalue::Repeat(..)
| Rvalue::Aggregate(..)
| Rvalue::Cast(..)
| Rvalue::ShallowInitBox(..)
| Rvalue::WrapUnsafeBinder(..) => true,
Rvalue::ThreadLocalRef(..)
| Rvalue::UnaryOp(..)

View file

@ -449,8 +449,6 @@ impl<'tcx> Validator<'_, 'tcx> {
self.validate_operand(operand)?;
}
Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable),
Rvalue::UnaryOp(op, operand) => {
match op {
// These operations can never fail.

View file

@ -1259,14 +1259,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
}
Rvalue::ShallowInitBox(operand, _) => {
if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(location, format!("ShallowInitBox after ElaborateBoxDerefs"))
}
let a = operand.ty(&self.body.local_decls, self.tcx);
check_kinds!(a, "Cannot shallow init type {:?}", ty::RawPtr(..));
}
Rvalue::Cast(kind, operand, target_type) => {
let op_ty = operand.ty(self.body, self.tcx);
match kind {

View file

@ -567,13 +567,6 @@ pub enum Rvalue {
/// [#74836]: https://github.com/rust-lang/rust/issues/74836
Repeat(Operand, TyConst),
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
///
/// This is different from a normal transmute because dataflow analysis will treat the box as
/// initialized but its content as uninitialized. Like other pointer casts, this in general
/// affects alias analysis.
ShallowInitBox(Operand, Ty),
/// Creates a pointer/reference to the given thread local.
///
/// The yielded type is a `*mut T` if the static is mutable, otherwise if the static is extern a
@ -651,7 +644,6 @@ impl Rvalue {
}
AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)),
},
Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)),
Rvalue::CopyForDeref(place) => place.ty(locals),
}
}

View file

@ -383,7 +383,6 @@ fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
Rvalue::Repeat(op, cnst) => {
write!(writer, "[{}; {}]", pretty_operand(op), pretty_ty_const(cnst))
}
Rvalue::ShallowInitBox(_, _) => Ok(()),
Rvalue::ThreadLocalRef(item) => {
write!(writer, "thread_local_ref{item:?}")
}

View file

@ -277,10 +277,6 @@ macro_rules! make_mir_visitor {
self.visit_operand(op, location);
self.visit_ty_const(constant, location);
}
Rvalue::ShallowInitBox(op, ty) => {
self.visit_ty(ty, location);
self.visit_operand(op, location)
}
Rvalue::ThreadLocalRef(_) => {}
Rvalue::UnaryOp(_, op) | Rvalue::Use(op) => {
self.visit_operand(op, location);

View file

@ -240,9 +240,6 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
let operands = operands.iter().map(|op| op.stable(tables, cx)).collect();
crate::mir::Rvalue::Aggregate(agg_kind.stable(tables, cx), operands)
}
ShallowInitBox(op, ty) => {
crate::mir::Rvalue::ShallowInitBox(op.stable(tables, cx), ty.stable(tables, cx))
}
CopyForDeref(place) => crate::mir::Rvalue::CopyForDeref(place.stable(tables, cx)),
WrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
}