@@ -28,12 +28,10 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
2828use rustc_span:: { self , Pos } ;
2929use rustc_typeck:: hir_ty_to_ty;
3030
31- use std:: cell:: RefCell ;
3231use std:: collections:: hash_map:: Entry ;
3332use std:: default:: Default ;
3433use std:: hash:: Hash ;
3534use std:: rc:: Rc ;
36- use std:: sync:: Arc ;
3735use std:: { mem, vec} ;
3836
3937use crate :: core:: { self , DocContext , ImplTraitParam } ;
@@ -50,13 +48,6 @@ pub use self::types::Type::*;
5048pub use self :: types:: Visibility :: { Inherited , Public } ;
5149pub use self :: types:: * ;
5250
53- thread_local ! ( static PRIMITIVES : RefCell <Arc <FxHashMap <PrimitiveType , DefId >>> =
54- Default :: default ( ) ) ;
55-
56- crate fn primitives ( ) -> Arc < FxHashMap < PrimitiveType , DefId > > {
57- PRIMITIVES . with ( |c| c. borrow ( ) . clone ( ) )
58- }
59-
6051const FN_OUTPUT_NAME : & str = "Output" ;
6152
6253pub trait Clean < T > {
@@ -93,48 +84,49 @@ impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
9384 }
9485}
9586
87+ /// Collect all inner modules which are tagged as implementations of
88+ /// primitives.
89+ ///
90+ /// Note that this loop only searches the top-level items of the crate,
91+ /// and this is intentional. If we were to search the entire crate for an
92+ /// item tagged with `#[doc(primitive)]` then we would also have to
93+ /// search the entirety of external modules for items tagged
94+ /// `#[doc(primitive)]`, which is a pretty inefficient process (decoding
95+ /// all that metadata unconditionally).
96+ ///
97+ /// In order to keep the metadata load under control, the
98+ /// `#[doc(primitive)]` feature is explicitly designed to only allow the
99+ /// primitive tags to show up as the top level items in a crate.
100+ ///
101+ /// Also note that this does not attempt to deal with modules tagged
102+ /// duplicately for the same primitive. This is handled later on when
103+ /// rendering by delegating everything to a hash map.
104+ crate fn as_primitive ( cx : & DocContext < ' _ > , res : Res ) -> Option < ( DefId , PrimitiveType , Attributes ) > {
105+ if let Res :: Def ( DefKind :: Mod , def_id) = res {
106+ let attrs = cx. tcx . get_attrs ( def_id) . clean ( cx) ;
107+ let mut prim = None ;
108+ for attr in attrs. lists ( sym:: doc) {
109+ if let Some ( v) = attr. value_str ( ) {
110+ if attr. check_name ( sym:: primitive) {
111+ prim = PrimitiveType :: from_symbol ( v) ;
112+ if prim. is_some ( ) {
113+ break ;
114+ }
115+ // FIXME: should warn on unknown primitives?
116+ }
117+ }
118+ }
119+ return prim. map ( |p| ( def_id, p, attrs) ) ;
120+ }
121+ None
122+ }
123+
96124impl Clean < ExternalCrate > for CrateNum {
97125 fn clean ( & self , cx : & DocContext < ' _ > ) -> ExternalCrate {
98126 let root = DefId { krate : * self , index : CRATE_DEF_INDEX } ;
99127 let krate_span = cx. tcx . def_span ( root) ;
100128 let krate_src = cx. sess ( ) . source_map ( ) . span_to_filename ( krate_span) ;
101129
102- // Collect all inner modules which are tagged as implementations of
103- // primitives.
104- //
105- // Note that this loop only searches the top-level items of the crate,
106- // and this is intentional. If we were to search the entire crate for an
107- // item tagged with `#[doc(primitive)]` then we would also have to
108- // search the entirety of external modules for items tagged
109- // `#[doc(primitive)]`, which is a pretty inefficient process (decoding
110- // all that metadata unconditionally).
111- //
112- // In order to keep the metadata load under control, the
113- // `#[doc(primitive)]` feature is explicitly designed to only allow the
114- // primitive tags to show up as the top level items in a crate.
115- //
116- // Also note that this does not attempt to deal with modules tagged
117- // duplicately for the same primitive. This is handled later on when
118- // rendering by delegating everything to a hash map.
119- let as_primitive = |res : Res | {
120- if let Res :: Def ( DefKind :: Mod , def_id) = res {
121- let attrs = cx. tcx . get_attrs ( def_id) . clean ( cx) ;
122- let mut prim = None ;
123- for attr in attrs. lists ( sym:: doc) {
124- if let Some ( v) = attr. value_str ( ) {
125- if attr. check_name ( sym:: primitive) {
126- prim = PrimitiveType :: from_symbol ( v) ;
127- if prim. is_some ( ) {
128- break ;
129- }
130- // FIXME: should warn on unknown primitives?
131- }
132- }
133- }
134- return prim. map ( |p| ( def_id, p, attrs) ) ;
135- }
136- None
137- } ;
138130 let primitives: Vec < ( DefId , PrimitiveType , Attributes ) > = if root. is_local ( ) {
139131 cx. tcx
140132 . hir ( )
@@ -146,14 +138,14 @@ impl Clean<ExternalCrate> for CrateNum {
146138 . filter_map ( |& id| {
147139 let item = cx. tcx . hir ( ) . expect_item ( id. id ) ;
148140 match item. kind {
149- hir:: ItemKind :: Mod ( _) => as_primitive ( Res :: Def (
150- DefKind :: Mod ,
151- cx. tcx . hir ( ) . local_def_id ( id. id ) . to_def_id ( ) ,
152- ) ) ,
141+ hir:: ItemKind :: Mod ( _) => as_primitive (
142+ cx ,
143+ Res :: Def ( DefKind :: Mod , cx. tcx . hir ( ) . local_def_id ( id. id ) . to_def_id ( ) ) ,
144+ ) ,
153145 hir:: ItemKind :: Use ( ref path, hir:: UseKind :: Single )
154146 if item. vis . node . is_pub ( ) =>
155147 {
156- as_primitive ( path. res ) . map ( |( _, prim, attrs) | {
148+ as_primitive ( cx , path. res ) . map ( |( _, prim, attrs) | {
157149 // Pretend the primitive is local.
158150 ( cx. tcx . hir ( ) . local_def_id ( id. id ) . to_def_id ( ) , prim, attrs)
159151 } )
@@ -167,16 +159,9 @@ impl Clean<ExternalCrate> for CrateNum {
167159 . item_children ( root)
168160 . iter ( )
169161 . map ( |item| item. res )
170- . filter_map ( as_primitive)
162+ . filter_map ( |res| as_primitive ( cx , res ) )
171163 . collect ( )
172164 } ;
173- PRIMITIVES . with ( |v| {
174- let mut tmp = v. borrow_mut ( ) ;
175- let stored_primitives = Arc :: make_mut ( & mut * tmp) ;
176- for ( prim, did) in primitives. iter ( ) . map ( |x| ( x. 1 , x. 0 ) ) {
177- stored_primitives. insert ( prim, did) ;
178- }
179- } ) ;
180165
181166 let as_keyword = |res : Res | {
182167 if let Res :: Def ( DefKind :: Mod , def_id) = res {
0 commit comments