Auto merge of #62094 - oli-obk:zst_intern, r=eddyb
Don't ICE on mutable zst slices fixes #62045
This commit is contained in:
commit
10deeae326
@ -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,18 +142,15 @@ fn visit_primitive(&mut self, mplace: MPlaceTy<'tcx>) -> InterpResult<'tcx> {
|
||||
// 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 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 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)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -178,8 +174,14 @@ fn visit_primitive(&mut self, mplace: MPlaceTy<'tcx>) -> InterpResult<'tcx> {
|
||||
(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`
|
||||
|
5
src/test/ui/consts/issue-62045.rs
Normal file
5
src/test/ui/consts/issue-62045.rs
Normal file
@ -0,0 +1,5 @@
|
||||
// compile-pass
|
||||
|
||||
fn main() {
|
||||
assert_eq!(&mut [0; 1][..], &mut []);
|
||||
}
|
@ -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 "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC"
|
||||
|
||||
#![allow(const_err)]
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user