@@ -29,8 +29,6 @@ use clean::{
29
29
self ,
30
30
GetDefId ,
31
31
ToSource ,
32
- get_auto_traits_with_def_id,
33
- get_blanket_impls_with_def_id,
34
32
} ;
35
33
36
34
use super :: Clean ;
@@ -56,7 +54,7 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa
56
54
let inner = match def {
57
55
Def :: Trait ( did) => {
58
56
record_extern_fqn ( cx, did, clean:: TypeKind :: Trait ) ;
59
- ret. extend ( build_impls ( cx, did, false ) ) ;
57
+ ret. extend ( build_impls ( cx, did) ) ;
60
58
clean:: TraitItem ( build_external_trait ( cx, did) )
61
59
}
62
60
Def :: Fn ( did) => {
@@ -65,27 +63,27 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa
65
63
}
66
64
Def :: Struct ( did) => {
67
65
record_extern_fqn ( cx, did, clean:: TypeKind :: Struct ) ;
68
- ret. extend ( build_impls ( cx, did, true ) ) ;
66
+ ret. extend ( build_impls ( cx, did) ) ;
69
67
clean:: StructItem ( build_struct ( cx, did) )
70
68
}
71
69
Def :: Union ( did) => {
72
70
record_extern_fqn ( cx, did, clean:: TypeKind :: Union ) ;
73
- ret. extend ( build_impls ( cx, did, true ) ) ;
71
+ ret. extend ( build_impls ( cx, did) ) ;
74
72
clean:: UnionItem ( build_union ( cx, did) )
75
73
}
76
74
Def :: TyAlias ( did) => {
77
75
record_extern_fqn ( cx, did, clean:: TypeKind :: Typedef ) ;
78
- ret. extend ( build_impls ( cx, did, false ) ) ;
76
+ ret. extend ( build_impls ( cx, did) ) ;
79
77
clean:: TypedefItem ( build_type_alias ( cx, did) , false )
80
78
}
81
79
Def :: Enum ( did) => {
82
80
record_extern_fqn ( cx, did, clean:: TypeKind :: Enum ) ;
83
- ret. extend ( build_impls ( cx, did, true ) ) ;
81
+ ret. extend ( build_impls ( cx, did) ) ;
84
82
clean:: EnumItem ( build_enum ( cx, did) )
85
83
}
86
84
Def :: ForeignTy ( did) => {
87
85
record_extern_fqn ( cx, did, clean:: TypeKind :: Foreign ) ;
88
- ret. extend ( build_impls ( cx, did, false ) ) ;
86
+ ret. extend ( build_impls ( cx, did) ) ;
89
87
clean:: ForeignTypeItem
90
88
}
91
89
// Never inline enum variants but leave them shown as re-exports.
@@ -159,12 +157,11 @@ pub fn load_attrs(cx: &DocContext, did: DefId) -> clean::Attributes {
159
157
/// These names are used later on by HTML rendering to generate things like
160
158
/// source links back to the original item.
161
159
pub fn record_extern_fqn ( cx : & DocContext , did : DefId , kind : clean:: TypeKind ) {
160
+ let mut crate_name = cx. tcx . crate_name ( did. krate ) . to_string ( ) ;
162
161
if did. is_local ( ) {
163
- debug ! ( "record_extern_fqn(did={:?}, kind+{:?}): def_id is local, aborting" , did, kind) ;
164
- return ;
162
+ crate_name = cx. crate_name . clone ( ) . unwrap_or ( crate_name) ;
165
163
}
166
164
167
- let crate_name = cx. tcx . crate_name ( did. krate ) . to_string ( ) ;
168
165
let relative = cx. tcx . def_path ( did) . data . into_iter ( ) . filter_map ( |elem| {
169
166
// extern blocks have an empty name
170
167
let s = elem. data . to_string ( ) ;
@@ -179,8 +176,13 @@ pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
179
176
} else {
180
177
once ( crate_name) . chain ( relative) . collect ( )
181
178
} ;
179
+
180
+ if did. is_local ( ) {
181
+ cx. renderinfo . borrow_mut ( ) . exact_paths . insert ( did, fqn) ;
182
+ } else {
182
183
cx. renderinfo . borrow_mut ( ) . external_paths . insert ( did, ( fqn, kind) ) ;
183
184
}
185
+ }
184
186
185
187
pub fn build_external_trait ( cx : & DocContext , did : DefId ) -> clean:: Trait {
186
188
let auto_trait = cx. tcx . trait_def ( did) . has_auto_impl ;
@@ -271,93 +273,14 @@ fn build_type_alias(cx: &DocContext, did: DefId) -> clean::Typedef {
271
273
}
272
274
}
273
275
274
- pub fn build_impls ( cx : & DocContext , did : DefId , auto_traits : bool ) -> Vec < clean:: Item > {
276
+ pub fn build_impls ( cx : & DocContext , did : DefId ) -> Vec < clean:: Item > {
275
277
let tcx = cx. tcx ;
276
278
let mut impls = Vec :: new ( ) ;
277
279
278
280
for & did in tcx. inherent_impls ( did) . iter ( ) {
279
281
build_impl ( cx, did, & mut impls) ;
280
282
}
281
283
282
- if auto_traits {
283
- let auto_impls = get_auto_traits_with_def_id ( cx, did) ;
284
- {
285
- let mut renderinfo = cx. renderinfo . borrow_mut ( ) ;
286
- let new_impls: Vec < clean:: Item > = auto_impls. into_iter ( )
287
- . filter ( |i| renderinfo. inlined . insert ( i. def_id ) ) . collect ( ) ;
288
-
289
- impls. extend ( new_impls) ;
290
- }
291
- impls. extend ( get_blanket_impls_with_def_id ( cx, did) ) ;
292
- }
293
-
294
- // If this is the first time we've inlined something from another crate, then
295
- // we inline *all* impls from all the crates into this crate. Note that there's
296
- // currently no way for us to filter this based on type, and we likely need
297
- // many impls for a variety of reasons.
298
- //
299
- // Primarily, the impls will be used to populate the documentation for this
300
- // type being inlined, but impls can also be used when generating
301
- // documentation for primitives (no way to find those specifically).
302
- if cx. populated_all_crate_impls . get ( ) {
303
- return impls;
304
- }
305
-
306
- cx. populated_all_crate_impls . set ( true ) ;
307
-
308
- for & cnum in tcx. crates ( ) . iter ( ) {
309
- for did in tcx. all_trait_implementations ( cnum) . iter ( ) {
310
- build_impl ( cx, * did, & mut impls) ;
311
- }
312
- }
313
-
314
- // Also try to inline primitive impls from other crates.
315
- let lang_items = tcx. lang_items ( ) ;
316
- let primitive_impls = [
317
- lang_items. isize_impl ( ) ,
318
- lang_items. i8_impl ( ) ,
319
- lang_items. i16_impl ( ) ,
320
- lang_items. i32_impl ( ) ,
321
- lang_items. i64_impl ( ) ,
322
- lang_items. i128_impl ( ) ,
323
- lang_items. usize_impl ( ) ,
324
- lang_items. u8_impl ( ) ,
325
- lang_items. u16_impl ( ) ,
326
- lang_items. u32_impl ( ) ,
327
- lang_items. u64_impl ( ) ,
328
- lang_items. u128_impl ( ) ,
329
- lang_items. f32_impl ( ) ,
330
- lang_items. f64_impl ( ) ,
331
- lang_items. f32_runtime_impl ( ) ,
332
- lang_items. f64_runtime_impl ( ) ,
333
- lang_items. char_impl ( ) ,
334
- lang_items. str_impl ( ) ,
335
- lang_items. slice_impl ( ) ,
336
- lang_items. slice_u8_impl ( ) ,
337
- lang_items. str_alloc_impl ( ) ,
338
- lang_items. slice_alloc_impl ( ) ,
339
- lang_items. slice_u8_alloc_impl ( ) ,
340
- lang_items. const_ptr_impl ( ) ,
341
- lang_items. mut_ptr_impl ( ) ,
342
- ] ;
343
-
344
- for def_id in primitive_impls. iter ( ) . filter_map ( |& def_id| def_id) {
345
- if !def_id. is_local ( ) {
346
- build_impl ( cx, def_id, & mut impls) ;
347
-
348
- let auto_impls = get_auto_traits_with_def_id ( cx, def_id) ;
349
- let blanket_impls = get_blanket_impls_with_def_id ( cx, def_id) ;
350
- let mut renderinfo = cx. renderinfo . borrow_mut ( ) ;
351
-
352
- let new_impls: Vec < clean:: Item > = auto_impls. into_iter ( )
353
- . chain ( blanket_impls. into_iter ( ) )
354
- . filter ( |i| renderinfo. inlined . insert ( i. def_id ) )
355
- . collect ( ) ;
356
-
357
- impls. extend ( new_impls) ;
358
- }
359
- }
360
-
361
284
impls
362
285
}
363
286
@@ -372,30 +295,60 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
372
295
373
296
// Only inline impl if the implemented trait is
374
297
// reachable in rustdoc generated documentation
298
+ if !did. is_local ( ) {
375
299
if let Some ( traitref) = associated_trait {
376
- if !cx. access_levels . borrow ( ) . is_doc_reachable ( traitref. def_id ) {
300
+ if !cx. renderinfo . borrow ( ) . access_levels . is_doc_reachable ( traitref. def_id ) {
377
301
return
378
302
}
379
303
}
304
+ }
380
305
381
- let for_ = tcx. type_of ( did) . clean ( cx) ;
306
+ let for_ = if let Some ( nodeid) = tcx. hir . as_local_node_id ( did) {
307
+ match tcx. hir . expect_item ( nodeid) . node {
308
+ hir:: ItemKind :: Impl ( .., ref t, _) => {
309
+ t. clean ( cx)
310
+ }
311
+ _ => panic ! ( "did given to build_impl was not an impl" ) ,
312
+ }
313
+ } else {
314
+ tcx. type_of ( did) . clean ( cx)
315
+ } ;
382
316
383
317
// Only inline impl if the implementing type is
384
318
// reachable in rustdoc generated documentation
319
+ if !did. is_local ( ) {
385
320
if let Some ( did) = for_. def_id ( ) {
386
- if !cx. access_levels . borrow ( ) . is_doc_reachable ( did) {
321
+ if !cx. renderinfo . borrow ( ) . access_levels . is_doc_reachable ( did) {
387
322
return
388
323
}
389
324
}
325
+ }
390
326
391
327
let predicates = tcx. predicates_of ( did) ;
392
- let trait_items = tcx. associated_items ( did) . filter_map ( |item| {
328
+ let ( trait_items, generics) = if let Some ( nodeid) = tcx. hir . as_local_node_id ( did) {
329
+ match tcx. hir . expect_item ( nodeid) . node {
330
+ hir:: ItemKind :: Impl ( .., ref gen, _, _, ref item_ids) => {
331
+ (
332
+ item_ids. iter ( )
333
+ . map ( |ii| tcx. hir . impl_item ( ii. id ) . clean ( cx) )
334
+ . collect :: < Vec < _ > > ( ) ,
335
+ gen. clean ( cx) ,
336
+ )
337
+ }
338
+ _ => panic ! ( "did given to build_impl was not an impl" ) ,
339
+ }
340
+ } else {
341
+ (
342
+ tcx. associated_items ( did) . filter_map ( |item| {
393
343
if associated_trait. is_some ( ) || item. vis == ty:: Visibility :: Public {
394
344
Some ( item. clean ( cx) )
395
345
} else {
396
346
None
397
347
}
398
- } ) . collect :: < Vec < _ > > ( ) ;
348
+ } ) . collect :: < Vec < _ > > ( ) ,
349
+ ( tcx. generics_of ( did) , & predicates) . clean ( cx) ,
350
+ )
351
+ } ;
399
352
let polarity = tcx. impl_polarity ( did) ;
400
353
let trait_ = associated_trait. clean ( cx) . map ( |bound| {
401
354
match bound {
@@ -417,10 +370,12 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
417
370
. collect ( )
418
371
} ) . unwrap_or ( FxHashSet ( ) ) ;
419
372
373
+ debug ! ( "build_impl: impl {:?} for {:?}" , trait_. def_id( ) , for_. def_id( ) ) ;
374
+
420
375
ret. push ( clean:: Item {
421
376
inner : clean:: ImplItem ( clean:: Impl {
422
377
unsafety : hir:: Unsafety :: Normal ,
423
- generics : ( tcx . generics_of ( did ) , & predicates ) . clean ( cx ) ,
378
+ generics,
424
379
provided_trait_methods : provided,
425
380
trait_,
426
381
for_,
@@ -465,8 +420,12 @@ fn build_module(cx: &DocContext, did: DefId, visited: &mut FxHashSet<DefId>) ->
465
420
}
466
421
467
422
pub fn print_inlined_const ( cx : & DocContext , did : DefId ) -> String {
423
+ if let Some ( node_id) = cx. tcx . hir . as_local_node_id ( did) {
424
+ cx. tcx . hir . node_to_pretty_string ( node_id)
425
+ } else {
468
426
cx. tcx . rendered_const ( did)
469
427
}
428
+ }
470
429
471
430
fn build_const ( cx : & DocContext , did : DefId ) -> clean:: Constant {
472
431
clean:: Constant {
@@ -576,16 +535,27 @@ fn separate_supertrait_bounds(mut g: clean::Generics)
576
535
}
577
536
578
537
pub fn record_extern_trait ( cx : & DocContext , did : DefId ) {
579
- if cx. external_traits . borrow ( ) . contains_key ( & did) ||
538
+ if did. is_local ( ) {
539
+ return ;
540
+ }
541
+
542
+ {
543
+ let external_traits = cx. external_traits . lock ( ) ;
544
+ if external_traits. borrow ( ) . contains_key ( & did) ||
580
545
cx. active_extern_traits . borrow ( ) . contains ( & did)
581
546
{
582
547
return ;
583
548
}
549
+ }
584
550
585
551
cx. active_extern_traits . borrow_mut ( ) . push ( did) ;
586
552
553
+ debug ! ( "record_extern_trait: {:?}" , did) ;
587
554
let trait_ = build_external_trait ( cx, did) ;
588
555
589
- cx. external_traits . borrow_mut ( ) . insert ( did, trait_) ;
556
+ {
557
+ let external_traits = cx. external_traits . lock ( ) ;
558
+ external_traits. borrow_mut ( ) . insert ( did, trait_) ;
559
+ }
590
560
cx. active_extern_traits . borrow_mut ( ) . remove_item ( & did) ;
591
561
}
0 commit comments