@@ -236,31 +236,12 @@ impl ExternalCrate {
236236 . unwrap_or ( Unknown ) // Well, at least we tried.
237237 }
238238
239- fn mapped_root_anon_consts < T > (
239+ fn fake_doc_items < T > (
240240 & self ,
241241 tcx : TyCtxt < ' _ > ,
242242 f : impl Fn ( DefId , TyCtxt < ' _ > ) -> Option < ( DefId , T ) > ,
243243 ) -> impl Iterator < Item = ( DefId , T ) > {
244- let root = self . def_id ( ) ;
245-
246- if root. is_local ( ) {
247- Either :: Left (
248- tcx. hir_root_module ( )
249- . item_ids
250- . iter ( )
251- . filter ( move |& & id| matches ! ( tcx. hir_item( id) . kind, hir:: ItemKind :: Const ( ..) ) )
252- . filter_map ( move |& id| f ( id. owner_id . into ( ) , tcx) ) ,
253- )
254- } else {
255- Either :: Right (
256- tcx. module_children ( root)
257- . iter ( )
258- . filter_map ( |item| {
259- if let Res :: Def ( DefKind :: Const , did) = item. res { Some ( did) } else { None }
260- } )
261- . filter_map ( move |did| f ( did, tcx) ) ,
262- )
263- }
244+ tcx. fake_doc_items ( self . crate_num ) . into_iter ( ) . filter_map ( move |did| f ( * did, tcx) )
264245 }
265246
266247 pub ( crate ) fn keywords ( & self , tcx : TyCtxt < ' _ > ) -> impl Iterator < Item = ( DefId , Symbol ) > {
@@ -281,7 +262,7 @@ impl ExternalCrate {
281262 let as_target = move |did : DefId , tcx : TyCtxt < ' _ > | -> Option < ( DefId , Symbol ) > {
282263 find_attr ! ( tcx, did, Doc ( d) => callback( d) ) . flatten ( ) . map ( |value| ( did, value) )
283264 } ;
284- self . mapped_root_anon_consts ( tcx, as_target)
265+ self . fake_doc_items ( tcx, as_target)
285266 }
286267
287268 pub ( crate ) fn primitives (
@@ -316,7 +297,7 @@ impl ExternalCrate {
316297 Some ( ( def_id, prim) )
317298 }
318299
319- self . mapped_root_anon_consts ( tcx, as_primitive)
300+ self . fake_doc_items ( tcx, as_primitive)
320301 }
321302}
322303
@@ -1891,27 +1872,35 @@ impl PrimitiveType {
18911872 /// `rustc_doc_primitive`, then it's entirely random whether `std` or the other crate is picked.
18921873 /// (no_std crates are usually fine unless multiple dependencies define a primitive.)
18931874 pub ( crate ) fn primitive_locations ( tcx : TyCtxt < ' _ > ) -> & FxIndexMap < PrimitiveType , DefId > {
1875+ fn as_primitive ( def_id : DefId , tcx : TyCtxt < ' _ > ) -> Option < PrimitiveType > {
1876+ let ( attr_span, prim_sym) = find_attr ! (
1877+ tcx, def_id,
1878+ RustcDocPrimitive ( span, prim) => ( * span, * prim)
1879+ ) ?;
1880+ let Some ( prim) = PrimitiveType :: from_symbol ( prim_sym) else {
1881+ span_bug ! ( attr_span, "primitive `{prim_sym}` is not a member of `PrimitiveType`" ) ;
1882+ } ;
1883+ Some ( prim)
1884+ }
1885+
18941886 static PRIMITIVE_LOCATIONS : OnceCell < FxIndexMap < PrimitiveType , DefId > > = OnceCell :: new ( ) ;
18951887 PRIMITIVE_LOCATIONS . get_or_init ( || {
18961888 let mut primitive_locations = FxIndexMap :: default ( ) ;
18971889 // NOTE: technically this misses crates that are only passed with `--extern` and not loaded when checking the crate.
18981890 // This is a degenerate case that I don't plan to support.
1899- for & crate_num in tcx . crates ( ( ) ) {
1900- let e = ExternalCrate { crate_num } ;
1901- let crate_name = e . name ( tcx ) ;
1902- debug ! ( ?crate_num , ?crate_name ) ;
1903- for ( def_id , prim ) in e . primitives ( tcx ) {
1904- // HACK: try to link to std instead where possible
1905- if crate_name == sym:: core && primitive_locations . contains_key ( & prim ) {
1906- continue ;
1907- }
1891+
1892+ let mut ids = tcx . all_fake_doc_items ( ( ) ) . clone ( ) ;
1893+
1894+ // HACK: Primitives are unhygienically duplicated by `include!`.
1895+ // Sort them with core first, so that if std is present in the crate graph,
1896+ // core's items are overridden and we link to std preferentially.
1897+ ids . iter_mut ( ) . partition_in_place ( |id| tcx . crate_name ( id . krate ) == sym:: core) ;
1898+ for def_id in ids {
1899+ if let Some ( prim ) = as_primitive ( def_id , tcx ) {
19081900 primitive_locations. insert ( prim, def_id) ;
19091901 }
19101902 }
1911- let local_primitives = ExternalCrate { crate_num : LOCAL_CRATE } . primitives ( tcx) ;
1912- for ( def_id, prim) in local_primitives {
1913- primitive_locations. insert ( prim, def_id) ;
1914- }
1903+
19151904 primitive_locations
19161905 } )
19171906 }
0 commit comments