Skip to content

Commit

Permalink
const_refs_to_cell: dont let mutable references sneak past the interi…
Browse files Browse the repository at this point in the history
…or mutability check
  • Loading branch information
RalfJung committed Sep 15, 2024
1 parent 9ad5728 commit 544a6a7
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 11 deletions.
13 changes: 12 additions & 1 deletion compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,18 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// `TransientCellBorrow` (we consider the equivalent mutable case a
// `TransientMutBorrow`), but such reborrows got accidentally stabilized already and
// it is too much of a breaking change to take back.
if borrowed_place_has_mut_interior && !place.is_indirect() {
// However, we only want to consider places that are obtained by dereferencing
// a *shared* reference. Mutable references to interior mutable data are stable,
// and we don't want `&*&mut interior_mut` to be accepted.
let is_indirect = place.iter_projections().any(|(base, proj)| {
matches!(proj, ProjectionElem::Deref)
&& matches!(
base.ty(self.body, self.tcx).ty.kind(),
ty::Ref(_, _, Mutability::Not) | ty::RawPtr(_, Mutability::Not)
)
});

if borrowed_place_has_mut_interior && !is_indirect {
match self.const_kind() {
// In a const fn all borrows are transient or point to the places given via
// references in the arguments (so we already checked them with
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ impl<T> [T] {
/// [`as_mut_ptr`]: slice::as_mut_ptr
#[stable(feature = "slice_ptr_range", since = "1.48.0")]
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
#[rustc_allow_const_fn_unstable(const_mut_refs)]
#[rustc_allow_const_fn_unstable(const_mut_refs, const_refs_to_cell)]
#[inline]
#[must_use]
pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> {
Expand Down
20 changes: 12 additions & 8 deletions tests/ui/feature-gates/feature-gate-const_refs_to_cell.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
//@ check-pass

#![feature(const_refs_to_cell)]

const FOO: () = {
let x = std::cell::Cell::new(42);
let y = &x;
let y = &x; //~ERROR: cannot borrow here
};

const FOO2: () = {
let mut x = std::cell::Cell::new(42);
let y = &*&mut x; //~ERROR: cannot borrow here
};

const FOO3: () = unsafe {
let mut x = std::cell::Cell::new(42);
let y = &*(&mut x as *mut _); //~ERROR: cannot borrow here
};

fn main() {
FOO;
}
fn main() {}
33 changes: 33 additions & 0 deletions tests/ui/feature-gates/feature-gate-const_refs_to_cell.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/feature-gate-const_refs_to_cell.rs:3:13
|
LL | let y = &x;
| ^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/feature-gate-const_refs_to_cell.rs:8:13
|
LL | let y = &*&mut x;
| ^^^^^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/feature-gate-const_refs_to_cell.rs:13:13
|
LL | let y = &*(&mut x as *mut _);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.
2 changes: 1 addition & 1 deletion tests/ui/statics/mutable_memory_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"

#![feature(const_refs_to_static)]
#![feature(const_refs_to_static, const_refs_to_cell)]

use std::cell::UnsafeCell;

Expand Down

0 comments on commit 544a6a7

Please sign in to comment.