add additional TypeFlags fast paths
This commit is contained in:
@@ -572,4 +572,8 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
|
||||
fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
|
||||
if p.flags().intersects(NEEDS_CANONICAL) { p.super_fold_with(self) } else { p }
|
||||
}
|
||||
|
||||
fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses {
|
||||
if c.flags().intersects(NEEDS_CANONICAL) { c.super_fold_with(self) } else { c }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::delegate::SolverDelegate;
|
||||
// EAGER RESOLUTION
|
||||
|
||||
/// Resolves ty, region, and const vars to their inferred values or their root vars.
|
||||
pub struct EagerResolver<'a, D, I = <D as SolverDelegate>::Interner>
|
||||
struct EagerResolver<'a, D, I = <D as SolverDelegate>::Interner>
|
||||
where
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
@@ -22,8 +22,20 @@ where
|
||||
cache: DelayedMap<I::Ty, I::Ty>,
|
||||
}
|
||||
|
||||
pub fn eager_resolve_vars<D: SolverDelegate, T: TypeFoldable<D::Interner>>(
|
||||
delegate: &D,
|
||||
value: T,
|
||||
) -> T {
|
||||
if value.has_infer() {
|
||||
let mut folder = EagerResolver::new(delegate);
|
||||
value.fold_with(&mut folder)
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, D: SolverDelegate> EagerResolver<'a, D> {
|
||||
pub fn new(delegate: &'a D) -> Self {
|
||||
fn new(delegate: &'a D) -> Self {
|
||||
EagerResolver { delegate, cache: Default::default() }
|
||||
}
|
||||
}
|
||||
@@ -90,4 +102,8 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for EagerResolv
|
||||
fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
|
||||
if p.has_infer() { p.super_fold_with(self) } else { p }
|
||||
}
|
||||
|
||||
fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses {
|
||||
if c.has_infer() { c.super_fold_with(self) } else { c }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ use tracing::{debug, instrument, trace};
|
||||
|
||||
use crate::canonicalizer::Canonicalizer;
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::resolve::EagerResolver;
|
||||
use crate::resolve::eager_resolve_vars;
|
||||
use crate::solve::eval_ctxt::CurrentGoalKind;
|
||||
use crate::solve::{
|
||||
CanonicalInput, CanonicalResponse, Certainty, EvalCtxt, ExternalConstraintsData, Goal,
|
||||
@@ -61,8 +61,7 @@ where
|
||||
// so we only canonicalize the lookup table and ignore
|
||||
// duplicate entries.
|
||||
let opaque_types = self.delegate.clone_opaque_types_lookup_table();
|
||||
let (goal, opaque_types) =
|
||||
(goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate));
|
||||
let (goal, opaque_types) = eager_resolve_vars(self.delegate, (goal, opaque_types));
|
||||
|
||||
let mut orig_values = Default::default();
|
||||
let canonical = Canonicalizer::canonicalize_input(
|
||||
@@ -157,8 +156,8 @@ where
|
||||
|
||||
let external_constraints =
|
||||
self.compute_external_query_constraints(certainty, normalization_nested_goals);
|
||||
let (var_values, mut external_constraints) = (self.var_values, external_constraints)
|
||||
.fold_with(&mut EagerResolver::new(self.delegate));
|
||||
let (var_values, mut external_constraints) =
|
||||
eager_resolve_vars(self.delegate, (self.var_values, external_constraints));
|
||||
|
||||
// Remove any trivial or duplicated region constraints once we've resolved regions
|
||||
let mut unique = HashSet::default();
|
||||
@@ -469,7 +468,7 @@ where
|
||||
{
|
||||
let var_values = CanonicalVarValues { var_values: delegate.cx().mk_args(var_values) };
|
||||
let state = inspect::State { var_values, data };
|
||||
let state = state.fold_with(&mut EagerResolver::new(delegate));
|
||||
let state = eager_resolve_vars(delegate, state);
|
||||
Canonicalizer::canonicalize_response(delegate, max_input_universe, &mut vec![], state)
|
||||
}
|
||||
|
||||
|
||||
@@ -848,6 +848,22 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_predicate(&mut self, p: I::Predicate) -> Self::Result {
|
||||
if p.has_non_region_infer() || p.has_placeholders() {
|
||||
p.super_visit_with(self)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_clauses(&mut self, c: I::Clauses) -> Self::Result {
|
||||
if c.has_non_region_infer() || c.has_placeholders() {
|
||||
c.super_visit_with(self)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut visitor = ContainsTermOrNotNameable {
|
||||
|
||||
Reference in New Issue
Block a user