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,8 +64,29 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
6364 let crate_map = tcx. crate_variances ( ( ) ) ;
6465 return crate_map. variances . get ( & item_def_id. to_def_id ( ) ) . copied ( ) . unwrap_or ( & [ ] ) ;
6566 }
67+ DefKind :: AssocTy => match tcx. opt_rpitit_info ( item_def_id. to_def_id ( ) ) {
68+ Some ( ty:: ImplTraitInTraitData :: Trait { opaque_def_id, .. } ) => {
69+ return variance_of_opaque (
70+ tcx,
71+ opaque_def_id. expect_local ( ) ,
72+ ForceCaptureTraitArgs :: Yes ,
73+ ) ;
74+ }
75+ None | Some ( ty:: ImplTraitInTraitData :: Impl { .. } ) => { }
76+ } ,
6677 DefKind :: OpaqueTy => {
67- return variance_of_opaque ( tcx, item_def_id) ;
78+ let force_capture_trait_args = if let hir:: OpaqueTyOrigin :: FnReturn {
79+ parent : _,
80+ in_trait_or_impl : Some ( hir:: RpitContext :: Trait ) ,
81+ } =
82+ tcx. hir_node_by_def_id ( item_def_id) . expect_opaque_ty ( ) . origin
83+ {
84+ ForceCaptureTraitArgs :: Yes
85+ } else {
86+ ForceCaptureTraitArgs :: No
87+ } ;
88+
89+ return variance_of_opaque ( tcx, item_def_id, force_capture_trait_args) ;
6890 }
6991 _ => { }
7092 }
@@ -73,8 +95,18 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
7395 span_bug ! ( tcx. def_span( item_def_id) , "asked to compute variance for wrong kind of item" ) ;
7496}
7597
98+ #[ derive( Debug , Copy , Clone ) ]
99+ enum ForceCaptureTraitArgs {
100+ Yes ,
101+ No ,
102+ }
103+
76104#[ instrument( level = "trace" , skip( tcx) , ret) ]
77- fn variance_of_opaque ( tcx : TyCtxt < ' _ > , item_def_id : LocalDefId ) -> & [ ty:: Variance ] {
105+ fn variance_of_opaque (
106+ tcx : TyCtxt < ' _ > ,
107+ item_def_id : LocalDefId ,
108+ force_capture_trait_args : ForceCaptureTraitArgs ,
109+ ) -> & [ ty:: Variance ] {
78110 let generics = tcx. generics_of ( item_def_id) ;
79111
80112 // Opaque types may only use regions that are bound. So for
@@ -115,9 +147,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
115147 #[ instrument( level = "trace" , skip( self ) , ret) ]
116148 fn visit_ty ( & mut self , t : Ty < ' tcx > ) {
117149 match t. kind ( ) {
118- ty:: Alias ( _, ty:: AliasTy { def_id, args, .. } )
119- if matches ! ( self . tcx. def_kind( * def_id) , DefKind :: OpaqueTy ) =>
120- {
150+ ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, args, .. } ) => {
121151 self . visit_opaque ( * def_id, args) ;
122152 }
123153 _ => t. super_visit_with ( self ) ,
@@ -135,6 +165,15 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
135165 let mut generics = generics;
136166 while let Some ( def_id) = generics. parent {
137167 generics = tcx. generics_of ( def_id) ;
168+
169+ // Don't mark trait params generic if we're in an RPITIT.
170+ if matches ! ( force_capture_trait_args, ForceCaptureTraitArgs :: Yes )
171+ && generics. parent . is_none ( )
172+ {
173+ debug_assert_eq ! ( tcx. def_kind( def_id) , DefKind :: Trait ) ;
174+ break ;
175+ }
176+
138177 for param in & generics. own_params {
139178 match param. kind {
140179 ty:: GenericParamDefKind :: Lifetime => {
0 commit comments