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.
This commit is contained in:
Matthias Krüger 2021-10-23 14:58:42 +02:00 committed by GitHub
commit 74a0c492c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 1 deletions

View file

@ -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`.

View 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;
}