@@ -2,17 +2,17 @@ use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
22use crate :: bounds:: Bounds ;
33use crate :: collect:: ItemCtxt ;
44use crate :: constrained_generic_params as cgp;
5- use hir:: { HirId , Node } ;
5+ use hir:: { HirId , Lifetime , Node } ;
66use rustc_data_structures:: fx:: FxIndexSet ;
77use rustc_hir as hir;
88use rustc_hir:: def:: DefKind ;
99use rustc_hir:: def_id:: { DefId , LocalDefId } ;
1010use rustc_hir:: intravisit:: { self , Visitor } ;
1111use rustc_middle:: ty:: subst:: InternalSubsts ;
1212use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
13- use rustc_middle:: ty:: { GenericPredicates , ToPredicate } ;
13+ use rustc_middle:: ty:: { GenericPredicates , Generics , ToPredicate } ;
1414use rustc_span:: symbol:: { sym, Ident } ;
15- use rustc_span:: { Span , DUMMY_SP } ;
15+ use rustc_span:: { Span , Symbol , DUMMY_SP } ;
1616
1717/// Returns a list of all type predicates (explicit and implicit) for the definition with
1818/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
@@ -289,38 +289,16 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
289289 bug ! ( "unexpected {opaque_ty_node:?}" )
290290 } ;
291291 debug ! ( ?lifetimes) ;
292- for ( arg, duplicate) in std:: iter:: zip ( lifetimes, ast_generics. params ) {
293- let hir:: GenericArg :: Lifetime ( arg) = arg else { bug ! ( ) } ;
294- let orig_region = icx. astconv ( ) . ast_region_to_region ( & arg, None ) ;
295- if !matches ! ( orig_region. kind( ) , ty:: ReEarlyBound ( ..) ) {
296- // Only early-bound regions can point to the original generic parameter.
297- continue ;
298- }
299-
300- let hir:: GenericParamKind :: Lifetime { .. } = duplicate. kind else { continue } ;
301- let dup_def = duplicate. def_id . to_def_id ( ) ;
302292
303- let Some ( dup_index) = generics. param_def_id_to_index ( tcx, dup_def) else { bug ! ( ) } ;
293+ let lifetime_mapping = std:: iter:: zip ( lifetimes, ast_generics. params )
294+ . map ( |( arg, dup) | {
295+ let hir:: GenericArg :: Lifetime ( arg) = arg else { bug ! ( ) } ;
296+ ( * * arg, dup)
297+ } )
298+ . filter ( |( _, dup) | matches ! ( dup. kind, hir:: GenericParamKind :: Lifetime { .. } ) )
299+ . map ( |( lifetime, dup) | ( lifetime, ( dup. def_id , dup. name . ident ( ) . name , dup. span ) ) ) ;
304300
305- let dup_region = ty:: Region :: new_early_bound (
306- tcx,
307- ty:: EarlyBoundRegion {
308- def_id : dup_def,
309- index : dup_index,
310- name : duplicate. name . ident ( ) . name ,
311- } ,
312- ) ;
313- predicates. push ( (
314- ty:: ClauseKind :: RegionOutlives ( ty:: OutlivesPredicate ( orig_region, dup_region) )
315- . to_predicate ( icx. tcx ) ,
316- duplicate. span ,
317- ) ) ;
318- predicates. push ( (
319- ty:: ClauseKind :: RegionOutlives ( ty:: OutlivesPredicate ( dup_region, orig_region) )
320- . to_predicate ( icx. tcx ) ,
321- duplicate. span ,
322- ) ) ;
323- }
301+ bidirectional_lifetime_predicates ( tcx, def_id, lifetime_mapping, generics, & mut predicates) ;
324302 debug ! ( ?predicates) ;
325303 }
326304
@@ -330,6 +308,46 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
330308 }
331309}
332310
311+ /// Opaques have duplicated lifetimes and we need to compute bidirectional outlives predicates to
312+ /// enforce that these lifetimes stay in sync.
313+ fn compute_bidirectional_outlives_predicates < ' tcx > (
314+ tcx : TyCtxt < ' tcx > ,
315+ item_def_id : LocalDefId ,
316+ lifetime_mapping : impl Iterator < Item = ( Lifetime , ( LocalDefId , Symbol , Span ) ) > ,
317+ generics : & Generics ,
318+ predicates : & mut Vec < ( ty:: Clause < ' tcx > , Span ) > ,
319+ ) {
320+ let icx = ItemCtxt :: new ( tcx, item_def_id) ;
321+
322+ for ( arg, ( dup_def, name, span) ) in lifetime_mapping {
323+ let orig_region = icx. astconv ( ) . ast_region_to_region ( & arg, None ) ;
324+ if !matches ! ( orig_region. kind( ) , ty:: ReEarlyBound ( ..) ) {
325+ // There is no late-bound lifetime to actually match up here, since the lifetime doesn't
326+ // show up in the opaque's parent's substs.
327+ continue ;
328+ }
329+
330+ let Some ( dup_index) = generics. param_def_id_to_index ( icx. tcx , dup_def. to_def_id ( ) ) else { bug ! ( ) } ;
331+
332+ let dup_region = ty:: Region :: new_early_bound (
333+ tcx,
334+ ty:: EarlyBoundRegion { def_id : dup_def. to_def_id ( ) , index : dup_index, name } ,
335+ ) ;
336+
337+ predicates. push ( (
338+ ty:: ClauseKind :: RegionOutlives ( ty:: OutlivesPredicate ( orig_region, dup_region) )
339+ . to_predicate ( tcx) ,
340+ span,
341+ ) ) ;
342+
343+ predicates. push ( (
344+ ty:: ClauseKind :: RegionOutlives ( ty:: OutlivesPredicate ( dup_region, orig_region) )
345+ . to_predicate ( tcx) ,
346+ span,
347+ ) ) ;
348+ }
349+ }
350+
333351fn const_evaluatable_predicates_of (
334352 tcx : TyCtxt < ' _ > ,
335353 def_id : LocalDefId ,
0 commit comments