@@ -84,40 +84,30 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
84
84
85
85
Node :: ImplItem ( item) => item. generics ,
86
86
87
- Node :: Item ( item) => {
88
- match item. kind {
89
- ItemKind :: Impl ( ref impl_) => {
90
- if impl_. defaultness . is_default ( ) {
91
- is_default_impl_trait = tcx. impl_trait_ref ( def_id) . map ( ty:: Binder :: dummy) ;
92
- }
93
- & impl_. generics
94
- }
95
- ItemKind :: Fn ( .., ref generics, _)
96
- | ItemKind :: TyAlias ( _, ref generics)
97
- | ItemKind :: Enum ( _, ref generics)
98
- | ItemKind :: Struct ( _, ref generics)
99
- | ItemKind :: Union ( _, ref generics) => * generics,
100
-
101
- ItemKind :: Trait ( _, _, ref generics, ..) => {
102
- is_trait = Some ( ty:: TraitRef :: identity ( tcx, def_id) ) ;
103
- * generics
104
- }
105
- ItemKind :: TraitAlias ( ref generics, _) => {
106
- is_trait = Some ( ty:: TraitRef :: identity ( tcx, def_id) ) ;
107
- * generics
87
+ Node :: Item ( item) => match item. kind {
88
+ ItemKind :: Impl ( ref impl_) => {
89
+ if impl_. defaultness . is_default ( ) {
90
+ is_default_impl_trait = tcx. impl_trait_ref ( def_id) . map ( ty:: Binder :: dummy) ;
108
91
}
109
- ItemKind :: OpaqueTy ( OpaqueTy {
110
- ref generics,
111
- origin : hir:: OpaqueTyOrigin :: TyAlias ,
112
- ..
113
- } ) => {
114
- // type-alias impl trait
115
- generics
116
- }
117
-
118
- _ => NO_GENERICS ,
92
+ & impl_. generics
119
93
}
120
- }
94
+ ItemKind :: Fn ( .., ref generics, _)
95
+ | ItemKind :: TyAlias ( _, ref generics)
96
+ | ItemKind :: Enum ( _, ref generics)
97
+ | ItemKind :: Struct ( _, ref generics)
98
+ | ItemKind :: Union ( _, ref generics) => * generics,
99
+
100
+ ItemKind :: Trait ( _, _, ref generics, ..) => {
101
+ is_trait = Some ( ty:: TraitRef :: identity ( tcx, def_id) ) ;
102
+ * generics
103
+ }
104
+ ItemKind :: TraitAlias ( ref generics, _) => {
105
+ is_trait = Some ( ty:: TraitRef :: identity ( tcx, def_id) ) ;
106
+ * generics
107
+ }
108
+ ItemKind :: OpaqueTy ( OpaqueTy { ref generics, .. } ) => generics,
109
+ _ => NO_GENERICS ,
110
+ } ,
121
111
122
112
Node :: ForeignItem ( item) => match item. kind {
123
113
ForeignItemKind :: Static ( ..) => NO_GENERICS ,
@@ -161,6 +151,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
161
151
162
152
trace ! ( ?predicates) ;
163
153
trace ! ( ?ast_generics) ;
154
+ trace ! ( ?generics) ;
164
155
165
156
// Collect the predicates that were written inline by the user on each
166
157
// type parameter (e.g., `<T: Foo>`).
@@ -279,6 +270,54 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
279
270
) ;
280
271
}
281
272
273
+ // Opaque types duplicate some of their generic parameters.
274
+ // We create bi-directional Outlives predicates between the original
275
+ // and the duplicated parameter, to ensure that they do not get out of sync.
276
+ if let Node :: Item ( & Item { kind : ItemKind :: OpaqueTy ( ..) , .. } ) = node {
277
+ let opaque_ty_id = tcx. hir ( ) . get_parent_node ( hir_id) ;
278
+ let opaque_ty_node = tcx. hir ( ) . get ( opaque_ty_id) ;
279
+ let Node :: Ty ( & Ty { kind : TyKind :: OpaqueDef ( _, lifetimes, _) , .. } ) = opaque_ty_node else {
280
+ bug ! ( "unexpected {opaque_ty_node:?}" )
281
+ } ;
282
+ debug ! ( ?lifetimes) ;
283
+ for ( arg, duplicate) in std:: iter:: zip ( lifetimes, ast_generics. params ) {
284
+ let hir:: GenericArg :: Lifetime ( arg) = arg else { bug ! ( ) } ;
285
+ let orig_region = <dyn AstConv < ' _ > >:: ast_region_to_region ( & icx, & arg, None ) ;
286
+ if !matches ! ( orig_region. kind( ) , ty:: ReEarlyBound ( ..) ) {
287
+ // Only early-bound regions can point to the original generic parameter.
288
+ continue ;
289
+ }
290
+
291
+ let hir:: GenericParamKind :: Lifetime { .. } = duplicate. kind else { continue } ;
292
+ let dup_def = tcx. hir ( ) . local_def_id ( duplicate. hir_id ) . to_def_id ( ) ;
293
+
294
+ let Some ( dup_index) = generics. param_def_id_to_index ( tcx, dup_def) else { bug ! ( ) } ;
295
+
296
+ let dup_region = tcx. mk_region ( ty:: ReEarlyBound ( ty:: EarlyBoundRegion {
297
+ def_id : dup_def,
298
+ index : dup_index,
299
+ name : duplicate. name . ident ( ) . name ,
300
+ } ) ) ;
301
+ predicates. push ( (
302
+ ty:: Binder :: dummy ( ty:: PredicateKind :: RegionOutlives ( ty:: OutlivesPredicate (
303
+ orig_region,
304
+ dup_region,
305
+ ) ) )
306
+ . to_predicate ( icx. tcx ) ,
307
+ duplicate. span ,
308
+ ) ) ;
309
+ predicates. push ( (
310
+ ty:: Binder :: dummy ( ty:: PredicateKind :: RegionOutlives ( ty:: OutlivesPredicate (
311
+ dup_region,
312
+ orig_region,
313
+ ) ) )
314
+ . to_predicate ( icx. tcx ) ,
315
+ duplicate. span ,
316
+ ) ) ;
317
+ }
318
+ debug ! ( ?predicates) ;
319
+ }
320
+
282
321
ty:: GenericPredicates {
283
322
parent : generics. parent ,
284
323
predicates : tcx. arena . alloc_from_iter ( predicates) ,
0 commit comments