Skip to content

Commit 9b6b1a6

Browse files
committed
Add new Deinit statement kind
1 parent d00e770 commit 9b6b1a6

File tree

27 files changed

+141
-66
lines changed

27 files changed

+141
-66
lines changed

compiler/rustc_borrowck/src/dataflow.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
386386

387387
mir::StatementKind::FakeRead(..)
388388
| mir::StatementKind::SetDiscriminant { .. }
389+
| mir::StatementKind::Deinit(..)
389390
| mir::StatementKind::StorageLive(..)
390391
| mir::StatementKind::Retag { .. }
391392
| mir::StatementKind::AscribeUserType(..)

compiler/rustc_borrowck/src/invalidation.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
6363
StatementKind::FakeRead(box (_, _)) => {
6464
// Only relevant for initialized/liveness/safety checks.
6565
}
66-
StatementKind::SetDiscriminant { place, variant_index: _ } => {
67-
self.mutate_place(location, **place, Shallow(None));
68-
}
6966
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
7067
ref src,
7168
ref dst,
@@ -91,6 +88,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
9188
LocalMutationIsAllowed::Yes,
9289
);
9390
}
91+
StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
92+
bug!("Statement not allowed in this MIR phase")
93+
}
9494
}
9595

9696
self.super_statement(statement, location);

compiler/rustc_borrowck/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -626,9 +626,6 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
626626
flow_state,
627627
);
628628
}
629-
StatementKind::SetDiscriminant { place, variant_index: _ } => {
630-
self.mutate_place(location, (**place, span), Shallow(None), flow_state);
631-
}
632629
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
633630
..
634631
}) => {
@@ -654,6 +651,9 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
654651
flow_state,
655652
);
656653
}
654+
StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
655+
bug!("Statement not allowed in this MIR phase")
656+
}
657657
}
658658
}
659659

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,28 +1303,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13031303
);
13041304
}
13051305
}
1306-
StatementKind::SetDiscriminant { ref place, variant_index } => {
1307-
let place_type = place.ty(body, tcx).ty;
1308-
let adt = match place_type.kind() {
1309-
ty::Adt(adt, _) if adt.is_enum() => adt,
1310-
_ => {
1311-
span_bug!(
1312-
stmt.source_info.span,
1313-
"bad set discriminant ({:?} = {:?}): lhs is not an enum",
1314-
place,
1315-
variant_index
1316-
);
1317-
}
1318-
};
1319-
if variant_index.as_usize() >= adt.variants().len() {
1320-
span_bug!(
1321-
stmt.source_info.span,
1322-
"bad set discriminant ({:?} = {:?}): value of of range",
1323-
place,
1324-
variant_index
1325-
);
1326-
};
1327-
}
13281306
StatementKind::AscribeUserType(box (ref place, ref projection), variance) => {
13291307
let place_ty = place.ty(body, tcx).ty;
13301308
if let Err(terr) = self.relate_type_and_user_type(
@@ -1358,6 +1336,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13581336
| StatementKind::Retag { .. }
13591337
| StatementKind::Coverage(..)
13601338
| StatementKind::Nop => {}
1339+
StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
1340+
bug!("Statement not allowed in this MIR phase")
1341+
}
13611342
}
13621343
}
13631344

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ fn codegen_stmt<'tcx>(
772772
}
773773
StatementKind::StorageLive(_)
774774
| StatementKind::StorageDead(_)
775+
| StatementKind::Deinit(_)
775776
| StatementKind::Nop
776777
| StatementKind::FakeRead(..)
777778
| StatementKind::Retag { .. }

compiler/rustc_codegen_cranelift/src/constant.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
518518
StatementKind::Assign(_)
519519
| StatementKind::FakeRead(_)
520520
| StatementKind::SetDiscriminant { .. }
521+
| StatementKind::Deinit(_)
521522
| StatementKind::StorageLive(_)
522523
| StatementKind::StorageDead(_)
523524
| StatementKind::Retag(_, _)

compiler/rustc_codegen_ssa/src/mir/statement.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
4848
.codegen_set_discr(&mut bx, variant_index);
4949
bx
5050
}
51+
mir::StatementKind::Deinit(..) => {
52+
// For now, don't codegen this to anything. In the future it may be worth
53+
// experimenting with what kind of information we can emit to LLVM without hurting
54+
// perf here
55+
bx
56+
}
5157
mir::StatementKind::StorageLive(local) => {
5258
if let LocalRef::Place(cg_place) = self.locals[local] {
5359
cg_place.storage_live(&mut bx);

compiler/rustc_const_eval/src/interpret/memory.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,11 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRefMut<'a, 'tcx, Tag, Extra> {
890890
) -> InterpResult<'tcx> {
891891
self.write_scalar(alloc_range(offset, self.tcx.data_layout().pointer_size), val)
892892
}
893+
894+
/// Mark the entire referenced range as uninitalized
895+
pub fn write_uninit(&mut self) {
896+
self.alloc.mark_init(self.range, false);
897+
}
893898
}
894899

895900
impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> {

compiler/rustc_const_eval/src/interpret/place.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,42 @@ where
791791
}
792792
}
793793

794+
pub fn write_uninit(&mut self, dest: &PlaceTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> {
795+
let mplace = match dest.place {
796+
Place::Ptr(mplace) => MPlaceTy { mplace, layout: dest.layout },
797+
Place::Local { frame, local } => {
798+
match M::access_local_mut(self, frame, local)? {
799+
Ok(local) => match dest.layout.abi {
800+
Abi::Scalar(_) => {
801+
*local = LocalValue::Live(Operand::Immediate(Immediate::Scalar(
802+
ScalarMaybeUninit::Uninit,
803+
)));
804+
return Ok(());
805+
}
806+
Abi::ScalarPair(..) => {
807+
*local = LocalValue::Live(Operand::Immediate(Immediate::ScalarPair(
808+
ScalarMaybeUninit::Uninit,
809+
ScalarMaybeUninit::Uninit,
810+
)));
811+
return Ok(());
812+
}
813+
_ => self.force_allocation(dest)?,
814+
},
815+
Err(mplace) => {
816+
// The local is in memory, go on below.
817+
MPlaceTy { mplace, layout: dest.layout }
818+
}
819+
}
820+
}
821+
};
822+
let Some(mut alloc) = self.get_place_alloc_mut(&mplace)? else {
823+
// Zero-sized access
824+
return Ok(());
825+
};
826+
alloc.write_uninit();
827+
Ok(())
828+
}
829+
794830
/// Copies the data from an operand to a place. This does not support transmuting!
795831
/// Use `copy_op_transmute` if the layouts could disagree.
796832
#[inline(always)]

compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
9090
self.write_discriminant(*variant_index, &dest)?;
9191
}
9292

93+
Deinit(place) => {
94+
let dest = self.eval_place(**place)?;
95+
self.write_uninit(&dest)?;
96+
}
97+
9398
// Mark locals as alive
9499
StorageLive(local) => {
95100
self.storage_live(*local)?;

0 commit comments

Comments
 (0)