1+ use crate :: clean:: types:: rustc_span;
12use crate :: clean:: { self , PrimitiveType } ;
23use crate :: html:: sources;
34
45use rustc_data_structures:: fx:: FxHashMap ;
56use rustc_hir:: def:: { DefKind , Res } ;
6- use rustc_hir:: def_id:: DefId ;
7+ use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
78use rustc_hir:: intravisit:: { self , Visitor } ;
89use rustc_hir:: { ExprKind , HirId , Mod , Node } ;
910use rustc_middle:: hir:: nested_filter;
11+ use rustc_hir:: { ExprKind , GenericParam , GenericParamKind , HirId , Item , ItemKind , Mod , Node } ;
1012use rustc_middle:: ty:: TyCtxt ;
1113use rustc_span:: Span ;
1214
@@ -24,6 +26,7 @@ pub(crate) enum LinkFromSrc {
2426 Local ( clean:: Span ) ,
2527 External ( DefId ) ,
2628 Primitive ( PrimitiveType ) ,
29+ Doc ( DefId ) ,
2730}
2831
2932/// This function will do at most two things:
@@ -91,6 +94,21 @@ impl<'tcx> SpanMapVisitor<'tcx> {
9194 self . matches . insert ( path_span. unwrap_or ( path. span ) , LinkFromSrc :: External ( def_id) ) ;
9295 }
9396 }
97+
98+ /// Used to generate links on items' definition to go to their documentation page.
99+ crate fn extract_info_from_hir_id ( & mut self , hir_id : HirId ) {
100+ if let Some ( def_id) = self . tcx . hir ( ) . opt_local_def_id ( hir_id) {
101+ if let Some ( span) = self . tcx . def_ident_span ( def_id) {
102+ let cspan = clean:: Span :: new ( span) ;
103+ let def_id = def_id. to_def_id ( ) ;
104+ // If the span isn't from the current crate, we ignore it.
105+ if cspan. is_dummy ( ) || cspan. cnum ( self . tcx . sess ) != LOCAL_CRATE {
106+ return ;
107+ }
108+ self . matches . insert ( span, LinkFromSrc :: Doc ( def_id) ) ;
109+ }
110+ }
111+ }
94112}
95113
96114impl < ' tcx > Visitor < ' tcx > for SpanMapVisitor < ' tcx > {
@@ -117,6 +135,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
117135 LinkFromSrc :: Local ( clean:: Span :: new ( m. spans . inner_span ) ) ,
118136 ) ;
119137 }
138+ } else {
139+ // If it's a "mod foo {}", we want to look to its documentation page.
140+ self . extract_info_from_hir_id ( id) ;
120141 }
121142 intravisit:: walk_mod ( self , m, id) ;
122143 }
@@ -151,4 +172,28 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
151172 self . handle_path ( path, None ) ;
152173 intravisit:: walk_use ( self , path, id) ;
153174 }
175+
176+ fn visit_item ( & mut self , item : & ' tcx Item < ' tcx > ) {
177+ match item. kind {
178+ ItemKind :: Static ( _, _, _)
179+ | ItemKind :: Const ( _, _)
180+ | ItemKind :: Fn ( _, _, _)
181+ | ItemKind :: Macro ( _)
182+ | ItemKind :: TyAlias ( _, _)
183+ | ItemKind :: Enum ( _, _)
184+ | ItemKind :: Struct ( _, _)
185+ | ItemKind :: Union ( _, _)
186+ | ItemKind :: Trait ( _, _, _, _, _)
187+ | ItemKind :: TraitAlias ( _, _) => self . extract_info_from_hir_id ( item. hir_id ( ) ) ,
188+ ItemKind :: Impl ( _)
189+ | ItemKind :: Use ( _, _)
190+ | ItemKind :: ExternCrate ( _)
191+ | ItemKind :: ForeignMod { .. }
192+ | ItemKind :: GlobalAsm ( _)
193+ | ItemKind :: OpaqueTy ( _)
194+ // We already have "visit_mod" above so no need to check it here.
195+ | ItemKind :: Mod ( _) => { }
196+ }
197+ intravisit:: walk_item ( self , item) ;
198+ }
154199}
0 commit comments