`addr_of!` grants mutable access, maybe?

The exact set of permissions granted when forming a raw reference is
currently undecided https://github.com/rust-lang/rust/issues/56604.

To avoid presupposing any particular outcome, adjust the const
qualification to be compatible with decision where raw reference
constructed from `addr_of!` grants mutable access.
This commit is contained in:
Tomasz Miąsko 2021-10-30 00:00:00 +00:00
parent b285e0c5d8
commit bc4931ed7e
4 changed files with 63 additions and 12 deletions

View File

@ -94,11 +94,10 @@ where
}
}
fn address_of_allows_mutation(&self, mt: mir::Mutability, place: mir::Place<'tcx>) -> bool {
match mt {
mir::Mutability::Mut => true,
mir::Mutability::Not => self.shared_borrow_allows_mutation(place),
}
fn address_of_allows_mutation(&self, _mt: mir::Mutability, _place: mir::Place<'tcx>) -> bool {
// Exact set of permissions granted by AddressOf is undecided. Conservatively assume that
// it might allow mutation until resolution of #56604.
true
}
fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool {
@ -110,7 +109,7 @@ where
}
}
/// `&` and `&raw` only allow mutation if the borrowed place is `!Freeze`.
/// `&` only allow mutation if the borrowed place is `!Freeze`.
///
/// This assumes that it is UB to take the address of a struct field whose type is
/// `Freeze`, then use pointer arithmetic to derive a pointer to a *different* field of

View File

@ -2,6 +2,7 @@
#![feature(const_mut_refs)]
#![feature(const_precise_live_drops)]
#![feature(const_swap)]
#![feature(raw_ref_op)]
// Mutable borrow of a field with drop impl.
pub const fn f() {
@ -42,3 +43,22 @@ pub const fn g2<T>() {
let _ = x.is_some();
let _y = x; //~ ERROR destructors cannot be evaluated
}
// Mutable raw reference to a Drop type.
pub const fn address_of_mut() {
let mut x: Option<String> = None; //~ ERROR destructors cannot be evaluated
&raw mut x;
let mut y: Option<String> = None; //~ ERROR destructors cannot be evaluated
std::ptr::addr_of_mut!(y);
}
// Const raw reference to a Drop type. Conservatively assumed to allow mutation
// until resolution of https://github.com/rust-lang/rust/issues/56604.
pub const fn address_of_const() {
let x: Option<String> = None; //~ ERROR destructors cannot be evaluated
&raw const x;
let y: Option<String> = None; //~ ERROR destructors cannot be evaluated
std::ptr::addr_of!(y);
}

View File

@ -1,33 +1,57 @@
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:8:9
--> $DIR/qualif-indirect-mutation-fail.rs:9:9
|
LL | let mut a: (u32, Option<String>) = (0, None);
| ^^^^^ constant functions cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:14:9
--> $DIR/qualif-indirect-mutation-fail.rs:15:9
|
LL | let mut x = None;
| ^^^^^ constants cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:30:9
--> $DIR/qualif-indirect-mutation-fail.rs:31:9
|
LL | let _z = x;
| ^^ constants cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:35:9
--> $DIR/qualif-indirect-mutation-fail.rs:36:9
|
LL | let x: Option<T> = None;
| ^ constant functions cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:43:9
--> $DIR/qualif-indirect-mutation-fail.rs:44:9
|
LL | let _y = x;
| ^^ constant functions cannot evaluate destructors
error: aborting due to 5 previous errors
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:52:9
|
LL | let mut y: Option<String> = None;
| ^^^^^ constant functions cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:49:9
|
LL | let mut x: Option<String> = None;
| ^^^^^ constant functions cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:62:9
|
LL | let y: Option<String> = None;
| ^ constant functions cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:59:9
|
LL | let x: Option<String> = None;
| ^ constant functions cannot evaluate destructors
error: aborting due to 9 previous errors
For more information about this error, try `rustc --explain E0493`.

View File

@ -3,6 +3,7 @@
#![feature(const_mut_refs)]
#![feature(const_precise_live_drops)]
// Mutable reference allows only mutation of !Drop place.
pub const fn f() {
let mut x: (Option<String>, u32) = (None, 0);
let mut a = 10;
@ -10,7 +11,14 @@ pub const fn f() {
x.1 = a;
}
// Mutable reference allows only mutation of !Drop place.
pub const fn g() {
let mut a: (u32, Option<String>) = (0, None);
let _ = &mut a.0;
}
// Shared reference does not allow for mutation.
pub const fn h() {
let x: Option<String> = None;
let _ = &x;
}