@@ -19,15 +19,26 @@ struct OpaqueTypeCollector<'tcx> {
1919
2020 /// Avoid infinite recursion due to recursive declarations.
2121 seen : FxHashSet < LocalDefId > ,
22+
23+ span : Option < Span > ,
2224}
2325
2426impl < ' tcx > OpaqueTypeCollector < ' tcx > {
2527 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 }
2729 }
2830
2931 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;
3142 }
3243
3344 fn parent_trait_ref ( & self ) -> Option < ty:: TraitRef < ' tcx > > {
@@ -72,13 +83,13 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
7283 self . opaques . push ( alias_ty. def_id . expect_local ( ) ) ;
7384
7485 // 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
7687 . tcx
7788 . explicit_item_bounds ( alias_ty. def_id )
7889 . subst_iter_copied ( self . tcx , alias_ty. substs )
7990 {
8091 trace ! ( ?pred) ;
81- pred . visit_with ( self ) ? ;
92+ self . visit_spanned ( span , pred ) ;
8293 }
8394
8495 ControlFlow :: Continue ( ( ) )
@@ -163,10 +174,23 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
163174 let mut collector = OpaqueTypeCollector :: new ( tcx, item) ;
164175 match kind {
165176 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+ }
167183 }
168184 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 ( ) ) ;
170194 }
171195 _ => unreachable ! ( ) ,
172196 }
0 commit comments