From b8523fd0ec19a70e9d02954d1e6e3145746b63d7 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sat, 25 Jan 2020 12:32:58 +1300 Subject: [PATCH] Erase regions before before performing const eval, to improve caching. --- src/librustc/mir/interpret/queries.rs | 36 ++++++++++------------ src/librustc/query/mod.rs | 2 +- src/librustc_mir/interpret/eval_context.rs | 6 +--- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/librustc/mir/interpret/queries.rs b/src/librustc/mir/interpret/queries.rs index ed57f81e7821..46bf1d969579 100644 --- a/src/librustc/mir/interpret/queries.rs +++ b/src/librustc/mir/interpret/queries.rs @@ -13,13 +13,13 @@ impl<'tcx> TyCtxt<'tcx> { pub fn const_eval_poly(self, def_id: DefId) -> ConstEvalResult<'tcx> { // In some situations def_id will have substitutions within scope, but they aren't allowed // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions - // into `const_eval` which will return `ErrorHandled::ToGeneric` if any og them are + // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are // encountered. let substs = InternalSubsts::identity_for_item(self, def_id); let instance = ty::Instance::new(def_id, substs); let cid = GlobalId { instance, promoted: None }; let param_env = self.param_env(def_id).with_reveal_all(); - self.const_eval_validated(param_env.and(cid)) + self.const_eval_global_id(param_env, cid, None) } /// Resolves and evaluates a constant. @@ -41,11 +41,8 @@ impl<'tcx> TyCtxt<'tcx> { ) -> ConstEvalResult<'tcx> { let instance = ty::Instance::resolve(self, param_env, def_id, substs); if let Some(instance) = instance { - if let Some(promoted) = promoted { - self.const_eval_promoted(param_env, instance, promoted) - } else { - self.const_eval_instance(param_env, instance, span) - } + let cid = GlobalId { instance, promoted }; + self.const_eval_global_id(param_env, cid, span) } else { Err(ErrorHandled::TooGeneric) } @@ -57,22 +54,23 @@ impl<'tcx> TyCtxt<'tcx> { instance: ty::Instance<'tcx>, span: Option, ) -> ConstEvalResult<'tcx> { - let cid = GlobalId { instance, promoted: None }; - if let Some(span) = span { - self.at(span).const_eval_validated(param_env.and(cid)) - } else { - self.const_eval_validated(param_env.and(cid)) - } + self.const_eval_global_id(param_env, GlobalId { instance, promoted: None }, span) } - /// Evaluate a promoted constant. - pub fn const_eval_promoted( + /// Evaluate a constant. + pub fn const_eval_global_id( self, param_env: ty::ParamEnv<'tcx>, - instance: ty::Instance<'tcx>, - promoted: mir::Promoted, + cid: GlobalId<'tcx>, + span: Option, ) -> ConstEvalResult<'tcx> { - let cid = GlobalId { instance, promoted: Some(promoted) }; - self.const_eval_validated(param_env.and(cid)) + // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should + // improve caching of queries. + let inputs = self.erase_regions(¶m_env.and(cid)); + if let Some(span) = span { + self.at(span).const_eval_validated(inputs) + } else { + self.const_eval_validated(inputs) + } } } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 45ab3fc0b85a..e119c214f337 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -502,7 +502,7 @@ rustc_queries! { /// returns a proper constant that is usable by the rest of the compiler. /// /// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`, - /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_promoted`. + /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_global_id`. query const_eval_validated(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> ConstEvalResult<'tcx> { no_force diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index fc4ba4d6cd97..cce4b90e224e 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -768,11 +768,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.param_env }; - let val = if let Some(promoted) = gid.promoted { - self.tcx.const_eval_promoted(param_env, gid.instance, promoted)? - } else { - self.tcx.const_eval_instance(param_env, gid.instance, Some(self.tcx.span))? - }; + let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.tcx.span))?; // Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a // recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not