@@ -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,7 +176,12 @@ 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
} ;
182
- cx. renderinfo . borrow_mut ( ) . external_paths . insert ( did, ( fqn, kind) ) ;
179
+
180
+ if did. is_local ( ) {
181
+ cx. renderinfo . borrow_mut ( ) . exact_paths . insert ( did, fqn) ;
182
+ } else {
183
+ cx. renderinfo . borrow_mut ( ) . external_paths . insert ( did, ( fqn, kind) ) ;
184
+ }
183
185
}
184
186
185
187
pub fn build_external_trait ( cx : & DocContext , did : DefId ) -> clean:: Trait {
@@ -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
375
- if let Some ( traitref) = associated_trait {
376
- if !cx. access_levels . borrow ( ) . is_doc_reachable ( traitref. def_id ) {
377
- return
298
+ if !did. is_local ( ) {
299
+ if let Some ( traitref) = associated_trait {
300
+ if !cx. renderinfo . borrow ( ) . access_levels . is_doc_reachable ( traitref. def_id ) {
301
+ return
302
+ }
378
303
}
379
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
385
- if let Some ( did) = for_. def_id ( ) {
386
- if !cx. access_levels . borrow ( ) . is_doc_reachable ( did) {
387
- return
319
+ if !did. is_local ( ) {
320
+ if let Some ( did) = for_. def_id ( ) {
321
+ if !cx. renderinfo . borrow ( ) . access_levels . is_doc_reachable ( did) {
322
+ return
323
+ }
388
324
}
389
325
}
390
326
391
327
let predicates = tcx. predicates_of ( did) ;
392
- let trait_items = tcx. associated_items ( did) . filter_map ( |item| {
393
- if associated_trait. is_some ( ) || item. vis == ty:: Visibility :: Public {
394
- Some ( item. clean ( cx) )
395
- } else {
396
- None
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" ) ,
397
339
}
398
- } ) . collect :: < Vec < _ > > ( ) ;
340
+ } else {
341
+ (
342
+ tcx. associated_items ( did) . filter_map ( |item| {
343
+ if associated_trait. is_some ( ) || item. vis == ty:: Visibility :: Public {
344
+ Some ( item. clean ( cx) )
345
+ } else {
346
+ None
347
+ }
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,7 +420,11 @@ 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 {
468
- cx. tcx . rendered_const ( did)
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 {
426
+ cx. tcx . rendered_const ( did)
427
+ }
469
428
}
470
429
471
430
fn build_const ( cx : & DocContext , did : DefId ) -> 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) ||
580
- cx. active_extern_traits . borrow ( ) . contains ( & did)
581
- {
538
+ if did. is_local ( ) {
582
539
return ;
583
540
}
584
541
542
+ {
543
+ let external_traits = cx. external_traits . lock ( ) ;
544
+ if external_traits. borrow ( ) . contains_key ( & did) ||
545
+ cx. active_extern_traits . borrow ( ) . contains ( & did)
546
+ {
547
+ return ;
548
+ }
549
+ }
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