@@ -27,11 +27,10 @@ use syntax::ptr::P;
27
27
use syntax:: symbol:: keywords;
28
28
use syntax_pos:: { self , DUMMY_SP , Pos } ;
29
29
30
- use rustc_trans:: back:: link;
31
30
use rustc:: middle:: privacy:: AccessLevels ;
32
31
use rustc:: middle:: resolve_lifetime:: DefRegion :: * ;
33
32
use 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 } ;
35
34
use rustc:: hir:: print as pprust;
36
35
use rustc:: ty:: subst:: Substs ;
37
36
use rustc:: ty:: { self , AdtKind } ;
@@ -45,7 +44,6 @@ use std::rc::Rc;
45
44
use std:: slice;
46
45
use std:: sync:: Arc ;
47
46
use std:: u32;
48
- use std:: env:: current_dir;
49
47
use std:: mem;
50
48
51
49
use core:: DocContext ;
@@ -110,19 +108,16 @@ pub struct Crate {
110
108
pub name : String ,
111
109
pub src : PathBuf ,
112
110
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 ) > ,
115
113
pub access_levels : Arc < AccessLevels < DefId > > ,
116
114
// These are later on moved into `CACHEKEY`, leaving the map empty.
117
115
// Only here so that they can be filtered through the rustdoc passes.
118
116
pub external_traits : FxHashMap < DefId , Trait > ,
119
117
}
120
118
121
- struct CrateNum ( def_id:: CrateNum ) ;
122
-
123
119
impl < ' a , ' tcx > Clean < Crate > for visit_ast:: RustdocVisitor < ' a , ' tcx > {
124
120
fn clean ( & self , cx : & DocContext ) -> Crate {
125
- use rustc:: session:: config:: Input ;
126
121
use :: visit_lib:: LibEmbargoVisitor ;
127
122
128
123
{
@@ -133,83 +128,41 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
133
128
134
129
let mut externs = Vec :: new ( ) ;
135
130
for cnum in cx. sess ( ) . cstore . crates ( ) {
136
- externs. push ( ( cnum, CrateNum ( cnum) . clean ( cx) ) ) ;
131
+ externs. push ( ( cnum, cnum. clean ( cx) ) ) ;
137
132
// Analyze doc-reachability for extern items
138
133
LibEmbargoVisitor :: new ( cx) . visit_lib ( cnum) ;
139
134
}
140
135
externs. sort_by ( |& ( a, _) , & ( b, _) | a. cmp ( & b) ) ;
141
136
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
-
146
137
// Clean the crate, translating the entire libsyntax AST to one that is
147
138
// understood by rustdoc.
148
139
let mut module = self . module . clean ( cx) ;
149
140
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) ;
168
142
{
169
143
let m = match module. inner {
170
144
ModuleItem ( ref mut m) => m,
171
145
_ => unreachable ! ( ) ,
172
146
} ;
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 {
184
149
source : Span :: empty ( ) ,
185
150
name : Some ( prim. to_url_str ( ) . to_string ( ) ) ,
186
- attrs : child . attrs . clone ( ) ,
151
+ attrs : attrs. clone ( ) ,
187
152
visibility : Some ( Public ) ,
188
153
stability : None ,
189
154
deprecation : None ,
190
- def_id : DefId :: local ( prim . to_def_index ( ) ) ,
155
+ def_id : def_id ,
191
156
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)
203
157
}
204
- } ,
205
- Input :: Str { ref name, .. } => PathBuf :: from ( name. clone ( ) ) ,
206
- } ;
158
+ } ) ) ;
159
+ }
207
160
208
161
let mut access_levels = cx. access_levels . borrow_mut ( ) ;
209
162
let mut external_traits = cx. external_traits . borrow_mut ( ) ;
210
163
211
164
Crate {
212
- name : name. to_string ( ) ,
165
+ name : name,
213
166
src : src,
214
167
module : Some ( module) ,
215
168
externs : externs,
@@ -223,21 +176,78 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
223
176
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
224
177
pub struct ExternalCrate {
225
178
pub name : String ,
179
+ pub src : PathBuf ,
226
180
pub attrs : Attributes ,
227
- pub primitives : Vec < PrimitiveType > ,
181
+ pub primitives : Vec < ( DefId , PrimitiveType , Attributes ) > ,
228
182
}
229
183
230
184
impl Clean < ExternalCrate > for CrateNum {
231
185
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
+
238
247
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) ,
241
251
primitives : primitives,
242
252
}
243
253
}
@@ -1460,7 +1470,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
1460
1470
deprecation : get_deprecation ( cx, self . def_id ) ,
1461
1471
def_id : self . def_id ,
1462
1472
attrs : inline:: load_attrs ( cx, self . def_id ) ,
1463
- source : Span :: empty ( ) ,
1473
+ source : cx . tcx . def_span ( self . def_id ) . clean ( cx ) ,
1464
1474
inner : inner,
1465
1475
}
1466
1476
}
@@ -1618,19 +1628,6 @@ impl PrimitiveType {
1618
1628
}
1619
1629
}
1620
1630
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
-
1634
1631
pub fn as_str ( & self ) -> & ' static str {
1635
1632
match * self {
1636
1633
PrimitiveType :: Isize => "isize" ,
@@ -1658,14 +1655,6 @@ impl PrimitiveType {
1658
1655
pub fn to_url_str ( & self ) -> & ' static str {
1659
1656
self . as_str ( )
1660
1657
}
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
- }
1669
1658
}
1670
1659
1671
1660
impl From < ast:: IntTy > for PrimitiveType {
@@ -1948,7 +1937,7 @@ impl<'tcx> Clean<Item> for ty::FieldDefData<'tcx, 'static> {
1948
1937
Item {
1949
1938
name : Some ( self . name ) . clean ( cx) ,
1950
1939
attrs : cx. tcx . get_attrs ( self . did ) . clean ( cx) ,
1951
- source : Span :: empty ( ) ,
1940
+ source : cx . tcx . def_span ( self . did ) . clean ( cx ) ,
1952
1941
visibility : self . vis . clean ( cx) ,
1953
1942
stability : get_stability ( cx, self . did ) ,
1954
1943
deprecation : get_deprecation ( cx, self . did ) ,
@@ -2115,7 +2104,7 @@ impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
2115
2104
fields_stripped : false ,
2116
2105
fields : self . fields . iter ( ) . map ( |field| {
2117
2106
Item {
2118
- source : Span :: empty ( ) ,
2107
+ source : cx . tcx . def_span ( field . did ) . clean ( cx ) ,
2119
2108
name : Some ( field. name . clean ( cx) ) ,
2120
2109
attrs : cx. tcx . get_attrs ( field. did ) . clean ( cx) ,
2121
2110
visibility : field. vis . clean ( cx) ,
@@ -2131,7 +2120,7 @@ impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
2131
2120
Item {
2132
2121
name : Some ( self . name . clean ( cx) ) ,
2133
2122
attrs : inline:: load_attrs ( cx, self . did ) ,
2134
- source : Span :: empty ( ) ,
2123
+ source : cx . tcx . def_span ( self . did ) . clean ( cx ) ,
2135
2124
visibility : Some ( Inherited ) ,
2136
2125
def_id : self . did ,
2137
2126
inner : VariantItem ( Variant { kind : kind } ) ,
0 commit comments