about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/borrow_check/used_muts.rs32
-rw-r--r--src/test/ui/nll/issue-61424.rs7
-rw-r--r--src/test/ui/nll/issue-61424.stderr16
3 files changed, 41 insertions, 14 deletions
diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs
index abfc2f9466c..4a4787337ab 100644
--- a/src/librustc_mir/borrow_check/used_muts.rs
+++ b/src/librustc_mir/borrow_check/used_muts.rs
@@ -52,6 +52,19 @@ struct GatherUsedMutsVisitor<'visit, 'cx: 'visit, 'gcx: 'tcx, 'tcx: 'cx> {
     mbcx: &'visit mut MirBorrowckCtxt<'cx, 'gcx, 'tcx>,
 }
 
+impl GatherUsedMutsVisitor<'_, '_, '_, '_> {
+    fn remove_never_initialized_mut_locals(&mut self, into: &Place<'_>) {
+        // Remove any locals that we found were initialized from the
+        // `never_initialized_mut_locals` set. At the end, the only remaining locals will
+        // be those that were never initialized - we will consider those as being used as
+        // they will either have been removed by unreachable code optimizations; or linted
+        // as unused variables.
+        if let Some(local) = into.base_local() {
+            let _ = self.never_initialized_mut_locals.remove(&local);
+        }
+    }
+}
+
 impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'gcx, 'tcx> {
     fn visit_terminator_kind(
         &mut self,
@@ -61,14 +74,10 @@ impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'c
         debug!("visit_terminator_kind: kind={:?}", kind);
         match &kind {
             TerminatorKind::Call { destination: Some((into, _)), .. } => {
-                if let Some(local) = into.base_local() {
-                    debug!(
-                        "visit_terminator_kind: kind={:?} local={:?} \
-                         never_initialized_mut_locals={:?}",
-                        kind, local, self.never_initialized_mut_locals
-                    );
-                    let _ = self.never_initialized_mut_locals.remove(&local);
-                }
+                self.remove_never_initialized_mut_locals(&into);
+            },
+            TerminatorKind::DropAndReplace { location, .. } => {
+                self.remove_never_initialized_mut_locals(&location);
             },
             _ => {},
         }
@@ -81,19 +90,14 @@ impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'c
     ) {
         match &statement.kind {
             StatementKind::Assign(into, _) => {
-                // Remove any locals that we found were initialized from the
-                // `never_initialized_mut_locals` set. At the end, the only remaining locals will
-                // be those that were never initialized - we will consider those as being used as
-                // they will either have been removed by unreachable code optimizations; or linted
-                // as unused variables.
                 if let Some(local) = into.base_local() {
                     debug!(
                         "visit_statement: statement={:?} local={:?} \
                          never_initialized_mut_locals={:?}",
                         statement, local, self.never_initialized_mut_locals
                     );
-                    let _ = self.never_initialized_mut_locals.remove(&local);
                 }
+                self.remove_never_initialized_mut_locals(into);
             },
             _ => {},
         }
diff --git a/src/test/ui/nll/issue-61424.rs b/src/test/ui/nll/issue-61424.rs
new file mode 100644
index 00000000000..44c8e9f7256
--- /dev/null
+++ b/src/test/ui/nll/issue-61424.rs
@@ -0,0 +1,7 @@
+#![deny(unused_mut)]
+
+fn main() {
+    let mut x; //~ ERROR: variable does not need to be mutable
+    x = String::new();
+    dbg!(x);
+}
diff --git a/src/test/ui/nll/issue-61424.stderr b/src/test/ui/nll/issue-61424.stderr
new file mode 100644
index 00000000000..ae336b2fe1c
--- /dev/null
+++ b/src/test/ui/nll/issue-61424.stderr
@@ -0,0 +1,16 @@
+error: variable does not need to be mutable
+  --> $DIR/issue-61424.rs:4:9
+   |
+LL |     let mut x;
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+   |
+note: lint level defined here
+  --> $DIR/issue-61424.rs:1:9
+   |
+LL | #![deny(unused_mut)]
+   |         ^^^^^^^^^^
+
+error: aborting due to previous error
+