@@ -412,6 +412,75 @@ fn check_gat_where_clauses(
412412 }
413413 }
414414
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+
415484 match clauses. as_mut ( ) {
416485 Some ( clauses) => {
417486 clauses. drain_filter ( |p| !function_clauses. contains ( p) ) ;
0 commit comments