5
5
6
6
use itertools:: Itertools ;
7
7
use rustc_arena:: DroplessArena ;
8
+ use rustc_hir as hir;
8
9
use rustc_hir:: def:: DefKind ;
9
10
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
10
11
use rustc_middle:: query:: Providers ;
@@ -63,8 +64,29 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
63
64
let crate_map = tcx. crate_variances ( ( ) ) ;
64
65
return crate_map. variances . get ( & item_def_id. to_def_id ( ) ) . copied ( ) . unwrap_or ( & [ ] ) ;
65
66
}
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
+ } ,
66
77
DefKind :: OpaqueTy => {
67
- return variance_of_opaque ( tcx, item_def_id) ;
78
+ let force_capture_trait_args = if let hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id) =
79
+ tcx. hir_node_by_def_id ( item_def_id) . expect_item ( ) . expect_opaque_ty ( ) . origin
80
+ && let Some ( ty:: AssocItem {
81
+ container : ty:: AssocItemContainer :: TraitContainer , ..
82
+ } ) = tcx. opt_associated_item ( fn_def_id. to_def_id ( ) )
83
+ {
84
+ ForceCaptureTraitArgs :: Yes
85
+ } else {
86
+ ForceCaptureTraitArgs :: No
87
+ } ;
88
+
89
+ return variance_of_opaque ( tcx, item_def_id, force_capture_trait_args) ;
68
90
}
69
91
_ => { }
70
92
}
@@ -73,8 +95,18 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
73
95
span_bug ! ( tcx. def_span( item_def_id) , "asked to compute variance for wrong kind of item" ) ;
74
96
}
75
97
98
+ #[ derive( Debug , Copy , Clone ) ]
99
+ enum ForceCaptureTraitArgs {
100
+ Yes ,
101
+ No ,
102
+ }
103
+
76
104
#[ 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 ] {
78
110
let generics = tcx. generics_of ( item_def_id) ;
79
111
80
112
// 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
115
147
#[ instrument( level = "trace" , skip( self ) , ret) ]
116
148
fn visit_ty ( & mut self , t : Ty < ' tcx > ) {
117
149
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, .. } ) => {
121
151
self . visit_opaque ( * def_id, args) ;
122
152
}
123
153
_ => t. super_visit_with ( self ) ,
@@ -135,6 +165,15 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
135
165
let mut generics = generics;
136
166
while let Some ( def_id) = generics. parent {
137
167
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
+
138
177
for param in & generics. own_params {
139
178
match param. kind {
140
179
ty:: GenericParamDefKind :: Lifetime => {
0 commit comments