Skip to content

Commit d5c6cb8

Browse files
committed
Eagerly evaluate in super_relate_consts
1 parent 908d97d commit d5c6cb8

File tree

2 files changed

+39
-58
lines changed

2 files changed

+39
-58
lines changed

src/librustc/ty/relate.rs

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ use crate::hir::def_id::DefId;
88
use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
99
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
1010
use crate::ty::error::{ExpectedFound, TypeError};
11-
use crate::mir::interpret::{GlobalId, ConstValue, Scalar};
12-
use syntax_pos::DUMMY_SP;
11+
use crate::mir::interpret::{ConstValue, Scalar, GlobalId};
1312
use std::rc::Rc;
1413
use std::iter;
1514
use rustc_target::spec::abi;
@@ -473,54 +472,8 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
473472
(&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) =>
474473
{
475474
let t = relation.relate(&a_t, &b_t)?;
476-
477-
let to_u64 = |ct: &'tcx ty::Const<'tcx>| -> Option<u64> {
478-
match ct.val {
479-
// FIXME(const_generics): this doesn't work right now,
480-
// because it tries to relate an `Infer` to a `Param`.
481-
ConstValue::Unevaluated(def_id, substs) => {
482-
// FIXME(eddyb) get the right param_env.
483-
let param_env = ty::ParamEnv::empty();
484-
if let Some(substs) = tcx.lift_to_global(&substs) {
485-
let instance = ty::Instance::resolve(
486-
tcx.global_tcx(),
487-
param_env,
488-
def_id,
489-
substs,
490-
);
491-
if let Some(instance) = instance {
492-
let cid = GlobalId {
493-
instance,
494-
promoted: None,
495-
};
496-
return tcx.const_eval(param_env.and(cid))
497-
.ok()
498-
.map(|c| c.unwrap_usize(tcx));
499-
}
500-
}
501-
None
502-
}
503-
_ => ct.assert_usize(tcx),
504-
}
505-
};
506-
match (to_u64(sz_a), to_u64(sz_b)) {
507-
(Some(sz_a_u64), Some(sz_b_u64)) => {
508-
if sz_a_u64 == sz_b_u64 {
509-
Ok(tcx.mk_ty(ty::Array(t, sz_a)))
510-
} else {
511-
Err(TypeError::FixedArraySize(
512-
expected_found(relation, &sz_a_u64, &sz_b_u64)))
513-
}
514-
}
515-
_ => {
516-
if let Ok(sz) = relation.relate(&sz_a, &sz_b) {
517-
Ok(tcx.mk_ty(ty::Array(t, sz)))
518-
} else {
519-
tcx.sess.delay_span_bug(DUMMY_SP, "array length could not be evaluated");
520-
Ok(tcx.types.err)
521-
}
522-
}
523-
}
475+
let sz = relation.relate(&sz_a, &sz_b)?;
476+
Ok(tcx.mk_ty(ty::Array(t, sz)))
524477
}
525478

526479
(&ty::Slice(a_t), &ty::Slice(b_t)) =>
@@ -594,11 +547,36 @@ where
594547
{
595548
let tcx = relation.tcx();
596549

550+
let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
551+
if let ConstValue::Unevaluated(def_id, substs) = x.val {
552+
// FIXME(eddyb) get the right param_env.
553+
let param_env = ty::ParamEnv::empty();
554+
if let Some(substs) = tcx.lift_to_global(&substs) {
555+
let instance = ty::Instance::resolve(
556+
tcx.global_tcx(),
557+
param_env,
558+
def_id,
559+
substs,
560+
);
561+
if let Some(instance) = instance {
562+
let cid = GlobalId {
563+
instance,
564+
promoted: None,
565+
};
566+
if let Ok(ct) = tcx.const_eval(param_env.and(cid)) {
567+
return ct.val;
568+
}
569+
}
570+
}
571+
}
572+
x.val
573+
};
574+
597575
// Currently, the values that can be unified are those that
598576
// implement both `PartialEq` and `Eq`, corresponding to
599577
// `structural_match` types.
600578
// FIXME(const_generics): check for `structural_match` synthetic attribute.
601-
match (a.val, b.val) {
579+
match (eagerly_eval(a), eagerly_eval(b)) {
602580
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
603581
// The caller should handle these cases!
604582
bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
@@ -609,8 +587,13 @@ where
609587
(ConstValue::Placeholder(p1), ConstValue::Placeholder(p2)) if p1 == p2 => {
610588
Ok(a)
611589
}
612-
(ConstValue::Scalar(Scalar::Raw { .. }), _) if a == b => {
613-
Ok(a)
590+
(a_val @ ConstValue::Scalar(Scalar::Raw { .. }), b_val @ _)
591+
if a.ty == b.ty && a_val == b_val =>
592+
{
593+
Ok(tcx.mk_const(ty::Const {
594+
val: a_val,
595+
ty: a.ty,
596+
}))
614597
}
615598
(ConstValue::ByRef(..), _) => {
616599
bug!(
@@ -631,9 +614,7 @@ where
631614
}))
632615
}
633616

634-
_ => {
635-
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
636-
}
617+
_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
637618
}
638619
}
639620

src/test/ui/consts/const-array-oob-arith.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
22
--> $DIR/const-array-oob-arith.rs:7:45
33
|
44
LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5];
5-
| ^^^ expected an array with a fixed size of 2 elements, found one with 1 elements
5+
| ^^^ expected `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 2 }) }`, found `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 1 }) }`
66
|
77
= note: expected type `[i32; 2]`
88
found type `[i32; 1]`
@@ -11,7 +11,7 @@ error[E0308]: mismatched types
1111
--> $DIR/const-array-oob-arith.rs:8:44
1212
|
1313
LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99];
14-
| ^^^^^^^ expected an array with a fixed size of 1 elements, found one with 2 elements
14+
| ^^^^^^^ expected `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 1 }) }`, found `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 2 }) }`
1515
|
1616
= note: expected type `[i32; 1]`
1717
found type `[i32; 2]`

0 commit comments

Comments
 (0)