diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index cf81b69fede..945b422e29c 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -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 } } diff --git a/src/test/ui/consts/partial_qualif.rs b/src/test/ui/consts/partial_qualif.rs index 4aacdec7c51..7c28b8b8a62 100644 --- a/src/test/ui/consts/partial_qualif.rs +++ b/src/test/ui/consts/partial_qualif.rs @@ -3,7 +3,7 @@ use std::cell::Cell; const FOO: &(Cell, 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() {} diff --git a/src/test/ui/consts/partial_qualif.stderr b/src/test/ui/consts/partial_qualif.stderr index 5ea0cbc4f7c..32c25be2173 100644 --- a/src/test/ui/consts/partial_qualif.stderr +++ b/src/test/ui/consts/partial_qualif.stderr @@ -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 diff --git a/src/test/ui/consts/qualif_overwrite.rs b/src/test/ui/consts/qualif_overwrite.rs index 485a4a2fcc3..aae4e41ffd7 100644 --- a/src/test/ui/consts/qualif_overwrite.rs +++ b/src/test/ui/consts/qualif_overwrite.rs @@ -7,7 +7,7 @@ use std::cell::Cell; const FOO: &Option> = { 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() {} diff --git a/src/test/ui/consts/qualif_overwrite.stderr b/src/test/ui/consts/qualif_overwrite.stderr index 995f8600587..86a669c433d 100644 --- a/src/test/ui/consts/qualif_overwrite.stderr +++ b/src/test/ui/consts/qualif_overwrite.stderr @@ -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 diff --git a/src/test/ui/consts/qualif_overwrite_2.rs b/src/test/ui/consts/qualif_overwrite_2.rs index 6b90988869d..1819d9a6d20 100644 --- a/src/test/ui/consts/qualif_overwrite_2.rs +++ b/src/test/ui/consts/qualif_overwrite_2.rs @@ -5,7 +5,7 @@ use std::cell::Cell; const FOO: &Option> = { 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() {} diff --git a/src/test/ui/consts/qualif_overwrite_2.stderr b/src/test/ui/consts/qualif_overwrite_2.stderr index 006199514fc..9eb123d0b01 100644 --- a/src/test/ui/consts/qualif_overwrite_2.stderr +++ b/src/test/ui/consts/qualif_overwrite_2.stderr @@ -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 diff --git a/src/test/ui/error-codes/E0492.stderr b/src/test/ui/error-codes/E0492.stderr index 9aa84c2bff3..e8041af99b5 100644 --- a/src/test/ui/error-codes/E0492.stderr +++ b/src/test/ui/error-codes/E0492.stderr @@ -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 diff --git a/src/test/ui/issues/issue-17718-const-borrow.rs b/src/test/ui/issues/issue-17718-const-borrow.rs index 4b13c0f0c15..89316dbd5c4 100644 --- a/src/test/ui/issues/issue-17718-const-borrow.rs +++ b/src/test/ui/issues/issue-17718-const-borrow.rs @@ -2,13 +2,13 @@ use std::cell::UnsafeCell; const A: UnsafeCell = UnsafeCell::new(1); const B: &'static UnsafeCell = &A; -//~^ ERROR: borrow to an interior mutable value +//~^ ERROR: cannot refer to interior mutable struct C { a: UnsafeCell } const D: C = C { a: UnsafeCell::new(1) }; const E: &'static UnsafeCell = &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() {} diff --git a/src/test/ui/issues/issue-17718-const-borrow.stderr b/src/test/ui/issues/issue-17718-const-borrow.stderr index c94ae2a3a18..e3ff6c923ad 100644 --- a/src/test/ui/issues/issue-17718-const-borrow.stderr +++ b/src/test/ui/issues/issue-17718-const-borrow.stderr @@ -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 = &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 = &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