@@ -4,6 +4,7 @@ use std::sync::{Arc, OnceLock as OnceCell};
4
4
use std:: { fmt, iter} ;
5
5
6
6
use arrayvec:: ArrayVec ;
7
+ use itertools:: Either ;
7
8
use rustc_abi:: { ExternAbi , VariantIdx } ;
8
9
use rustc_attr_data_structures:: {
9
10
AttributeKind , ConstStability , Deprecation , Stability , StableSince ,
@@ -199,49 +200,49 @@ impl ExternalCrate {
199
200
. unwrap_or ( Unknown ) // Well, at least we tried.
200
201
}
201
202
202
- pub ( crate ) fn keywords ( & self , tcx : TyCtxt < ' _ > ) -> ThinVec < ( DefId , Symbol ) > {
203
+ fn mapped_root_modules < T > (
204
+ & self ,
205
+ tcx : TyCtxt < ' _ > ,
206
+ f : impl Fn ( DefId , TyCtxt < ' _ > ) -> Option < ( DefId , T ) > ,
207
+ ) -> impl Iterator < Item = ( DefId , T ) > {
203
208
let root = self . def_id ( ) ;
204
209
205
- let as_keyword = |res : Res < !> | {
206
- if let Res :: Def ( DefKind :: Mod , def_id) = res {
207
- let mut keyword = None ;
208
- let meta_items = tcx
209
- . get_attrs ( def_id, sym:: doc)
210
- . flat_map ( |attr| attr. meta_item_list ( ) . unwrap_or_default ( ) ) ;
211
- for meta in meta_items {
212
- if meta. has_name ( sym:: keyword)
213
- && let Some ( v) = meta. value_str ( )
214
- {
215
- keyword = Some ( v) ;
216
- break ;
217
- }
218
- }
219
- return keyword. map ( |p| ( def_id, p) ) ;
220
- }
221
- None
222
- } ;
223
210
if root. is_local ( ) {
224
- tcx. hir_root_module ( )
225
- . item_ids
226
- . iter ( )
227
- . filter_map ( |& id| {
228
- let item = tcx. hir_item ( id) ;
229
- match item. kind {
230
- hir:: ItemKind :: Mod ( ..) => {
231
- as_keyword ( Res :: Def ( DefKind :: Mod , id. owner_id . to_def_id ( ) ) )
232
- }
233
- _ => None ,
234
- }
235
- } )
236
- . collect ( )
211
+ Either :: Left (
212
+ tcx. hir_root_module ( )
213
+ . item_ids
214
+ . iter ( )
215
+ . filter ( move |& & id| matches ! ( tcx. hir_item( id) . kind, hir:: ItemKind :: Mod ( ..) ) )
216
+ . filter_map ( move |& id| f ( id. owner_id . into ( ) , tcx) ) ,
217
+ )
237
218
} else {
238
- tcx. module_children ( root) . iter ( ) . map ( |item| item. res ) . filter_map ( as_keyword) . collect ( )
219
+ Either :: Right (
220
+ tcx. module_children ( root)
221
+ . iter ( )
222
+ . filter_map ( |item| {
223
+ if let Res :: Def ( DefKind :: Mod , did) = item. res { Some ( did) } else { None }
224
+ } )
225
+ . filter_map ( move |did| as_t ( did, tcx) ) ,
226
+ )
239
227
}
240
228
}
241
229
242
- pub ( crate ) fn primitives ( & self , tcx : TyCtxt < ' _ > ) -> ThinVec < ( DefId , PrimitiveType ) > {
243
- let root = self . def_id ( ) ;
230
+ pub ( crate ) fn keywords ( & self , tcx : TyCtxt < ' _ > ) -> impl Iterator < Item = ( DefId , Symbol ) > {
231
+ fn as_keyword ( did : DefId , tcx : TyCtxt < ' _ > ) -> Option < ( DefId , Symbol ) > {
232
+ tcx. get_attrs ( did, sym:: doc)
233
+ . flat_map ( |attr| attr. meta_item_list ( ) . unwrap_or_default ( ) )
234
+ . filter ( |meta| meta. has_name ( sym:: keyword) )
235
+ . find_map ( |meta| meta. value_str ( ) )
236
+ . map ( |value| ( did, value) )
237
+ }
244
238
239
+ self . mapped_root_modules ( tcx, as_keyword)
240
+ }
241
+
242
+ pub ( crate ) fn primitives (
243
+ & self ,
244
+ tcx : TyCtxt < ' _ > ,
245
+ ) -> impl Iterator < Item = ( DefId , PrimitiveType ) > {
245
246
// Collect all inner modules which are tagged as implementations of
246
247
// primitives.
247
248
//
@@ -259,40 +260,21 @@ impl ExternalCrate {
259
260
// Also note that this does not attempt to deal with modules tagged
260
261
// duplicately for the same primitive. This is handled later on when
261
262
// rendering by delegating everything to a hash map.
262
- let as_primitive = |res : Res < !> | {
263
- let Res :: Def ( DefKind :: Mod , def_id) = res else { return None } ;
264
- tcx. get_attrs ( def_id, sym:: rustc_doc_primitive)
265
- . map ( |attr| {
266
- let attr_value = attr. value_str ( ) . expect ( "syntax should already be validated" ) ;
267
- let Some ( prim) = PrimitiveType :: from_symbol ( attr_value) else {
268
- span_bug ! (
269
- attr. span( ) ,
270
- "primitive `{attr_value}` is not a member of `PrimitiveType`"
271
- ) ;
272
- } ;
273
-
274
- ( def_id, prim)
275
- } )
276
- . next ( )
277
- } ;
263
+ fn as_primitive ( def_id : DefId , tcx : TyCtxt < ' _ > ) -> Option < ( DefId , PrimitiveType ) > {
264
+ tcx. get_attrs ( def_id, sym:: rustc_doc_primitive) . next ( ) . map ( |attr| {
265
+ let attr_value = attr. value_str ( ) . expect ( "syntax should already be validated" ) ;
266
+ let Some ( prim) = PrimitiveType :: from_symbol ( attr_value) else {
267
+ span_bug ! (
268
+ attr. span( ) ,
269
+ "primitive `{attr_value}` is not a member of `PrimitiveType`"
270
+ ) ;
271
+ } ;
278
272
279
- if root. is_local ( ) {
280
- tcx. hir_root_module ( )
281
- . item_ids
282
- . iter ( )
283
- . filter_map ( |& id| {
284
- let item = tcx. hir_item ( id) ;
285
- match item. kind {
286
- hir:: ItemKind :: Mod ( ..) => {
287
- as_primitive ( Res :: Def ( DefKind :: Mod , id. owner_id . to_def_id ( ) ) )
288
- }
289
- _ => None ,
290
- }
291
- } )
292
- . collect ( )
293
- } else {
294
- tcx. module_children ( root) . iter ( ) . map ( |item| item. res ) . filter_map ( as_primitive) . collect ( )
273
+ ( def_id, prim)
274
+ } )
295
275
}
276
+
277
+ self . mapped_root_modules ( tcx, as_primitive)
296
278
}
297
279
}
298
280
@@ -1966,7 +1948,7 @@ impl PrimitiveType {
1966
1948
let e = ExternalCrate { crate_num } ;
1967
1949
let crate_name = e. name ( tcx) ;
1968
1950
debug ! ( ?crate_num, ?crate_name) ;
1969
- for & ( def_id, prim) in & e. primitives ( tcx) {
1951
+ for ( def_id, prim) in e. primitives ( tcx) {
1970
1952
// HACK: try to link to std instead where possible
1971
1953
if crate_name == sym:: core && primitive_locations. contains_key ( & prim) {
1972
1954
continue ;
0 commit comments