@@ -27,11 +27,10 @@ use syntax::ptr::P;
2727use syntax:: symbol:: keywords;
2828use syntax_pos:: { self , DUMMY_SP , Pos } ;
2929
30- use rustc_trans:: back:: link;
3130use rustc:: middle:: privacy:: AccessLevels ;
3231use rustc:: middle:: resolve_lifetime:: DefRegion :: * ;
3332use rustc:: hir:: def:: { Def , CtorKind } ;
34- use rustc:: hir:: def_id:: { self , DefId , DefIndex , CRATE_DEF_INDEX } ;
33+ use rustc:: hir:: def_id:: { CrateNum , DefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
3534use rustc:: hir:: print as pprust;
3635use rustc:: ty:: subst:: Substs ;
3736use rustc:: ty:: { self , AdtKind } ;
@@ -45,7 +44,6 @@ use std::rc::Rc;
4544use std:: slice;
4645use std:: sync:: Arc ;
4746use std:: u32;
48- use std:: env:: current_dir;
4947use std:: mem;
5048
5149use core:: DocContext ;
@@ -110,19 +108,16 @@ pub struct Crate {
110108 pub name : String ,
111109 pub src : PathBuf ,
112110 pub module : Option < Item > ,
113- pub externs : Vec < ( def_id :: CrateNum , ExternalCrate ) > ,
114- pub primitives : Vec < PrimitiveType > ,
111+ pub externs : Vec < ( CrateNum , ExternalCrate ) > ,
112+ pub primitives : Vec < ( DefId , PrimitiveType , Attributes ) > ,
115113 pub access_levels : Arc < AccessLevels < DefId > > ,
116114 // These are later on moved into `CACHEKEY`, leaving the map empty.
117115 // Only here so that they can be filtered through the rustdoc passes.
118116 pub external_traits : FxHashMap < DefId , Trait > ,
119117}
120118
121- struct CrateNum ( def_id:: CrateNum ) ;
122-
123119impl < ' a , ' tcx > Clean < Crate > for visit_ast:: RustdocVisitor < ' a , ' tcx > {
124120 fn clean ( & self , cx : & DocContext ) -> Crate {
125- use rustc:: session:: config:: Input ;
126121 use :: visit_lib:: LibEmbargoVisitor ;
127122
128123 {
@@ -133,83 +128,41 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
133128
134129 let mut externs = Vec :: new ( ) ;
135130 for cnum in cx. sess ( ) . cstore . crates ( ) {
136- externs. push ( ( cnum, CrateNum ( cnum) . clean ( cx) ) ) ;
131+ externs. push ( ( cnum, cnum. clean ( cx) ) ) ;
137132 // Analyze doc-reachability for extern items
138133 LibEmbargoVisitor :: new ( cx) . visit_lib ( cnum) ;
139134 }
140135 externs. sort_by ( |& ( a, _) , & ( b, _) | a. cmp ( & b) ) ;
141136
142- // Figure out the name of this crate
143- let input = & cx. input ;
144- let name = link:: find_crate_name ( None , & self . attrs , input) ;
145-
146137 // Clean the crate, translating the entire libsyntax AST to one that is
147138 // understood by rustdoc.
148139 let mut module = self . module . clean ( cx) ;
149140
150- // Collect all inner modules which are tagged as implementations of
151- // primitives.
152- //
153- // Note that this loop only searches the top-level items of the crate,
154- // and this is intentional. If we were to search the entire crate for an
155- // item tagged with `#[doc(primitive)]` then we would also have to
156- // search the entirety of external modules for items tagged
157- // `#[doc(primitive)]`, which is a pretty inefficient process (decoding
158- // all that metadata unconditionally).
159- //
160- // In order to keep the metadata load under control, the
161- // `#[doc(primitive)]` feature is explicitly designed to only allow the
162- // primitive tags to show up as the top level items in a crate.
163- //
164- // Also note that this does not attempt to deal with modules tagged
165- // duplicately for the same primitive. This is handled later on when
166- // rendering by delegating everything to a hash map.
167- let mut primitives = Vec :: new ( ) ;
141+ let ExternalCrate { name, src, primitives, .. } = LOCAL_CRATE . clean ( cx) ;
168142 {
169143 let m = match module. inner {
170144 ModuleItem ( ref mut m) => m,
171145 _ => unreachable ! ( ) ,
172146 } ;
173- let mut tmp = Vec :: new ( ) ;
174- for child in & mut m. items {
175- if !child. is_mod ( ) {
176- continue ;
177- }
178- let prim = match PrimitiveType :: find ( & child. attrs ) {
179- Some ( prim) => prim,
180- None => continue ,
181- } ;
182- primitives. push ( prim) ;
183- tmp. push ( Item {
147+ m. items . extend ( primitives. iter ( ) . map ( |& ( def_id, prim, ref attrs) | {
148+ Item {
184149 source : Span :: empty ( ) ,
185150 name : Some ( prim. to_url_str ( ) . to_string ( ) ) ,
186- attrs : child . attrs . clone ( ) ,
151+ attrs : attrs. clone ( ) ,
187152 visibility : Some ( Public ) ,
188153 stability : None ,
189154 deprecation : None ,
190- def_id : DefId :: local ( prim . to_def_index ( ) ) ,
155+ def_id : def_id ,
191156 inner : PrimitiveItem ( prim) ,
192- } ) ;
193- }
194- m. items . extend ( tmp) ;
195- }
196-
197- let src = match cx. input {
198- Input :: File ( ref path) => {
199- if path. is_absolute ( ) {
200- path. clone ( )
201- } else {
202- current_dir ( ) . unwrap ( ) . join ( path)
203157 }
204- } ,
205- Input :: Str { ref name, .. } => PathBuf :: from ( name. clone ( ) ) ,
206- } ;
158+ } ) ) ;
159+ }
207160
208161 let mut access_levels = cx. access_levels . borrow_mut ( ) ;
209162 let mut external_traits = cx. external_traits . borrow_mut ( ) ;
210163
211164 Crate {
212- name : name. to_string ( ) ,
165+ name : name,
213166 src : src,
214167 module : Some ( module) ,
215168 externs : externs,
@@ -223,21 +176,78 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
223176#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
224177pub struct ExternalCrate {
225178 pub name : String ,
179+ pub src : PathBuf ,
226180 pub attrs : Attributes ,
227- pub primitives : Vec < PrimitiveType > ,
181+ pub primitives : Vec < ( DefId , PrimitiveType , Attributes ) > ,
228182}
229183
230184impl Clean < ExternalCrate > for CrateNum {
231185 fn clean ( & self , cx : & DocContext ) -> ExternalCrate {
232- let mut primitives = Vec :: new ( ) ;
233- let root = DefId { krate : self . 0 , index : CRATE_DEF_INDEX } ;
234- for item in cx. tcx . sess . cstore . item_children ( root) {
235- let attrs = inline:: load_attrs ( cx, item. def . def_id ( ) ) ;
236- PrimitiveType :: find ( & attrs) . map ( |prim| primitives. push ( prim) ) ;
237- }
186+ let root = DefId { krate : * self , index : CRATE_DEF_INDEX } ;
187+ let krate_span = cx. tcx . def_span ( root) ;
188+ let krate_src = cx. sess ( ) . codemap ( ) . span_to_filename ( krate_span) ;
189+
190+ // Collect all inner modules which are tagged as implementations of
191+ // primitives.
192+ //
193+ // Note that this loop only searches the top-level items of the crate,
194+ // and this is intentional. If we were to search the entire crate for an
195+ // item tagged with `#[doc(primitive)]` then we would also have to
196+ // search the entirety of external modules for items tagged
197+ // `#[doc(primitive)]`, which is a pretty inefficient process (decoding
198+ // all that metadata unconditionally).
199+ //
200+ // In order to keep the metadata load under control, the
201+ // `#[doc(primitive)]` feature is explicitly designed to only allow the
202+ // primitive tags to show up as the top level items in a crate.
203+ //
204+ // Also note that this does not attempt to deal with modules tagged
205+ // duplicately for the same primitive. This is handled later on when
206+ // rendering by delegating everything to a hash map.
207+ let as_primitive = |def : Def | {
208+ if let Def :: Mod ( def_id) = def {
209+ let attrs = cx. tcx . get_attrs ( def_id) . clean ( cx) ;
210+ let mut prim = None ;
211+ for attr in attrs. lists ( "doc" ) {
212+ if let Some ( v) = attr. value_str ( ) {
213+ if attr. check_name ( "primitive" ) {
214+ prim = PrimitiveType :: from_str ( & v. as_str ( ) ) ;
215+ if prim. is_some ( ) {
216+ break ;
217+ }
218+ }
219+ }
220+ }
221+ return prim. map ( |p| ( def_id, p, attrs) ) ;
222+ }
223+ None
224+ } ;
225+ let primitives = if root. is_local ( ) {
226+ cx. tcx . map . krate ( ) . module . item_ids . iter ( ) . filter_map ( |& id| {
227+ let item = cx. tcx . map . expect_item ( id. id ) ;
228+ match item. node {
229+ hir:: ItemMod ( _) => {
230+ as_primitive ( Def :: Mod ( cx. tcx . map . local_def_id ( id. id ) ) )
231+ }
232+ hir:: ItemUse ( ref path, hir:: UseKind :: Single )
233+ if item. vis == hir:: Visibility :: Public => {
234+ as_primitive ( path. def ) . map ( |( _, prim, attrs) | {
235+ // Pretend the primitive is local.
236+ ( cx. tcx . map . local_def_id ( id. id ) , prim, attrs)
237+ } )
238+ }
239+ _ => None
240+ }
241+ } ) . collect ( )
242+ } else {
243+ cx. tcx . sess . cstore . item_children ( root) . iter ( ) . map ( |item| item. def )
244+ . filter_map ( as_primitive) . collect ( )
245+ } ;
246+
238247 ExternalCrate {
239- name : cx. sess ( ) . cstore . crate_name ( self . 0 ) . to_string ( ) ,
240- attrs : cx. sess ( ) . cstore . item_attrs ( root) . clean ( cx) ,
248+ name : cx. tcx . crate_name ( * self ) . to_string ( ) ,
249+ src : PathBuf :: from ( krate_src) ,
250+ attrs : cx. tcx . get_attrs ( root) . clean ( cx) ,
241251 primitives : primitives,
242252 }
243253 }
@@ -1460,7 +1470,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
14601470 deprecation : get_deprecation ( cx, self . def_id ) ,
14611471 def_id : self . def_id ,
14621472 attrs : inline:: load_attrs ( cx, self . def_id ) ,
1463- source : Span :: empty ( ) ,
1473+ source : cx . tcx . def_span ( self . def_id ) . clean ( cx ) ,
14641474 inner : inner,
14651475 }
14661476 }
@@ -1618,19 +1628,6 @@ impl PrimitiveType {
16181628 }
16191629 }
16201630
1621- fn find ( attrs : & Attributes ) -> Option < PrimitiveType > {
1622- for attr in attrs. lists ( "doc" ) {
1623- if let Some ( v) = attr. value_str ( ) {
1624- if attr. check_name ( "primitive" ) {
1625- if let ret@Some ( ..) = PrimitiveType :: from_str ( & v. as_str ( ) ) {
1626- return ret;
1627- }
1628- }
1629- }
1630- }
1631- None
1632- }
1633-
16341631 pub fn as_str ( & self ) -> & ' static str {
16351632 match * self {
16361633 PrimitiveType :: Isize => "isize" ,
@@ -1658,14 +1655,6 @@ impl PrimitiveType {
16581655 pub fn to_url_str ( & self ) -> & ' static str {
16591656 self . as_str ( )
16601657 }
1661-
1662- /// Creates a rustdoc-specific node id for primitive types.
1663- ///
1664- /// These node ids are generally never used by the AST itself.
1665- pub fn to_def_index ( & self ) -> DefIndex {
1666- let x = u32:: MAX - 1 - ( * self as u32 ) ;
1667- DefIndex :: new ( x as usize )
1668- }
16691658}
16701659
16711660impl From < ast:: IntTy > for PrimitiveType {
@@ -1948,7 +1937,7 @@ impl<'tcx> Clean<Item> for ty::FieldDefData<'tcx, 'static> {
19481937 Item {
19491938 name : Some ( self . name ) . clean ( cx) ,
19501939 attrs : cx. tcx . get_attrs ( self . did ) . clean ( cx) ,
1951- source : Span :: empty ( ) ,
1940+ source : cx . tcx . def_span ( self . did ) . clean ( cx ) ,
19521941 visibility : self . vis . clean ( cx) ,
19531942 stability : get_stability ( cx, self . did ) ,
19541943 deprecation : get_deprecation ( cx, self . did ) ,
@@ -2115,7 +2104,7 @@ impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
21152104 fields_stripped : false ,
21162105 fields : self . fields . iter ( ) . map ( |field| {
21172106 Item {
2118- source : Span :: empty ( ) ,
2107+ source : cx . tcx . def_span ( field . did ) . clean ( cx ) ,
21192108 name : Some ( field. name . clean ( cx) ) ,
21202109 attrs : cx. tcx . get_attrs ( field. did ) . clean ( cx) ,
21212110 visibility : field. vis . clean ( cx) ,
@@ -2131,7 +2120,7 @@ impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
21312120 Item {
21322121 name : Some ( self . name . clean ( cx) ) ,
21332122 attrs : inline:: load_attrs ( cx, self . did ) ,
2134- source : Span :: empty ( ) ,
2123+ source : cx . tcx . def_span ( self . did ) . clean ( cx ) ,
21352124 visibility : Some ( Inherited ) ,
21362125 def_id : self . did ,
21372126 inner : VariantItem ( Variant { kind : kind } ) ,
0 commit comments