/// Used only for types with layout::abi::Scalar ABI and ZSTs
Scalar(Scalar),
/// Used only for types with layout::abi::ScalarPair
- ScalarPair(Scalar, Scalar),
+ ///
+ /// The second field may be undef in case of `Option<usize>::None`
+ ScalarPair(Scalar, ScalarMaybeUndef),
/// Used only for the remaining cases. An allocation + offset into the allocation
ByRef(&'tcx Allocation, Size),
}
pub fn from_byval_value(val: Value) -> EvalResult<'static, Self> {
Ok(match val {
Value::ByRef(..) => bug!(),
- Value::ScalarPair(a, b) => ConstValue::ScalarPair(
- a.unwrap_or_err()?,
- b.unwrap_or_err()?,
- ),
+ Value::ScalarPair(a, b) => ConstValue::ScalarPair(a.unwrap_or_err()?, b),
Value::Scalar(val) => ConstValue::Scalar(val.unwrap_or_err()?),
})
}
match *self {
ConstValue::Unevaluated(..) |
ConstValue::ByRef(..) => None,
- ConstValue::ScalarPair(a, b) => Some(Value::ScalarPair(a.into(), b.into())),
+ ConstValue::ScalarPair(a, b) => Some(Value::ScalarPair(a.into(), b)),
ConstValue::Scalar(val) => Some(Value::Scalar(val.into())),
}
}
use rustc::mir::interpret::ConstEvalErr;
use rustc::mir;
-use rustc::mir::interpret::ConstValue;
+use rustc::mir::interpret::{ConstValue, ScalarMaybeUndef};
use rustc::ty;
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
use rustc_data_structures::indexed_vec::Idx;
a_scalar,
layout.scalar_pair_element_llvm_type(bx.cx, 0, true),
);
- let b_llval = scalar_to_llvm(
- bx.cx,
- b,
- b_scalar,
- layout.scalar_pair_element_llvm_type(bx.cx, 1, true),
- );
+ let b_layout = layout.scalar_pair_element_llvm_type(bx.cx, 1, true);
+ let b_llval = match b {
+ ScalarMaybeUndef::Scalar(b) => scalar_to_llvm(
+ bx.cx,
+ b,
+ b_scalar,
+ b_layout,
+ ),
+ ScalarMaybeUndef::Undef => C_undef(b_layout),
+ };
OperandValue::Pair(a_llval, b_llval)
},
ConstValue::ByRef(alloc, offset) => {
len_b,
),
) if ptr_a.offset.bytes() == 0 && ptr_b.offset.bytes() == 0 => {
+ let len_a = len_a.unwrap_or_err().ok();
+ let len_b = len_b.unwrap_or_err().ok();
+ if len_a.is_none() || len_b.is_none() {
+ tcx.sess.struct_err("str slice len is undef").delay_as_bug();
+ }
+ let len_a = len_a?;
+ let len_b = len_b?;
if let Ok(len_a) = len_a.to_bits(tcx.data_layout.pointer_size) {
if let Ok(len_b) = len_b.to_bits(tcx.data_layout.pointer_size) {
if len_a == len_b {
}
let val = match val {
Value::Scalar(val) => ConstValue::Scalar(val.unwrap_or_err()?),
- Value::ScalarPair(a, b) => ConstValue::ScalarPair(a.unwrap_or_err()?, b.unwrap_or_err()?),
+ Value::ScalarPair(a, b) => ConstValue::ScalarPair(a.unwrap_or_err()?, b),
Value::ByRef(ptr, align) => {
let ptr = ptr.to_ptr().unwrap();
let alloc = ecx.memory.get(ptr.alloc_id)?;
use rustc::hir::map as hir_map;
use rustc::hir::def_id::DefId;
-use rustc::mir::interpret::{AllocId, ConstValue};
+use rustc::mir::interpret::{AllocId, ConstValue, ScalarMaybeUndef};
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
use rustc::ty::subst::Substs;
use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind};
};
match val {
ConstValue::Unevaluated(..) => bug!("const eval yielded unevaluated const"),
- ConstValue::ScalarPair(Scalar::Ptr(a), Scalar::Ptr(b)) => {
+ ConstValue::ScalarPair(Scalar::Ptr(a), ScalarMaybeUndef::Scalar(Scalar::Ptr(b))) => {
collect_miri(tcx, a.alloc_id, output);
collect_miri(tcx, b.alloc_id, output);
}
- ConstValue::ScalarPair(_, Scalar::Ptr(ptr)) |
+ ConstValue::ScalarPair(_, ScalarMaybeUndef::Scalar(Scalar::Ptr(ptr))) |
ConstValue::ScalarPair(Scalar::Ptr(ptr), _) |
ConstValue::Scalar(Scalar::Ptr(ptr)) =>
collect_miri(tcx, ptr.alloc_id, output),
enum Bar {
Boo = [unsafe { Foo { b: () }.a }; 4][3],
- //~^ ERROR constant evaluation of enum discriminant resulted in non-integer
+ //~^ ERROR could not evaluate enum discriminant
}
fn main() {