| @@ -4,6 +4,7 @@ use rustc_infer::traits::{self, ObligationCause, PredicateObligations}; |
|
|
| 4 |
4 |
use rustc_middle::traits::solve::GoalSource; |
| 5 |
5 |
use rustc_middle::ty::{self, Ty, TypeVisitableExt}; |
| 6 |
6 |
use rustc_span::Span; |
|
7 |
+use rustc_trait_selection::solve::Certainty; |
| 7 |
8 |
use rustc_trait_selection::solve::inspect::{ |
| 8 |
9 |
InspectConfig, InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor, |
| 9 |
10 |
}; |
| @@ -117,6 +118,20 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> { |
|
|
| 117 |
118 |
} |
| 118 |
119 |
|
| 119 |
120 |
fn visit_goal(&mut self, inspect_goal: &InspectGoal<'_, 'tcx>) { |
|
121 |
+// No need to walk into goal subtrees that certainly hold, since they |
|
122 |
+// wouldn't then be stalled on an infer var. |
|
123 |
+// FIXME: We also walk into normalizes-to goals since their certainty |
|
124 |
+// is forced to `Certainty::Yes` since they pass down ambiguous subgoals |
|
125 |
+// to their parent. |
|
126 |
+if inspect_goal.result() == Ok(Certainty::Yes) |
|
127 |
+ && !matches!( |
|
128 |
+ inspect_goal.goal().predicate.kind().skip_binder(), |
|
129 |
+ ty::PredicateKind::NormalizesTo(_) |
|
130 |
+) |
|
131 |
+{ |
|
132 |
+return; |
|
133 |
+} |
|
134 |
+ |
| 120 |
135 |
let tcx = self.fcx.tcx; |
| 121 |
136 |
let goal = inspect_goal.goal(); |
| 122 |
137 |
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty) |