From e4aeeca667b6ce0446703f22f95552a64954df0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 22 Oct 2021 00:00:00 +0000 Subject: [PATCH] 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. --- .../src/transform/check_consts/resolver.rs | 11 +++++++++- src/test/ui/consts/promoted-storage.rs | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/consts/promoted-storage.rs 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 8e1b69a1d7413..e20b86dd4523c 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 0000000000000..52ef685e8f4f8 --- /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; +}