Eagerly evaluate in super_relate_consts
This commit is contained in:
parent
908d97d03c
commit
d5c6cb8778
2 changed files with 39 additions and 58 deletions
|
|
@ -8,8 +8,7 @@ use crate::hir::def_id::DefId;
|
|||
use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
|
||||
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use crate::ty::error::{ExpectedFound, TypeError};
|
||||
use crate::mir::interpret::{GlobalId, ConstValue, Scalar};
|
||||
use syntax_pos::DUMMY_SP;
|
||||
use crate::mir::interpret::{ConstValue, Scalar, GlobalId};
|
||||
use std::rc::Rc;
|
||||
use std::iter;
|
||||
use rustc_target::spec::abi;
|
||||
|
|
@ -473,54 +472,8 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
|||
(&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) =>
|
||||
{
|
||||
let t = relation.relate(&a_t, &b_t)?;
|
||||
|
||||
let to_u64 = |ct: &'tcx ty::Const<'tcx>| -> Option<u64> {
|
||||
match ct.val {
|
||||
// FIXME(const_generics): this doesn't work right now,
|
||||
// because it tries to relate an `Infer` to a `Param`.
|
||||
ConstValue::Unevaluated(def_id, substs) => {
|
||||
// FIXME(eddyb) get the right param_env.
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
if let Some(substs) = tcx.lift_to_global(&substs) {
|
||||
let instance = ty::Instance::resolve(
|
||||
tcx.global_tcx(),
|
||||
param_env,
|
||||
def_id,
|
||||
substs,
|
||||
);
|
||||
if let Some(instance) = instance {
|
||||
let cid = GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
return tcx.const_eval(param_env.and(cid))
|
||||
.ok()
|
||||
.map(|c| c.unwrap_usize(tcx));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
_ => ct.assert_usize(tcx),
|
||||
}
|
||||
};
|
||||
match (to_u64(sz_a), to_u64(sz_b)) {
|
||||
(Some(sz_a_u64), Some(sz_b_u64)) => {
|
||||
if sz_a_u64 == sz_b_u64 {
|
||||
Ok(tcx.mk_ty(ty::Array(t, sz_a)))
|
||||
} else {
|
||||
Err(TypeError::FixedArraySize(
|
||||
expected_found(relation, &sz_a_u64, &sz_b_u64)))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if let Ok(sz) = relation.relate(&sz_a, &sz_b) {
|
||||
Ok(tcx.mk_ty(ty::Array(t, sz)))
|
||||
} else {
|
||||
tcx.sess.delay_span_bug(DUMMY_SP, "array length could not be evaluated");
|
||||
Ok(tcx.types.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
let sz = relation.relate(&sz_a, &sz_b)?;
|
||||
Ok(tcx.mk_ty(ty::Array(t, sz)))
|
||||
}
|
||||
|
||||
(&ty::Slice(a_t), &ty::Slice(b_t)) =>
|
||||
|
|
@ -594,11 +547,36 @@ where
|
|||
{
|
||||
let tcx = relation.tcx();
|
||||
|
||||
let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
|
||||
if let ConstValue::Unevaluated(def_id, substs) = x.val {
|
||||
// FIXME(eddyb) get the right param_env.
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
if let Some(substs) = tcx.lift_to_global(&substs) {
|
||||
let instance = ty::Instance::resolve(
|
||||
tcx.global_tcx(),
|
||||
param_env,
|
||||
def_id,
|
||||
substs,
|
||||
);
|
||||
if let Some(instance) = instance {
|
||||
let cid = GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
if let Ok(ct) = tcx.const_eval(param_env.and(cid)) {
|
||||
return ct.val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
x.val
|
||||
};
|
||||
|
||||
// Currently, the values that can be unified are those that
|
||||
// implement both `PartialEq` and `Eq`, corresponding to
|
||||
// `structural_match` types.
|
||||
// FIXME(const_generics): check for `structural_match` synthetic attribute.
|
||||
match (a.val, b.val) {
|
||||
match (eagerly_eval(a), eagerly_eval(b)) {
|
||||
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
|
||||
// The caller should handle these cases!
|
||||
bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
|
||||
|
|
@ -609,8 +587,13 @@ where
|
|||
(ConstValue::Placeholder(p1), ConstValue::Placeholder(p2)) if p1 == p2 => {
|
||||
Ok(a)
|
||||
}
|
||||
(ConstValue::Scalar(Scalar::Raw { .. }), _) if a == b => {
|
||||
Ok(a)
|
||||
(a_val @ ConstValue::Scalar(Scalar::Raw { .. }), b_val @ _)
|
||||
if a.ty == b.ty && a_val == b_val =>
|
||||
{
|
||||
Ok(tcx.mk_const(ty::Const {
|
||||
val: a_val,
|
||||
ty: a.ty,
|
||||
}))
|
||||
}
|
||||
(ConstValue::ByRef(..), _) => {
|
||||
bug!(
|
||||
|
|
@ -631,9 +614,7 @@ where
|
|||
}))
|
||||
}
|
||||
|
||||
_ => {
|
||||
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
|
||||
}
|
||||
_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
|||
--> $DIR/const-array-oob-arith.rs:7:45
|
||||
|
|
||||
LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5];
|
||||
| ^^^ expected an array with a fixed size of 2 elements, found one with 1 elements
|
||||
| ^^^ expected `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 2 }) }`, found `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 1 }) }`
|
||||
|
|
||||
= note: expected type `[i32; 2]`
|
||||
found type `[i32; 1]`
|
||||
|
|
@ -11,7 +11,7 @@ error[E0308]: mismatched types
|
|||
--> $DIR/const-array-oob-arith.rs:8:44
|
||||
|
|
||||
LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99];
|
||||
| ^^^^^^^ expected an array with a fixed size of 1 elements, found one with 2 elements
|
||||
| ^^^^^^^ expected `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 1 }) }`, found `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 2 }) }`
|
||||
|
|
||||
= note: expected type `[i32; 1]`
|
||||
found type `[i32; 2]`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue