Skip to content

Commit e4aeeca

Browse files
committed
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.
1 parent a3f7c4d commit e4aeeca

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

compiler/rustc_const_eval/src/transform/check_consts/resolver.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
use rustc_index::bit_set::BitSet;
66
use rustc_middle::mir::visit::Visitor;
7-
use rustc_middle::mir::{self, BasicBlock, Local, Location};
7+
use rustc_middle::mir::{self, BasicBlock, Local, Location, Statement, StatementKind};
88

99
use std::marker::PhantomData;
1010

@@ -120,6 +120,15 @@ where
120120
self.super_assign(place, rvalue, location);
121121
}
122122

123+
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
124+
match statement.kind {
125+
StatementKind::StorageDead(local) => {
126+
self.qualifs_per_local.remove(local);
127+
}
128+
_ => self.super_statement(statement, location),
129+
}
130+
}
131+
123132
fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
124133
// The effect of assignment to the return place in `TerminatorKind::Call` is not applied
125134
// here; that occurs in `apply_call_return_effect`.
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Check that storage statements reset local qualification.
2+
// check-pass
3+
use std::cell::Cell;
4+
5+
const C: Option<Cell<u32>> = {
6+
let mut c = None;
7+
let mut i = 0;
8+
while i == 0 {
9+
let mut x = None;
10+
c = x;
11+
x = Some(Cell::new(0));
12+
let _ = x;
13+
i += 1;
14+
}
15+
c
16+
};
17+
18+
fn main() {
19+
let _: &'static _ = &C;
20+
}

0 commit comments

Comments
 (0)