1
+ use crate :: clean:: types:: rustc_span;
1
2
use crate :: clean:: { self , PrimitiveType } ;
2
3
use crate :: html:: sources;
3
4
4
5
use rustc_data_structures:: fx:: FxHashMap ;
5
6
use rustc_hir:: def:: { DefKind , Res } ;
6
- use rustc_hir:: def_id:: DefId ;
7
+ use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
7
8
use rustc_hir:: intravisit:: { self , Visitor } ;
8
9
use rustc_hir:: { ExprKind , HirId , Mod , Node } ;
9
10
use rustc_middle:: hir:: nested_filter;
11
+ use rustc_hir:: { ExprKind , GenericParam , GenericParamKind , HirId , Item , ItemKind , Mod , Node } ;
10
12
use rustc_middle:: ty:: TyCtxt ;
11
13
use rustc_span:: Span ;
12
14
@@ -24,6 +26,7 @@ pub(crate) enum LinkFromSrc {
24
26
Local ( clean:: Span ) ,
25
27
External ( DefId ) ,
26
28
Primitive ( PrimitiveType ) ,
29
+ Doc ( DefId ) ,
27
30
}
28
31
29
32
/// This function will do at most two things:
@@ -91,6 +94,21 @@ impl<'tcx> SpanMapVisitor<'tcx> {
91
94
self . matches . insert ( path_span. unwrap_or ( path. span ) , LinkFromSrc :: External ( def_id) ) ;
92
95
}
93
96
}
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
+ }
94
112
}
95
113
96
114
impl < ' tcx > Visitor < ' tcx > for SpanMapVisitor < ' tcx > {
@@ -117,6 +135,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
117
135
LinkFromSrc :: Local ( clean:: Span :: new ( m. spans . inner_span ) ) ,
118
136
) ;
119
137
}
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) ;
120
141
}
121
142
intravisit:: walk_mod ( self , m, id) ;
122
143
}
@@ -151,4 +172,28 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
151
172
self . handle_path ( path, None ) ;
152
173
intravisit:: walk_use ( self , path, id) ;
153
174
}
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
+ }
154
199
}
0 commit comments