about summary refs log tree commit diff
path: root/compiler/rustc_next_trait_solver/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_next_trait_solver/src')
-rw-r--r--compiler/rustc_next_trait_solver/src/delegate.rs8
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs11
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs8
3 files changed, 23 insertions, 4 deletions
diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs
index 90a7c2e9f78..bb923612cff 100644
--- a/compiler/rustc_next_trait_solver/src/delegate.rs
+++ b/compiler/rustc_next_trait_solver/src/delegate.rs
@@ -3,6 +3,8 @@ use std::ops::Deref;
 use rustc_type_ir::solve::{Certainty, Goal, NoSolution};
 use rustc_type_ir::{self as ty, InferCtxtLike, Interner, TypeFoldable};
 
+use crate::solve::HasChanged;
+
 pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
     type Infcx: InferCtxtLike<Interner = Self::Interner>;
     type Interner: Interner;
@@ -17,6 +19,12 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
     where
         V: TypeFoldable<Self::Interner>;
 
+    fn compute_goal_fast_path(
+        &self,
+        goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
+        span: <Self::Interner as Interner>::Span,
+    ) -> Option<HasChanged>;
+
     fn fresh_var_for_kind_with_span(
         &self,
         arg: <Self::Interner as Interner>::GenericArg,
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index 36f68808a2c..c62f2e2e0e9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -12,6 +12,7 @@
 use std::iter;
 
 use rustc_index::IndexVec;
+use rustc_type_ir::data_structures::HashSet;
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::relate::solver_relating::RelateExt;
 use rustc_type_ir::{
@@ -158,10 +159,12 @@ where
             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));
-        // Remove any trivial region constraints once we've resolved regions
-        external_constraints
-            .region_constraints
-            .retain(|outlives| outlives.0.as_region().is_none_or(|re| re != outlives.1));
+
+        // Remove any trivial or duplicated region constraints once we've resolved regions
+        let mut unique = HashSet::default();
+        external_constraints.region_constraints.retain(|outlives| {
+            outlives.0.as_region().is_none_or(|re| re != outlives.1) && unique.insert(*outlives)
+        });
 
         let canonical = Canonicalizer::canonicalize_response(
             self.delegate,
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index fc5dad9a3ed..9a4b95903a9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -603,6 +603,14 @@ where
         // If this loop did not result in any progress, what's our final certainty.
         let mut unchanged_certainty = Some(Certainty::Yes);
         for (source, goal) in mem::take(&mut self.nested_goals) {
+            if let Some(has_changed) = self.delegate.compute_goal_fast_path(goal, self.origin_span)
+            {
+                if matches!(has_changed, HasChanged::Yes) {
+                    unchanged_certainty = None;
+                }
+                continue;
+            }
+
             // We treat normalizes-to goals specially here. In each iteration we take the
             // RHS of the projection, replace it with a fresh inference variable, and only
             // after evaluating that goal do we equate the fresh inference variable with the