]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/interpret/intern.rs
Don't ICE on mutable zst slices
[rust.git] / src / librustc_mir / interpret / intern.rs
index c7545b7101c5c946aec3e7eec75d6323054b4507..f0d64e217a28fe5c2eb430f41ef39988f2bb8a63 100644 (file)
@@ -147,13 +147,13 @@ fn visit_primitive(&mut self, mplace: MPlaceTy<'tcx>) -> InterpResult<'tcx> {
             // 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 @@ 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`