@@ -19,15 +19,26 @@ struct OpaqueTypeCollector<'tcx> {
19
19
20
20
/// Avoid infinite recursion due to recursive declarations.
21
21
seen : FxHashSet < LocalDefId > ,
22
+
23
+ span : Option < Span > ,
22
24
}
23
25
24
26
impl < ' tcx > OpaqueTypeCollector < ' tcx > {
25
27
fn new ( tcx : TyCtxt < ' tcx > , item : LocalDefId ) -> Self {
26
- Self { tcx, opaques : Vec :: new ( ) , item, seen : Default :: default ( ) }
28
+ Self { tcx, opaques : Vec :: new ( ) , item, seen : Default :: default ( ) , span : None }
27
29
}
28
30
29
31
fn span ( & self ) -> Span {
30
- self . tcx . def_span ( self . item )
32
+ self . span . unwrap_or_else ( || {
33
+ self . tcx . def_ident_span ( self . item ) . unwrap_or_else ( || self . tcx . def_span ( self . item ) )
34
+ } )
35
+ }
36
+
37
+ fn visit_spanned ( & mut self , span : Span , value : impl TypeVisitable < TyCtxt < ' tcx > > ) {
38
+ let old = self . span ;
39
+ self . span = Some ( span) ;
40
+ value. visit_with ( self ) ;
41
+ self . span = old;
31
42
}
32
43
33
44
fn parent_trait_ref ( & self ) -> Option < ty:: TraitRef < ' tcx > > {
@@ -72,13 +83,13 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
72
83
self . opaques . push ( alias_ty. def_id . expect_local ( ) ) ;
73
84
74
85
// Collect opaque types nested within the associated type bounds of this opaque type.
75
- for ( pred, _span ) in self
86
+ for ( pred, span ) in self
76
87
. tcx
77
88
. explicit_item_bounds ( alias_ty. def_id )
78
89
. subst_iter_copied ( self . tcx , alias_ty. substs )
79
90
{
80
91
trace ! ( ?pred) ;
81
- pred . visit_with ( self ) ? ;
92
+ self . visit_spanned ( span , pred ) ;
82
93
}
83
94
84
95
ControlFlow :: Continue ( ( ) )
@@ -163,10 +174,23 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
163
174
let mut collector = OpaqueTypeCollector :: new ( tcx, item) ;
164
175
match kind {
165
176
DefKind :: AssocFn | DefKind :: Fn => {
166
- tcx. fn_sig ( item) . subst_identity ( ) . visit_with ( & mut collector) ;
177
+ let ty_sig = tcx. fn_sig ( item) . subst_identity ( ) ;
178
+ let hir_sig = tcx. hir ( ) . get_by_def_id ( item) . fn_sig ( ) . unwrap ( ) ;
179
+ collector. visit_spanned ( hir_sig. decl . output . span ( ) , ty_sig. output ( ) ) ;
180
+ for ( hir, ty) in hir_sig. decl . inputs . iter ( ) . zip ( ty_sig. inputs ( ) . iter ( ) ) {
181
+ collector. visit_spanned ( hir. span , ty. map_bound ( |x| * x) ) ;
182
+ }
167
183
}
168
184
DefKind :: AssocTy | DefKind :: AssocConst => {
169
- tcx. type_of ( item) . subst_identity ( ) . visit_with ( & mut collector) ;
185
+ let span = match tcx. hir ( ) . get_by_def_id ( item) {
186
+ rustc_hir:: Node :: ImplItem ( it) => match it. kind {
187
+ rustc_hir:: ImplItemKind :: Const ( ty, _) => ty. span ,
188
+ rustc_hir:: ImplItemKind :: Type ( ty) => ty. span ,
189
+ other => span_bug ! ( tcx. def_span( item) , "{other:#?}" ) ,
190
+ } ,
191
+ other => span_bug ! ( tcx. def_span( item) , "{other:#?}" ) ,
192
+ } ;
193
+ collector. visit_spanned ( span, tcx. type_of ( item) . subst_identity ( ) ) ;
170
194
}
171
195
_ => unreachable ! ( ) ,
172
196
}
0 commit comments