about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2020-10-25 10:22:56 +0100
committerRalf Jung <post@ralfj.de>2020-10-26 08:56:54 +0100
commit9b501edf08e7088c4a9b8fe9b12523b9f421e588 (patch)
treebdf482132f0ea9b803978f3d0633a1a4c4e69810
parent0e014be35971f19001bb58c1e9a904e9f596a052 (diff)
downloadrust-9b501edf08e7088c4a9b8fe9b12523b9f421e588.tar.gz
rust-9b501edf08e7088c4a9b8fe9b12523b9f421e588.zip
move &mut-in-const check from interning to validation
-rw-r--r--compiler/rustc_mir/src/interpret/intern.rs4
-rw-r--r--compiler/rustc_mir/src/interpret/validity.rs10
-rw-r--r--src/test/ui/consts/miri_unleashed/mutable_references_err.rs2
-rw-r--r--src/test/ui/consts/miri_unleashed/mutable_references_err.stderr6
4 files changed, 16 insertions, 6 deletions
diff --git a/compiler/rustc_mir/src/interpret/intern.rs b/compiler/rustc_mir/src/interpret/intern.rs
index 53ce4deeff8..2a889bfb59b 100644
--- a/compiler/rustc_mir/src/interpret/intern.rs
+++ b/compiler/rustc_mir/src/interpret/intern.rs
@@ -263,13 +263,13 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir
                         // This helps to prevent users from accidentally exploiting UB that they
                         // caused (by somehow getting a mutable reference in a `const`).
                         if ref_mutability == Mutability::Mut {
-                            match referenced_ty.kind() {
+                            /*match referenced_ty.kind() {
                                 ty::Array(_, n) if n.eval_usize(*tcx, self.ecx.param_env) == 0 => {}
                                 ty::Slice(_)
                                     if mplace.meta.unwrap_meta().to_machine_usize(self.ecx)?
                                         == 0 => {}
                                 _ => mutable_memory_in_const(tcx, "`&mut`"),
-                            }
+                            }*/
                         } else {
                             // A shared reference. We cannot check `freeze` here due to references
                             // like `&dyn Trait` that are actually immutable.  We do check for
diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs
index 3026b6c6c49..1c3dc1cfd0f 100644
--- a/compiler/rustc_mir/src/interpret/validity.rs
+++ b/compiler/rustc_mir/src/interpret/validity.rs
@@ -540,7 +540,15 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                 }
                 Ok(true)
             }
-            ty::Ref(..) => {
+            ty::Ref(_, ty, mutbl) => {
+                if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) && *mutbl == hir::Mutability::Mut {
+                    // A mutable reference inside a const? That does not seem right (except of it is
+                    // a ZST).
+                    let layout = self.ecx.layout_of(ty)?;
+                    if !layout.is_zst() {
+                        throw_validation_failure!(self.path, { "mutable reference in a `const`" });
+                    }
+                }
                 self.check_safe_pointer(value, "reference")?;
                 Ok(true)
             }
diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_err.rs b/src/test/ui/consts/miri_unleashed/mutable_references_err.rs
index e9f6f9140e7..195414dbad9 100644
--- a/src/test/ui/consts/miri_unleashed/mutable_references_err.rs
+++ b/src/test/ui/consts/miri_unleashed/mutable_references_err.rs
@@ -28,7 +28,7 @@ const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
 
 // Make sure we also catch mutable references.
 const BLUNT: &mut i32 = &mut 42;
-//~^ ERROR: mutable memory (`&mut`) is not allowed in constant
+//~^ ERROR: it is undefined behavior to use this value
 
 fn main() {
     unsafe {
diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_err.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_err.stderr
index b5b34642ed1..0c206dd51aa 100644
--- a/src/test/ui/consts/miri_unleashed/mutable_references_err.stderr
+++ b/src/test/ui/consts/miri_unleashed/mutable_references_err.stderr
@@ -16,11 +16,13 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
-error: mutable memory (`&mut`) is not allowed in constant
+error[E0080]: it is undefined behavior to use this value
   --> $DIR/mutable_references_err.rs:30:1
    |
 LL | const BLUNT: &mut i32 = &mut 42;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered mutable reference in a `const`
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 warning: skipping const checks
    |