@@ -122,6 +122,28 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
122122 && goal. param_env . visit_with ( & mut visitor) . is_continue ( )
123123 }
124124
125+ /// After normalizing the projection to `normalized_alias` with the given
126+ /// `normalization_certainty`, constrain the inference variable `term` to it
127+ /// and return a query response.
128+ fn eq_term_and_make_canonical_response (
129+ & mut self ,
130+ goal : Goal < ' tcx , ProjectionPredicate < ' tcx > > ,
131+ normalization_certainty : Certainty ,
132+ normalized_alias : impl Into < ty:: Term < ' tcx > > ,
133+ ) -> QueryResult < ' tcx > {
134+ // The term of our goal should be fully unconstrained, so this should never fail.
135+ //
136+ // It can however be ambiguous when the `normalized_alias` contains a projection.
137+ let nested_goals = self
138+ . infcx
139+ . eq ( goal. param_env , goal. predicate . term , normalized_alias. into ( ) )
140+ . expect ( "failed to unify with unconstrained term" ) ;
141+ let rhs_certainty =
142+ self . evaluate_all ( nested_goals) . expect ( "failed to unify with unconstrained term" ) ;
143+
144+ self . make_canonical_response ( normalization_certainty. unify_and ( rhs_certainty) )
145+ }
146+
125147 fn merge_project_candidates (
126148 & mut self ,
127149 mut candidates : Vec < Candidate < ' tcx > > ,
@@ -218,7 +240,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
218240 . map ( |pred| goal. with ( tcx, pred) ) ;
219241
220242 nested_goals. extend ( where_clause_bounds) ;
221- let trait_ref_certainty = ecx. evaluate_all ( nested_goals) ?;
243+ let match_impl_certainty = ecx. evaluate_all ( nested_goals) ?;
222244
223245 // In case the associated item is hidden due to specialization, we have to
224246 // return ambiguity this would otherwise be incomplete, resulting in
@@ -230,7 +252,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
230252 goal. predicate . def_id ( ) ,
231253 impl_def_id
232254 ) ? else {
233- return ecx. make_canonical_response ( trait_ref_certainty . unify_and ( Certainty :: AMBIGUOUS ) ) ;
255+ return ecx. make_canonical_response ( match_impl_certainty . unify_and ( Certainty :: AMBIGUOUS ) ) ;
234256 } ;
235257
236258 if !assoc_def. item . defaultness ( tcx) . has_value ( ) {
@@ -277,17 +299,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
277299 ty. map_bound ( |ty| ty. into ( ) )
278300 } ;
279301
280- // The term of our goal should be fully unconstrained, so this should never fail.
281- //
282- // It can however be ambiguous when the resolved type is a projection.
283- let nested_goals = ecx
284- . infcx
285- . eq ( goal. param_env , goal. predicate . term , term. subst ( tcx, substs) )
286- . expect ( "failed to unify with unconstrained term" ) ;
287- let rhs_certainty =
288- ecx. evaluate_all ( nested_goals) . expect ( "failed to unify with unconstrained term" ) ;
289-
290- ecx. make_canonical_response ( trait_ref_certainty. unify_and ( rhs_certainty) )
302+ ecx. eq_term_and_make_canonical_response ( goal, match_impl_certainty, term. subst ( tcx, substs) )
291303 } )
292304 }
293305
@@ -307,18 +319,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
307319 ) ?;
308320 let subst_certainty = ecx. evaluate_all ( nested_goals) ?;
309321
310- // The term of our goal should be fully unconstrained, so this should never fail.
311- //
312- // It can however be ambiguous when the resolved type is a projection.
313- let nested_goals = ecx
314- . infcx
315- . eq ( goal. param_env , goal. predicate . term , assumption_projection_pred. term )
316- . expect ( "failed to unify with unconstrained term" ) ;
317- let rhs_certainty = ecx
318- . evaluate_all ( nested_goals)
319- . expect ( "failed to unify with unconstrained term" ) ;
320-
321- ecx. make_canonical_response ( subst_certainty. unify_and ( rhs_certainty) )
322+ ecx. eq_term_and_make_canonical_response (
323+ goal,
324+ subst_certainty,
325+ assumption_projection_pred. term ,
326+ )
322327 } )
323328 } else {
324329 Err ( NoSolution )
@@ -434,14 +439,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
434439 [ ty:: GenericArg :: from ( goal. predicate . self_ty ( ) ) ] ,
435440 ) ) ;
436441
437- let mut nested_goals = ecx. infcx . eq (
438- goal. param_env ,
439- goal. predicate . term . ty ( ) . unwrap ( ) ,
442+ let is_sized_certainty = ecx. evaluate_goal ( goal. with ( tcx, sized_predicate) ) ?. 1 ;
443+ return ecx. eq_term_and_make_canonical_response (
444+ goal,
445+ is_sized_certainty,
440446 tcx. types . unit ,
441- ) ?;
442- nested_goals. push ( goal. with ( tcx, sized_predicate) ) ;
443-
444- return ecx. evaluate_all_and_make_canonical_response ( nested_goals) ;
447+ ) ;
445448 }
446449
447450 ty:: Adt ( def, substs) if def. is_struct ( ) => {
@@ -453,7 +456,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
453456 tcx,
454457 ty:: Binder :: dummy ( goal. predicate . with_self_ty ( tcx, self_ty) ) ,
455458 ) ;
456- return ecx. evaluate_all_and_make_canonical_response ( vec ! [ new_goal] ) ;
459+ let ( _, certainty) = ecx. evaluate_goal ( new_goal) ?;
460+ return ecx. make_canonical_response ( certainty) ;
457461 }
458462 }
459463 }
@@ -466,7 +470,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
466470 tcx,
467471 ty:: Binder :: dummy ( goal. predicate . with_self_ty ( tcx, self_ty) ) ,
468472 ) ;
469- return ecx. evaluate_all_and_make_canonical_response ( vec ! [ new_goal] ) ;
473+ let ( _, certainty) = ecx. evaluate_goal ( new_goal) ?;
474+ return ecx. make_canonical_response ( certainty) ;
470475 }
471476 } ,
472477
@@ -479,9 +484,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
479484 ) ,
480485 } ;
481486
482- let nested_goals =
483- ecx. infcx . eq ( goal. param_env , goal. predicate . term . ty ( ) . unwrap ( ) , metadata_ty) ?;
484- ecx. evaluate_all_and_make_canonical_response ( nested_goals)
487+ ecx. eq_term_and_make_canonical_response ( goal, Certainty :: Yes , metadata_ty)
485488 } )
486489 }
487490
0 commit comments