Explain why we do not overwrite qualification of locals

This commit is contained in:
Oliver Scherer 2018-11-21 11:58:28 +01:00
parent 22aebd57c8
commit 6db8c6c6d9
5 changed files with 34 additions and 7 deletions

View File

@ -277,9 +277,12 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
};
debug!("store to var {:?}", index);
match &mut self.local_qualif[index] {
// update
// this is overly restrictive, because even full assignments do not clear the qualif
// While we could special case full assignments, this would be inconsistent with
// aggregates where we overwrite all fields via assignments, which would not get
// that feature.
Some(ref mut qualif) => *qualif = *qualif | self.qualif,
// or insert
// insert new qualification
qualif @ None => *qualif = Some(self.qualif),
}
return;

View File

@ -1,13 +1,15 @@
// compile-pass
#![feature(const_let)]
use std::cell::Cell;
// this is overly conservative. The reset to `None` should clear `a` of all qualifications
// while we could fix this, it would be inconsistent with `qualif_overwrite_2.rs`.
// We can fix this properly in the future by allowing constants that do not depend on generics
// to be checked by an analysis on the final value instead of looking at the body.
const FOO: &Option<Cell<usize>> = {
let mut a = Some(Cell::new(0));
a = None; // resets `qualif(a)` to `qualif(None)`
&{a}
a = None; // sets `qualif(a)` to `qualif(a) | qualif(None)`
&{a} //~ ERROR cannot borrow a constant which may contain interior mutability
};
fn main() {}

View File

@ -1,5 +1,5 @@
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
--> $DIR/qualif_overwrite.rs:8:5
--> $DIR/qualif_overwrite.rs:12:5
|
LL | &{a} //~ ERROR cannot borrow a constant which may contain interior mutability
| ^^^^

View File

@ -0,0 +1,13 @@
#![feature(const_let)]
use std::cell::Cell;
// const qualification is not smart enough to know about fields and always assumes that there might
// be other fields that caused the qualification
const FOO: &Option<Cell<usize>> = {
let mut a = (Some(Cell::new(0)),);
a.0 = None; // sets `qualif(a)` to `qualif(a) | qualif(None)`
&{a.0} //~ ERROR cannot borrow a constant which may contain interior mutability
};
fn main() {}

View File

@ -0,0 +1,9 @@
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
--> $DIR/qualif_overwrite_2.rs:10:5
|
LL | &{a.0} //~ ERROR cannot borrow a constant which may contain interior mutability
| ^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0492`.