about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/resolver.rs11
-rw-r--r--src/test/ui/consts/qualif-indirect-mutation-fail.rs20
-rw-r--r--src/test/ui/consts/qualif-indirect-mutation-fail.stderr36
-rw-r--r--src/test/ui/consts/qualif-indirect-mutation-pass.rs8
4 files changed, 63 insertions, 12 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
index 2420f31ac08..fcce829eba4 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
@@ -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
diff --git a/src/test/ui/consts/qualif-indirect-mutation-fail.rs b/src/test/ui/consts/qualif-indirect-mutation-fail.rs
index cedead00fec..f74a25a346f 100644
--- a/src/test/ui/consts/qualif-indirect-mutation-fail.rs
+++ b/src/test/ui/consts/qualif-indirect-mutation-fail.rs
@@ -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);
+}
diff --git a/src/test/ui/consts/qualif-indirect-mutation-fail.stderr b/src/test/ui/consts/qualif-indirect-mutation-fail.stderr
index aa6ed465594..713df12b7a5 100644
--- a/src/test/ui/consts/qualif-indirect-mutation-fail.stderr
+++ b/src/test/ui/consts/qualif-indirect-mutation-fail.stderr
@@ -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`.
diff --git a/src/test/ui/consts/qualif-indirect-mutation-pass.rs b/src/test/ui/consts/qualif-indirect-mutation-pass.rs
index 35a9b70a5f6..06af6a03b8f 100644
--- a/src/test/ui/consts/qualif-indirect-mutation-pass.rs
+++ b/src/test/ui/consts/qualif-indirect-mutation-pass.rs
@@ -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;
+}