8
8
/// and could be improved in the future. This is mostly good enough for
9
9
/// coherence right now and was annoying to implement, so I am leaving it
10
10
/// as is until we start using it for something else.
11
- use std:: ops:: ControlFlow ;
12
-
13
11
use rustc_infer:: infer:: InferCtxt ;
14
12
use rustc_middle:: traits:: query:: NoSolution ;
15
13
use rustc_middle:: traits:: solve:: { inspect, QueryResult } ;
16
14
use rustc_middle:: traits:: solve:: { Certainty , Goal } ;
17
15
use rustc_middle:: ty;
16
+ use rustc_type_ir:: try_visit;
17
+ use rustc_type_ir:: visit:: VisitorResult ;
18
18
19
19
use crate :: solve:: inspect:: ProofTreeBuilder ;
20
20
use crate :: solve:: { GenerateProofTree , InferCtxtEvalExt } ;
@@ -53,10 +53,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
53
53
/// to also use it to compute the most relevant goal
54
54
/// for fulfillment errors. Will do that once we actually
55
55
/// need it.
56
- pub fn visit_nested < V : ProofTreeVisitor < ' tcx > > (
57
- & self ,
58
- visitor : & mut V ,
59
- ) -> ControlFlow < V :: BreakTy > {
56
+ pub fn visit_nested < V : ProofTreeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> V :: Result {
60
57
// HACK: An arbitrary cutoff to avoid dealing with overflow and cycles.
61
58
if self . goal . depth <= 10 {
62
59
let infcx = self . goal . infcx ;
@@ -75,7 +72,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
75
72
"unexpected failure when instantiating {:?}: {:?}" ,
76
73
goal, self . nested_goals
77
74
) ;
78
- return ControlFlow :: Continue ( ( ) ) ;
75
+ return V :: Result :: output ( ) ;
79
76
}
80
77
} ;
81
78
instantiated_goals. push ( goal) ;
@@ -84,17 +81,18 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
84
81
for & goal in & instantiated_goals {
85
82
let ( _, proof_tree) = infcx. evaluate_root_goal ( goal, GenerateProofTree :: Yes ) ;
86
83
let proof_tree = proof_tree. unwrap ( ) ;
87
- visitor. visit_goal ( & InspectGoal :: new (
84
+ try_visit ! ( visitor. visit_goal( & InspectGoal :: new(
88
85
infcx,
89
86
self . goal. depth + 1 ,
90
87
& proof_tree,
91
- ) ) ? ;
88
+ ) ) ) ;
92
89
}
93
90
94
- ControlFlow :: Continue ( ( ) )
95
- } ) ?;
91
+ V :: Result :: output ( )
92
+ } )
93
+ } else {
94
+ V :: Result :: output ( )
96
95
}
97
- ControlFlow :: Continue ( ( ) )
98
96
}
99
97
}
100
98
@@ -211,9 +209,9 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
211
209
212
210
/// The public API to interact with proof trees.
213
211
pub trait ProofTreeVisitor < ' tcx > {
214
- type BreakTy ;
212
+ type Result : VisitorResult = ( ) ;
215
213
216
- fn visit_goal ( & mut self , goal : & InspectGoal < ' _ , ' tcx > ) -> ControlFlow < Self :: BreakTy > ;
214
+ fn visit_goal ( & mut self , goal : & InspectGoal < ' _ , ' tcx > ) -> Self :: Result ;
217
215
}
218
216
219
217
#[ extension( pub trait ProofTreeInferCtxtExt <' tcx>) ]
@@ -222,7 +220,7 @@ impl<'tcx> InferCtxt<'tcx> {
222
220
& self ,
223
221
goal : Goal < ' tcx , ty:: Predicate < ' tcx > > ,
224
222
visitor : & mut V ,
225
- ) -> ControlFlow < V :: BreakTy > {
223
+ ) -> V :: Result {
226
224
self . probe ( |_| {
227
225
let ( _, proof_tree) = self . evaluate_root_goal ( goal, GenerateProofTree :: Yes ) ;
228
226
let proof_tree = proof_tree. unwrap ( ) ;
0 commit comments