Skip to content

Commit 6db8c6c

Browse files
committed
Explain why we do not overwrite qualification of locals
1 parent 22aebd5 commit 6db8c6c

File tree

5 files changed

+34
-7
lines changed

5 files changed

+34
-7
lines changed

src/librustc_mir/transform/qualify_consts.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,12 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
277277
};
278278
debug!("store to var {:?}", index);
279279
match &mut self.local_qualif[index] {
280-
// update
280+
// this is overly restrictive, because even full assignments do not clear the qualif
281+
// While we could special case full assignments, this would be inconsistent with
282+
// aggregates where we overwrite all fields via assignments, which would not get
283+
// that feature.
281284
Some(ref mut qualif) => *qualif = *qualif | self.qualif,
282-
// or insert
285+
// insert new qualification
283286
qualif @ None => *qualif = Some(self.qualif),
284287
}
285288
return;
+6-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
// compile-pass
2-
31
#![feature(const_let)]
42

53
use std::cell::Cell;
64

5+
// this is overly conservative. The reset to `None` should clear `a` of all qualifications
6+
// while we could fix this, it would be inconsistent with `qualif_overwrite_2.rs`.
7+
// We can fix this properly in the future by allowing constants that do not depend on generics
8+
// to be checked by an analysis on the final value instead of looking at the body.
79
const FOO: &Option<Cell<usize>> = {
810
let mut a = Some(Cell::new(0));
9-
a = None; // resets `qualif(a)` to `qualif(None)`
10-
&{a}
11+
a = None; // sets `qualif(a)` to `qualif(a) | qualif(None)`
12+
&{a} //~ ERROR cannot borrow a constant which may contain interior mutability
1113
};
1214

1315
fn main() {}

src/test/ui/consts/qualif_overwrite.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
2-
--> $DIR/qualif_overwrite.rs:8:5
2+
--> $DIR/qualif_overwrite.rs:12:5
33
|
44
LL | &{a} //~ ERROR cannot borrow a constant which may contain interior mutability
55
| ^^^^
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(const_let)]
2+
3+
use std::cell::Cell;
4+
5+
// const qualification is not smart enough to know about fields and always assumes that there might
6+
// be other fields that caused the qualification
7+
const FOO: &Option<Cell<usize>> = {
8+
let mut a = (Some(Cell::new(0)),);
9+
a.0 = None; // sets `qualif(a)` to `qualif(a) | qualif(None)`
10+
&{a.0} //~ ERROR cannot borrow a constant which may contain interior mutability
11+
};
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
2+
--> $DIR/qualif_overwrite_2.rs:10:5
3+
|
4+
LL | &{a.0} //~ ERROR cannot borrow a constant which may contain interior mutability
5+
| ^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0492`.

0 commit comments

Comments
 (0)