@@ -4,6 +4,7 @@ use std::sync::{Arc, OnceLock as OnceCell};
44use std:: { fmt, iter} ;
55
66use arrayvec:: ArrayVec ;
7+ use itertools:: Either ;
78use rustc_abi:: { ExternAbi , VariantIdx } ;
89use rustc_attr_data_structures:: {
910 AttributeKind , ConstStability , Deprecation , Stability , StableSince ,
@@ -199,49 +200,49 @@ impl ExternalCrate {
199200 . unwrap_or ( Unknown ) // Well, at least we tried.
200201 }
201202
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 ) > {
203208 let root = self . def_id ( ) ;
204209
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- } ;
223210 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+ )
237218 } 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+ )
239227 }
240228 }
241229
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+ }
244238
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 ) > {
245246 // Collect all inner modules which are tagged as implementations of
246247 // primitives.
247248 //
@@ -259,40 +260,21 @@ impl ExternalCrate {
259260 // Also note that this does not attempt to deal with modules tagged
260261 // duplicately for the same primitive. This is handled later on when
261262 // 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+ } ;
278272
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+ } )
295275 }
276+
277+ self . mapped_root_modules ( tcx, as_primitive)
296278 }
297279}
298280
@@ -1966,7 +1948,7 @@ impl PrimitiveType {
19661948 let e = ExternalCrate { crate_num } ;
19671949 let crate_name = e. name ( tcx) ;
19681950 debug ! ( ?crate_num, ?crate_name) ;
1969- for & ( def_id, prim) in & e. primitives ( tcx) {
1951+ for ( def_id, prim) in e. primitives ( tcx) {
19701952 // HACK: try to link to std instead where possible
19711953 if crate_name == sym:: core && primitive_locations. contains_key ( & prim) {
19721954 continue ;
0 commit comments