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> = { + 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; +}