Skip to content

Commit 5ebd300

Browse files
committed
ty: erase lifetimes early in ty::Const::eval.
1 parent 38d3834 commit 5ebd300

File tree

1 file changed

+28
-30
lines changed

1 file changed

+28
-30
lines changed

src/librustc_middle/ty/sty.rs

+28-30
Original file line numberDiff line numberDiff line change
@@ -2339,43 +2339,41 @@ impl<'tcx> Const<'tcx> {
23392339
/// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the
23402340
/// unevaluated constant.
23412341
pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> {
2342-
let try_const_eval = |did, param_env: ParamEnv<'tcx>, substs, promoted| {
2342+
if let ConstKind::Unevaluated(did, substs, promoted) = self.val {
23432343
let param_env_and_substs = param_env.with_reveal_all().and(substs);
23442344

2345-
// Avoid querying `tcx.const_eval(...)` with any inference vars.
2346-
if param_env_and_substs.needs_infer() {
2347-
return None;
2348-
}
2345+
// HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
2346+
// also does later, but we want to do it before checking for
2347+
// inference variables.
2348+
let param_env_and_substs = tcx.erase_regions(&param_env_and_substs);
2349+
2350+
// HACK(eddyb) when the query key would contain inference variables,
2351+
// attempt using identity substs and `ParamEnv` instead, that will succeed
2352+
// when the expression doesn't depend on any parameters.
2353+
// FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
2354+
// we can call `infcx.const_eval_resolve` which handles inference variables.
2355+
let param_env_and_substs = if param_env_and_substs.needs_infer() {
2356+
tcx.param_env(did).and(InternalSubsts::identity_for_item(tcx, did))
2357+
} else {
2358+
param_env_and_substs
2359+
};
23492360

2361+
// FIXME(eddyb) maybe the `const_eval_*` methods should take
2362+
// `ty::ParamEnvAnd<SubstsRef>` instead of having them separate.
23502363
let (param_env, substs) = param_env_and_substs.into_parts();
2351-
23522364
// try to resolve e.g. associated constants to their definition on an impl, and then
23532365
// evaluate the const.
2354-
tcx.const_eval_resolve(param_env, did, substs, promoted, None)
2355-
.ok()
2356-
.map(|val| Const::from_value(tcx, val, self.ty))
2357-
};
2358-
2359-
match self.val {
2360-
ConstKind::Unevaluated(did, substs, promoted) => {
2361-
// HACK(eddyb) when substs contain inference variables,
2362-
// attempt using identity substs instead, that will succeed
2363-
// when the expression doesn't depend on any parameters.
2364-
// FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
2365-
// we can call `infcx.const_eval_resolve` which handles inference variables.
2366-
if substs.needs_infer() {
2367-
let identity_substs = InternalSubsts::identity_for_item(tcx, did);
2368-
// The `ParamEnv` needs to match the `identity_substs`.
2369-
let identity_param_env = tcx.param_env(did);
2370-
match try_const_eval(did, identity_param_env, identity_substs, promoted) {
2371-
Some(ct) => ct.subst(tcx, substs),
2372-
None => self,
2373-
}
2374-
} else {
2375-
try_const_eval(did, param_env, substs, promoted).unwrap_or(self)
2376-
}
2366+
match tcx.const_eval_resolve(param_env, did, substs, promoted, None) {
2367+
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
2368+
// and we use the original type, so nothing from `substs`
2369+
// (which may be identity substs, see above),
2370+
// can leak through `val` into the const we return.
2371+
Ok(val) => Const::from_value(tcx, val, self.ty),
2372+
2373+
Err(_) => self,
23772374
}
2378-
_ => self,
2375+
} else {
2376+
self
23792377
}
23802378
}
23812379

0 commit comments

Comments
 (0)