Don't abort on unevaluated constants without at least tryting to eval them
This commit is contained in:
parent
437f017e2e
commit
9b87d22ea8
@ -896,7 +896,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||
|
||||
// Always promote `[T; 0]` (even when e.g., borrowed mutably).
|
||||
let promotable = match expr_ty.sty {
|
||||
ty::Array(_, len) if len.assert_usize(self.tcx) == Some(0) => true,
|
||||
ty::Array(_, len) if len.try_eval_usize(self.tcx) == Some(0) => true,
|
||||
_ => promotable,
|
||||
};
|
||||
|
||||
|
@ -90,7 +90,7 @@ impl<'tcx> PlaceTy<'tcx> {
|
||||
ProjectionElem::Subslice { from, to } => {
|
||||
PlaceTy::from_ty(match self.ty.sty {
|
||||
ty::Array(inner, size) => {
|
||||
let size = size.unwrap_usize(tcx);
|
||||
let size = size.eval_usize(tcx);
|
||||
let len = size - (from as u64) - (to as u64);
|
||||
tcx.mk_array(inner, len)
|
||||
}
|
||||
|
@ -417,7 +417,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
Some(format!("[{}]", self.tcx.type_of(def.did).to_string())),
|
||||
));
|
||||
let tcx = self.tcx;
|
||||
if let Some(len) = len.assert_usize(tcx) {
|
||||
if let Some(len) = len.try_eval_usize(tcx) {
|
||||
flags.push((
|
||||
sym::_Self,
|
||||
Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)),
|
||||
|
@ -194,7 +194,7 @@ impl<'tcx> ty::TyS<'tcx> {
|
||||
ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
|
||||
ty::Array(_, n) => {
|
||||
let n = tcx.lift_to_global(&n).unwrap();
|
||||
match n.assert_usize(tcx) {
|
||||
match n.try_eval_usize(tcx) {
|
||||
Some(n) => format!("array of {} elements", n).into(),
|
||||
None => "array".into(),
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ impl<'tcx> TyS<'tcx> {
|
||||
}))
|
||||
}
|
||||
|
||||
Array(ty, len) => match len.assert_usize(tcx) {
|
||||
Array(ty, len) => match len.try_eval_usize(tcx) {
|
||||
// If the array is definitely non-empty, it's uninhabited if
|
||||
// the type of its elements is uninhabited.
|
||||
Some(n) if n != 0 => ty.uninhabited_from(tcx),
|
||||
|
@ -594,7 +594,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
}
|
||||
}
|
||||
|
||||
let count = count.assert_usize(tcx).ok_or(LayoutError::Unknown(ty))?;
|
||||
let count = count.try_eval_usize(tcx).ok_or(LayoutError::Unknown(ty))?;
|
||||
let element = self.layout_of(element)?;
|
||||
let size = element.size.checked_mul(count, dl)
|
||||
.ok_or(LayoutError::SizeOverflow(ty))?;
|
||||
|
@ -2368,7 +2368,7 @@ impl<'tcx> AdtDef {
|
||||
match tcx.const_eval(param_env.and(cid)) {
|
||||
Ok(val) => {
|
||||
// FIXME: Find the right type and use it instead of `val.ty` here
|
||||
if let Some(b) = val.assert_bits(tcx.global_tcx(), val.ty) {
|
||||
if let Some(b) = val.try_eval_bits(tcx.global_tcx(), val.ty) {
|
||||
trace!("discriminants: {} ({:?})", b, repr_type);
|
||||
Some(Discr {
|
||||
val: b,
|
||||
|
@ -89,7 +89,7 @@ impl DefPathBasedNames<'tcx> {
|
||||
ty::Array(inner_type, len) => {
|
||||
output.push('[');
|
||||
self.push_type_name(inner_type, output, debug);
|
||||
write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap();
|
||||
write!(output, "; {}", len.eval_usize(self.tcx)).unwrap();
|
||||
output.push(']');
|
||||
}
|
||||
ty::Slice(inner_type) => {
|
||||
|
@ -696,7 +696,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
},
|
||||
ty::Array(ty, sz) => {
|
||||
p!(write("["), print(ty), write("; "));
|
||||
if let Some(n) = sz.assert_usize(self.tcx()) {
|
||||
if let Some(n) = sz.try_eval_usize(self.tcx()) {
|
||||
p!(write("{}", n));
|
||||
} else {
|
||||
p!(write("_"));
|
||||
@ -915,7 +915,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
if let ty::Ref(_, ref_ty, _) = ct.ty.sty {
|
||||
let byte_str = match (ct.val, &ref_ty.sty) {
|
||||
(ConstValue::Scalar(Scalar::Ptr(ptr)), ty::Array(t, n)) if *t == u8 => {
|
||||
let n = n.unwrap_usize(self.tcx());
|
||||
let n = n.eval_usize(self.tcx());
|
||||
Some(self.tcx()
|
||||
.alloc_map.lock()
|
||||
.unwrap_memory(ptr.alloc_id)
|
||||
|
@ -466,7 +466,7 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
|
||||
Err(err) => {
|
||||
// Check whether the lengths are both concrete/known values,
|
||||
// but are unequal, for better diagnostics.
|
||||
match (sz_a.assert_usize(tcx), sz_b.assert_usize(tcx)) {
|
||||
match (sz_a.try_eval_usize(tcx), sz_b.try_eval_usize(tcx)) {
|
||||
(Some(sz_a_val), Some(sz_b_val)) => {
|
||||
Err(TypeError::FixedArraySize(
|
||||
expected_found(relation, &sz_a_val, &sz_b_val)
|
||||
|
@ -15,7 +15,7 @@ use crate::ty::{self, AdtDef, Discr, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFolda
|
||||
use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
|
||||
use crate::ty::layout::VariantIdx;
|
||||
use crate::util::captures::Captures;
|
||||
use crate::mir::interpret::Scalar;
|
||||
use crate::mir::interpret::{Scalar, GlobalId};
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use std::borrow::Cow;
|
||||
@ -1726,7 +1726,7 @@ impl<'tcx> TyS<'tcx> {
|
||||
ty.expect_ty().conservative_is_privately_uninhabited(tcx)
|
||||
}),
|
||||
ty::Array(ty, len) => {
|
||||
match len.assert_usize(tcx) {
|
||||
match len.try_eval_usize(tcx) {
|
||||
// If the array is definitely non-empty, it's uninhabited if
|
||||
// the type of its elements is uninhabited.
|
||||
Some(n) if n != 0 => ty.conservative_is_privately_uninhabited(tcx),
|
||||
@ -2291,16 +2291,32 @@ impl<'tcx> Const<'tcx> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn assert_bits(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<u128> {
|
||||
pub fn try_eval_bits(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<u128> {
|
||||
assert_eq!(self.ty, ty);
|
||||
let ty = tcx.lift_to_global(&ty).unwrap();
|
||||
// FIXME(eddyb, oli-obk) get the right param_env.
|
||||
let size = tcx.layout_of(ParamEnv::empty().and(ty)).ok()?.size;
|
||||
self.val.try_to_bits(size)
|
||||
match self.val {
|
||||
// FIXME(const_generics): this doesn't work right now,
|
||||
// because it tries to relate an `Infer` to a `Param`.
|
||||
ConstValue::Unevaluated(did, substs) => {
|
||||
let substs = tcx.lift_to_global(&substs).unwrap();
|
||||
let instance = ty::Instance::resolve(tcx, ParamEnv::empty(), did, substs)?;
|
||||
let gid = GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
let evaluated = tcx.const_eval(ParamEnv::empty().and(gid)).ok()?;
|
||||
evaluated.val.try_to_bits(size)
|
||||
},
|
||||
// FIXME(const_generics): try to evaluate generic consts with a given param env?
|
||||
// E.g. when you have an associated constant whose value depends on a generic const
|
||||
_ => self.val.try_to_bits(size),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn assert_bool(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
|
||||
self.assert_bits(tcx, tcx.types.bool).and_then(|v| match v {
|
||||
pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
|
||||
self.try_eval_bits(tcx, tcx.types.bool).and_then(|v| match v {
|
||||
0 => Some(false),
|
||||
1 => Some(true),
|
||||
_ => None,
|
||||
@ -2308,19 +2324,19 @@ impl<'tcx> Const<'tcx> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn assert_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
|
||||
self.assert_bits(tcx, tcx.types.usize).map(|v| v as u64)
|
||||
pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
|
||||
self.try_eval_bits(tcx, tcx.types.usize).map(|v| v as u64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn unwrap_bits(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> u128 {
|
||||
self.assert_bits(tcx, ty).unwrap_or_else(||
|
||||
pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> u128 {
|
||||
self.try_eval_bits(tcx, ty).unwrap_or_else(||
|
||||
bug!("expected bits of {}, got {:#?}", ty, self))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn unwrap_usize(&self, tcx: TyCtxt<'tcx>) -> u64 {
|
||||
self.unwrap_bits(tcx, tcx.types.usize) as u64
|
||||
pub fn eval_usize(&self, tcx: TyCtxt<'tcx>) -> u64 {
|
||||
self.eval_bits(tcx, tcx.types.usize) as u64
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,7 +341,7 @@ fn fixed_vec_metadata(
|
||||
let (size, align) = cx.size_and_align_of(array_or_slice_type);
|
||||
|
||||
let upper_bound = match array_or_slice_type.sty {
|
||||
ty::Array(_, len) => len.unwrap_usize(cx.tcx) as c_longlong,
|
||||
ty::Array(_, len) => len.eval_usize(cx.tcx) as c_longlong,
|
||||
_ => -1
|
||||
};
|
||||
|
||||
|
@ -132,7 +132,7 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>(
|
||||
cx.tcx().struct_lockstep_tails_erasing_lifetimes(source, target, cx.param_env());
|
||||
match (&source.sty, &target.sty) {
|
||||
(&ty::Array(_, len), &ty::Slice(_)) => {
|
||||
cx.const_usize(len.unwrap_usize(cx.tcx()))
|
||||
cx.const_usize(len.eval_usize(cx.tcx()))
|
||||
}
|
||||
(&ty::Dynamic(..), &ty::Dynamic(..)) => {
|
||||
// For now, upcasts are limited to changes in marker
|
||||
|
@ -89,7 +89,7 @@ pub fn push_debuginfo_type_name<'tcx>(
|
||||
ty::Array(inner_type, len) => {
|
||||
output.push('[');
|
||||
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
|
||||
output.push_str(&format!("; {}", len.unwrap_usize(tcx)));
|
||||
output.push_str(&format!("; {}", len.eval_usize(tcx)));
|
||||
output.push(']');
|
||||
},
|
||||
ty::Slice(inner_type) => {
|
||||
|
@ -41,7 +41,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
.map(|c| {
|
||||
let field_ty = c.ty.builtin_index().unwrap();
|
||||
let fields = match c.ty.sty {
|
||||
ty::Array(_, n) => n.unwrap_usize(bx.tcx()),
|
||||
ty::Array(_, n) => n.eval_usize(bx.tcx()),
|
||||
_ => bug!("invalid simd shuffle type: {}", c.ty),
|
||||
};
|
||||
let values: Vec<_> = (0..fields).map(|field| {
|
||||
|
@ -521,7 +521,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
} = *place {
|
||||
if let LocalRef::Operand(Some(op)) = self.locals[index] {
|
||||
if let ty::Array(_, n) = op.layout.ty.sty {
|
||||
let n = n.unwrap_usize(bx.cx().tcx());
|
||||
let n = n.eval_usize(bx.cx().tcx());
|
||||
return bx.cx().const_usize(n);
|
||||
}
|
||||
}
|
||||
|
@ -512,7 +512,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
|
||||
}
|
||||
self = ct.ty.print(self)?;
|
||||
|
||||
if let Some(bits) = ct.assert_bits(self.tcx, ty::ParamEnv::empty().and(ct.ty)) {
|
||||
if let Some(bits) = ct.try_eval_bits(self.tcx, ct.ty) {
|
||||
let _ = write!(self.out, "{:x}_", bits);
|
||||
} else {
|
||||
// NOTE(eddyb) despite having the path, we need to
|
||||
|
@ -208,7 +208,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
|
||||
}
|
||||
has_emitted
|
||||
}
|
||||
ty::Array(ty, len) => match len.assert_usize(cx.tcx) {
|
||||
ty::Array(ty, len) => match len.try_eval_usize(cx.tcx) {
|
||||
// If the array is definitely non-empty, we can do `#[must_use]` checking.
|
||||
Some(n) if n != 0 => {
|
||||
let descr_pre = &format!(
|
||||
|
@ -669,7 +669,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
ProjectionElem::Subslice { from, to } => PlaceTy::from_ty(
|
||||
match base_ty.sty {
|
||||
ty::Array(inner, size) => {
|
||||
let size = size.unwrap_usize(tcx);
|
||||
let size = size.eval_usize(tcx);
|
||||
let min_size = (from as u64) + (to as u64);
|
||||
if let Some(rest_size) = size.checked_sub(min_size) {
|
||||
tcx.mk_array(inner, rest_size)
|
||||
|
@ -339,7 +339,7 @@ fn place_base_conflict<'tcx>(
|
||||
(StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => {
|
||||
if promoted_1 == promoted_2 {
|
||||
if let ty::Array(_, len) = s1.ty.sty {
|
||||
if let Some(0) = len.assert_usize(tcx) {
|
||||
if let Some(0) = len.try_eval_usize(tcx) {
|
||||
// Ignore conflicts with promoted [T; 0].
|
||||
debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED");
|
||||
return Overlap::Disjoint;
|
||||
|
@ -111,7 +111,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
PatternKind::Constant { value } => {
|
||||
indices.entry(value)
|
||||
.or_insert_with(|| {
|
||||
options.push(value.unwrap_bits(self.hir.tcx(), switch_ty));
|
||||
options.push(value.eval_bits(self.hir.tcx(), switch_ty));
|
||||
options.len() - 1
|
||||
});
|
||||
true
|
||||
|
@ -556,7 +556,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
||||
};
|
||||
let span = cx.tcx.def_span(def_id);
|
||||
let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) {
|
||||
Ok(cv) => cv.unwrap_usize(cx.tcx),
|
||||
Ok(cv) => cv.eval_usize(cx.tcx),
|
||||
Err(ErrorHandled::Reported) => 0,
|
||||
Err(ErrorHandled::TooGeneric) => {
|
||||
cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters");
|
||||
|
@ -228,7 +228,7 @@ impl LiteralExpander<'tcx> {
|
||||
ConstValue::Slice {
|
||||
data: self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id),
|
||||
start: p.offset.bytes().try_into().unwrap(),
|
||||
end: n.unwrap_usize(self.tcx).try_into().unwrap(),
|
||||
end: n.eval_usize(self.tcx).try_into().unwrap(),
|
||||
}
|
||||
},
|
||||
// fat pointers stay the same
|
||||
@ -646,8 +646,8 @@ fn all_constructors<'a, 'tcx>(
|
||||
ConstantValue(ty::Const::from_bool(cx.tcx, b))
|
||||
}).collect()
|
||||
}
|
||||
ty::Array(ref sub_ty, len) if len.assert_usize(cx.tcx).is_some() => {
|
||||
let len = len.unwrap_usize(cx.tcx);
|
||||
ty::Array(ref sub_ty, len) if len.try_eval_usize(cx.tcx).is_some() => {
|
||||
let len = len.eval_usize(cx.tcx);
|
||||
if len != 0 && cx.is_uninhabited(sub_ty) {
|
||||
vec![]
|
||||
} else {
|
||||
@ -789,7 +789,7 @@ where
|
||||
match (value.val, &value.ty.sty) {
|
||||
(_, ty::Array(_, n)) => max_fixed_len = cmp::max(
|
||||
max_fixed_len,
|
||||
n.unwrap_usize(cx.tcx),
|
||||
n.eval_usize(cx.tcx),
|
||||
),
|
||||
(ConstValue::Slice{ start, end, .. }, ty::Slice(_)) => max_fixed_len = cmp::max(
|
||||
max_fixed_len,
|
||||
@ -856,7 +856,7 @@ impl<'tcx> IntRange<'tcx> {
|
||||
}
|
||||
ConstantValue(val) if is_integral(val.ty) => {
|
||||
let ty = val.ty;
|
||||
if let Some(val) = val.assert_bits(tcx, ty) {
|
||||
if let Some(val) = val.try_eval_bits(tcx, ty) {
|
||||
let bias = IntRange::signed_bias(tcx, ty);
|
||||
let val = val ^ bias;
|
||||
Some(IntRange { range: val..=val, ty })
|
||||
@ -873,8 +873,8 @@ impl<'tcx> IntRange<'tcx> {
|
||||
match pat.kind {
|
||||
box PatternKind::Constant { value } => break ConstantValue(value),
|
||||
box PatternKind::Range(PatternRange { lo, hi, ty, end }) => break ConstantRange(
|
||||
lo.unwrap_bits(tcx, ty),
|
||||
hi.unwrap_bits(tcx, ty),
|
||||
lo.eval_bits(tcx, ty),
|
||||
hi.eval_bits(tcx, ty),
|
||||
ty,
|
||||
end,
|
||||
),
|
||||
@ -1327,14 +1327,14 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>,
|
||||
PatternKind::Constant { value } => Some(vec![ConstantValue(value)]),
|
||||
PatternKind::Range(PatternRange { lo, hi, ty, end }) =>
|
||||
Some(vec![ConstantRange(
|
||||
lo.unwrap_bits(cx.tcx, ty),
|
||||
hi.unwrap_bits(cx.tcx, ty),
|
||||
lo.eval_bits(cx.tcx, ty),
|
||||
hi.eval_bits(cx.tcx, ty),
|
||||
ty,
|
||||
end,
|
||||
)]),
|
||||
PatternKind::Array { .. } => match pcx.ty.sty {
|
||||
ty::Array(_, length) => Some(vec![
|
||||
Slice(length.unwrap_usize(cx.tcx))
|
||||
Slice(length.eval_usize(cx.tcx))
|
||||
]),
|
||||
_ => span_bug!(pat.span, "bad ty {:?} for array pattern", pcx.ty)
|
||||
},
|
||||
@ -1402,7 +1402,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx>(
|
||||
match ty.sty {
|
||||
// If the field type returned is an array of an unknown
|
||||
// size return an TyErr.
|
||||
ty::Array(_, len) if len.assert_usize(cx.tcx).is_none() =>
|
||||
ty::Array(_, len) if len.try_eval_usize(cx.tcx).is_none() =>
|
||||
cx.tcx.types.err,
|
||||
_ => ty,
|
||||
}
|
||||
@ -1436,7 +1436,7 @@ fn slice_pat_covered_by_const<'tcx>(
|
||||
let data: &[u8] = match (const_val.val, &const_val.ty.sty) {
|
||||
(ConstValue::ByRef { offset, alloc, .. }, ty::Array(t, n)) => {
|
||||
assert_eq!(*t, tcx.types.u8);
|
||||
let n = n.assert_usize(tcx).unwrap();
|
||||
let n = n.eval_usize(tcx);
|
||||
let ptr = Pointer::new(AllocId(0), offset);
|
||||
alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap()
|
||||
},
|
||||
@ -1464,7 +1464,7 @@ fn slice_pat_covered_by_const<'tcx>(
|
||||
{
|
||||
match pat.kind {
|
||||
box PatternKind::Constant { value } => {
|
||||
let b = value.unwrap_bits(tcx, pat.ty);
|
||||
let b = value.eval_bits(tcx, pat.ty);
|
||||
assert_eq!(b as u8 as u128, b);
|
||||
if b as u8 != *ch {
|
||||
return Ok(false);
|
||||
@ -1760,7 +1760,7 @@ fn specialize<'p, 'a: 'p, 'tcx>(
|
||||
ConstValue::ByRef { offset, alloc, .. } => (
|
||||
alloc,
|
||||
offset,
|
||||
n.unwrap_usize(cx.tcx),
|
||||
n.eval_usize(cx.tcx),
|
||||
t,
|
||||
),
|
||||
_ => span_bug!(
|
||||
|
@ -728,7 +728,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
|
||||
ty::Array(_, len) => {
|
||||
// fixed-length array
|
||||
let len = len.unwrap_usize(self.tcx);
|
||||
let len = len.eval_usize(self.tcx);
|
||||
assert!(len >= prefix.len() as u64 + suffix.len() as u64);
|
||||
PatternKind::Array { prefix: prefix, slice: slice, suffix: suffix }
|
||||
}
|
||||
@ -1123,7 +1123,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
}
|
||||
ty::Array(_, n) => {
|
||||
PatternKind::Array {
|
||||
prefix: (0..n.unwrap_usize(self.tcx))
|
||||
prefix: (0..n.eval_usize(self.tcx))
|
||||
.map(|i| adt_subpattern(i as usize, None))
|
||||
.collect(),
|
||||
slice: None,
|
||||
@ -1206,7 +1206,7 @@ fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>,
|
||||
// (But still tell caller to continue search.)
|
||||
return false;
|
||||
}
|
||||
ty::Array(_, n) if n.assert_usize(self.tcx) == Some(0) => {
|
||||
ty::Array(_, n) if n.try_eval_usize(self.tcx) == Some(0) => {
|
||||
// rust-lang/rust#62336: ignore type of contents
|
||||
// for empty array.
|
||||
return false;
|
||||
@ -1470,7 +1470,7 @@ pub fn compare_const_vals<'tcx>(
|
||||
return fallback();
|
||||
}
|
||||
|
||||
if let (Some(a), Some(b)) = (a.assert_bits(tcx, ty), b.assert_bits(tcx, ty)) {
|
||||
if let (Some(a), Some(b)) = (a.try_eval_bits(tcx, ty), b.try_eval_bits(tcx, ty)) {
|
||||
use ::rustc_apfloat::Float;
|
||||
return match ty.sty {
|
||||
ty::Float(ast::FloatTy::F32) => {
|
||||
|
@ -253,7 +253,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// u64 cast is from usize to u64, which is always good
|
||||
let val = Immediate::new_slice(
|
||||
ptr,
|
||||
length.unwrap_usize(self.tcx.tcx),
|
||||
length.eval_usize(self.tcx.tcx),
|
||||
self,
|
||||
);
|
||||
self.write_immediate(val, dest)
|
||||
|
@ -176,7 +176,7 @@ for
|
||||
(InternMode::ConstBase, hir::Mutability::MutMutable) |
|
||||
(InternMode::Const, hir::Mutability::MutMutable) => {
|
||||
match referenced_ty.sty {
|
||||
ty::Array(_, n) if n.unwrap_usize(self.ecx.tcx.tcx) == 0 => {}
|
||||
ty::Array(_, n) if n.eval_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"),
|
||||
|
@ -313,7 +313,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
|
||||
match self_ty.sty {
|
||||
_ if is_copy => builder.copy_shim(),
|
||||
ty::Array(ty, len) => {
|
||||
let len = len.unwrap_usize(tcx);
|
||||
let len = len.eval_usize(tcx);
|
||||
builder.array_shim(dest, src, ty, len)
|
||||
}
|
||||
ty::Closure(def_id, substs) => {
|
||||
|
@ -367,7 +367,7 @@ impl Qualif for HasMutInterior {
|
||||
} else if let ty::Array(_, len) = ty.sty {
|
||||
// FIXME(eddyb) the `cx.mode == Mode::NonConstFn` condition
|
||||
// seems unnecessary, given that this is merely a ZST.
|
||||
match len.assert_usize(cx.tcx) {
|
||||
match len.try_eval_usize(cx.tcx) {
|
||||
Some(0) if cx.mode == Mode::NonConstFn => {},
|
||||
_ => return true,
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ impl MirPass for SimplifyBranches {
|
||||
TerminatorKind::SwitchInt {
|
||||
discr: Operand::Constant(ref c), switch_ty, ref values, ref targets, ..
|
||||
} => {
|
||||
let constant = c.literal.assert_bits(tcx, switch_ty);
|
||||
let constant = c.literal.try_eval_bits(tcx, switch_ty);
|
||||
if let Some(constant) = constant {
|
||||
let (otherwise, targets) = targets.split_last().unwrap();
|
||||
let mut ret = TerminatorKind::Goto { target: *otherwise };
|
||||
@ -43,7 +43,7 @@ impl MirPass for SimplifyBranches {
|
||||
},
|
||||
TerminatorKind::Assert {
|
||||
target, cond: Operand::Constant(ref c), expected, ..
|
||||
} if (c.literal.assert_bool(tcx) == Some(true)) == expected =>
|
||||
} if (c.literal.try_eval_bool(tcx) == Some(true)) == expected =>
|
||||
TerminatorKind::Goto { target },
|
||||
TerminatorKind::FalseEdges { real_target, .. } => {
|
||||
TerminatorKind::Goto { target: real_target }
|
||||
|
@ -68,7 +68,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> {
|
||||
let place_ty =
|
||||
Place::ty_from(&src_place.base, &proj.base, self.body, self.tcx).ty;
|
||||
if let ty::Array(item_ty, const_size) = place_ty.sty {
|
||||
if let Some(size) = const_size.assert_usize(self.tcx) {
|
||||
if let Some(size) = const_size.try_eval_usize(self.tcx) {
|
||||
assert!(size <= u32::max_value() as u64,
|
||||
"uniform array move out doesn't supported
|
||||
for array bigger then u32");
|
||||
@ -219,7 +219,7 @@ impl MirPass for RestoreSubsliceArrayMoveOut {
|
||||
let src_ty =
|
||||
Place::ty_from(src_place.base, src_place.projection, body, tcx).ty;
|
||||
if let ty::Array(_, ref size_o) = src_ty.sty {
|
||||
size_o.assert_usize(tcx)
|
||||
size_o.try_eval_usize(tcx)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -821,7 +821,7 @@ where
|
||||
self.complete_drop(Some(DropFlagMode::Deep), succ, unwind)
|
||||
}
|
||||
ty::Array(ety, size) => {
|
||||
let size = size.assert_usize(self.tcx());
|
||||
let size = size.try_eval_usize(self.tcx());
|
||||
self.open_drop_for_array(ety, size)
|
||||
},
|
||||
ty::Slice(ety) => self.open_drop_for_array(ety, None),
|
||||
|
@ -423,7 +423,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let expected_ty = self.structurally_resolved_type(pat.span, expected);
|
||||
let (inner_ty, slice_ty) = match expected_ty.sty {
|
||||
ty::Array(inner_ty, size) => {
|
||||
if let Some(size) = size.assert_usize(tcx) {
|
||||
if let Some(size) = size.try_eval_usize(tcx) {
|
||||
let min_len = before.len() as u64 + after.len() as u64;
|
||||
if slice.is_none() {
|
||||
if min_len != size {
|
||||
|
@ -1386,7 +1386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
ty::Array(_, len) => {
|
||||
if let (Some(len), Ok(user_index)) = (
|
||||
len.assert_usize(self.tcx),
|
||||
len.try_eval_usize(self.tcx),
|
||||
field.as_str().parse::<u64>()
|
||||
) {
|
||||
let base = self.tcx.sess.source_map()
|
||||
|
Loading…
x
Reference in New Issue
Block a user