Skip to content

Commit c471519

Browse files
committed
Auto merge of rust-lang#59369 - oli-obk:unwrap_usICE, r=eddyb,nikomatsakis
`unwrap_usize` should at least try to evaluate the underlying constant r? @eddyb fixes rust-lang#59016 I know that I'm still using `ParamEnv` wrongly, but that's a preexisting issue not amplified by this PR.
2 parents f6ecdc2 + bd57498 commit c471519

File tree

53 files changed

+298
-142
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+298
-142
lines changed

src/librustc/infer/combine.rs

+4
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
340340
ambient_variance,
341341
needs_wf: false,
342342
root_ty: ty,
343+
param_env: self.param_env,
343344
};
344345

345346
let ty = match generalize.relate(&ty, &ty) {
@@ -379,6 +380,8 @@ struct Generalizer<'cx, 'tcx> {
379380

380381
/// The root type that we are generalizing. Used when reporting cycles.
381382
root_ty: Ty<'tcx>,
383+
384+
param_env: ty::ParamEnv<'tcx>,
382385
}
383386

384387
/// Result from a generalization operation. This includes
@@ -419,6 +422,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
419422
fn tcx(&self) -> TyCtxt<'tcx> {
420423
self.infcx.tcx
421424
}
425+
fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env }
422426

423427
fn tag(&self) -> &'static str {
424428
"Generalizer"

src/librustc/infer/equate.rs

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
3030

3131
fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() }
3232

33+
fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env }
34+
3335
fn a_is_expected(&self) -> bool { self.a_is_expected }
3436

3537
fn relate_item_substs(&mut self,

src/librustc/infer/glb.rs

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
2727

2828
fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() }
2929

30+
fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env }
31+
3032
fn a_is_expected(&self) -> bool { self.a_is_expected }
3133

3234
fn relate_with_variance<T: Relate<'tcx>>(&mut self,

src/librustc/infer/lub.rs

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
2727

2828
fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() }
2929

30+
fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env }
31+
3032
fn a_is_expected(&self) -> bool { self.a_is_expected }
3133

3234
fn relate_with_variance<T: Relate<'tcx>>(&mut self,

src/librustc/infer/nll_relate/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,9 @@ where
502502
self.infcx.tcx
503503
}
504504

505+
// FIXME(oli-obk): not sure how to get the correct ParamEnv
506+
fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() }
507+
505508
fn tag(&self) -> &'static str {
506509
"nll::subtype"
507510
}
@@ -831,6 +834,9 @@ where
831834
self.infcx.tcx
832835
}
833836

837+
// FIXME(oli-obk): not sure how to get the correct ParamEnv
838+
fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() }
839+
834840
fn tag(&self) -> &'static str {
835841
"nll::generalizer"
836842
}

src/librustc/infer/outlives/env.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::ty::{self, Ty};
2727
/// interested in the `OutlivesEnvironment`. -nmatsakis
2828
#[derive(Clone)]
2929
pub struct OutlivesEnvironment<'tcx> {
30-
param_env: ty::ParamEnv<'tcx>,
30+
pub param_env: ty::ParamEnv<'tcx>,
3131
free_region_map: FreeRegionMap<'tcx>,
3232

3333
// Contains, for each body B that we are checking (that is, the fn

src/librustc/infer/sub.rs

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ impl<'combine, 'infcx, 'tcx> Sub<'combine, 'infcx, 'tcx> {
3535
impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
3636
fn tag(&self) -> &'static str { "Sub" }
3737
fn tcx(&self) -> TyCtxt<'tcx> { self.fields.infcx.tcx }
38+
39+
fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env }
40+
3841
fn a_is_expected(&self) -> bool { self.a_is_expected }
3942

4043
fn with_cause<F,R>(&mut self, cause: Cause, f: F) -> R

src/librustc/middle/expr_use_visitor.rs

+2
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
277277
) -> Self {
278278
ExprUseVisitor {
279279
mc: mc::MemCategorizationContext::new(tcx,
280+
param_env,
280281
body_owner,
281282
region_scope_tree,
282283
tables,
@@ -299,6 +300,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
299300
ExprUseVisitor {
300301
mc: mc::MemCategorizationContext::with_infer(
301302
infcx,
303+
param_env,
302304
body_owner,
303305
region_scope_tree,
304306
tables,

src/librustc/middle/mem_categorization.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ impl HirNode for hir::Pat {
214214
#[derive(Clone)]
215215
pub struct MemCategorizationContext<'a, 'tcx> {
216216
pub tcx: TyCtxt<'tcx>,
217+
param_env: ty::ParamEnv<'tcx>,
217218
pub body_owner: DefId,
218219
pub upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
219220
pub region_scope_tree: &'a region::ScopeTree,
@@ -330,6 +331,7 @@ impl MutabilityCategory {
330331
impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
331332
pub fn new(
332333
tcx: TyCtxt<'tcx>,
334+
param_env: ty::ParamEnv<'tcx>,
333335
body_owner: DefId,
334336
region_scope_tree: &'a region::ScopeTree,
335337
tables: &'a ty::TypeckTables<'tcx>,
@@ -342,7 +344,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
342344
region_scope_tree,
343345
tables,
344346
rvalue_promotable_map,
345-
infcx: None
347+
infcx: None,
348+
param_env,
346349
}
347350
}
348351
}
@@ -359,6 +362,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
359362
/// known, the results around upvar accesses may be incorrect.
360363
pub fn with_infer(
361364
infcx: &'a InferCtxt<'a, 'tcx>,
365+
param_env: ty::ParamEnv<'tcx>,
362366
body_owner: DefId,
363367
region_scope_tree: &'a region::ScopeTree,
364368
tables: &'a ty::TypeckTables<'tcx>,
@@ -379,6 +383,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
379383
tables,
380384
rvalue_promotable_map,
381385
infcx: Some(infcx),
386+
param_env,
382387
}
383388
}
384389

@@ -896,7 +901,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
896901

897902
// Always promote `[T; 0]` (even when e.g., borrowed mutably).
898903
let promotable = match expr_ty.sty {
899-
ty::Array(_, len) if len.assert_usize(self.tcx) == Some(0) => true,
904+
ty::Array(_, len) if len.try_eval_usize(self.tcx, self.param_env) == Some(0) => true,
900905
_ => promotable,
901906
};
902907

src/librustc/mir/tcx.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl<'tcx> PlaceTy<'tcx> {
5757
/// `PlaceElem`, where we can just use the `Ty` that is already
5858
/// stored inline on field projection elems.
5959
pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: &PlaceElem<'tcx>) -> PlaceTy<'tcx> {
60-
self.projection_ty_core(tcx, elem, |_, _, ty| ty)
60+
self.projection_ty_core(tcx, ty::ParamEnv::empty(), elem, |_, _, ty| ty)
6161
}
6262

6363
/// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
@@ -68,6 +68,7 @@ impl<'tcx> PlaceTy<'tcx> {
6868
pub fn projection_ty_core<V, T>(
6969
self,
7070
tcx: TyCtxt<'tcx>,
71+
param_env: ty::ParamEnv<'tcx>,
7172
elem: &ProjectionElem<V, T>,
7273
mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>,
7374
) -> PlaceTy<'tcx>
@@ -90,7 +91,7 @@ impl<'tcx> PlaceTy<'tcx> {
9091
ProjectionElem::Subslice { from, to } => {
9192
PlaceTy::from_ty(match self.ty.sty {
9293
ty::Array(inner, size) => {
93-
let size = size.unwrap_usize(tcx);
94+
let size = size.eval_usize(tcx, param_env);
9495
let len = size - (from as u64) - (to as u64);
9596
tcx.mk_array(inner, len)
9697
}

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, ty::ParamEnv::empty()) {
421421
flags.push((
422422
sym::_Self,
423423
Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)),

src/librustc/traits/select.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10821082
}
10831083
if unbound_input_types && stack.iter().skip(1).any(|prev| {
10841084
stack.obligation.param_env == prev.obligation.param_env
1085-
&& self.match_fresh_trait_refs(&stack.fresh_trait_ref, &prev.fresh_trait_ref)
1085+
&& self.match_fresh_trait_refs(
1086+
&stack.fresh_trait_ref, &prev.fresh_trait_ref, prev.obligation.param_env)
10861087
}) {
10871088
debug!(
10881089
"evaluate_stack({:?}) --> unbound argument, recursive --> giving up",
@@ -3798,8 +3799,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
37983799
&self,
37993800
previous: &ty::PolyTraitRef<'tcx>,
38003801
current: &ty::PolyTraitRef<'tcx>,
3802+
param_env: ty::ParamEnv<'tcx>,
38013803
) -> bool {
3802-
let mut matcher = ty::_match::Match::new(self.tcx());
3804+
let mut matcher = ty::_match::Match::new(self.tcx(), param_env);
38033805
matcher.relate(previous, current).is_ok()
38043806
}
38053807

src/librustc/ty/_match.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,19 @@ use crate::mir::interpret::ConstValue;
2121
/// affects any type variables or unification state.
2222
pub struct Match<'tcx> {
2323
tcx: TyCtxt<'tcx>,
24+
param_env: ty::ParamEnv<'tcx>,
2425
}
2526

2627
impl Match<'tcx> {
27-
pub fn new(tcx: TyCtxt<'tcx>) -> Match<'tcx> {
28-
Match { tcx }
28+
pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Match<'tcx> {
29+
Match { tcx, param_env }
2930
}
3031
}
3132

3233
impl TypeRelation<'tcx> for Match<'tcx> {
3334
fn tag(&self) -> &'static str { "Match" }
3435
fn tcx(&self) -> TyCtxt<'tcx> { self.tcx }
36+
fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env }
3537
fn a_is_expected(&self) -> bool { true } // irrelevant
3638

3739
fn relate_with_variance<T: Relate<'tcx>>(&mut self,

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, ty::ParamEnv::empty()) {
198198
Some(n) => format!("array of {} elements", n).into(),
199199
None => "array".into(),
200200
}

src/librustc/ty/inhabitedness/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::ty::{AdtDef, VariantDef, FieldDef, Ty, TyS};
33
use crate::ty::{DefId, SubstsRef};
44
use crate::ty::{AdtKind, Visibility};
55
use crate::ty::TyKind::*;
6+
use crate::ty;
67

78
pub use self::def_id_forest::DefIdForest;
89

@@ -190,7 +191,7 @@ impl<'tcx> TyS<'tcx> {
190191
}))
191192
}
192193

193-
Array(ty, len) => match len.assert_usize(tcx) {
194+
Array(ty, len) => match len.try_eval_usize(tcx, ty::ParamEnv::empty()) {
194195
// If the array is definitely non-empty, it's uninhabited if
195196
// the type of its elements is uninhabited.
196197
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, param_env).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

+2-2
Original file line numberDiff line numberDiff line change
@@ -2357,7 +2357,7 @@ impl<'tcx> AdtDef {
23572357

23582358
#[inline]
23592359
pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
2360-
let param_env = ParamEnv::empty();
2360+
let param_env = tcx.param_env(expr_did);
23612361
let repr_type = self.repr.discr_type();
23622362
let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), expr_did);
23632363
let instance = ty::Instance::new(expr_did, substs);
@@ -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(), param_env.and(val.ty)) {
2371+
if let Some(b) = val.try_eval_bits(tcx.global_tcx(), param_env, val.ty) {
23722372
trace!("discriminants: {} ({:?})", b, repr_type);
23732373
Some(Discr {
23742374
val: b,

src/librustc/ty/print/obsolete.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ 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+
let len = len.eval_usize(self.tcx, ty::ParamEnv::reveal_all());
93+
write!(output, "; {}", len).unwrap();
9394
output.push(']');
9495
}
9596
ty::Slice(inner_type) => {

src/librustc/ty/print/pretty.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,12 @@ 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 ConstValue::Unevaluated(..) = sz.val {
700+
// do not try to evalute unevaluated constants. If we are const evaluating an
701+
// array length anon const, rustc will (with debug assertions) print the
702+
// constant's path. Which will end up here again.
703+
p!(write("_"));
704+
} else if let Some(n) = sz.try_eval_usize(self.tcx(), ty::ParamEnv::empty()) {
700705
p!(write("{}", n));
701706
} else {
702707
p!(write("_"));
@@ -915,7 +920,7 @@ pub trait PrettyPrinter<'tcx>:
915920
if let ty::Ref(_, ref_ty, _) = ct.ty.sty {
916921
let byte_str = match (ct.val, &ref_ty.sty) {
917922
(ConstValue::Scalar(Scalar::Ptr(ptr)), ty::Array(t, n)) if *t == u8 => {
918-
let n = n.unwrap_usize(self.tcx());
923+
let n = n.eval_usize(self.tcx(), ty::ParamEnv::empty());
919924
Some(self.tcx()
920925
.alloc_map.lock()
921926
.unwrap_memory(ptr.alloc_id)

src/librustc/ty/relate.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub enum Cause {
2525
pub trait TypeRelation<'tcx>: Sized {
2626
fn tcx(&self) -> TyCtxt<'tcx>;
2727

28+
fn param_env(&self) -> ty::ParamEnv<'tcx>;
29+
2830
/// Returns a static string we can use for printouts.
2931
fn tag(&self) -> &'static str;
3032

@@ -466,7 +468,9 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
466468
Err(err) => {
467469
// Check whether the lengths are both concrete/known values,
468470
// but are unequal, for better diagnostics.
469-
match (sz_a.assert_usize(tcx), sz_b.assert_usize(tcx)) {
471+
let sz_a = sz_a.try_eval_usize(tcx, relation.param_env());
472+
let sz_b = sz_b.try_eval_usize(tcx, relation.param_env());
473+
match (sz_a, sz_b) {
470474
(Some(sz_a_val), Some(sz_b_val)) => {
471475
Err(TypeError::FixedArraySize(
472476
expected_found(relation, &sz_a_val, &sz_b_val)

0 commit comments

Comments
 (0)