about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-10-23 14:58:42 +0200
committerGitHub <noreply@github.com>2021-10-23 14:58:42 +0200
commit74a0c492c190185552837e3d94baef4dbdacd230 (patch)
treea019c5cbe196d7868df7149ef634acd5bb6f5c74
parent2b874f0242ee8e27af9961dd1a8712390832f1ad (diff)
parente4aeeca667b6ce0446703f22f95552a64954df0d (diff)
downloadrust-74a0c492c190185552837e3d94baef4dbdacd230.tar.gz
rust-74a0c492c190185552837e3d94baef4dbdacd230.zip
Rollup merge of #90168 - tmiasko:const-qualif-storage, r=matthewjasper
Reset qualifs when a storage of a local ends

Reset qualifs when a storage of a local ends to ensure that the local qualifs
are affected by the state from previous loop iterations only if the local is
kept alive.

The change should be forward compatible with a stricter handling of indirect
assignments, since storage dead invalidates all existing pointers to the local.
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/resolver.rs11
-rw-r--r--src/test/ui/consts/promoted-storage.rs20
2 files changed, 30 insertions, 1 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
index 8e1b69a1d74..e20b86dd452 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
@@ -4,7 +4,7 @@
 
 use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::{self, BasicBlock, Local, Location};
+use rustc_middle::mir::{self, BasicBlock, Local, Location, Statement, StatementKind};
 
 use std::marker::PhantomData;
 
@@ -120,6 +120,15 @@ where
         self.super_assign(place, rvalue, location);
     }
 
+    fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
+        match statement.kind {
+            StatementKind::StorageDead(local) => {
+                self.qualifs_per_local.remove(local);
+            }
+            _ => self.super_statement(statement, location),
+        }
+    }
+
     fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
         // The effect of assignment to the return place in `TerminatorKind::Call` is not applied
         // here; that occurs in `apply_call_return_effect`.
diff --git a/src/test/ui/consts/promoted-storage.rs b/src/test/ui/consts/promoted-storage.rs
new file mode 100644
index 00000000000..52ef685e8f4
--- /dev/null
+++ b/src/test/ui/consts/promoted-storage.rs
@@ -0,0 +1,20 @@
+// Check that storage statements reset local qualification.
+// check-pass
+use std::cell::Cell;
+
+const C: Option<Cell<u32>> = {
+    let mut c = None;
+    let mut i = 0;
+    while i == 0 {
+        let mut x = None;
+        c = x;
+        x = Some(Cell::new(0));
+        let _ = x;
+        i += 1;
+    }
+    c
+};
+
+fn main() {
+    let _: &'static _ = &C;
+}