From 354163d478a4fc089af07203948036c4b1e237d3 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 24 Jun 2019 15:31:25 +0200 Subject: [PATCH 1/4] Simplify vtable interning --- src/librustc_mir/interpret/intern.rs | 8 ++------ .../ui/consts/miri_unleashed/mutable_references_ice.rs | 1 + .../consts/miri_unleashed/mutable_references_ice.stderr | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 416b66daa0594..c7545b7101c5c 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -3,7 +3,6 @@ //! After a const evaluation has computed a value, before we destroy the const evaluator's session //! memory, we need to extract all memory allocations to the global memory pool so they stay around. -use rustc::ty::layout::LayoutOf; use rustc::ty::{Ty, TyCtxt, ParamEnv, self}; use rustc::mir::interpret::{ InterpResult, ErrorHandled, @@ -143,13 +142,11 @@ for // Handle Reference types, as these are the only relocations supported by const eval. // Raw pointers (and boxes) are handled by the `leftover_relocations` logic. let ty = mplace.layout.ty; - if let ty::Ref(_, _, mutability) = ty.sty { + if let ty::Ref(_, referenced_ty, mutability) = ty.sty { let value = self.ecx.read_immediate(mplace.into())?; // Handle trait object vtables if let Ok(meta) = value.to_meta() { - let layout = self.ecx.layout_of(ty.builtin_deref(true).unwrap().ty)?; - if layout.is_unsized() { - if let ty::Dynamic(..) = self.ecx.tcx.struct_tail(layout.ty).sty { + if let ty::Dynamic(..) = self.ecx.tcx.struct_tail(referenced_ty).sty { if let Ok(vtable) = meta.unwrap().to_ptr() { // explitly choose `Immutable` here, since vtables are immutable, even // if the reference of the fat pointer is mutable @@ -157,7 +154,6 @@ for } } } - } let mplace = self.ecx.ref_to_mplace(value)?; // Check if we have encountered this pointer+layout combination before. // Only recurse for allocation-backed pointers. diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_ice.rs b/src/test/ui/consts/miri_unleashed/mutable_references_ice.rs index 4a77534c6c70c..9352d9bfd7c02 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_references_ice.rs +++ b/src/test/ui/consts/miri_unleashed/mutable_references_ice.rs @@ -3,6 +3,7 @@ // rustc-env:RUST_BACKTRACE=0 // normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" // normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" +// normalize-stderr-test "src/librustc_mir/interpret/intern.rs:[0-9]*:[0-9]*" -> "src/librustc_mir/interpret/intern.rs:LL:CC" #![allow(const_err)] diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr index ff2351e1fdc50..82569e260143c 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr @@ -1,12 +1,12 @@ warning: skipping const checks - --> $DIR/mutable_references_ice.rs:26:9 + --> $DIR/mutable_references_ice.rs:27:9 | LL | *MUH.x.get() = 99; | ^^^^^^^^^^^^^^^^^ thread 'rustc' panicked at 'assertion failed: `(left != right)` left: `Const`, - right: `Const`: UnsafeCells are not allowed behind references in constants. This should have been prevented statically by const qualification. If this were allowed one would be able to change a constant at one use site and other use sites may arbitrarily decide to change, too.', src/librustc_mir/interpret/intern.rs:127:17 + right: `Const`: UnsafeCells are not allowed behind references in constants. This should have been prevented statically by const qualification. If this were allowed one would be able to change a constant at one use site and other use sites may arbitrarily decide to change, too.', src/librustc_mir/interpret/intern.rs:LL:CC note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. error: internal compiler error: unexpected panic From 6b26fdad0a39c3e0b36cc3a5da8bf81f305aa383 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 24 Jun 2019 15:31:52 +0200 Subject: [PATCH 2/4] Don't ICE on mutable zst slices --- src/librustc_mir/interpret/intern.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index c7545b7101c5c..f0d64e217a28f 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -147,13 +147,13 @@ for // Handle trait object vtables if let Ok(meta) = value.to_meta() { if let ty::Dynamic(..) = self.ecx.tcx.struct_tail(referenced_ty).sty { - if let Ok(vtable) = meta.unwrap().to_ptr() { - // explitly choose `Immutable` here, since vtables are immutable, even - // if the reference of the fat pointer is mutable - self.intern_shallow(vtable, Mutability::Immutable)?; - } + if let Ok(vtable) = meta.unwrap().to_ptr() { + // explitly choose `Immutable` here, since vtables are immutable, even + // if the reference of the fat pointer is mutable + self.intern_shallow(vtable, Mutability::Immutable)?; } } + } let mplace = self.ecx.ref_to_mplace(value)?; // Check if we have encountered this pointer+layout combination before. // Only recurse for allocation-backed pointers. @@ -174,8 +174,14 @@ for (InternMode::Static, hir::Mutability::MutMutable) => {}, // we statically prevent `&mut T` via `const_qualif` and double check this here (InternMode::ConstBase, hir::Mutability::MutMutable) | - (InternMode::Const, hir::Mutability::MutMutable) => - bug!("const qualif failed to prevent mutable references"), + (InternMode::Const, hir::Mutability::MutMutable) => { + match referenced_ty.sty { + ty::Array(_, n) if n.unwrap_usize(self.ecx.tcx.tcx) == 0 => {} + ty::Slice(_) + if value.to_meta().unwrap().unwrap().to_usize(self.ecx)? == 0 => {} + _ => bug!("const qualif failed to prevent mutable references"), + } + }, } // Compute the mutability with which we'll start visiting the allocation. This is // what gets changed when we encounter an `UnsafeCell` From 1140a916f6c6cb1bd863bdbe7a0582f417485673 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 24 Jun 2019 15:34:29 +0200 Subject: [PATCH 3/4] Add regression test --- src/test/ui/consts/issue-62045.rs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/ui/consts/issue-62045.rs diff --git a/src/test/ui/consts/issue-62045.rs b/src/test/ui/consts/issue-62045.rs new file mode 100644 index 0000000000000..d1cfcb0387033 --- /dev/null +++ b/src/test/ui/consts/issue-62045.rs @@ -0,0 +1,6 @@ +// compile-pass + +fn main() { + assert_eq!(&mut [0; 1][..], &mut []); +} + From 91a15e285783b89219b31803eadfe855e38312a4 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 24 Jun 2019 16:34:50 +0200 Subject: [PATCH 4/4] Pacify tidy --- src/test/ui/consts/issue-62045.rs | 1 - src/test/ui/consts/miri_unleashed/mutable_references_ice.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/ui/consts/issue-62045.rs b/src/test/ui/consts/issue-62045.rs index d1cfcb0387033..9f41ed9a24523 100644 --- a/src/test/ui/consts/issue-62045.rs +++ b/src/test/ui/consts/issue-62045.rs @@ -3,4 +3,3 @@ fn main() { assert_eq!(&mut [0; 1][..], &mut []); } - diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_ice.rs b/src/test/ui/consts/miri_unleashed/mutable_references_ice.rs index 9352d9bfd7c02..4fcd89a74db61 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_references_ice.rs +++ b/src/test/ui/consts/miri_unleashed/mutable_references_ice.rs @@ -3,7 +3,7 @@ // rustc-env:RUST_BACKTRACE=0 // normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET" // normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS" -// normalize-stderr-test "src/librustc_mir/interpret/intern.rs:[0-9]*:[0-9]*" -> "src/librustc_mir/interpret/intern.rs:LL:CC" +// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" #![allow(const_err)]