Change:
The build of smoltcp on nightly started failing recently with an ICE: https://travis- ~I suspect this might be caused by E0713, but it shouldn't be an ICE in any case.~
I believe the fundamental cause of the error is that the code looks like the following: That's pretty obviously unsound.
Correction for earlier comment: E0713 is completely unrelated. I've eliminated the problematic code that caused it in m-labs/smoltcp but the crash is still there.
cc (also, such an ICE should say "const checking" or similar - we should maybe even rename the pass itself in the compiler - the "qualify" part isn't as primary for MIR as it is for the AST side).
<details<summaryFull backtrace</summary</details<details<summaryfunction </summary</details
MCVE: : ok : ICE I'm bisecting it now.
Bisected to / .
Oh, I forgot about the ZST trickery, sorry, will have a fix tomorrow
What's the ZST here? in ?
Yes. That's a that gets unsized to .

Discussion:
//! 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. <del> use rustc::ty::layout::LayoutOf; </del> use rustc::ty::{Ty, TyCtxt, ParamEnv, self}; use rustc::mir::interpret::{ InterpResult, ErrorHandled,

// 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; <del> if let ty::Ref(_, _, mutability) = ty.sty { </del> <ins> if let ty::Ref(_, referenced_ty, mutability) = ty.sty { </ins> let value = self.ecx.read_immediate(mplace.into())?; // Handle trait object vtables if let Ok(meta) = value.to_meta() { <del> 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)?; } </del> <ins> 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)?; </ins> } } }

(InternMode::Static, hir::Mutability::MutMutable) => {}, // we statically prevent `&mut T` via `const_qualif` and double check this here (InternMode::ConstBase, hir::Mutability::MutMutable) | <del> (InternMode::Const, hir::Mutability::MutMutable) => bug!("const qualif failed to prevent mutable references"), </del> <ins> (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"), } }, </ins> } // Compute the mutability with which we'll start visiting the allocation. This is // what gets changed when we encounter an `UnsafeCell`

<ins> // compile-pass fn main() { assert_eq!(&mut [0; 1][..], &mut []); } </ins>

// 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" <ins> // normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC" </ins> #![allow(const_err)]

warning: skipping const checks <del> --> $DIR/mutable_references_ice.rs:26:9 </del> <ins> --> $DIR/mutable_references_ice.rs:27:9 </ins> | LL |         *MUH.x.get() = 99; |         ^^^^^^^^^^^^^^^^^ thread 'rustc' panicked at 'assertion failed: `(left != right)` left: `Const`, <del> 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 </del> <ins> 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 </ins> note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. error: internal compiler error: unexpected panic