@@ -194,47 +194,57 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
194
194
195
195
let goals = instantiated_goals
196
196
. into_iter ( )
197
- . map ( |( source, goal) | match goal. predicate . kind ( ) . no_bound_vars ( ) {
198
- Some ( ty:: PredicateKind :: NormalizesTo ( ty:: NormalizesTo { alias, term } ) ) => {
199
- let unconstrained_term = match term. unpack ( ) {
200
- ty:: TermKind :: Ty ( _) => infcx. next_ty_var ( span) . into ( ) ,
201
- ty:: TermKind :: Const ( _) => infcx. next_const_var ( span) . into ( ) ,
202
- } ;
203
- let goal =
204
- goal. with ( infcx. tcx , ty:: NormalizesTo { alias, term : unconstrained_term } ) ;
205
- // We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the
206
- // expected term. This means that candidates which only fail due to nested goals
207
- // and which normalize to a different term then the final result could ICE: when
208
- // building their proof tree, the expected term was unconstrained, but when
209
- // instantiating the candidate it is already constrained to the result of another
210
- // candidate.
211
- let proof_tree = infcx
212
- . probe ( |_| infcx. evaluate_root_goal_raw ( goal, GenerateProofTree :: Yes ) . 1 ) ;
213
- InspectGoal :: new (
214
- infcx,
215
- self . goal . depth + 1 ,
216
- proof_tree. unwrap ( ) ,
217
- Some ( NormalizesToTermHack { term, unconstrained_term } ) ,
218
- source,
219
- )
220
- }
221
- _ => {
222
- // We're using a probe here as evaluating a goal could constrain
223
- // inference variables by choosing one candidate. If we then recurse
224
- // into another candidate who ends up with different inference
225
- // constraints, we get an ICE if we already applied the constraints
226
- // from the chosen candidate.
227
- let proof_tree = infcx
228
- . probe ( |_| infcx. evaluate_root_goal ( goal, GenerateProofTree :: Yes ) . 1 )
229
- . unwrap ( ) ;
230
- InspectGoal :: new ( infcx, self . goal . depth + 1 , proof_tree, None , source)
231
- }
232
- } )
197
+ . map ( |( source, goal) | self . instantiate_proof_tree_for_nested_goal ( source, goal, span) )
233
198
. collect ( ) ;
234
199
235
200
( goals, opt_impl_args)
236
201
}
237
202
203
+ pub fn instantiate_proof_tree_for_nested_goal (
204
+ & self ,
205
+ source : GoalSource ,
206
+ goal : Goal < ' tcx , ty:: Predicate < ' tcx > > ,
207
+ span : Span ,
208
+ ) -> InspectGoal < ' a , ' tcx > {
209
+ let infcx = self . goal . infcx ;
210
+ match goal. predicate . kind ( ) . no_bound_vars ( ) {
211
+ Some ( ty:: PredicateKind :: NormalizesTo ( ty:: NormalizesTo { alias, term } ) ) => {
212
+ let unconstrained_term = match term. unpack ( ) {
213
+ ty:: TermKind :: Ty ( _) => infcx. next_ty_var ( span) . into ( ) ,
214
+ ty:: TermKind :: Const ( _) => infcx. next_const_var ( span) . into ( ) ,
215
+ } ;
216
+ let goal =
217
+ goal. with ( infcx. tcx , ty:: NormalizesTo { alias, term : unconstrained_term } ) ;
218
+ // We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the
219
+ // expected term. This means that candidates which only fail due to nested goals
220
+ // and which normalize to a different term then the final result could ICE: when
221
+ // building their proof tree, the expected term was unconstrained, but when
222
+ // instantiating the candidate it is already constrained to the result of another
223
+ // candidate.
224
+ let proof_tree =
225
+ infcx. probe ( |_| infcx. evaluate_root_goal_raw ( goal, GenerateProofTree :: Yes ) . 1 ) ;
226
+ InspectGoal :: new (
227
+ infcx,
228
+ self . goal . depth + 1 ,
229
+ proof_tree. unwrap ( ) ,
230
+ Some ( NormalizesToTermHack { term, unconstrained_term } ) ,
231
+ source,
232
+ )
233
+ }
234
+ _ => {
235
+ // We're using a probe here as evaluating a goal could constrain
236
+ // inference variables by choosing one candidate. If we then recurse
237
+ // into another candidate who ends up with different inference
238
+ // constraints, we get an ICE if we already applied the constraints
239
+ // from the chosen candidate.
240
+ let proof_tree = infcx
241
+ . probe ( |_| infcx. evaluate_root_goal ( goal, GenerateProofTree :: Yes ) . 1 )
242
+ . unwrap ( ) ;
243
+ InspectGoal :: new ( infcx, self . goal . depth + 1 , proof_tree, None , source)
244
+ }
245
+ }
246
+ }
247
+
238
248
/// Visit all nested goals of this candidate, rolling back
239
249
/// all inference constraints.
240
250
pub fn visit_nested_in_probe < V : ProofTreeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> V :: Result {
0 commit comments