@@ -84,40 +84,30 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
8484
8585 Node :: ImplItem ( item) => item. generics ,
8686
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) ;
10891 }
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
11993 }
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+ } ,
121111
122112 Node :: ForeignItem ( item) => match item. kind {
123113 ForeignItemKind :: Static ( ..) => NO_GENERICS ,
@@ -161,6 +151,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
161151
162152 trace ! ( ?predicates) ;
163153 trace ! ( ?ast_generics) ;
154+ trace ! ( ?generics) ;
164155
165156 // Collect the predicates that were written inline by the user on each
166157 // type parameter (e.g., `<T: Foo>`).
@@ -279,6 +270,54 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
279270 ) ;
280271 }
281272
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+
282321 ty:: GenericPredicates {
283322 parent : generics. parent ,
284323 predicates : tcx. arena . alloc_from_iter ( predicates) ,
0 commit comments