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:
parent
b285e0c5d8
commit
bc4931ed7e
4 changed files with 63 additions and 12 deletions
compiler/rustc_const_eval/src/transform/check_consts
src/test/ui/consts
|
@ -94,11 +94,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_of_allows_mutation(&self, mt: mir::Mutability, place: mir::Place<'tcx>) -> bool {
|
fn address_of_allows_mutation(&self, _mt: mir::Mutability, _place: mir::Place<'tcx>) -> bool {
|
||||||
match mt {
|
// Exact set of permissions granted by AddressOf is undecided. Conservatively assume that
|
||||||
mir::Mutability::Mut => true,
|
// it might allow mutation until resolution of #56604.
|
||||||
mir::Mutability::Not => self.shared_borrow_allows_mutation(place),
|
true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool {
|
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
|
/// 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
|
/// `Freeze`, then use pointer arithmetic to derive a pointer to a *different* field of
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![feature(const_precise_live_drops)]
|
#![feature(const_precise_live_drops)]
|
||||||
#![feature(const_swap)]
|
#![feature(const_swap)]
|
||||||
|
#![feature(raw_ref_op)]
|
||||||
|
|
||||||
// Mutable borrow of a field with drop impl.
|
// Mutable borrow of a field with drop impl.
|
||||||
pub const fn f() {
|
pub const fn f() {
|
||||||
|
@ -42,3 +43,22 @@ pub const fn g2<T>() {
|
||||||
let _ = x.is_some();
|
let _ = x.is_some();
|
||||||
let _y = x; //~ ERROR destructors cannot be evaluated
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -1,33 +1,57 @@
|
||||||
error[E0493]: destructors cannot be evaluated at compile-time
|
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);
|
LL | let mut a: (u32, Option<String>) = (0, None);
|
||||||
| ^^^^^ constant functions cannot evaluate destructors
|
| ^^^^^ constant functions cannot evaluate destructors
|
||||||
|
|
||||||
error[E0493]: destructors cannot be evaluated at compile-time
|
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;
|
LL | let mut x = None;
|
||||||
| ^^^^^ constants cannot evaluate destructors
|
| ^^^^^ constants cannot evaluate destructors
|
||||||
|
|
||||||
error[E0493]: destructors cannot be evaluated at compile-time
|
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;
|
LL | let _z = x;
|
||||||
| ^^ constants cannot evaluate destructors
|
| ^^ constants cannot evaluate destructors
|
||||||
|
|
||||||
error[E0493]: destructors cannot be evaluated at compile-time
|
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;
|
LL | let x: Option<T> = None;
|
||||||
| ^ constant functions cannot evaluate destructors
|
| ^ constant functions cannot evaluate destructors
|
||||||
|
|
||||||
error[E0493]: destructors cannot be evaluated at compile-time
|
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;
|
LL | let _y = x;
|
||||||
| ^^ constant functions cannot evaluate destructors
|
| ^^ 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`.
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![feature(const_precise_live_drops)]
|
#![feature(const_precise_live_drops)]
|
||||||
|
|
||||||
|
// Mutable reference allows only mutation of !Drop place.
|
||||||
pub const fn f() {
|
pub const fn f() {
|
||||||
let mut x: (Option<String>, u32) = (None, 0);
|
let mut x: (Option<String>, u32) = (None, 0);
|
||||||
let mut a = 10;
|
let mut a = 10;
|
||||||
|
@ -10,7 +11,14 @@ pub const fn f() {
|
||||||
x.1 = a;
|
x.1 = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mutable reference allows only mutation of !Drop place.
|
||||||
pub const fn g() {
|
pub const fn g() {
|
||||||
let mut a: (u32, Option<String>) = (0, None);
|
let mut a: (u32, Option<String>) = (0, None);
|
||||||
let _ = &mut a.0;
|
let _ = &mut a.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shared reference does not allow for mutation.
|
||||||
|
pub const fn h() {
|
||||||
|
let x: Option<String> = None;
|
||||||
|
let _ = &x;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue