]> git.lizzy.rs Git - rust.git/commitdiff
Add new `Deinit` statement kind
authorJakob Degen <jakob.e.degen@gmail.com>
Tue, 5 Apr 2022 21:14:59 +0000 (17:14 -0400)
committerJakob Degen <jakob.e.degen@gmail.com>
Mon, 11 Apr 2022 12:55:03 +0000 (08:55 -0400)
27 files changed:
compiler/rustc_borrowck/src/dataflow.rs
compiler/rustc_borrowck/src/invalidation.rs
compiler/rustc_borrowck/src/lib.rs
compiler/rustc_borrowck/src/type_check/mod.rs
compiler/rustc_codegen_cranelift/src/base.rs
compiler/rustc_codegen_cranelift/src/constant.rs
compiler/rustc_codegen_ssa/src/mir/statement.rs
compiler/rustc_const_eval/src/interpret/memory.rs
compiler/rustc_const_eval/src/interpret/place.rs
compiler/rustc_const_eval/src/interpret/step.rs
compiler/rustc_const_eval/src/transform/check_consts/check.rs
compiler/rustc_const_eval/src/transform/validate.rs
compiler/rustc_const_eval/src/util/aggregate.rs
compiler/rustc_middle/src/mir/mod.rs
compiler/rustc_middle/src/mir/spanview.rs
compiler/rustc_middle/src/mir/visit.rs
compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
compiler/rustc_mir_dataflow/src/move_paths/builder.rs
compiler/rustc_mir_transform/src/check_unsafety.rs
compiler/rustc_mir_transform/src/coverage/spans.rs
compiler/rustc_mir_transform/src/dest_prop.rs
compiler/rustc_mir_transform/src/generator.rs
compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
compiler/rustc_mir_transform/src/remove_zsts.rs
compiler/rustc_mir_transform/src/separate_const_switch.rs
compiler/rustc_mir_transform/src/simplify.rs
src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs

index 684eba82667fa4897471fbe3ce0f86098a9cb347..d38e89cd79edd785476d5a49c810d3ee8d01567c 100644 (file)
@@ -386,6 +386,7 @@ fn statement_effect(
 
             mir::StatementKind::FakeRead(..)
             | mir::StatementKind::SetDiscriminant { .. }
+            | mir::StatementKind::Deinit(..)
             | mir::StatementKind::StorageLive(..)
             | mir::StatementKind::Retag { .. }
             | mir::StatementKind::AscribeUserType(..)
index 1a789009f061196a4f06a590e4e741d9eb9d0dbb..76d240bb89f59cfb5dce98a0913ce876046d16d8 100644 (file)
@@ -63,9 +63,6 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
             StatementKind::FakeRead(box (_, _)) => {
                 // Only relevant for initialized/liveness/safety checks.
             }
-            StatementKind::SetDiscriminant { place, variant_index: _ } => {
-                self.mutate_place(location, **place, Shallow(None));
-            }
             StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
                 ref src,
                 ref dst,
@@ -91,6 +88,9 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
                     LocalMutationIsAllowed::Yes,
                 );
             }
+            StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
+                bug!("Statement not allowed in this MIR phase")
+            }
         }
 
         self.super_statement(statement, location);
index 0a1eae39d75ce59b3dbad6dea9f4fca259523a2e..0c0676f93ad9bf4e0fd26d201bc18af351b3e267 100644 (file)
@@ -626,9 +626,6 @@ fn visit_statement_before_primary_effect(
                     flow_state,
                 );
             }
-            StatementKind::SetDiscriminant { place, variant_index: _ } => {
-                self.mutate_place(location, (**place, span), Shallow(None), flow_state);
-            }
             StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
                 ..
             }) => {
@@ -654,6 +651,9 @@ fn visit_statement_before_primary_effect(
                     flow_state,
                 );
             }
+            StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
+                bug!("Statement not allowed in this MIR phase")
+            }
         }
     }
 
index e9fa33f656f31006b12a39d0536091830056e4f6..ece801716b2dbacc6715dc87e2d37113304fce63 100644 (file)
@@ -1303,28 +1303,6 @@ fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Lo
                     );
                 }
             }
-            StatementKind::SetDiscriminant { ref place, variant_index } => {
-                let place_type = place.ty(body, tcx).ty;
-                let adt = match place_type.kind() {
-                    ty::Adt(adt, _) if adt.is_enum() => adt,
-                    _ => {
-                        span_bug!(
-                            stmt.source_info.span,
-                            "bad set discriminant ({:?} = {:?}): lhs is not an enum",
-                            place,
-                            variant_index
-                        );
-                    }
-                };
-                if variant_index.as_usize() >= adt.variants().len() {
-                    span_bug!(
-                        stmt.source_info.span,
-                        "bad set discriminant ({:?} = {:?}): value of of range",
-                        place,
-                        variant_index
-                    );
-                };
-            }
             StatementKind::AscribeUserType(box (ref place, ref projection), variance) => {
                 let place_ty = place.ty(body, tcx).ty;
                 if let Err(terr) = self.relate_type_and_user_type(
@@ -1358,6 +1336,9 @@ fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Lo
             | StatementKind::Retag { .. }
             | StatementKind::Coverage(..)
             | StatementKind::Nop => {}
+            StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
+                bug!("Statement not allowed in this MIR phase")
+            }
         }
     }
 
index a9ff710c91ed6f865cb4486e7f96031b0f4e3b56..8c45993a8b76bf7e4a171be65c81def5e6e6025c 100644 (file)
@@ -772,6 +772,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
         }
         StatementKind::StorageLive(_)
         | StatementKind::StorageDead(_)
+        | StatementKind::Deinit(_)
         | StatementKind::Nop
         | StatementKind::FakeRead(..)
         | StatementKind::Retag { .. }
index 4657791345b8eb22d3f0d1c304d829ca2132c2ff..57074f00210fe88111b4f369de5bb49f50237b35 100644 (file)
@@ -518,6 +518,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
                         StatementKind::Assign(_)
                         | StatementKind::FakeRead(_)
                         | StatementKind::SetDiscriminant { .. }
+                        | StatementKind::Deinit(_)
                         | StatementKind::StorageLive(_)
                         | StatementKind::StorageDead(_)
                         | StatementKind::Retag(_, _)
index 773dc2adcfa0c93705c544bffa4c8a517cd7440e..d9ebfc3e871436b901f4139b4d9524c5981a64bd 100644 (file)
@@ -48,6 +48,12 @@ pub fn codegen_statement(&mut self, mut bx: Bx, statement: &mir::Statement<'tcx>
                     .codegen_set_discr(&mut bx, variant_index);
                 bx
             }
+            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
+                bx
+            }
             mir::StatementKind::StorageLive(local) => {
                 if let LocalRef::Place(cg_place) = self.locals[local] {
                     cg_place.storage_live(&mut bx);
index 556a44a52381960ba47bae4242f04ef315767e73..a165fa23f30acf5e40af7a2a4d4171ba84ada542 100644 (file)
@@ -890,6 +890,11 @@ pub fn write_ptr_sized(
     ) -> InterpResult<'tcx> {
         self.write_scalar(alloc_range(offset, self.tcx.data_layout().pointer_size), val)
     }
+
+    /// Mark the entire referenced range as uninitalized
+    pub fn write_uninit(&mut self) {
+        self.alloc.mark_init(self.range, false);
+    }
 }
 
 impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> {
index 51d47af2f8e24c960db26a3619dd4fd82bda3588..8dc74035d61d009b0ec59dbd2ec4c69b4e694e66 100644 (file)
@@ -791,6 +791,42 @@ fn write_immediate_to_mplace_no_validate(
         }
     }
 
+    pub fn write_uninit(&mut self, dest: &PlaceTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> {
+        let mplace = match dest.place {
+            Place::Ptr(mplace) => MPlaceTy { mplace, layout: dest.layout },
+            Place::Local { frame, local } => {
+                match M::access_local_mut(self, frame, local)? {
+                    Ok(local) => match dest.layout.abi {
+                        Abi::Scalar(_) => {
+                            *local = LocalValue::Live(Operand::Immediate(Immediate::Scalar(
+                                ScalarMaybeUninit::Uninit,
+                            )));
+                            return Ok(());
+                        }
+                        Abi::ScalarPair(..) => {
+                            *local = LocalValue::Live(Operand::Immediate(Immediate::ScalarPair(
+                                ScalarMaybeUninit::Uninit,
+                                ScalarMaybeUninit::Uninit,
+                            )));
+                            return Ok(());
+                        }
+                        _ => self.force_allocation(dest)?,
+                    },
+                    Err(mplace) => {
+                        // The local is in memory, go on below.
+                        MPlaceTy { mplace, layout: dest.layout }
+                    }
+                }
+            }
+        };
+        let Some(mut alloc) = self.get_place_alloc_mut(&mplace)? else {
+            // Zero-sized access
+            return Ok(());
+        };
+        alloc.write_uninit();
+        Ok(())
+    }
+
     /// Copies the data from an operand to a place. This does not support transmuting!
     /// Use `copy_op_transmute` if the layouts could disagree.
     #[inline(always)]
index 84563daa0880d64446739a509a16f9d86a81155e..eb1a184bf9b219139c00b16fa4431cf8735d4b18 100644 (file)
@@ -90,6 +90,11 @@ pub fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> InterpResult<'tcx> {
                 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)?;
index 625f57b872bf7ecf6fc3a39a5663994b05847175..7e2a50444db062d24cf0b06757927c07c034ba38 100644 (file)
@@ -692,6 +692,7 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
         match statement.kind {
             StatementKind::Assign(..)
             | StatementKind::SetDiscriminant { .. }
+            | StatementKind::Deinit(..)
             | StatementKind::FakeRead(..)
             | StatementKind::StorageLive(_)
             | StatementKind::StorageDead(_)
index 263959f3cb376ed3e41468edf9039872550bf88f..58a7f6d1be0b173e32a1932e29b5124d38c5368b 100644 (file)
@@ -346,9 +346,24 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
                     self.fail(location, format!("bad arg ({:?} != usize)", op_cnt_ty))
                 }
             }
-            StatementKind::SetDiscriminant { .. } => {
-                if self.mir_phase < MirPhase::DropsLowered {
-                    self.fail(location, "`SetDiscriminant` is not allowed until drop elaboration");
+            StatementKind::SetDiscriminant { place, .. } => {
+                if self.mir_phase < MirPhase::Deaggregated {
+                    self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
+                }
+                let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind();
+                if !matches!(pty, ty::Adt(..) | ty::Generator(..) | ty::Opaque(..)) {
+                    self.fail(
+                        location,
+                        format!(
+                            "`SetDiscriminant` is only allowed on ADTs and generators, not {:?}",
+                            pty
+                        ),
+                    );
+                }
+            }
+            StatementKind::Deinit(..) => {
+                if self.mir_phase < MirPhase::Deaggregated {
+                    self.fail(location, "`Deinit`is not allowed until deaggregation");
                 }
             }
             StatementKind::Retag(_, _) => {
index e5f5e7072d5906e4ef25de23f481340c0980aa3b..180a40043db0788c1d4ab881d7a105598f03bcad 100644 (file)
 /// (lhs as Variant).field1 = arg1;
 /// discriminant(lhs) = variant_index;  // If lhs is an enum or generator.
 pub fn expand_aggregate<'tcx>(
-    mut lhs: Place<'tcx>,
+    orig_lhs: Place<'tcx>,
     operands: impl Iterator<Item = (Operand<'tcx>, Ty<'tcx>)> + TrustedLen,
     kind: AggregateKind<'tcx>,
     source_info: SourceInfo,
     tcx: TyCtxt<'tcx>,
 ) -> impl Iterator<Item = Statement<'tcx>> + TrustedLen {
+    let mut lhs = orig_lhs;
     let mut set_discriminant = None;
     let active_field_index = match kind {
         AggregateKind::Adt(adt_did, variant_index, _, _, active_field_index) => {
             let adt_def = tcx.adt_def(adt_did);
             if adt_def.is_enum() {
                 set_discriminant = Some(Statement {
-                    kind: StatementKind::SetDiscriminant { place: Box::new(lhs), variant_index },
+                    kind: StatementKind::SetDiscriminant {
+                        place: Box::new(orig_lhs),
+                        variant_index,
+                    },
                     source_info,
                 });
-                lhs = tcx.mk_place_downcast(lhs, adt_def, variant_index);
+                lhs = tcx.mk_place_downcast(orig_lhs, adt_def, variant_index);
             }
             active_field_index
         }
@@ -38,7 +42,7 @@ pub fn expand_aggregate<'tcx>(
             // variant 0 (Unresumed).
             let variant_index = VariantIdx::new(0);
             set_discriminant = Some(Statement {
-                kind: StatementKind::SetDiscriminant { place: Box::new(lhs), variant_index },
+                kind: StatementKind::SetDiscriminant { place: Box::new(orig_lhs), variant_index },
                 source_info,
             });
 
@@ -50,27 +54,24 @@ pub fn expand_aggregate<'tcx>(
         _ => None,
     };
 
-    operands
-        .enumerate()
-        .map(move |(i, (op, ty))| {
-            let lhs_field = if let AggregateKind::Array(_) = kind {
-                let offset = u64::try_from(i).unwrap();
-                tcx.mk_place_elem(
-                    lhs,
-                    ProjectionElem::ConstantIndex {
-                        offset,
-                        min_length: offset + 1,
-                        from_end: false,
-                    },
-                )
-            } else {
-                let field = Field::new(active_field_index.unwrap_or(i));
-                tcx.mk_place_field(lhs, field, ty)
-            };
-            Statement {
-                source_info,
-                kind: StatementKind::Assign(Box::new((lhs_field, Rvalue::Use(op)))),
-            }
-        })
+    let operands = operands.enumerate().map(move |(i, (op, ty))| {
+        let lhs_field = if let AggregateKind::Array(_) = kind {
+            let offset = u64::try_from(i).unwrap();
+            tcx.mk_place_elem(
+                lhs,
+                ProjectionElem::ConstantIndex { offset, min_length: offset + 1, from_end: false },
+            )
+        } else {
+            let field = Field::new(active_field_index.unwrap_or(i));
+            tcx.mk_place_field(lhs, field, ty)
+        };
+        Statement {
+            source_info,
+            kind: StatementKind::Assign(Box::new((lhs_field, Rvalue::Use(op)))),
+        }
+    });
+    [Statement { source_info, kind: StatementKind::Deinit(Box::new(orig_lhs)) }]
+        .into_iter()
+        .chain(operands)
         .chain(set_discriminant)
 }
index 0a4f84558fee410f229daca537a941b5972c71cc..3832025f0385314c610695714b67bf1e28ac8397 100644 (file)
@@ -1590,6 +1590,8 @@ pub enum StatementKind<'tcx> {
     /// Write the discriminant for a variant to the enum Place.
     SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
 
+    Deinit(Box<Place<'tcx>>),
+
     /// Start a live range for the storage of the local.
     StorageLive(Local),
 
@@ -1739,6 +1741,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
             SetDiscriminant { ref place, variant_index } => {
                 write!(fmt, "discriminant({:?}) = {:?}", place, variant_index)
             }
+            Deinit(ref place) => write!(fmt, "Deinit({:?})", place),
             AscribeUserType(box (ref place, ref c_ty), ref variance) => {
                 write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
             }
index 965d30a7b92c9121dfd13f43695f1b6d91c0c4df..afcd5db8f487c0d8da1db8b5dfb337ea97c19a3b 100644 (file)
@@ -243,6 +243,7 @@ pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str {
         Assign(..) => "Assign",
         FakeRead(..) => "FakeRead",
         SetDiscriminant { .. } => "SetDiscriminant",
+        Deinit(..) => "Deinit",
         StorageLive(..) => "StorageLive",
         StorageDead(..) => "StorageDead",
         Retag(..) => "Retag",
index aeb0f956eb4f78c7337f48df710ed012a9a09110..49a789072f95dc2bf87ed92e476f27a8c1d947ca 100644 (file)
@@ -399,6 +399,13 @@ fn super_statement(&mut self,
                             location
                         );
                     }
+                    StatementKind::Deinit(place) => {
+                        self.visit_place(
+                            place,
+                            PlaceContext::MutatingUse(MutatingUseContext::Store),
+                            location
+                        )
+                    }
                     StatementKind::StorageLive(local) => {
                         self.visit_local(
                             local,
index 60cde6546dcfc62d2a7c0e5be2fa7e999d463869..2730e8bd49b7696ce409e1b1198cee3d52139db4 100644 (file)
@@ -131,7 +131,8 @@ fn before_statement_effect(
 
             // If a place is assigned to in a statement, it needs storage for that statement.
             StatementKind::Assign(box (place, _))
-            | StatementKind::SetDiscriminant { box place, .. } => {
+            | StatementKind::SetDiscriminant { box place, .. }
+            | StatementKind::Deinit(box place) => {
                 trans.gen(place.local);
             }
 
index 26bbc34e780bb03a5545706f6f1bc6ddaba3a9f3..73072464872c307c96a470059d2d6448508f9bdf 100644 (file)
@@ -296,10 +296,10 @@ fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
             StatementKind::StorageDead(local) => {
                 self.gather_move(Place::from(*local));
             }
-            StatementKind::SetDiscriminant { .. } => {
+            StatementKind::SetDiscriminant { .. } | StatementKind::Deinit(..) => {
                 span_bug!(
                     stmt.source_info.span,
-                    "SetDiscriminant should not exist during borrowck"
+                    "SetDiscriminant/Deinit should not exist during borrowck"
                 );
             }
             StatementKind::Retag { .. }
index f5d82315c4e38db79274477a6bb5494bcc66b3bd..d1d6e7cfe2fed77e17e30fb6c9b907b3ef6ca168 100644 (file)
@@ -97,6 +97,7 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
             StatementKind::Assign(..)
             | StatementKind::FakeRead(..)
             | StatementKind::SetDiscriminant { .. }
+            | StatementKind::Deinit(..)
             | StatementKind::StorageLive(..)
             | StatementKind::StorageDead(..)
             | StatementKind::Retag { .. }
index 5e366d7fb7dde9c953e423a5b3531f3773e32473..5b7b343949c02f02288e9f303103241e856af3aa 100644 (file)
@@ -827,6 +827,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span>
         | StatementKind::CopyNonOverlapping(..)
         | StatementKind::Assign(_)
         | StatementKind::SetDiscriminant { .. }
+        | StatementKind::Deinit(..)
         | StatementKind::Retag(_, _)
         | StatementKind::AscribeUserType(_, _) => {
             Some(statement.source_info.span)
index 5d0b58e9c53604cf00035359ca4a29c8c24f805f..3732a308e3ac3276a4093291988cef991691c8fd 100644 (file)
@@ -530,6 +530,7 @@ fn record_statement_conflicts(&mut self, stmt: &Statement<'_>) {
             StatementKind::Assign(_) => {}
 
             StatementKind::SetDiscriminant { .. }
+            | StatementKind::Deinit(..)
             | StatementKind::StorageLive(..)
             | StatementKind::StorageDead(..)
             | StatementKind::Retag(..)
index 04b5c4e0919588480d5d31f8770a84c8b1ea4585..144ea0ec61931c377bffa6f53fe8e0c881a01ed1 100644 (file)
@@ -1441,6 +1441,7 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
 
             StatementKind::FakeRead(..)
             | StatementKind::SetDiscriminant { .. }
+            | StatementKind::Deinit(..)
             | StatementKind::StorageLive(_)
             | StatementKind::StorageDead(_)
             | StatementKind::Retag(..)
index 03b9ecc959695f126e77db8a5b28c52d817b65ac..4d214b0356ca7f1a56925c1344bbe7659226aa65 100644 (file)
@@ -50,6 +50,7 @@ fn is_nop_landing_pad(
 
                 StatementKind::Assign { .. }
                 | StatementKind::SetDiscriminant { .. }
+                | StatementKind::Deinit(..)
                 | StatementKind::CopyNonOverlapping(..)
                 | StatementKind::Retag { .. } => {
                     return false;
index 785716ebecc28af40190279294cb50399e121e64..aaee6f491cd33750a88c5a030dc8fa2dd7b12061 100644 (file)
@@ -21,7 +21,9 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
         for block in basic_blocks.iter_mut() {
             for statement in block.statements.iter_mut() {
-                if let StatementKind::Assign(box (place, _)) = statement.kind {
+                if let StatementKind::Assign(box (place, _)) | StatementKind::Deinit(box place) =
+                    statement.kind
+                {
                     let place_ty = place.ty(local_decls, tcx).ty;
                     if !maybe_zst(place_ty) {
                         continue;
index d265720e18296bfad3ff6469aa7e406a3c6cf8bb..33ea1c4ba2f59a5d3664c03dc6fa1c88e5d5f7e0 100644 (file)
@@ -242,6 +242,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData<
             // These statements have no influence on the place
             // we are interested in
             StatementKind::FakeRead(_)
+            | StatementKind::Deinit(_)
             | StatementKind::StorageLive(_)
             | StatementKind::Retag(_, _)
             | StatementKind::AscribeUserType(_, _)
@@ -308,6 +309,7 @@ fn find_determining_place<'tcx>(
             // These statements have no influence on the place
             // we are interested in
             StatementKind::FakeRead(_)
+            | StatementKind::Deinit(_)
             | StatementKind::StorageLive(_)
             | StatementKind::StorageDead(_)
             | StatementKind::Retag(_, _)
index d8b58ce53f838ae0acd9f86c9588f8c7259e1f80..b42e3909cf386bc7b322383ac424dceaf4f28aec 100644 (file)
@@ -498,7 +498,8 @@ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
                 self.visit_rvalue(rvalue, location);
             }
 
-            StatementKind::SetDiscriminant { ref place, variant_index: _ } => {
+            StatementKind::SetDiscriminant { ref place, variant_index: _ }
+            | StatementKind::Deinit(ref place) => {
                 self.visit_lhs(place, location);
             }
         }
@@ -534,9 +535,8 @@ fn remove_unused_definitions(used_locals: &mut UsedLocals, body: &mut Body<'_>)
                     }
                     StatementKind::Assign(box (place, _)) => used_locals.is_used(place.local),
 
-                    StatementKind::SetDiscriminant { ref place, .. } => {
-                        used_locals.is_used(place.local)
-                    }
+                    StatementKind::SetDiscriminant { ref place, .. }
+                    | StatementKind::Deinit(ref place) => used_locals.is_used(place.local),
                     _ => true,
                 };
 
index 891531951c1a03c0f6f5a3947544a04297151fcf..fe411220484890f33e6abaa68d2a53477eea7f17 100644 (file)
@@ -211,7 +211,8 @@ fn check_statement<'tcx>(
 
         StatementKind::FakeRead(box (_, place)) => check_place(tcx, *place, span, body),
         // just an assignment
-        StatementKind::SetDiscriminant { place, .. } => check_place(tcx, **place, span, body),
+        StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => 
+            check_place(tcx, **place, span, body),
 
         StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { dst, src, count }) => {
             check_operand(tcx, dst, span, body)?;