Remove some duplication when resolving constants

This commit is contained in:
Oliver Scherer 2019-08-21 02:29:08 +02:00
parent 51879c3aba
commit 7dbc4b95fc
2 changed files with 20 additions and 28 deletions

View file

@ -8,7 +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::{ConstValue, Scalar, GlobalId};
use crate::mir::interpret::{ConstValue, Scalar};
use std::rc::Rc;
use std::iter;
use rustc_target::spec::abi;
@ -551,26 +551,8 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
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 !substs.has_local_value() {
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;
}
}
}
if !x.val.has_local_value() {
return x.eval(tcx, relation.param_env()).val;
}
x.val
};

View file

@ -2299,23 +2299,33 @@ impl<'tcx> Const<'tcx> {
assert_eq!(self.ty, ty);
// if `ty` does not depend on generic parameters, use an empty param_env
let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
self.eval(tcx, param_env).val.try_to_bits(size)
}
#[inline]
pub fn eval(
&self,
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
) -> &Const<'tcx> {
// FIXME(const_generics): this doesn't work right now,
// because it tries to relate an `Infer` to a `Param`.
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) => {
// if `substs` has no unresolved components, use and empty param_env
let (param_env, substs) = param_env.with_reveal_all().and(substs).into_parts();
// try to resolve e.g. associated constants to their definition on an impl
let instance = ty::Instance::resolve(tcx, param_env, did, substs)?;
let instance = match ty::Instance::resolve(tcx, param_env, did, substs) {
Some(instance) => instance,
None => return self,
};
let gid = GlobalId {
instance,
promoted: None,
};
let evaluated = tcx.const_eval(param_env.and(gid)).ok()?;
evaluated.val.try_to_bits(size)
tcx.const_eval(param_env.and(gid)).unwrap_or(self)
},
// otherwise just extract a `ConstValue`'s bits if possible
_ => self.val.try_to_bits(size),
_ => self,
}
}