Skip to content

Commit bc4931e

Browse files
committed
addr_of! grants mutable access, maybe?
The exact set of permissions granted when forming a raw reference is currently undecided #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.
1 parent b285e0c commit bc4931e

File tree

4 files changed

+63
-12
lines changed

4 files changed

+63
-12
lines changed

compiler/rustc_const_eval/src/transform/check_consts/resolver.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,10 @@ where
9494
}
9595
}
9696

97-
fn address_of_allows_mutation(&self, mt: mir::Mutability, place: mir::Place<'tcx>) -> bool {
98-
match mt {
99-
mir::Mutability::Mut => true,
100-
mir::Mutability::Not => self.shared_borrow_allows_mutation(place),
101-
}
97+
fn address_of_allows_mutation(&self, _mt: mir::Mutability, _place: mir::Place<'tcx>) -> bool {
98+
// Exact set of permissions granted by AddressOf is undecided. Conservatively assume that
99+
// it might allow mutation until resolution of #56604.
100+
true
102101
}
103102

104103
fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool {
@@ -110,7 +109,7 @@ where
110109
}
111110
}
112111

113-
/// `&` and `&raw` only allow mutation if the borrowed place is `!Freeze`.
112+
/// `&` only allow mutation if the borrowed place is `!Freeze`.
114113
///
115114
/// This assumes that it is UB to take the address of a struct field whose type is
116115
/// `Freeze`, then use pointer arithmetic to derive a pointer to a *different* field of

src/test/ui/consts/qualif-indirect-mutation-fail.rs

+20
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![feature(const_mut_refs)]
33
#![feature(const_precise_live_drops)]
44
#![feature(const_swap)]
5+
#![feature(raw_ref_op)]
56

67
// Mutable borrow of a field with drop impl.
78
pub const fn f() {
@@ -42,3 +43,22 @@ pub const fn g2<T>() {
4243
let _ = x.is_some();
4344
let _y = x; //~ ERROR destructors cannot be evaluated
4445
}
46+
47+
// Mutable raw reference to a Drop type.
48+
pub const fn address_of_mut() {
49+
let mut x: Option<String> = None; //~ ERROR destructors cannot be evaluated
50+
&raw mut x;
51+
52+
let mut y: Option<String> = None; //~ ERROR destructors cannot be evaluated
53+
std::ptr::addr_of_mut!(y);
54+
}
55+
56+
// Const raw reference to a Drop type. Conservatively assumed to allow mutation
57+
// until resolution of https://github.com/rust-lang/rust/issues/56604.
58+
pub const fn address_of_const() {
59+
let x: Option<String> = None; //~ ERROR destructors cannot be evaluated
60+
&raw const x;
61+
62+
let y: Option<String> = None; //~ ERROR destructors cannot be evaluated
63+
std::ptr::addr_of!(y);
64+
}
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,57 @@
11
error[E0493]: destructors cannot be evaluated at compile-time
2-
--> $DIR/qualif-indirect-mutation-fail.rs:8:9
2+
--> $DIR/qualif-indirect-mutation-fail.rs:9:9
33
|
44
LL | let mut a: (u32, Option<String>) = (0, None);
55
| ^^^^^ constant functions cannot evaluate destructors
66

77
error[E0493]: destructors cannot be evaluated at compile-time
8-
--> $DIR/qualif-indirect-mutation-fail.rs:14:9
8+
--> $DIR/qualif-indirect-mutation-fail.rs:15:9
99
|
1010
LL | let mut x = None;
1111
| ^^^^^ constants cannot evaluate destructors
1212

1313
error[E0493]: destructors cannot be evaluated at compile-time
14-
--> $DIR/qualif-indirect-mutation-fail.rs:30:9
14+
--> $DIR/qualif-indirect-mutation-fail.rs:31:9
1515
|
1616
LL | let _z = x;
1717
| ^^ constants cannot evaluate destructors
1818

1919
error[E0493]: destructors cannot be evaluated at compile-time
20-
--> $DIR/qualif-indirect-mutation-fail.rs:35:9
20+
--> $DIR/qualif-indirect-mutation-fail.rs:36:9
2121
|
2222
LL | let x: Option<T> = None;
2323
| ^ constant functions cannot evaluate destructors
2424

2525
error[E0493]: destructors cannot be evaluated at compile-time
26-
--> $DIR/qualif-indirect-mutation-fail.rs:43:9
26+
--> $DIR/qualif-indirect-mutation-fail.rs:44:9
2727
|
2828
LL | let _y = x;
2929
| ^^ constant functions cannot evaluate destructors
3030

31-
error: aborting due to 5 previous errors
31+
error[E0493]: destructors cannot be evaluated at compile-time
32+
--> $DIR/qualif-indirect-mutation-fail.rs:52:9
33+
|
34+
LL | let mut y: Option<String> = None;
35+
| ^^^^^ constant functions cannot evaluate destructors
36+
37+
error[E0493]: destructors cannot be evaluated at compile-time
38+
--> $DIR/qualif-indirect-mutation-fail.rs:49:9
39+
|
40+
LL | let mut x: Option<String> = None;
41+
| ^^^^^ constant functions cannot evaluate destructors
42+
43+
error[E0493]: destructors cannot be evaluated at compile-time
44+
--> $DIR/qualif-indirect-mutation-fail.rs:62:9
45+
|
46+
LL | let y: Option<String> = None;
47+
| ^ constant functions cannot evaluate destructors
48+
49+
error[E0493]: destructors cannot be evaluated at compile-time
50+
--> $DIR/qualif-indirect-mutation-fail.rs:59:9
51+
|
52+
LL | let x: Option<String> = None;
53+
| ^ constant functions cannot evaluate destructors
54+
55+
error: aborting due to 9 previous errors
3256

3357
For more information about this error, try `rustc --explain E0493`.

src/test/ui/consts/qualif-indirect-mutation-pass.rs

+8
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@
33
#![feature(const_mut_refs)]
44
#![feature(const_precise_live_drops)]
55

6+
// Mutable reference allows only mutation of !Drop place.
67
pub const fn f() {
78
let mut x: (Option<String>, u32) = (None, 0);
89
let mut a = 10;
910
*(&mut a) = 11;
1011
x.1 = a;
1112
}
1213

14+
// Mutable reference allows only mutation of !Drop place.
1315
pub const fn g() {
1416
let mut a: (u32, Option<String>) = (0, None);
1517
let _ = &mut a.0;
1618
}
19+
20+
// Shared reference does not allow for mutation.
21+
pub const fn h() {
22+
let x: Option<String> = None;
23+
let _ = &x;
24+
}

0 commit comments

Comments
 (0)