|
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