@@ -884,6 +884,7 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>(
884
884
candidate_set,
885
885
ProjectionTyCandidate :: ParamEnv ,
886
886
obligation. param_env . caller_bounds ( ) . iter ( ) ,
887
+ false ,
887
888
) ;
888
889
}
889
890
@@ -927,6 +928,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
927
928
candidate_set,
928
929
ProjectionTyCandidate :: TraitDef ,
929
930
bounds. iter ( ) ,
931
+ true ,
930
932
)
931
933
}
932
934
@@ -937,6 +939,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
937
939
candidate_set : & mut ProjectionTyCandidateSet < ' tcx > ,
938
940
ctor : fn ( ty:: PolyProjectionPredicate < ' tcx > ) -> ProjectionTyCandidate < ' tcx > ,
939
941
env_predicates : impl Iterator < Item = ty:: Predicate < ' tcx > > ,
942
+ potentially_unnormalized_candidates : bool ,
940
943
) {
941
944
debug ! ( "assemble_candidates_from_predicates(obligation={:?})" , obligation) ;
942
945
let infcx = selcx. infcx ( ) ;
@@ -948,16 +951,12 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
948
951
949
952
let is_match = same_def_id
950
953
&& 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
+ )
961
960
} ) ;
962
961
963
962
debug ! (
@@ -1157,9 +1156,12 @@ fn confirm_candidate<'cx, 'tcx>(
1157
1156
debug ! ( "confirm_candidate(candidate={:?}, obligation={:?})" , candidate, obligation) ;
1158
1157
1159
1158
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 )
1163
1165
}
1164
1166
1165
1167
ProjectionTyCandidate :: Select ( impl_source) => {
@@ -1272,7 +1274,7 @@ fn confirm_object_candidate<'cx, 'tcx>(
1272
1274
}
1273
1275
} ;
1274
1276
1275
- confirm_param_env_candidate ( selcx, obligation, env_predicate)
1277
+ confirm_param_env_candidate ( selcx, obligation, env_predicate, false )
1276
1278
}
1277
1279
1278
1280
fn confirm_generator_candidate < ' cx , ' tcx > (
@@ -1323,7 +1325,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
1323
1325
}
1324
1326
} ) ;
1325
1327
1326
- confirm_param_env_candidate ( selcx, obligation, predicate)
1328
+ confirm_param_env_candidate ( selcx, obligation, predicate, false )
1327
1329
. with_addl_obligations ( impl_source. nested )
1328
1330
. with_addl_obligations ( obligations)
1329
1331
}
@@ -1345,7 +1347,7 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
1345
1347
ty : self_ty. discriminant_ty ( tcx) ,
1346
1348
} ;
1347
1349
1348
- confirm_param_env_candidate ( selcx, obligation, ty:: Binder :: bind ( predicate) )
1350
+ confirm_param_env_candidate ( selcx, obligation, ty:: Binder :: bind ( predicate) , false )
1349
1351
}
1350
1352
1351
1353
fn confirm_fn_pointer_candidate < ' cx , ' tcx > (
@@ -1420,13 +1422,14 @@ fn confirm_callable_candidate<'cx, 'tcx>(
1420
1422
ty : ret_type,
1421
1423
} ) ;
1422
1424
1423
- confirm_param_env_candidate ( selcx, obligation, predicate)
1425
+ confirm_param_env_candidate ( selcx, obligation, predicate, false )
1424
1426
}
1425
1427
1426
1428
fn confirm_param_env_candidate < ' cx , ' tcx > (
1427
1429
selcx : & mut SelectionContext < ' cx , ' tcx > ,
1428
1430
obligation : & ProjectionTyObligation < ' tcx > ,
1429
1431
poly_cache_entry : ty:: PolyProjectionPredicate < ' tcx > ,
1432
+ potentially_unnormalized_candidate : bool ,
1430
1433
) -> Progress < ' tcx > {
1431
1434
let infcx = selcx. infcx ( ) ;
1432
1435
let cause = & obligation. cause ;
@@ -1440,8 +1443,27 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
1440
1443
1441
1444
let cache_trait_ref = cache_entry. projection_ty . trait_ref ( infcx. tcx ) ;
1442
1445
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
+
1443
1462
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
+ }
1445
1467
Err ( e) => {
1446
1468
let msg = format ! (
1447
1469
"Failed to unify obligation `{:?}` with poly_projection `{:?}`: {:?}" ,
0 commit comments