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