@@ -34,9 +34,9 @@ pub struct InspectConfig {
34
34
pub struct InspectGoal < ' a , ' tcx > {
35
35
infcx : & ' a InferCtxt < ' tcx > ,
36
36
depth : usize ,
37
- orig_values : & ' a [ ty:: GenericArg < ' tcx > ] ,
37
+ orig_values : Vec < ty:: GenericArg < ' tcx > > ,
38
38
goal : Goal < ' tcx , ty:: Predicate < ' tcx > > ,
39
- evaluation : & ' a inspect:: GoalEvaluation < ' tcx > ,
39
+ evaluation : inspect:: CanonicalGoalEvaluation < ' tcx > ,
40
40
}
41
41
42
42
pub struct InspectCandidate < ' a , ' tcx > {
@@ -57,6 +57,10 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
57
57
self . result . map ( |c| c. value . certainty )
58
58
}
59
59
60
+ pub fn goal ( & self ) -> & ' a InspectGoal < ' a , ' tcx > {
61
+ self . goal
62
+ }
63
+
60
64
/// Certainty passed into `evaluate_added_goals_and_make_canonical_response`.
61
65
///
62
66
/// If this certainty is `Yes`, then we must be confident that the candidate
@@ -74,46 +78,55 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
74
78
/// the state of the `infcx`.
75
79
pub fn visit_nested_no_probe < V : ProofTreeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> V :: Result {
76
80
if self . goal . depth < visitor. config ( ) . max_depth {
77
- let infcx = self . goal . infcx ;
78
- let param_env = self . goal . goal . param_env ;
79
- let mut orig_values = self . goal . orig_values . to_vec ( ) ;
80
- let mut instantiated_goals = vec ! [ ] ;
81
- for goal in & self . nested_goals {
82
- let goal = canonical:: instantiate_canonical_state (
81
+ for goal in self . instantiate_nested_goals ( visitor. span ( ) ) {
82
+ try_visit ! ( visitor. visit_goal( & goal) ) ;
83
+ }
84
+ }
85
+
86
+ V :: Result :: output ( )
87
+ }
88
+
89
+ /// Instantiate the nested goals for the candidate without rolling back their
90
+ /// inference constraints. This function modifies the state of the `infcx`.
91
+ pub fn instantiate_nested_goals ( & self , span : Span ) -> Vec < InspectGoal < ' a , ' tcx > > {
92
+ let infcx = self . goal . infcx ;
93
+ let param_env = self . goal . goal . param_env ;
94
+ let mut orig_values = self . goal . orig_values . to_vec ( ) ;
95
+ let instantiated_goals: Vec < _ > = self
96
+ . nested_goals
97
+ . iter ( )
98
+ . map ( |goal| {
99
+ canonical:: instantiate_canonical_state (
83
100
infcx,
84
- visitor . span ( ) ,
101
+ span,
85
102
param_env,
86
103
& mut orig_values,
87
104
* goal,
88
- ) ;
89
- instantiated_goals . push ( goal ) ;
90
- }
105
+ )
106
+ } )
107
+ . collect ( ) ;
91
108
92
- let ( ) = canonical:: instantiate_canonical_state (
93
- infcx,
94
- visitor . span ( ) ,
95
- param_env,
96
- & mut orig_values,
97
- self . final_state ,
98
- ) ;
109
+ let ( ) = canonical:: instantiate_canonical_state (
110
+ infcx,
111
+ span,
112
+ param_env,
113
+ & mut orig_values,
114
+ self . final_state ,
115
+ ) ;
99
116
100
- for & goal in & instantiated_goals {
117
+ instantiated_goals
118
+ . into_iter ( )
119
+ . map ( |goal| {
101
120
let proof_tree = match goal. predicate . kind ( ) . no_bound_vars ( ) {
102
121
Some ( ty:: PredicateKind :: NormalizesTo ( ty:: NormalizesTo { alias, term } ) ) => {
103
122
let unconstrained_term = match term. unpack ( ) {
104
123
ty:: TermKind :: Ty ( _) => infcx
105
- . next_ty_var ( TypeVariableOrigin {
106
- param_def_id : None ,
107
- span : visitor. span ( ) ,
108
- } )
124
+ . next_ty_var ( TypeVariableOrigin { param_def_id : None , span } )
109
125
. into ( ) ,
110
126
ty:: TermKind :: Const ( ct) => infcx
111
127
. next_const_var (
112
128
ct. ty ( ) ,
113
- ConstVariableOrigin {
114
- param_def_id : None ,
115
- span : visitor. span ( ) ,
116
- } ,
129
+ ConstVariableOrigin { param_def_id : None , span } ,
117
130
)
118
131
. into ( ) ,
119
132
} ;
@@ -129,22 +142,16 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
129
142
} )
130
143
. 1 ;
131
144
let InferOk { value : ( ) , obligations : _ } = infcx
132
- . at ( & ObligationCause :: dummy ( ) , param_env)
145
+ . at ( & ObligationCause :: dummy_with_span ( span ) , param_env)
133
146
. eq ( DefineOpaqueTypes :: Yes , term, unconstrained_term)
134
147
. unwrap ( ) ;
135
148
proof_tree
136
149
}
137
150
_ => infcx. evaluate_root_goal ( goal, GenerateProofTree :: Yes ) . 1 ,
138
151
} ;
139
- try_visit ! ( visitor. visit_goal( & InspectGoal :: new(
140
- infcx,
141
- self . goal. depth + 1 ,
142
- & proof_tree. unwrap( ) ,
143
- ) ) ) ;
144
- }
145
- }
146
-
147
- V :: Result :: output ( )
152
+ InspectGoal :: new ( infcx, self . goal . depth + 1 , proof_tree. unwrap ( ) )
153
+ } )
154
+ . collect ( )
148
155
}
149
156
150
157
/// Visit all nested goals of this candidate, rolling back
@@ -164,7 +171,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
164
171
}
165
172
166
173
pub fn result ( & self ) -> Result < Certainty , NoSolution > {
167
- self . evaluation . evaluation . result . map ( |c| c. value . certainty )
174
+ self . evaluation . result . map ( |c| c. value . certainty )
168
175
}
169
176
170
177
fn candidates_recur (
@@ -221,7 +228,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
221
228
222
229
pub fn candidates ( & ' a self ) -> Vec < InspectCandidate < ' a , ' tcx > > {
223
230
let mut candidates = vec ! [ ] ;
224
- let last_eval_step = match self . evaluation . evaluation . kind {
231
+ let last_eval_step = match self . evaluation . kind {
225
232
inspect:: CanonicalGoalEvaluationKind :: Overflow
226
233
| inspect:: CanonicalGoalEvaluationKind :: CycleInStack
227
234
| inspect:: CanonicalGoalEvaluationKind :: ProvisionalCacheHit => {
@@ -254,18 +261,15 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
254
261
candidates. pop ( ) . filter ( |_| candidates. is_empty ( ) )
255
262
}
256
263
257
- fn new (
258
- infcx : & ' a InferCtxt < ' tcx > ,
259
- depth : usize ,
260
- root : & ' a inspect:: GoalEvaluation < ' tcx > ,
261
- ) -> Self {
262
- match root. kind {
263
- inspect:: GoalEvaluationKind :: Root { ref orig_values } => InspectGoal {
264
+ fn new ( infcx : & ' a InferCtxt < ' tcx > , depth : usize , root : inspect:: GoalEvaluation < ' tcx > ) -> Self {
265
+ let inspect:: GoalEvaluation { uncanonicalized_goal, kind, evaluation } = root;
266
+ match kind {
267
+ inspect:: GoalEvaluationKind :: Root { orig_values } => InspectGoal {
264
268
infcx,
265
269
depth,
266
270
orig_values,
267
- goal : root . uncanonicalized_goal . fold_with ( & mut EagerResolver :: new ( infcx) ) ,
268
- evaluation : root ,
271
+ goal : uncanonicalized_goal. fold_with ( & mut EagerResolver :: new ( infcx) ) ,
272
+ evaluation,
269
273
} ,
270
274
inspect:: GoalEvaluationKind :: Nested { .. } => unreachable ! ( ) ,
271
275
}
@@ -294,6 +298,6 @@ impl<'tcx> InferCtxt<'tcx> {
294
298
) -> V :: Result {
295
299
let ( _, proof_tree) = self . evaluate_root_goal ( goal, GenerateProofTree :: Yes ) ;
296
300
let proof_tree = proof_tree. unwrap ( ) ;
297
- visitor. visit_goal ( & InspectGoal :: new ( self , 0 , & proof_tree) )
301
+ visitor. visit_goal ( & InspectGoal :: new ( self , 0 , proof_tree) )
298
302
}
299
303
}
0 commit comments