Skip to content

Allow references to interior mutable data behind a feature gate #80418

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions compiler/rustc_mir/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,32 @@ impl NonConstOp for TransientCellBorrow {
pub struct CellBorrow;
impl NonConstOp for CellBorrow {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
struct_span_err!(
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
E0492,
"this borrow to an interior mutable value may end up in the final value of this {}",
"{}s cannot refer to interior mutable data",
ccx.const_kind(),
)
);
err.span_label(
span,
format!("this borrow of an interior mutable value may end up in the final value"),
);
if let hir::ConstContext::Static(_) = ccx.const_kind() {
err.help(
"To fix this, the value can be extracted to separate \
`static` and then referenced.",
);
}
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
"A constant containing interior mutable data behind a reference can allow you
to modify that data. This would make multiple uses of a constant to be able to
see different values and allow one to escape the `Send` and `Sync` requirements
for shared mutable data, which is unsound.",
);
}
err
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/partial_qualif.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::cell::Cell;
const FOO: &(Cell<usize>, bool) = {
let mut a = (Cell::new(0), false);
a.1 = true; // sets `qualif(a)` to `qualif(a) | qualif(true)`
&{a} //~ ERROR borrow to an interior mutable value may end up in the final value
&{a} //~ ERROR cannot refer to interior mutable
};

fn main() {}
4 changes: 2 additions & 2 deletions src/test/ui/consts/partial_qualif.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0492]: this borrow to an interior mutable value may end up in the final value of this constant
error[E0492]: constants cannot refer to interior mutable data
--> $DIR/partial_qualif.rs:6:5
|
LL | &{a}
| ^^^^
| ^^^^ this borrow of an interior mutable value may end up in the final value

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/qualif_overwrite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::cell::Cell;
const FOO: &Option<Cell<usize>> = {
let mut a = Some(Cell::new(0));
a = None; // sets `qualif(a)` to `qualif(a) | qualif(None)`
&{a} //~ ERROR borrow to an interior mutable value may end up in the final value
&{a} //~ ERROR cannot refer to interior mutable
};

fn main() {}
4 changes: 2 additions & 2 deletions src/test/ui/consts/qualif_overwrite.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0492]: this borrow to an interior mutable value may end up in the final value of this constant
error[E0492]: constants cannot refer to interior mutable data
--> $DIR/qualif_overwrite.rs:10:5
|
LL | &{a}
| ^^^^
| ^^^^ this borrow of an interior mutable value may end up in the final value

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/qualif_overwrite_2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::cell::Cell;
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 borrow to an interior mutable value may end up in the final value
&{a.0} //~ ERROR cannot refer to interior mutable
};

fn main() {}
4 changes: 2 additions & 2 deletions src/test/ui/consts/qualif_overwrite_2.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0492]: this borrow to an interior mutable value may end up in the final value of this constant
error[E0492]: constants cannot refer to interior mutable data
--> $DIR/qualif_overwrite_2.rs:8:5
|
LL | &{a.0}
| ^^^^^^
| ^^^^^^ this borrow of an interior mutable value may end up in the final value

error: aborting due to previous error

Expand Down
10 changes: 6 additions & 4 deletions src/test/ui/error-codes/E0492.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
error[E0492]: this borrow to an interior mutable value may end up in the final value of this constant
error[E0492]: constants cannot refer to interior mutable data
--> $DIR/E0492.rs:4:33
|
LL | const B: &'static AtomicUsize = &A;
| ^^
| ^^ this borrow of an interior mutable value may end up in the final value

error[E0492]: this borrow to an interior mutable value may end up in the final value of this static
error[E0492]: statics cannot refer to interior mutable data
--> $DIR/E0492.rs:5:34
|
LL | static C: &'static AtomicUsize = &A;
| ^^
| ^^ this borrow of an interior mutable value may end up in the final value
|
= help: To fix this, the value can be extracted to separate `static` and then referenced.

error: aborting due to 2 previous errors

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-17718-const-borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use std::cell::UnsafeCell;

const A: UnsafeCell<usize> = UnsafeCell::new(1);
const B: &'static UnsafeCell<usize> = &A;
//~^ ERROR: borrow to an interior mutable value
//~^ ERROR: cannot refer to interior mutable

struct C { a: UnsafeCell<usize> }
const D: C = C { a: UnsafeCell::new(1) };
const E: &'static UnsafeCell<usize> = &D.a;
//~^ ERROR: borrow to an interior mutable value
//~^ ERROR: cannot refer to interior mutable
const F: &'static C = &D;
//~^ ERROR: borrow to an interior mutable value
//~^ ERROR: cannot refer to interior mutable

fn main() {}
12 changes: 6 additions & 6 deletions src/test/ui/issues/issue-17718-const-borrow.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
error[E0492]: this borrow to an interior mutable value may end up in the final value of this constant
error[E0492]: constants cannot refer to interior mutable data
--> $DIR/issue-17718-const-borrow.rs:4:39
|
LL | const B: &'static UnsafeCell<usize> = &A;
| ^^
| ^^ this borrow of an interior mutable value may end up in the final value

error[E0492]: this borrow to an interior mutable value may end up in the final value of this constant
error[E0492]: constants cannot refer to interior mutable data
--> $DIR/issue-17718-const-borrow.rs:9:39
|
LL | const E: &'static UnsafeCell<usize> = &D.a;
| ^^^^
| ^^^^ this borrow of an interior mutable value may end up in the final value

error[E0492]: this borrow to an interior mutable value may end up in the final value of this constant
error[E0492]: constants cannot refer to interior mutable data
--> $DIR/issue-17718-const-borrow.rs:11:23
|
LL | const F: &'static C = &D;
| ^^
| ^^ this borrow of an interior mutable value may end up in the final value

error: aborting due to 3 previous errors

Expand Down