55
66use itertools:: Itertools ;
77use rustc_arena:: DroplessArena ;
8+ use rustc_hir as hir;
89use rustc_hir:: def:: DefKind ;
910use rustc_hir:: def_id:: { DefId , LocalDefId } ;
1011use rustc_middle:: query:: Providers ;
@@ -63,13 +64,27 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
6364 }
6465 DefKind :: AssocTy => match tcx. opt_rpitit_info ( item_def_id. to_def_id ( ) ) {
6566 Some ( ty:: ImplTraitInTraitData :: Trait { opaque_def_id, .. } ) => {
66- return variance_of_opaque ( tcx, opaque_def_id. expect_local ( ) ) ;
67+ return variance_of_opaque (
68+ tcx,
69+ opaque_def_id. expect_local ( ) ,
70+ ForceCaptureTraitArgs :: Yes ,
71+ ) ;
6772 }
68- None => { }
69- Some ( ty:: ImplTraitInTraitData :: Impl { .. } ) => { }
73+ None | Some ( ty:: ImplTraitInTraitData :: Impl { .. } ) => { }
7074 } ,
7175 DefKind :: OpaqueTy => {
72- return variance_of_opaque ( tcx, item_def_id) ;
76+ let force_capture_trait_args = if let hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id) =
77+ tcx. hir_node_by_def_id ( item_def_id) . expect_item ( ) . expect_opaque_ty ( ) . origin
78+ && let Some ( ty:: AssocItem {
79+ container : ty:: AssocItemContainer :: TraitContainer , ..
80+ } ) = tcx. opt_associated_item ( fn_def_id. to_def_id ( ) )
81+ {
82+ ForceCaptureTraitArgs :: Yes
83+ } else {
84+ ForceCaptureTraitArgs :: No
85+ } ;
86+
87+ return variance_of_opaque ( tcx, item_def_id, force_capture_trait_args) ;
7388 }
7489 _ => { }
7590 }
@@ -78,8 +93,18 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
7893 span_bug ! ( tcx. def_span( item_def_id) , "asked to compute variance for wrong kind of item" ) ;
7994}
8095
96+ #[ derive( Debug , Copy , Clone ) ]
97+ enum ForceCaptureTraitArgs {
98+ Yes ,
99+ No ,
100+ }
101+
81102#[ instrument( level = "trace" , skip( tcx) , ret) ]
82- fn variance_of_opaque ( tcx : TyCtxt < ' _ > , item_def_id : LocalDefId ) -> & [ ty:: Variance ] {
103+ fn variance_of_opaque (
104+ tcx : TyCtxt < ' _ > ,
105+ item_def_id : LocalDefId ,
106+ force_capture_trait_args : ForceCaptureTraitArgs ,
107+ ) -> & [ ty:: Variance ] {
83108 let generics = tcx. generics_of ( item_def_id) ;
84109
85110 // Opaque types may only use regions that are bound. So for
@@ -120,9 +145,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
120145 #[ instrument( level = "trace" , skip( self ) , ret) ]
121146 fn visit_ty ( & mut self , t : Ty < ' tcx > ) {
122147 match t. kind ( ) {
123- ty:: Alias ( _, ty:: AliasTy { def_id, args, .. } )
124- if matches ! ( self . tcx. def_kind( * def_id) , DefKind :: OpaqueTy ) =>
125- {
148+ ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, args, .. } ) => {
126149 self . visit_opaque ( * def_id, args) ;
127150 }
128151 _ => t. super_visit_with ( self ) ,
@@ -140,6 +163,15 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
140163 let mut generics = generics;
141164 while let Some ( def_id) = generics. parent {
142165 generics = tcx. generics_of ( def_id) ;
166+
167+ // Don't mark trait params generic if we're in an RPITIT.
168+ if matches ! ( force_capture_trait_args, ForceCaptureTraitArgs :: Yes )
169+ && generics. parent . is_none ( )
170+ {
171+ debug_assert_eq ! ( tcx. def_kind( def_id) , DefKind :: Trait ) ;
172+ break ;
173+ }
174+
143175 for param in & generics. own_params {
144176 match param. kind {
145177 ty:: GenericParamDefKind :: Lifetime => {
0 commit comments