@@ -412,6 +412,75 @@ fn check_gat_where_clauses(
412
412
}
413
413
}
414
414
415
+ // For each region argument (e.g., 'a in our example), also check for a
416
+ // relationship to the other region arguments. If there is an
417
+ // outlives relationship, then we want to ensure that is
418
+ // reflected in a where clause on the GAT itself.
419
+ for ( region_a, region_a_idx) in & visitor. regions {
420
+ for ( region_b, region_b_idx) in & visitor. regions {
421
+ if region_a == region_b {
422
+ continue ;
423
+ }
424
+
425
+ // Unfortunately, we have to use a new `InferCtxt` for each
426
+ // pair, because region constraints get added and solved there,
427
+ // and we need to test each pair individually.
428
+ tcx. infer_ctxt ( ) . enter ( |infcx| {
429
+ let mut outlives_environment = OutlivesEnvironment :: new ( param_env) ;
430
+ outlives_environment. add_implied_bounds ( & infcx, wf_tys. clone ( ) , id, DUMMY_SP ) ;
431
+ outlives_environment. save_implied_bounds ( id) ;
432
+
433
+ let cause =
434
+ ObligationCause :: new ( DUMMY_SP , id, ObligationCauseCode :: MiscObligation ) ;
435
+
436
+ let origin = SubregionOrigin :: from_obligation_cause ( & cause, || {
437
+ infer:: RelateRegionParamBound ( cause. span )
438
+ } ) ;
439
+
440
+ use rustc_infer:: infer:: outlives:: obligations:: TypeOutlivesDelegate ;
441
+ ( & infcx) . push_sub_region_constraint ( origin, region_a, region_b) ;
442
+
443
+ let errors = infcx. resolve_regions (
444
+ trait_item. def_id . to_def_id ( ) ,
445
+ & outlives_environment,
446
+ RegionckMode :: default ( ) ,
447
+ ) ;
448
+
449
+ debug ! ( ?errors, "errors" ) ;
450
+
451
+ // If we were able to prove that Self: 'a without an error,
452
+ // it must be because of the implied or explicit bounds...
453
+ if errors. is_empty ( ) {
454
+ debug ! ( ?region_a_idx, ?region_b_idx) ;
455
+ debug ! ( "required clause: {} must outlive {}" , region_a, region_b) ;
456
+ // Translate into the generic parameters of the GAT.
457
+ let region_a_param = generics. param_at ( * region_a_idx, tcx) ;
458
+ let region_a_param =
459
+ tcx. mk_region ( ty:: RegionKind :: ReEarlyBound ( ty:: EarlyBoundRegion {
460
+ def_id : region_a_param. def_id ,
461
+ index : region_a_param. index ,
462
+ name : region_a_param. name ,
463
+ } ) ) ;
464
+ // Same for the region.
465
+ let region_b_param = generics. param_at ( * region_b_idx, tcx) ;
466
+ let region_b_param =
467
+ tcx. mk_region ( ty:: RegionKind :: ReEarlyBound ( ty:: EarlyBoundRegion {
468
+ def_id : region_b_param. def_id ,
469
+ index : region_b_param. index ,
470
+ name : region_b_param. name ,
471
+ } ) ) ;
472
+ // The predicate we expect to see.
473
+ let clause = ty:: PredicateKind :: RegionOutlives ( ty:: OutlivesPredicate (
474
+ region_a_param,
475
+ region_b_param,
476
+ ) ) ;
477
+ let clause = tcx. mk_predicate ( ty:: Binder :: dummy ( clause) ) ;
478
+ function_clauses. insert ( clause) ;
479
+ }
480
+ } ) ;
481
+ }
482
+ }
483
+
415
484
match clauses. as_mut ( ) {
416
485
Some ( clauses) => {
417
486
clauses. drain_filter ( |p| !function_clauses. contains ( p) ) ;
0 commit comments