Skip to content

Commit

Permalink
Remove some duplication when resolving constants
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Aug 21, 2019
1 parent 51879c3 commit 7dbc4b9
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 28 deletions.
24 changes: 3 additions & 21 deletions src/librustc/ty/relate.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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
};
Expand Down
24 changes: 17 additions & 7 deletions src/librustc/ty/sty.rs
Expand Up @@ -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,
}
}

Expand Down

0 comments on commit 7dbc4b9

Please sign in to comment.