mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 16:15:03 +00:00
Add a variant to ConstVal for storing miri results
This commit is contained in:
parent
cdcca78646
commit
38b5ddd39b
@ -21,6 +21,7 @@ use std::mem;
|
||||
use middle::region;
|
||||
use traits;
|
||||
use ty;
|
||||
use mir;
|
||||
|
||||
impl<'gcx, T> HashStable<StableHashingContext<'gcx>>
|
||||
for &'gcx ty::Slice<T>
|
||||
@ -388,6 +389,9 @@ for ::middle::const_val::ConstVal<'gcx> {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
substs.hash_stable(hcx, hasher);
|
||||
}
|
||||
Value(ref value) => {
|
||||
value.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -396,6 +400,26 @@ impl_stable_hash_for!(struct ::middle::const_val::ByteArray<'tcx> {
|
||||
data
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(enum mir::interpret::Value {
|
||||
ByVal(v),
|
||||
ByValPair(a, b),
|
||||
ByRef(ptr, align)
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct mir::interpret::MemoryPointer {
|
||||
alloc_id,
|
||||
offset
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(tuple_struct mir::interpret::AllocId{id});
|
||||
impl_stable_hash_for!(struct mir::interpret::Pointer{primval});
|
||||
|
||||
impl_stable_hash_for!(enum mir::interpret::PrimVal {
|
||||
Bytes(b),
|
||||
Ptr(p),
|
||||
Undef
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct ty::Const<'tcx> {
|
||||
ty,
|
||||
val
|
||||
|
@ -49,6 +49,7 @@
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(drain_filter)]
|
||||
#![feature(dyn_trait)]
|
||||
#![feature(entry_or_default)]
|
||||
#![feature(from_ref)]
|
||||
#![feature(fs_read_write)]
|
||||
#![feature(i128)]
|
||||
|
@ -14,6 +14,7 @@ use hir::def_id::DefId;
|
||||
use ty::{self, TyCtxt, layout};
|
||||
use ty::subst::Substs;
|
||||
use rustc_const_math::*;
|
||||
use mir::interpret::Value;
|
||||
|
||||
use graphviz::IntoCow;
|
||||
use errors::DiagnosticBuilder;
|
||||
@ -38,6 +39,8 @@ pub enum ConstVal<'tcx> {
|
||||
Function(DefId, &'tcx Substs<'tcx>),
|
||||
Aggregate(ConstAggregate<'tcx>),
|
||||
Unevaluated(DefId, &'tcx Substs<'tcx>),
|
||||
/// A miri value, currently only produced if old ctfe fails, but miri succeeds
|
||||
Value(Value),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, RustcEncodable, Eq, PartialEq)]
|
||||
|
@ -41,7 +41,7 @@ pub enum AccessKind {
|
||||
}
|
||||
|
||||
/// Uniquely identifies a specific constant or static.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub struct GlobalId<'tcx> {
|
||||
/// For a constant or static, the `Instance` of the item itself.
|
||||
/// For a promoted global, the `Instance` of the function they belong to.
|
||||
@ -101,7 +101,7 @@ pub trait PointerArithmetic: layout::HasDataLayout {
|
||||
impl<T: layout::HasDataLayout> PointerArithmetic for T {}
|
||||
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
|
||||
pub struct MemoryPointer {
|
||||
pub alloc_id: AllocId,
|
||||
pub offset: u64,
|
||||
@ -148,13 +148,16 @@ impl<'tcx> MemoryPointer {
|
||||
#[derive(Copy, Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
|
||||
pub struct AllocId(pub u64);
|
||||
|
||||
impl ::rustc_serialize::UseSpecializedEncodable for AllocId {}
|
||||
impl ::rustc_serialize::UseSpecializedDecodable for AllocId {}
|
||||
|
||||
impl fmt::Display for AllocId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub struct Allocation {
|
||||
/// The actual bytes of the allocation.
|
||||
/// Note that the bytes of a pointer represent the offset of the pointer
|
||||
@ -188,7 +191,7 @@ impl Allocation {
|
||||
type Block = u64;
|
||||
const BLOCK_SIZE: u64 = 64;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub struct UndefMask {
|
||||
blocks: Vec<Block>,
|
||||
len: u64,
|
||||
|
@ -29,7 +29,7 @@ pub fn bytes_to_f64(bits: u128) -> ConstFloat {
|
||||
/// For optimization of a few very common cases, there is also a representation for a pair of
|
||||
/// primitive values (`ByValPair`). It allows Miri to avoid making allocations for checked binary
|
||||
/// operations and fat pointers. This idea was taken from rustc's trans.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
|
||||
pub enum Value {
|
||||
ByRef(Pointer, Align),
|
||||
ByVal(PrimVal),
|
||||
@ -43,9 +43,9 @@ pub enum Value {
|
||||
/// I (@oli-obk) believe it is less easy to mix up generic primvals and primvals that are just
|
||||
/// the representation of pointers. Also all the sites that convert between primvals and pointers
|
||||
/// are explicit now (and rare!)
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
|
||||
pub struct Pointer {
|
||||
primval: PrimVal,
|
||||
pub primval: PrimVal,
|
||||
}
|
||||
|
||||
impl<'tcx> Pointer {
|
||||
@ -138,7 +138,7 @@ impl ::std::convert::From<MemoryPointer> for Pointer {
|
||||
/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
|
||||
/// size. Like a range of bytes in an `Allocation`, a `PrimVal` can either represent the raw bytes
|
||||
/// of a simple value, a pointer into another `Allocation`, or be undefined.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
|
||||
pub enum PrimVal {
|
||||
/// The raw bytes of a simple value.
|
||||
Bytes(u128),
|
||||
|
@ -1881,7 +1881,8 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ConstVal) -> fmt::Result {
|
||||
Variant(def_id) |
|
||||
Function(def_id, _) => write!(fmt, "{}", item_path_str(def_id)),
|
||||
Aggregate(_) => bug!("`ConstVal::{:?}` should not be in MIR", const_val),
|
||||
Unevaluated(..) => write!(fmt, "{:?}", const_val)
|
||||
Unevaluated(..) => write!(fmt, "{:?}", const_val),
|
||||
Value(val) => write!(fmt, "{:?}", val),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -905,6 +905,11 @@ pub struct InterpretInterner<'tcx> {
|
||||
/// Allows obtaining const allocs via a unique identifier
|
||||
alloc_by_id: FxHashMap<interpret::AllocId, &'tcx interpret::Allocation>,
|
||||
|
||||
/// Reverse map of `alloc_cache`
|
||||
///
|
||||
/// Multiple globals may share the same memory
|
||||
global_cache: FxHashMap<interpret::Pointer, Vec<interpret::GlobalId<'tcx>>>,
|
||||
|
||||
/// The AllocId to assign to the next new regular allocation.
|
||||
/// Always incremented, never gets smaller.
|
||||
next_id: interpret::AllocId,
|
||||
@ -955,11 +960,25 @@ impl<'tcx> InterpretInterner<'tcx> {
|
||||
global_id: interpret::GlobalId<'tcx>,
|
||||
ptr: interpret::AllocId,
|
||||
) {
|
||||
if let interpret::PrimVal::Ptr(ptr) = ptr.primval {
|
||||
assert!(ptr.offset == 0);
|
||||
}
|
||||
self.global_cache.entry(ptr).or_default().push(global_id);
|
||||
if let Some(old) = self.alloc_cache.insert(global_id, ptr) {
|
||||
bug!("tried to cache {:?}, but was already existing as {:#?}", global_id, old);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_globals(
|
||||
&self,
|
||||
ptr: interpret::Pointer,
|
||||
) -> &[interpret::GlobalId<'tcx>] {
|
||||
match self.global_cache.get(&ptr) {
|
||||
Some(v) => v,
|
||||
None => &[],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn intern_at_reserved(
|
||||
&mut self,
|
||||
id: interpret::AllocId,
|
||||
|
@ -224,6 +224,7 @@ impl FlagComputation {
|
||||
ConstVal::ByteStr(_) |
|
||||
ConstVal::Bool(_) |
|
||||
ConstVal::Char(_) |
|
||||
ConstVal::Value(_) |
|
||||
ConstVal::Variant(_) => {}
|
||||
ConstVal::Function(_, substs) => {
|
||||
self.add_substs(substs);
|
||||
|
@ -17,13 +17,13 @@ use util::ppaux;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct Instance<'tcx> {
|
||||
pub def: InstanceDef<'tcx>,
|
||||
pub substs: &'tcx Substs<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub enum InstanceDef<'tcx> {
|
||||
Item(DefId),
|
||||
Intrinsic(DefId),
|
||||
|
@ -342,7 +342,7 @@ impl AddAssign for Size {
|
||||
/// Each field is a power of two, giving the alignment a maximum
|
||||
/// value of 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a i32, with
|
||||
/// a maximum capacity of 2<sup>31</sup> - 1 or 2147483647.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct Align {
|
||||
abi: u8,
|
||||
pref: u8,
|
||||
|
@ -1249,6 +1249,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstVal<'tcx> {
|
||||
ConstVal::ByteStr(b) => ConstVal::ByteStr(b),
|
||||
ConstVal::Bool(b) => ConstVal::Bool(b),
|
||||
ConstVal::Char(c) => ConstVal::Char(c),
|
||||
ConstVal::Value(v) => ConstVal::Value(v),
|
||||
ConstVal::Variant(def_id) => ConstVal::Variant(def_id),
|
||||
ConstVal::Function(def_id, substs) => {
|
||||
ConstVal::Function(def_id, substs.fold_with(folder))
|
||||
@ -1304,6 +1305,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstVal<'tcx> {
|
||||
ConstVal::ByteStr(_) |
|
||||
ConstVal::Bool(_) |
|
||||
ConstVal::Char(_) |
|
||||
ConstVal::Value(_) |
|
||||
ConstVal::Variant(_) => false,
|
||||
ConstVal::Function(_, substs) => substs.visit_with(visitor),
|
||||
ConstVal::Aggregate(ConstAggregate::Struct(fields)) => {
|
||||
|
@ -146,6 +146,7 @@ fn push_const<'tcx>(stack: &mut TypeWalkerStack<'tcx>, constant: &'tcx ty::Const
|
||||
ConstVal::ByteStr(_) |
|
||||
ConstVal::Bool(_) |
|
||||
ConstVal::Char(_) |
|
||||
ConstVal::Value(_) |
|
||||
ConstVal::Variant(_) => {}
|
||||
ConstVal::Function(_, substs) => {
|
||||
stack.extend(substs.types().rev());
|
||||
|
@ -224,6 +224,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
ConstVal::Bool(_) |
|
||||
ConstVal::Char(_) |
|
||||
ConstVal::Variant(_) |
|
||||
ConstVal::Value(_) |
|
||||
ConstVal::Function(..) => {}
|
||||
ConstVal::Aggregate(ConstAggregate::Struct(fields)) => {
|
||||
for &(_, v) in fields {
|
||||
|
@ -121,6 +121,7 @@ fn print_const_val(value: &ConstVal, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
ConstVal::Variant(_) |
|
||||
ConstVal::Function(..) |
|
||||
ConstVal::Aggregate(_) |
|
||||
ConstVal::Value(_) |
|
||||
ConstVal::Unevaluated(..) => bug!("{:?} not printable in a pattern", value)
|
||||
}
|
||||
}
|
||||
|
@ -24,11 +24,12 @@ use rustc::hir::def_id::{CrateNum, DefId, DefIndex,
|
||||
CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc::ich::Fingerprint;
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::mir;
|
||||
use rustc::mir::{self, interpret};
|
||||
use rustc::session::Session;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::codec::TyDecoder;
|
||||
use rustc::mir::Mir;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
|
||||
use std::cell::Ref;
|
||||
use std::collections::BTreeMap;
|
||||
@ -54,6 +55,9 @@ pub struct DecodeContext<'a, 'tcx: 'a> {
|
||||
last_filemap_index: usize,
|
||||
|
||||
lazy_state: LazyState,
|
||||
|
||||
// interpreter allocation cache
|
||||
interpret_alloc_cache: FxHashMap<usize, interpret::AllocId>,
|
||||
}
|
||||
|
||||
/// Abstract over the various ways one can create metadata decoders.
|
||||
@ -72,6 +76,7 @@ pub trait Metadata<'a, 'tcx>: Copy {
|
||||
tcx,
|
||||
last_filemap_index: 0,
|
||||
lazy_state: LazyState::NoNode,
|
||||
interpret_alloc_cache: FxHashMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -268,6 +273,45 @@ impl<'a, 'tcx> SpecializedDecoder<DefIndex> for DecodeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> SpecializedDecoder<interpret::AllocId> for DecodeContext<'a, 'tcx> {
|
||||
fn specialized_decode(&mut self) -> Result<interpret::AllocId, Self::Error> {
|
||||
const MAX1: usize = usize::max_value() - 1;
|
||||
let mut interpret_interner = self.tcx.unwrap().interpret_interner.borrow_mut();
|
||||
let pos = self.position();
|
||||
match self.read_usize()? {
|
||||
::std::usize::MAX => {
|
||||
let allocation = interpret::Allocation::decode(self)?;
|
||||
let id = interpret_interner.reserve();
|
||||
let allocation = self.tcx.unwrap().intern_const_alloc(allocation);
|
||||
interpret_interner.intern_at_reserved(id, allocation);
|
||||
let id = interpret::AllocId(id);
|
||||
self.interpret_alloc_cache.insert(pos, id);
|
||||
|
||||
let num = usize::decode(self)?;
|
||||
let ptr = interpret::Pointer {
|
||||
primval: interpret::PrimVal::Ptr(interpret::MemoryPointer {
|
||||
alloc_id: id,
|
||||
offset: 0,
|
||||
}),
|
||||
};
|
||||
for _ in 0..num {
|
||||
let glob = interpret::GlobalId::decode(self)?;
|
||||
interpret_interner.cache(glob, ptr);
|
||||
}
|
||||
|
||||
Ok(id)
|
||||
},
|
||||
MAX1 => {
|
||||
let instance = ty::Instance::decode(self)?;
|
||||
let id = interpret::AllocId(interpret_interner.create_fn_alloc(instance));
|
||||
self.interpret_alloc_cache.insert(pos, id);
|
||||
Ok(id)
|
||||
},
|
||||
shorthand => Ok(self.interpret_alloc_cache[&shorthand]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
|
||||
fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
|
||||
let tag = u8::decode(self)?;
|
||||
|
@ -23,7 +23,7 @@ use rustc::middle::dependency_format::Linkage;
|
||||
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel,
|
||||
metadata_symbol_name};
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::mir;
|
||||
use rustc::mir::{self, interpret};
|
||||
use rustc::traits::specialization_graph;
|
||||
use rustc::ty::{self, Ty, TyCtxt, ReprOptions, SymbolName};
|
||||
use rustc::ty::codec::{self as ty_codec, TyEncoder};
|
||||
@ -59,6 +59,7 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
|
||||
lazy_state: LazyState,
|
||||
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
|
||||
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
|
||||
interpret_alloc_shorthands: FxHashMap<interpret::AllocId, usize>,
|
||||
|
||||
// This is used to speed up Span encoding.
|
||||
filemap_cache: Lrc<FileMap>,
|
||||
@ -186,6 +187,41 @@ impl<'a, 'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'a, 'tcx> {
|
||||
fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
|
||||
if let Some(shorthand) = self.interpret_alloc_shorthands.get(alloc_id).cloned() {
|
||||
return self.emit_usize(shorthand);
|
||||
}
|
||||
let start = self.position();
|
||||
let interpret_interner = self.tcx.interpret_interner.borrow();
|
||||
if let Some(alloc) = interpret_interner.get_alloc(alloc_id.0) {
|
||||
usize::max_value().encode(self)?;
|
||||
alloc.encode(self)?;
|
||||
let globals = interpret_interner.get_globals(interpret::Pointer {
|
||||
primval: interpret::PrimVal::Ptr(interpret::MemoryPointer {
|
||||
alloc_id: *alloc_id,
|
||||
offset: 0,
|
||||
}),
|
||||
});
|
||||
globals.len().encode(self)?;
|
||||
for glob in globals {
|
||||
glob.encode(self)?;
|
||||
}
|
||||
} else if let Some(fn_instance) = interpret_interner.get_fn(alloc_id.0) {
|
||||
(usize::max_value() - 1).encode(self)?;
|
||||
fn_instance.encode(self)?;
|
||||
} else {
|
||||
bug!("alloc id without corresponding allocation: {}", alloc_id.0);
|
||||
}
|
||||
let len = self.position() - start * 7;
|
||||
// Check that the shorthand is a not longer than the
|
||||
// full encoding itself, i.e. it's an obvious win.
|
||||
assert!(len >= 64 || (start as u64) < (1 << len));
|
||||
self.interpret_alloc_shorthands.insert(*alloc_id, start);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext<'a, 'tcx> {
|
||||
fn specialized_encode(&mut self,
|
||||
predicates: &ty::GenericPredicates<'tcx>)
|
||||
@ -1699,6 +1735,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
type_shorthands: Default::default(),
|
||||
predicate_shorthands: Default::default(),
|
||||
filemap_cache: tcx.sess.codemap().files()[0].clone(),
|
||||
interpret_alloc_shorthands: Default::default(),
|
||||
};
|
||||
|
||||
// Encode the rustc version string in a predictable location.
|
||||
|
@ -241,24 +241,24 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
||||
}
|
||||
|
||||
pub(super) fn const_to_value(&mut self, const_val: &ConstVal<'tcx>, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
|
||||
use rustc::middle::const_val::ConstVal::*;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
|
||||
let primval = match *const_val {
|
||||
Integral(const_int) => PrimVal::Bytes(const_int.to_u128_unchecked()),
|
||||
ConstVal::Integral(const_int) => PrimVal::Bytes(const_int.to_u128_unchecked()),
|
||||
|
||||
Float(val) => PrimVal::Bytes(val.bits),
|
||||
ConstVal::Float(val) => PrimVal::Bytes(val.bits),
|
||||
|
||||
Bool(b) => PrimVal::from_bool(b),
|
||||
Char(c) => PrimVal::from_char(c),
|
||||
ConstVal::Bool(b) => PrimVal::from_bool(b),
|
||||
ConstVal::Char(c) => PrimVal::from_char(c),
|
||||
|
||||
Str(ref s) => return self.str_to_value(s),
|
||||
ConstVal::Str(ref s) => return self.str_to_value(s),
|
||||
|
||||
ByteStr(ref bs) => {
|
||||
ConstVal::ByteStr(ref bs) => {
|
||||
let ptr = self.memory.allocate_cached(bs.data);
|
||||
PrimVal::Ptr(ptr)
|
||||
}
|
||||
|
||||
Unevaluated(def_id, substs) => {
|
||||
ConstVal::Unevaluated(def_id, substs) => {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
return Ok(self.read_global_as_value(GlobalId {
|
||||
instance,
|
||||
@ -266,10 +266,11 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
||||
}, self.layout_of(ty)?));
|
||||
}
|
||||
|
||||
Aggregate(..) |
|
||||
Variant(_) => bug!("should not have aggregate or variant constants in MIR"),
|
||||
ConstVal::Aggregate(..) |
|
||||
ConstVal::Variant(_) => bug!("should not have aggregate or variant constants in MIR"),
|
||||
// function items are zero sized and thus have no readable value
|
||||
Function(..) => PrimVal::Undef,
|
||||
ConstVal::Function(..) => PrimVal::Undef,
|
||||
ConstVal::Value(val) => return Ok(val),
|
||||
};
|
||||
|
||||
Ok(Value::ByVal(primval))
|
||||
|
@ -108,6 +108,7 @@ impl<'a, 'tcx> Const<'tcx> {
|
||||
ConstVal::Unevaluated(..) => {
|
||||
bug!("MIR must not use `{:?}` (aggregates are expanded to MIR rvalues)", cv)
|
||||
}
|
||||
ConstVal::Value(_) => unimplemented!(),
|
||||
};
|
||||
|
||||
assert!(!ty.has_erasable_regions());
|
||||
|
Loading…
Reference in New Issue
Block a user