Remove StatementKind::Deinit.

This commit is contained in:
Camille Gillot 2025-10-10 01:48:09 +00:00
parent 0b278a5394
commit b7c2b3dc80
43 changed files with 14 additions and 109 deletions

View file

@ -577,7 +577,6 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
mir::StatementKind::FakeRead(..)
| mir::StatementKind::SetDiscriminant { .. }
| mir::StatementKind::Deinit(..)
| mir::StatementKind::StorageLive(..)
| mir::StatementKind::Retag { .. }
| mir::StatementKind::PlaceMention(..)

View file

@ -80,7 +80,7 @@ pub(crate) fn categorize(context: PlaceContext) -> Option<DefUse> {
// Backwards incompatible drop hint is not a use, just a marker for linting.
PlaceContext::NonUse(NonUseContext::BackwardIncompatibleDropHint) => None,
PlaceContext::MutatingUse(MutatingUseContext::Deinit | MutatingUseContext::SetDiscriminant) => {
PlaceContext::MutatingUse(MutatingUseContext::SetDiscriminant) => {
bug!("These statements are not allowed in this MIR phase")
}
}

View file

@ -857,7 +857,6 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a,
}
StatementKind::Nop
| StatementKind::Retag { .. }
| StatementKind::Deinit(..)
| StatementKind::SetDiscriminant { .. } => {
bug!("Statement not allowed in this MIR phase")
}

View file

@ -84,7 +84,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
StatementKind::ConstEvalCounter
| StatementKind::Nop
| StatementKind::Retag { .. }
| StatementKind::Deinit(..)
| StatementKind::BackwardIncompatibleDropHint { .. }
| StatementKind::SetDiscriminant { .. } => {
bug!("Statement not allowed in this MIR phase")

View file

@ -748,7 +748,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
| StatementKind::BackwardIncompatibleDropHint { .. }
| StatementKind::Nop => {}
StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(..))
| StatementKind::Deinit(..)
| StatementKind::SetDiscriminant { .. } => {
bug!("Statement not allowed in this MIR phase")
}

View file

@ -932,7 +932,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
}
StatementKind::StorageLive(_)
| StatementKind::StorageDead(_)
| StatementKind::Deinit(_)
| StatementKind::ConstEvalCounter
| StatementKind::Nop
| StatementKind::FakeRead(..)

View file

@ -597,7 +597,6 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
StatementKind::Assign(_)
| StatementKind::FakeRead(_)
| StatementKind::SetDiscriminant { .. }
| StatementKind::Deinit(_)
| StatementKind::StorageLive(_)
| StatementKind::StorageDead(_)
| StatementKind::Retag(_, _)

View file

@ -229,7 +229,6 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer
PlaceContext::MutatingUse(
MutatingUseContext::Store
| MutatingUseContext::Deinit
| MutatingUseContext::SetDiscriminant
| MutatingUseContext::AsmOutput
| MutatingUseContext::Borrow

View file

@ -50,11 +50,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::StatementKind::SetDiscriminant { box ref place, variant_index } => {
self.codegen_place(bx, place.as_ref()).codegen_set_discr(bx, variant_index);
}
mir::StatementKind::Deinit(..) => {
// For now, don't codegen this to anything. In the future it may be worth
// experimenting with what kind of information we can emit to LLVM without hurting
// perf here
}
mir::StatementKind::StorageLive(local) => {
if let LocalRef::Place(cg_place) = self.locals[local] {
cg_place.storage_live(bx);

View file

@ -732,7 +732,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
match statement.kind {
StatementKind::Assign(..)
| StatementKind::SetDiscriminant { .. }
| StatementKind::Deinit(..)
| StatementKind::FakeRead(..)
| StatementKind::StorageLive(_)
| StatementKind::StorageDead(_)

View file

@ -98,11 +98,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_discriminant(*variant_index, &dest)?;
}
Deinit(place) => {
let dest = self.eval_place(**place)?;
self.write_uninit(&dest)?;
}
// Mark locals as alive
StorageLive(local) => {
self.storage_live(*local)?;

View file

@ -818,7 +818,6 @@ impl Debug for Statement<'_> {
SetDiscriminant { ref place, variant_index } => {
write!(fmt, "discriminant({place:?}) = {variant_index:?}")
}
Deinit(ref place) => write!(fmt, "Deinit({place:?})"),
PlaceMention(ref place) => {
write!(fmt, "PlaceMention({place:?})")
}

View file

@ -50,7 +50,6 @@ impl<'tcx> StatementKind<'tcx> {
StatementKind::Assign(..) => "Assign",
StatementKind::FakeRead(..) => "FakeRead",
StatementKind::SetDiscriminant { .. } => "SetDiscriminant",
StatementKind::Deinit(..) => "Deinit",
StatementKind::StorageLive(..) => "StorageLive",
StatementKind::StorageDead(..) => "StorageDead",
StatementKind::Retag(..) => "Retag",

View file

@ -135,7 +135,6 @@ pub enum RuntimePhase {
/// And the following variants are allowed:
/// * [`StatementKind::Retag`]
/// * [`StatementKind::SetDiscriminant`]
/// * [`StatementKind::Deinit`]
///
/// Furthermore, `Copy` operands are allowed for non-`Copy` types.
Initial = 0,
@ -362,11 +361,6 @@ pub enum StatementKind<'tcx> {
/// the type.
SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
/// Deinitializes the place.
///
/// This writes `uninit` bytes to the entire place.
Deinit(Box<Place<'tcx>>),
/// `StorageLive` and `StorageDead` statements mark the live range of a local.
///
/// At any point during the execution of a function, each local is either allocated or

View file

@ -445,13 +445,6 @@ macro_rules! make_mir_visitor {
location
);
}
StatementKind::Deinit(place) => {
self.visit_place(
place,
PlaceContext::MutatingUse(MutatingUseContext::Deinit),
location
)
}
StatementKind::StorageLive(local) => {
self.visit_local(
$(& $mutability)? *local,
@ -1372,8 +1365,6 @@ pub enum MutatingUseContext {
Store,
/// Appears on `SetDiscriminant`
SetDiscriminant,
/// Appears on `Deinit`
Deinit,
/// Output operand of an inline assembly block.
AsmOutput,
/// Destination of a call.

View file

@ -24,9 +24,6 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
let op = self.parse_operand(args[0])?;
Ok(StatementKind::Intrinsic(Box::new(NonDivergingIntrinsic::Assume(op))))
},
@call(mir_deinit, args) => {
Ok(StatementKind::Deinit(Box::new(self.parse_place(args[0])?)))
},
@call(mir_retag, args) => {
Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?)))
},

View file

@ -159,8 +159,7 @@ impl DefUse {
MutatingUseContext::Call
| MutatingUseContext::Yield
| MutatingUseContext::AsmOutput
| MutatingUseContext::Store
| MutatingUseContext::Deinit,
| MutatingUseContext::Store,
) => {
// Treat derefs as a use of the base local. `*p = 4` is not a def of `p` but a use.
if place.is_indirect() {
@ -238,7 +237,7 @@ impl<'a> MaybeTransitiveLiveLocals<'a> {
&& (!debuginfo_locals.contains(place.local)
|| (place.as_local().is_some() && stmt_kind.as_debuginfo().is_some())))
.then_some(*place),
StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => {
StatementKind::SetDiscriminant { place, .. } => {
(!debuginfo_locals.contains(place.local)).then_some(**place)
}
StatementKind::FakeRead(_)

View file

@ -156,8 +156,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
// If a place is assigned to in a statement, it needs storage for that statement.
StatementKind::Assign(box (place, _))
| StatementKind::SetDiscriminant { box place, .. }
| StatementKind::Deinit(box place) => {
| StatementKind::SetDiscriminant { box place, .. } => {
state.gen_(place.local);
}

View file

@ -371,7 +371,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
self.gather_move(Place::from(*local));
}
}
StatementKind::SetDiscriminant { .. } | StatementKind::Deinit(..) => {
StatementKind::SetDiscriminant { .. } => {
span_bug!(
stmt.source_info.span,
"SetDiscriminant/Deinit should not exist during borrowck"

View file

@ -1723,7 +1723,6 @@ impl<'tcx> Visitor<'tcx> for EnsureCoroutineFieldAssignmentsNeverAlias<'_> {
StatementKind::FakeRead(..)
| StatementKind::SetDiscriminant { .. }
| StatementKind::Deinit(..)
| StatementKind::StorageLive(_)
| StatementKind::StorageDead(_)
| StatementKind::Retag(..)

View file

@ -91,7 +91,6 @@ fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span> {
)
| StatementKind::Assign(_)
| StatementKind::SetDiscriminant { .. }
| StatementKind::Deinit(..)
| StatementKind::Retag(_, _)
| StatementKind::PlaceMention(..)
| StatementKind::AscribeUserType(_, _) => Some(statement.source_info.span),

View file

@ -115,10 +115,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
// Don't count StorageLive/StorageDead in the inlining cost.
match statement.kind {
StatementKind::StorageLive(_)
| StatementKind::StorageDead(_)
| StatementKind::Deinit(_)
| StatementKind::Nop => {}
StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Nop => {}
_ => self.statements += 1,
}
}

View file

@ -178,10 +178,6 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
FlatSet::<Scalar>::BOTTOM,
);
}
StatementKind::Deinit(box place) => {
// Deinit makes the place uninitialized.
state.flood_with(place.as_ref(), &self.map, FlatSet::<Scalar>::BOTTOM);
}
StatementKind::Retag(..) => {
// We don't track references.
}

View file

@ -332,8 +332,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> {
stmt: &Statement<'tcx>,
) -> Option<(Place<'tcx>, Option<TrackElem>)> {
match stmt.kind {
StatementKind::Assign(box (place, _))
| StatementKind::Deinit(box place) => Some((place, None)),
StatementKind::Assign(box (place, _)) => Some((place, None)),
StatementKind::SetDiscriminant { box place, variant_index: _ } => {
Some((place, Some(TrackElem::Discriminant)))
}

View file

@ -926,7 +926,6 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
// mutations of the same local via `Store`
| MutatingUse(MutatingUseContext::Call)
| MutatingUse(MutatingUseContext::AsmOutput)
| MutatingUse(MutatingUseContext::Deinit)
// Actual store that can possibly even propagate a value
| MutatingUse(MutatingUseContext::Store)
| MutatingUse(MutatingUseContext::SetDiscriminant) => {

View file

@ -126,8 +126,6 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(src), src_cast_ty),
)));
let deinit_old = StatementKind::Deinit(Box::new(dst));
let copy_bytes = StatementKind::Intrinsic(Box::new(
NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
src: Operand::Copy(src_cast_place),
@ -148,7 +146,6 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
dst_cast,
src_ptr,
src_cast,
deinit_old,
copy_bytes,
store_dead,
];

View file

@ -113,7 +113,6 @@ impl RemoveNoopLandingPads {
StatementKind::Assign { .. }
| StatementKind::SetDiscriminant { .. }
| StatementKind::Deinit(..)
| StatementKind::Intrinsic(..)
| StatementKind::Retag { .. } => {
return false;

View file

@ -122,8 +122,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
StatementKind::Assign(box (place, ref rvalue)) => {
rvalue.is_safe_to_remove().then_some(place)
}
StatementKind::Deinit(box place)
| StatementKind::SetDiscriminant { box place, variant_index: _ }
StatementKind::SetDiscriminant { box place, variant_index: _ }
| StatementKind::AscribeUserType(box (place, _), _)
| StatementKind::Retag(_, box place)
| StatementKind::PlaceMention(box place)

View file

@ -590,7 +590,6 @@ impl<'tcx> Visitor<'tcx> for UsedLocals {
}
StatementKind::SetDiscriminant { ref place, variant_index: _ }
| StatementKind::Deinit(ref place)
| StatementKind::BackwardIncompatibleDropHint { ref place, reason: _ } => {
self.visit_lhs(place, location);
}
@ -630,8 +629,9 @@ fn remove_unused_definitions_helper(used_locals: &mut UsedLocals, body: &mut Bod
}
StatementKind::Assign(box (place, _))
| StatementKind::SetDiscriminant { box place, .. }
| StatementKind::BackwardIncompatibleDropHint { box place, .. }
| StatementKind::Deinit(box place) => used_locals.is_used(place.local),
| StatementKind::BackwardIncompatibleDropHint { box place, .. } => {
used_locals.is_used(place.local)
}
_ => continue,
};
if keep_statement {

View file

@ -136,9 +136,7 @@ fn escaping_locals<'tcx>(
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
match statement.kind {
// Storage statements are expanded in run_pass.
StatementKind::StorageLive(..)
| StatementKind::StorageDead(..)
| StatementKind::Deinit(..) => return,
StatementKind::StorageLive(..) | StatementKind::StorageDead(..) => return,
_ => self.super_statement(statement, location),
}
}
@ -331,16 +329,6 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
}
return;
}
StatementKind::Deinit(box place) => {
if let Some(final_locals) = self.replacements.place_fragments(place) {
for (_, _, fl) in final_locals {
self.patch
.add_statement(location, StatementKind::Deinit(Box::new(fl.into())));
}
statement.make_nop(true);
return;
}
}
// We have `a = Struct { 0: x, 1: y, .. }`.
// We replace it by

View file

@ -313,11 +313,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
}
}
StatementKind::Deinit(..) => {
if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(location, "`Deinit`is not allowed until deaggregation");
}
}
StatementKind::Retag(kind, _) => {
// FIXME(JakobDegen) The validator should check that `self.body.phase <
// DropsLowered`. However, this causes ICEs with generation of drop shims, which
@ -1501,11 +1496,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
);
}
}
StatementKind::Deinit(..) => {
if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(location, "`Deinit`is not allowed until deaggregation");
}
}
StatementKind::Retag(kind, _) => {
// FIXME(JakobDegen) The validator should check that `self.body.phase <
// DropsLowered`. However, this causes ICEs with generation of drop shims, which

View file

@ -478,7 +478,6 @@ pub enum StatementKind {
Assign(Place, Rvalue),
FakeRead(FakeReadCause, Place),
SetDiscriminant { place: Place, variant_index: VariantIdx },
Deinit(Place),
StorageLive(Local),
StorageDead(Local),
Retag(RetagKind, Place),

View file

@ -102,7 +102,6 @@ fn pretty_statement<W: Write>(writer: &mut W, statement: &StatementKind) -> io::
StatementKind::SetDiscriminant { place, variant_index } => {
writeln!(writer, "{INDENT}discriminant({place:?}) = {};", variant_index.to_index())
}
StatementKind::Deinit(place) => writeln!(writer, "Deinit({place:?};"),
StatementKind::StorageLive(local) => {
writeln!(writer, "{INDENT}StorageLive(_{local});")
}

View file

@ -170,7 +170,6 @@ macro_rules! make_mir_visitor {
self.visit_place(place, PlaceContext::NON_MUTATING, location);
}
StatementKind::SetDiscriminant { place, .. }
| StatementKind::Deinit(place)
| StatementKind::Retag(_, place) => {
self.visit_place(place, PlaceContext::MUTATING, location);
}

View file

@ -149,9 +149,6 @@ impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
variant_index: variant_index.stable(tables, cx),
}
}
mir::StatementKind::Deinit(place) => {
crate::mir::StatementKind::Deinit(place.stable(tables, cx))
}
mir::StatementKind::StorageLive(place) => {
crate::mir::StatementKind::StorageLive(place.stable(tables, cx))

View file

@ -227,7 +227,7 @@
//!
//! #### Statements
//! - Assign statements work via normal Rust assignment.
//! - [`Retag`], [`StorageLive`], [`StorageDead`], [`Deinit`] statements have an associated function.
//! - [`Retag`], [`StorageLive`], [`StorageDead`] statements have an associated function.
//!
//! #### Rvalues
//!
@ -400,7 +400,6 @@ define!("mir_unwind_resume",
define!("mir_storage_live", fn StorageLive<T>(local: T));
define!("mir_storage_dead", fn StorageDead<T>(local: T));
define!("mir_assume", fn Assume(operand: bool));
define!("mir_deinit", fn Deinit<T>(place: T));
define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
define!(
"mir_ptr_metadata",

View file

@ -232,7 +232,7 @@ fn check_statement<'tcx>(
StatementKind::FakeRead(box (_, place)) => check_place(cx, *place, span, body, msrv),
// just an assignment
StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => {
StatementKind::SetDiscriminant { place, .. } => {
check_place(cx, **place, span, body, msrv)
},

View file

@ -88,7 +88,6 @@ fn switch_option_repr(option: Bool) -> bool {
fn set_discr(option: &mut Option<()>) {
mir! {
{
Deinit(*option);
SetDiscriminant(*option, 0);
Return()
}

View file

@ -4,7 +4,6 @@ fn set_discr(_1: &mut Option<()>) -> () {
let mut _0: ();
bb0: {
Deinit((*_1));
discriminant((*_1)) = 0;
return;
}

View file

@ -44,7 +44,6 @@
+ _9 = copy _8 as *mut u8 (PtrToPtr);
+ _10 = &raw const _2;
+ _11 = copy _10 as *const u8 (PtrToPtr);
+ Deinit(_8);
+ copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7);
+ StorageDead(_4);
+ nop;
@ -59,7 +58,6 @@
+ _17 = copy _16 as *mut u8 (PtrToPtr);
+ _18 = &raw const _1;
+ _19 = copy _18 as *const u8 (PtrToPtr);
+ Deinit(_16);
+ copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15);
+ StorageDead(_12);
+ nop;

View file

@ -44,7 +44,6 @@
+ _9 = copy _8 as *mut u8 (PtrToPtr);
+ _10 = &raw const _2;
+ _11 = copy _10 as *const u8 (PtrToPtr);
+ Deinit(_8);
+ copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7);
+ StorageDead(_4);
+ nop;
@ -59,7 +58,6 @@
+ _17 = copy _16 as *mut u8 (PtrToPtr);
+ _18 = &raw const _1;
+ _19 = copy _18 as *const u8 (PtrToPtr);
+ Deinit(_16);
+ copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15);
+ StorageDead(_12);
+ nop;

View file

@ -44,7 +44,6 @@
+ _9 = copy _8 as *mut u8 (PtrToPtr);
+ _10 = &raw const _2;
+ _11 = copy _10 as *const u8 (PtrToPtr);
+ Deinit(_8);
+ copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7);
+ StorageDead(_4);
+ nop;
@ -59,7 +58,6 @@
+ _17 = copy _16 as *mut u8 (PtrToPtr);
+ _18 = &raw const _1;
+ _19 = copy _18 as *const u8 (PtrToPtr);
+ Deinit(_16);
+ copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15);
+ StorageDead(_12);
+ nop;

View file

@ -44,7 +44,6 @@
+ _9 = copy _8 as *mut u8 (PtrToPtr);
+ _10 = &raw const _2;
+ _11 = copy _10 as *const u8 (PtrToPtr);
+ Deinit(_8);
+ copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7);
+ StorageDead(_4);
+ nop;
@ -59,7 +58,6 @@
+ _17 = copy _16 as *mut u8 (PtrToPtr);
+ _18 = &raw const _1;
+ _19 = copy _18 as *const u8 (PtrToPtr);
+ Deinit(_16);
+ copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15);
+ StorageDead(_12);
+ nop;