Skip to content

Commit 9b87d22

Browse files
committed
Don't abort on unevaluated constants without at least tryting to eval them
1 parent 437f017 commit 9b87d22

File tree

33 files changed

+80
-64
lines changed

33 files changed

+80
-64
lines changed

src/librustc/middle/mem_categorization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
896896

897897
// Always promote `[T; 0]` (even when e.g., borrowed mutably).
898898
let promotable = match expr_ty.sty {
899-
ty::Array(_, len) if len.assert_usize(self.tcx) == Some(0) => true,
899+
ty::Array(_, len) if len.try_eval_usize(self.tcx) == Some(0) => true,
900900
_ => promotable,
901901
};
902902

src/librustc/mir/tcx.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl<'tcx> PlaceTy<'tcx> {
9090
ProjectionElem::Subslice { from, to } => {
9191
PlaceTy::from_ty(match self.ty.sty {
9292
ty::Array(inner, size) => {
93-
let size = size.unwrap_usize(tcx);
93+
let size = size.eval_usize(tcx);
9494
let len = size - (from as u64) - (to as u64);
9595
tcx.mk_array(inner, len)
9696
}

src/librustc/traits/error_reporting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
417417
Some(format!("[{}]", self.tcx.type_of(def.did).to_string())),
418418
));
419419
let tcx = self.tcx;
420-
if let Some(len) = len.assert_usize(tcx) {
420+
if let Some(len) = len.try_eval_usize(tcx) {
421421
flags.push((
422422
sym::_Self,
423423
Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)),

src/librustc/ty/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ impl<'tcx> ty::TyS<'tcx> {
194194
ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
195195
ty::Array(_, n) => {
196196
let n = tcx.lift_to_global(&n).unwrap();
197-
match n.assert_usize(tcx) {
197+
match n.try_eval_usize(tcx) {
198198
Some(n) => format!("array of {} elements", n).into(),
199199
None => "array".into(),
200200
}

src/librustc/ty/inhabitedness/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ impl<'tcx> TyS<'tcx> {
190190
}))
191191
}
192192

193-
Array(ty, len) => match len.assert_usize(tcx) {
193+
Array(ty, len) => match len.try_eval_usize(tcx) {
194194
// If the array is definitely non-empty, it's uninhabited if
195195
// the type of its elements is uninhabited.
196196
Some(n) if n != 0 => ty.uninhabited_from(tcx),

src/librustc/ty/layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
594594
}
595595
}
596596

597-
let count = count.assert_usize(tcx).ok_or(LayoutError::Unknown(ty))?;
597+
let count = count.try_eval_usize(tcx).ok_or(LayoutError::Unknown(ty))?;
598598
let element = self.layout_of(element)?;
599599
let size = element.size.checked_mul(count, dl)
600600
.ok_or(LayoutError::SizeOverflow(ty))?;

src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2368,7 +2368,7 @@ impl<'tcx> AdtDef {
23682368
match tcx.const_eval(param_env.and(cid)) {
23692369
Ok(val) => {
23702370
// FIXME: Find the right type and use it instead of `val.ty` here
2371-
if let Some(b) = val.assert_bits(tcx.global_tcx(), val.ty) {
2371+
if let Some(b) = val.try_eval_bits(tcx.global_tcx(), val.ty) {
23722372
trace!("discriminants: {} ({:?})", b, repr_type);
23732373
Some(Discr {
23742374
val: b,

src/librustc/ty/print/obsolete.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl DefPathBasedNames<'tcx> {
8989
ty::Array(inner_type, len) => {
9090
output.push('[');
9191
self.push_type_name(inner_type, output, debug);
92-
write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap();
92+
write!(output, "; {}", len.eval_usize(self.tcx)).unwrap();
9393
output.push(']');
9494
}
9595
ty::Slice(inner_type) => {

src/librustc/ty/print/pretty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ pub trait PrettyPrinter<'tcx>:
696696
},
697697
ty::Array(ty, sz) => {
698698
p!(write("["), print(ty), write("; "));
699-
if let Some(n) = sz.assert_usize(self.tcx()) {
699+
if let Some(n) = sz.try_eval_usize(self.tcx()) {
700700
p!(write("{}", n));
701701
} else {
702702
p!(write("_"));
@@ -915,7 +915,7 @@ pub trait PrettyPrinter<'tcx>:
915915
if let ty::Ref(_, ref_ty, _) = ct.ty.sty {
916916
let byte_str = match (ct.val, &ref_ty.sty) {
917917
(ConstValue::Scalar(Scalar::Ptr(ptr)), ty::Array(t, n)) if *t == u8 => {
918-
let n = n.unwrap_usize(self.tcx());
918+
let n = n.eval_usize(self.tcx());
919919
Some(self.tcx()
920920
.alloc_map.lock()
921921
.unwrap_memory(ptr.alloc_id)

src/librustc/ty/relate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
466466
Err(err) => {
467467
// Check whether the lengths are both concrete/known values,
468468
// but are unequal, for better diagnostics.
469-
match (sz_a.assert_usize(tcx), sz_b.assert_usize(tcx)) {
469+
match (sz_a.try_eval_usize(tcx), sz_b.try_eval_usize(tcx)) {
470470
(Some(sz_a_val), Some(sz_b_val)) => {
471471
Err(TypeError::FixedArraySize(
472472
expected_found(relation, &sz_a_val, &sz_b_val)

src/librustc/ty/sty.rs

+29-13
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::ty::{self, AdtDef, Discr, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFolda
1515
use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
1616
use crate::ty::layout::VariantIdx;
1717
use crate::util::captures::Captures;
18-
use crate::mir::interpret::Scalar;
18+
use crate::mir::interpret::{Scalar, GlobalId};
1919

2020
use smallvec::SmallVec;
2121
use std::borrow::Cow;
@@ -1726,7 +1726,7 @@ impl<'tcx> TyS<'tcx> {
17261726
ty.expect_ty().conservative_is_privately_uninhabited(tcx)
17271727
}),
17281728
ty::Array(ty, len) => {
1729-
match len.assert_usize(tcx) {
1729+
match len.try_eval_usize(tcx) {
17301730
// If the array is definitely non-empty, it's uninhabited if
17311731
// the type of its elements is uninhabited.
17321732
Some(n) if n != 0 => ty.conservative_is_privately_uninhabited(tcx),
@@ -2291,36 +2291,52 @@ impl<'tcx> Const<'tcx> {
22912291
}
22922292

22932293
#[inline]
2294-
pub fn assert_bits(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<u128> {
2294+
pub fn try_eval_bits(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<u128> {
22952295
assert_eq!(self.ty, ty);
2296-
let ty = tcx.lift_to_global(&ty).unwrap();
2296+
// FIXME(eddyb, oli-obk) get the right param_env.
22972297
let size = tcx.layout_of(ParamEnv::empty().and(ty)).ok()?.size;
2298-
self.val.try_to_bits(size)
2298+
match self.val {
2299+
// FIXME(const_generics): this doesn't work right now,
2300+
// because it tries to relate an `Infer` to a `Param`.
2301+
ConstValue::Unevaluated(did, substs) => {
2302+
let substs = tcx.lift_to_global(&substs).unwrap();
2303+
let instance = ty::Instance::resolve(tcx, ParamEnv::empty(), did, substs)?;
2304+
let gid = GlobalId {
2305+
instance,
2306+
promoted: None,
2307+
};
2308+
let evaluated = tcx.const_eval(ParamEnv::empty().and(gid)).ok()?;
2309+
evaluated.val.try_to_bits(size)
2310+
},
2311+
// FIXME(const_generics): try to evaluate generic consts with a given param env?
2312+
// E.g. when you have an associated constant whose value depends on a generic const
2313+
_ => self.val.try_to_bits(size),
2314+
}
22992315
}
23002316

23012317
#[inline]
2302-
pub fn assert_bool(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
2303-
self.assert_bits(tcx, tcx.types.bool).and_then(|v| match v {
2318+
pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
2319+
self.try_eval_bits(tcx, tcx.types.bool).and_then(|v| match v {
23042320
0 => Some(false),
23052321
1 => Some(true),
23062322
_ => None,
23072323
})
23082324
}
23092325

23102326
#[inline]
2311-
pub fn assert_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
2312-
self.assert_bits(tcx, tcx.types.usize).map(|v| v as u64)
2327+
pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
2328+
self.try_eval_bits(tcx, tcx.types.usize).map(|v| v as u64)
23132329
}
23142330

23152331
#[inline]
2316-
pub fn unwrap_bits(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> u128 {
2317-
self.assert_bits(tcx, ty).unwrap_or_else(||
2332+
pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> u128 {
2333+
self.try_eval_bits(tcx, ty).unwrap_or_else(||
23182334
bug!("expected bits of {}, got {:#?}", ty, self))
23192335
}
23202336

23212337
#[inline]
2322-
pub fn unwrap_usize(&self, tcx: TyCtxt<'tcx>) -> u64 {
2323-
self.unwrap_bits(tcx, tcx.types.usize) as u64
2338+
pub fn eval_usize(&self, tcx: TyCtxt<'tcx>) -> u64 {
2339+
self.eval_bits(tcx, tcx.types.usize) as u64
23242340
}
23252341
}
23262342

src/librustc_codegen_llvm/debuginfo/metadata.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ fn fixed_vec_metadata(
341341
let (size, align) = cx.size_and_align_of(array_or_slice_type);
342342

343343
let upper_bound = match array_or_slice_type.sty {
344-
ty::Array(_, len) => len.unwrap_usize(cx.tcx) as c_longlong,
344+
ty::Array(_, len) => len.eval_usize(cx.tcx) as c_longlong,
345345
_ => -1
346346
};
347347

src/librustc_codegen_ssa/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>(
132132
cx.tcx().struct_lockstep_tails_erasing_lifetimes(source, target, cx.param_env());
133133
match (&source.sty, &target.sty) {
134134
(&ty::Array(_, len), &ty::Slice(_)) => {
135-
cx.const_usize(len.unwrap_usize(cx.tcx()))
135+
cx.const_usize(len.eval_usize(cx.tcx()))
136136
}
137137
(&ty::Dynamic(..), &ty::Dynamic(..)) => {
138138
// For now, upcasts are limited to changes in marker

src/librustc_codegen_ssa/debuginfo/type_names.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub fn push_debuginfo_type_name<'tcx>(
8989
ty::Array(inner_type, len) => {
9090
output.push('[');
9191
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
92-
output.push_str(&format!("; {}", len.unwrap_usize(tcx)));
92+
output.push_str(&format!("; {}", len.eval_usize(tcx)));
9393
output.push(']');
9494
},
9595
ty::Slice(inner_type) => {

src/librustc_codegen_ssa/mir/constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
4141
.map(|c| {
4242
let field_ty = c.ty.builtin_index().unwrap();
4343
let fields = match c.ty.sty {
44-
ty::Array(_, n) => n.unwrap_usize(bx.tcx()),
44+
ty::Array(_, n) => n.eval_usize(bx.tcx()),
4545
_ => bug!("invalid simd shuffle type: {}", c.ty),
4646
};
4747
let values: Vec<_> = (0..fields).map(|field| {

src/librustc_codegen_ssa/mir/rvalue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
521521
} = *place {
522522
if let LocalRef::Operand(Some(op)) = self.locals[index] {
523523
if let ty::Array(_, n) = op.layout.ty.sty {
524-
let n = n.unwrap_usize(bx.cx().tcx());
524+
let n = n.eval_usize(bx.cx().tcx());
525525
return bx.cx().const_usize(n);
526526
}
527527
}

src/librustc_codegen_utils/symbol_names/v0.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
512512
}
513513
self = ct.ty.print(self)?;
514514

515-
if let Some(bits) = ct.assert_bits(self.tcx, ty::ParamEnv::empty().and(ct.ty)) {
515+
if let Some(bits) = ct.try_eval_bits(self.tcx, ct.ty) {
516516
let _ = write!(self.out, "{:x}_", bits);
517517
} else {
518518
// NOTE(eddyb) despite having the path, we need to

src/librustc_lint/unused.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
208208
}
209209
has_emitted
210210
}
211-
ty::Array(ty, len) => match len.assert_usize(cx.tcx) {
211+
ty::Array(ty, len) => match len.try_eval_usize(cx.tcx) {
212212
// If the array is definitely non-empty, we can do `#[must_use]` checking.
213213
Some(n) if n != 0 => {
214214
let descr_pre = &format!(

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
669669
ProjectionElem::Subslice { from, to } => PlaceTy::from_ty(
670670
match base_ty.sty {
671671
ty::Array(inner, size) => {
672-
let size = size.unwrap_usize(tcx);
672+
let size = size.eval_usize(tcx);
673673
let min_size = (from as u64) + (to as u64);
674674
if let Some(rest_size) = size.checked_sub(min_size) {
675675
tcx.mk_array(inner, rest_size)

src/librustc_mir/borrow_check/places_conflict.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ fn place_base_conflict<'tcx>(
339339
(StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => {
340340
if promoted_1 == promoted_2 {
341341
if let ty::Array(_, len) = s1.ty.sty {
342-
if let Some(0) = len.assert_usize(tcx) {
342+
if let Some(0) = len.try_eval_usize(tcx) {
343343
// Ignore conflicts with promoted [T; 0].
344344
debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED");
345345
return Overlap::Disjoint;

src/librustc_mir/build/matches/test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
111111
PatternKind::Constant { value } => {
112112
indices.entry(value)
113113
.or_insert_with(|| {
114-
options.push(value.unwrap_bits(self.hir.tcx(), switch_ty));
114+
options.push(value.eval_bits(self.hir.tcx(), switch_ty));
115115
options.len() - 1
116116
});
117117
true

src/librustc_mir/hair/cx/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
556556
};
557557
let span = cx.tcx.def_span(def_id);
558558
let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) {
559-
Ok(cv) => cv.unwrap_usize(cx.tcx),
559+
Ok(cv) => cv.eval_usize(cx.tcx),
560560
Err(ErrorHandled::Reported) => 0,
561561
Err(ErrorHandled::TooGeneric) => {
562562
cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters");

src/librustc_mir/hair/pattern/_match.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ impl LiteralExpander<'tcx> {
228228
ConstValue::Slice {
229229
data: self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id),
230230
start: p.offset.bytes().try_into().unwrap(),
231-
end: n.unwrap_usize(self.tcx).try_into().unwrap(),
231+
end: n.eval_usize(self.tcx).try_into().unwrap(),
232232
}
233233
},
234234
// fat pointers stay the same
@@ -646,8 +646,8 @@ fn all_constructors<'a, 'tcx>(
646646
ConstantValue(ty::Const::from_bool(cx.tcx, b))
647647
}).collect()
648648
}
649-
ty::Array(ref sub_ty, len) if len.assert_usize(cx.tcx).is_some() => {
650-
let len = len.unwrap_usize(cx.tcx);
649+
ty::Array(ref sub_ty, len) if len.try_eval_usize(cx.tcx).is_some() => {
650+
let len = len.eval_usize(cx.tcx);
651651
if len != 0 && cx.is_uninhabited(sub_ty) {
652652
vec![]
653653
} else {
@@ -789,7 +789,7 @@ where
789789
match (value.val, &value.ty.sty) {
790790
(_, ty::Array(_, n)) => max_fixed_len = cmp::max(
791791
max_fixed_len,
792-
n.unwrap_usize(cx.tcx),
792+
n.eval_usize(cx.tcx),
793793
),
794794
(ConstValue::Slice{ start, end, .. }, ty::Slice(_)) => max_fixed_len = cmp::max(
795795
max_fixed_len,
@@ -856,7 +856,7 @@ impl<'tcx> IntRange<'tcx> {
856856
}
857857
ConstantValue(val) if is_integral(val.ty) => {
858858
let ty = val.ty;
859-
if let Some(val) = val.assert_bits(tcx, ty) {
859+
if let Some(val) = val.try_eval_bits(tcx, ty) {
860860
let bias = IntRange::signed_bias(tcx, ty);
861861
let val = val ^ bias;
862862
Some(IntRange { range: val..=val, ty })
@@ -873,8 +873,8 @@ impl<'tcx> IntRange<'tcx> {
873873
match pat.kind {
874874
box PatternKind::Constant { value } => break ConstantValue(value),
875875
box PatternKind::Range(PatternRange { lo, hi, ty, end }) => break ConstantRange(
876-
lo.unwrap_bits(tcx, ty),
877-
hi.unwrap_bits(tcx, ty),
876+
lo.eval_bits(tcx, ty),
877+
hi.eval_bits(tcx, ty),
878878
ty,
879879
end,
880880
),
@@ -1327,14 +1327,14 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>,
13271327
PatternKind::Constant { value } => Some(vec![ConstantValue(value)]),
13281328
PatternKind::Range(PatternRange { lo, hi, ty, end }) =>
13291329
Some(vec![ConstantRange(
1330-
lo.unwrap_bits(cx.tcx, ty),
1331-
hi.unwrap_bits(cx.tcx, ty),
1330+
lo.eval_bits(cx.tcx, ty),
1331+
hi.eval_bits(cx.tcx, ty),
13321332
ty,
13331333
end,
13341334
)]),
13351335
PatternKind::Array { .. } => match pcx.ty.sty {
13361336
ty::Array(_, length) => Some(vec![
1337-
Slice(length.unwrap_usize(cx.tcx))
1337+
Slice(length.eval_usize(cx.tcx))
13381338
]),
13391339
_ => span_bug!(pat.span, "bad ty {:?} for array pattern", pcx.ty)
13401340
},
@@ -1402,7 +1402,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx>(
14021402
match ty.sty {
14031403
// If the field type returned is an array of an unknown
14041404
// size return an TyErr.
1405-
ty::Array(_, len) if len.assert_usize(cx.tcx).is_none() =>
1405+
ty::Array(_, len) if len.try_eval_usize(cx.tcx).is_none() =>
14061406
cx.tcx.types.err,
14071407
_ => ty,
14081408
}
@@ -1436,7 +1436,7 @@ fn slice_pat_covered_by_const<'tcx>(
14361436
let data: &[u8] = match (const_val.val, &const_val.ty.sty) {
14371437
(ConstValue::ByRef { offset, alloc, .. }, ty::Array(t, n)) => {
14381438
assert_eq!(*t, tcx.types.u8);
1439-
let n = n.assert_usize(tcx).unwrap();
1439+
let n = n.eval_usize(tcx);
14401440
let ptr = Pointer::new(AllocId(0), offset);
14411441
alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap()
14421442
},
@@ -1464,7 +1464,7 @@ fn slice_pat_covered_by_const<'tcx>(
14641464
{
14651465
match pat.kind {
14661466
box PatternKind::Constant { value } => {
1467-
let b = value.unwrap_bits(tcx, pat.ty);
1467+
let b = value.eval_bits(tcx, pat.ty);
14681468
assert_eq!(b as u8 as u128, b);
14691469
if b as u8 != *ch {
14701470
return Ok(false);
@@ -1760,7 +1760,7 @@ fn specialize<'p, 'a: 'p, 'tcx>(
17601760
ConstValue::ByRef { offset, alloc, .. } => (
17611761
alloc,
17621762
offset,
1763-
n.unwrap_usize(cx.tcx),
1763+
n.eval_usize(cx.tcx),
17641764
t,
17651765
),
17661766
_ => span_bug!(

0 commit comments

Comments
 (0)