@@ -2,17 +2,17 @@ use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
2
2
use crate :: bounds:: Bounds ;
3
3
use crate :: collect:: ItemCtxt ;
4
4
use crate :: constrained_generic_params as cgp;
5
- use hir:: { HirId , Node } ;
5
+ use hir:: { HirId , Lifetime , Node } ;
6
6
use rustc_data_structures:: fx:: FxIndexSet ;
7
7
use rustc_hir as hir;
8
8
use rustc_hir:: def:: DefKind ;
9
9
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
10
10
use rustc_hir:: intravisit:: { self , Visitor } ;
11
11
use rustc_middle:: ty:: subst:: InternalSubsts ;
12
12
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
13
- use rustc_middle:: ty:: { GenericPredicates , ToPredicate } ;
13
+ use rustc_middle:: ty:: { GenericPredicates , Generics , ToPredicate } ;
14
14
use rustc_span:: symbol:: { sym, Ident } ;
15
- use rustc_span:: { Span , DUMMY_SP } ;
15
+ use rustc_span:: { Span , Symbol , DUMMY_SP } ;
16
16
17
17
/// Returns a list of all type predicates (explicit and implicit) for the definition with
18
18
/// 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
289
289
bug ! ( "unexpected {opaque_ty_node:?}" )
290
290
} ;
291
291
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 ( ) ;
302
292
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 ) ) ) ;
304
300
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) ;
324
302
debug ! ( ?predicates) ;
325
303
}
326
304
@@ -330,6 +308,46 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
330
308
}
331
309
}
332
310
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
+
333
351
fn const_evaluatable_predicates_of (
334
352
tcx : TyCtxt < ' _ > ,
335
353
def_id : LocalDefId ,
0 commit comments