|
3 | 3 | //! After a const evaluation has computed a value, before we destroy the const evaluator's session |
4 | 4 | //! memory, we need to extract all memory allocations to the global memory pool so they stay around. |
5 | 5 |
|
6 | | -use rustc::ty::layout::LayoutOf; |
7 | 6 | use rustc::ty::{Ty, TyCtxt, ParamEnv, self}; |
8 | 7 | use rustc::mir::interpret::{ |
9 | 8 | InterpResult, ErrorHandled, |
@@ -143,18 +142,15 @@ for |
143 | 142 | // Handle Reference types, as these are the only relocations supported by const eval. |
144 | 143 | // Raw pointers (and boxes) are handled by the `leftover_relocations` logic. |
145 | 144 | let ty = mplace.layout.ty; |
146 | | - if let ty::Ref(_, _, mutability) = ty.sty { |
| 145 | + if let ty::Ref(_, referenced_ty, mutability) = ty.sty { |
147 | 146 | let value = self.ecx.read_immediate(mplace.into())?; |
148 | 147 | // Handle trait object vtables |
149 | 148 | if let Ok(meta) = value.to_meta() { |
150 | | - let layout = self.ecx.layout_of(ty.builtin_deref(true).unwrap().ty)?; |
151 | | - if layout.is_unsized() { |
152 | | - if let ty::Dynamic(..) = self.ecx.tcx.struct_tail(layout.ty).sty { |
153 | | - if let Ok(vtable) = meta.unwrap().to_ptr() { |
154 | | - // explitly choose `Immutable` here, since vtables are immutable, even |
155 | | - // if the reference of the fat pointer is mutable |
156 | | - self.intern_shallow(vtable, Mutability::Immutable)?; |
157 | | - } |
| 149 | + if let ty::Dynamic(..) = self.ecx.tcx.struct_tail(referenced_ty).sty { |
| 150 | + if let Ok(vtable) = meta.unwrap().to_ptr() { |
| 151 | + // explitly choose `Immutable` here, since vtables are immutable, even |
| 152 | + // if the reference of the fat pointer is mutable |
| 153 | + self.intern_shallow(vtable, Mutability::Immutable)?; |
158 | 154 | } |
159 | 155 | } |
160 | 156 | } |
|
178 | 174 | (InternMode::Static, hir::Mutability::MutMutable) => {}, |
179 | 175 | // we statically prevent `&mut T` via `const_qualif` and double check this here |
180 | 176 | (InternMode::ConstBase, hir::Mutability::MutMutable) | |
181 | | - (InternMode::Const, hir::Mutability::MutMutable) => |
182 | | - bug!("const qualif failed to prevent mutable references"), |
| 177 | + (InternMode::Const, hir::Mutability::MutMutable) => { |
| 178 | + match referenced_ty.sty { |
| 179 | + ty::Array(_, n) if n.unwrap_usize(self.ecx.tcx.tcx) == 0 => {} |
| 180 | + ty::Slice(_) |
| 181 | + if value.to_meta().unwrap().unwrap().to_usize(self.ecx)? == 0 => {} |
| 182 | + _ => bug!("const qualif failed to prevent mutable references"), |
| 183 | + } |
| 184 | + }, |
183 | 185 | } |
184 | 186 | // Compute the mutability with which we'll start visiting the allocation. This is |
185 | 187 | // what gets changed when we encounter an `UnsafeCell` |
|
0 commit comments