]> git.lizzy.rs Git - rust.git/commitdiff
move &mut-in-const check from interning to validation
authorRalf Jung <post@ralfj.de>
Sun, 25 Oct 2020 09:22:56 +0000 (10:22 +0100)
committerRalf Jung <post@ralfj.de>
Mon, 26 Oct 2020 07:56:54 +0000 (08:56 +0100)
compiler/rustc_mir/src/interpret/intern.rs
compiler/rustc_mir/src/interpret/validity.rs
src/test/ui/consts/miri_unleashed/mutable_references_err.rs
src/test/ui/consts/miri_unleashed/mutable_references_err.stderr

index 53ce4deeff8267cc044db7eceba5355db6eb1549..2a889bfb59bb1dc7c98953bf0c7f7c0db46e3791 100644 (file)
@@ -263,13 +263,13 @@ fn visit_value(&mut self, mplace: MPlaceTy<'tcx>) -> InterpResult<'tcx> {
                         // 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
index 3026b6c6c4931bb9f2a7c9721117bc16fcccb7bf..1c3dc1cfd0f523d7da2ce9d0fb255ac49784f8bd 100644 (file)
@@ -540,7 +540,15 @@ fn try_visit_primitive(
                 }
                 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)
             }
index e9f6f9140e778af0b7d582514d644846fb8e487c..195414dbad9a2395ddce4654f5296c067ae418cb 100644 (file)
@@ -28,7 +28,7 @@ unsafe impl Sync for Synced {}
 
 // 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 {
index b5b34642ed19674378f965e641f169beccb5530d..0c206dd51aaabe2ea2f38fc7134285347fdd4279 100644 (file)
@@ -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
    |