const_refs_to_cell: dont let mutable references sneak past the interior mutability check

This commit is contained in:
Ralf Jung 2024-08-21 22:30:16 +02:00
parent 9ad5728593
commit 544a6a7df3
5 changed files with 59 additions and 11 deletions

View File

@ -433,7 +433,18 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
// `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

View File

@ -846,7 +846,7 @@ pub const fn as_ptr_range(&self) -> Range<*const 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> {

View File

@ -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
};
fn main() {
FOO;
}
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() {}

View File

@ -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`.

View File

@ -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;