Skip to content

Commit 544a6a7

Browse files
committed
const_refs_to_cell: dont let mutable references sneak past the interior mutability check
1 parent 9ad5728 commit 544a6a7

File tree

5 files changed

+59
-11
lines changed

5 files changed

+59
-11
lines changed

compiler/rustc_const_eval/src/check_consts/check.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,18 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
433433
// `TransientCellBorrow` (we consider the equivalent mutable case a
434434
// `TransientMutBorrow`), but such reborrows got accidentally stabilized already and
435435
// it is too much of a breaking change to take back.
436-
if borrowed_place_has_mut_interior && !place.is_indirect() {
436+
// However, we only want to consider places that are obtained by dereferencing
437+
// a *shared* reference. Mutable references to interior mutable data are stable,
438+
// and we don't want `&*&mut interior_mut` to be accepted.
439+
let is_indirect = place.iter_projections().any(|(base, proj)| {
440+
matches!(proj, ProjectionElem::Deref)
441+
&& matches!(
442+
base.ty(self.body, self.tcx).ty.kind(),
443+
ty::Ref(_, _, Mutability::Not) | ty::RawPtr(_, Mutability::Not)
444+
)
445+
});
446+
447+
if borrowed_place_has_mut_interior && !is_indirect {
437448
match self.const_kind() {
438449
// In a const fn all borrows are transient or point to the places given via
439450
// references in the arguments (so we already checked them with

library/core/src/slice/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@ impl<T> [T] {
846846
/// [`as_mut_ptr`]: slice::as_mut_ptr
847847
#[stable(feature = "slice_ptr_range", since = "1.48.0")]
848848
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
849-
#[rustc_allow_const_fn_unstable(const_mut_refs)]
849+
#[rustc_allow_const_fn_unstable(const_mut_refs, const_refs_to_cell)]
850850
#[inline]
851851
#[must_use]
852852
pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> {
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
//@ check-pass
2-
3-
#![feature(const_refs_to_cell)]
4-
51
const FOO: () = {
62
let x = std::cell::Cell::new(42);
7-
let y = &x;
3+
let y = &x; //~ERROR: cannot borrow here
4+
};
5+
6+
const FOO2: () = {
7+
let mut x = std::cell::Cell::new(42);
8+
let y = &*&mut x; //~ERROR: cannot borrow here
9+
};
10+
11+
const FOO3: () = unsafe {
12+
let mut x = std::cell::Cell::new(42);
13+
let y = &*(&mut x as *mut _); //~ERROR: cannot borrow here
814
};
915

10-
fn main() {
11-
FOO;
12-
}
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
2+
--> $DIR/feature-gate-const_refs_to_cell.rs:3:13
3+
|
4+
LL | let y = &x;
5+
| ^^
6+
|
7+
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
8+
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
12+
--> $DIR/feature-gate-const_refs_to_cell.rs:8:13
13+
|
14+
LL | let y = &*&mut x;
15+
| ^^^^^^^^
16+
|
17+
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
18+
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
19+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
20+
21+
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
22+
--> $DIR/feature-gate-const_refs_to_cell.rs:13:13
23+
|
24+
LL | let y = &*(&mut x as *mut _);
25+
| ^^^^^^^^^^^^^^^^^^^^
26+
|
27+
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
28+
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
29+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
30+
31+
error: aborting due to 3 previous errors
32+
33+
For more information about this error, try `rustc --explain E0658`.

tests/ui/statics/mutable_memory_validation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
55
//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
66

7-
#![feature(const_refs_to_static)]
7+
#![feature(const_refs_to_static, const_refs_to_cell)]
88

99
use std::cell::UnsafeCell;
1010

0 commit comments

Comments
 (0)