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.
This commit is contained in:
parent
a3f7c4db03
commit
e4aeeca667
@ -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 @@ fn visit_assign(
|
||||
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`.
|
||||
|
20
src/test/ui/consts/promoted-storage.rs
Normal file
20
src/test/ui/consts/promoted-storage.rs
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user