@@ -884,6 +884,7 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>(
884884 candidate_set,
885885 ProjectionTyCandidate :: ParamEnv ,
886886 obligation. param_env . caller_bounds ( ) . iter ( ) ,
887+ false ,
887888 ) ;
888889}
889890
@@ -927,6 +928,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
927928 candidate_set,
928929 ProjectionTyCandidate :: TraitDef ,
929930 bounds. iter ( ) ,
931+ true ,
930932 )
931933}
932934
@@ -937,6 +939,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
937939 candidate_set : & mut ProjectionTyCandidateSet < ' tcx > ,
938940 ctor : fn ( ty:: PolyProjectionPredicate < ' tcx > ) -> ProjectionTyCandidate < ' tcx > ,
939941 env_predicates : impl Iterator < Item = ty:: Predicate < ' tcx > > ,
942+ potentially_unnormalized_candidates : bool ,
940943) {
941944 debug ! ( "assemble_candidates_from_predicates(obligation={:?})" , obligation) ;
942945 let infcx = selcx. infcx ( ) ;
@@ -948,16 +951,12 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
948951
949952 let is_match = same_def_id
950953 && infcx. probe ( |_| {
951- let data_poly_trait_ref = data. to_poly_trait_ref ( infcx. tcx ) ;
952- let obligation_poly_trait_ref = obligation_trait_ref. to_poly_trait_ref ( ) ;
953- infcx
954- . at ( & obligation. cause , obligation. param_env )
955- . sup ( obligation_poly_trait_ref, data_poly_trait_ref)
956- . map ( |InferOk { obligations : _, value : ( ) } | {
957- // FIXME(#32730) -- do we need to take obligations
958- // into account in any way? At the moment, no.
959- } )
960- . is_ok ( )
954+ selcx. match_projection_projections (
955+ obligation,
956+ obligation_trait_ref,
957+ & data,
958+ potentially_unnormalized_candidates,
959+ )
961960 } ) ;
962961
963962 debug ! (
@@ -1157,9 +1156,12 @@ fn confirm_candidate<'cx, 'tcx>(
11571156 debug ! ( "confirm_candidate(candidate={:?}, obligation={:?})" , candidate, obligation) ;
11581157
11591158 let mut progress = match candidate {
1160- ProjectionTyCandidate :: ParamEnv ( poly_projection)
1161- | ProjectionTyCandidate :: TraitDef ( poly_projection) => {
1162- confirm_param_env_candidate ( selcx, obligation, poly_projection)
1159+ ProjectionTyCandidate :: ParamEnv ( poly_projection) => {
1160+ confirm_param_env_candidate ( selcx, obligation, poly_projection, false )
1161+ }
1162+
1163+ ProjectionTyCandidate :: TraitDef ( poly_projection) => {
1164+ confirm_param_env_candidate ( selcx, obligation, poly_projection, true )
11631165 }
11641166
11651167 ProjectionTyCandidate :: Select ( impl_source) => {
@@ -1272,7 +1274,7 @@ fn confirm_object_candidate<'cx, 'tcx>(
12721274 }
12731275 } ;
12741276
1275- confirm_param_env_candidate ( selcx, obligation, env_predicate)
1277+ confirm_param_env_candidate ( selcx, obligation, env_predicate, false )
12761278}
12771279
12781280fn confirm_generator_candidate < ' cx , ' tcx > (
@@ -1323,7 +1325,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
13231325 }
13241326 } ) ;
13251327
1326- confirm_param_env_candidate ( selcx, obligation, predicate)
1328+ confirm_param_env_candidate ( selcx, obligation, predicate, false )
13271329 . with_addl_obligations ( impl_source. nested )
13281330 . with_addl_obligations ( obligations)
13291331}
@@ -1345,7 +1347,7 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
13451347 ty : self_ty. discriminant_ty ( tcx) ,
13461348 } ;
13471349
1348- confirm_param_env_candidate ( selcx, obligation, ty:: Binder :: bind ( predicate) )
1350+ confirm_param_env_candidate ( selcx, obligation, ty:: Binder :: bind ( predicate) , false )
13491351}
13501352
13511353fn confirm_fn_pointer_candidate < ' cx , ' tcx > (
@@ -1420,13 +1422,14 @@ fn confirm_callable_candidate<'cx, 'tcx>(
14201422 ty : ret_type,
14211423 } ) ;
14221424
1423- confirm_param_env_candidate ( selcx, obligation, predicate)
1425+ confirm_param_env_candidate ( selcx, obligation, predicate, false )
14241426}
14251427
14261428fn confirm_param_env_candidate < ' cx , ' tcx > (
14271429 selcx : & mut SelectionContext < ' cx , ' tcx > ,
14281430 obligation : & ProjectionTyObligation < ' tcx > ,
14291431 poly_cache_entry : ty:: PolyProjectionPredicate < ' tcx > ,
1432+ potentially_unnormalized_candidate : bool ,
14301433) -> Progress < ' tcx > {
14311434 let infcx = selcx. infcx ( ) ;
14321435 let cause = & obligation. cause ;
@@ -1440,8 +1443,27 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
14401443
14411444 let cache_trait_ref = cache_entry. projection_ty . trait_ref ( infcx. tcx ) ;
14421445 let obligation_trait_ref = obligation. predicate . trait_ref ( infcx. tcx ) ;
1446+ let mut nested_obligations = Vec :: new ( ) ;
1447+ let cache_trait_ref = if potentially_unnormalized_candidate {
1448+ ensure_sufficient_stack ( || {
1449+ normalize_with_depth_to (
1450+ selcx,
1451+ obligation. param_env ,
1452+ obligation. cause . clone ( ) ,
1453+ obligation. recursion_depth + 1 ,
1454+ & cache_trait_ref,
1455+ & mut nested_obligations,
1456+ )
1457+ } )
1458+ } else {
1459+ cache_trait_ref
1460+ } ;
1461+
14431462 match infcx. at ( cause, param_env) . eq ( cache_trait_ref, obligation_trait_ref) {
1444- Ok ( InferOk { value : _, obligations } ) => Progress { ty : cache_entry. ty , obligations } ,
1463+ Ok ( InferOk { value : _, obligations } ) => {
1464+ nested_obligations. extend ( obligations) ;
1465+ Progress { ty : cache_entry. ty , obligations : nested_obligations }
1466+ }
14451467 Err ( e) => {
14461468 let msg = format ! (
14471469 "Failed to unify obligation `{:?}` with poly_projection `{:?}`: {:?}" ,
0 commit comments