@@ -433,19 +433,97 @@ pub(crate) fn merge_attrs(
433
433
}
434
434
}
435
435
436
+ /// Inline an `impl`, inherent or of a trait. The `did` must be for an `impl` defined in the current crate.
437
+ pub ( crate ) fn build_local_impl (
438
+ cx : & mut DocContext < ' _ > ,
439
+ did : DefId ,
440
+ attrs : Option < ( & [ hir:: Attribute ] , Option < LocalDefId > ) > ,
441
+ ret : & mut Vec < clean:: Item > ,
442
+ ) {
443
+ if !cx. inlined . insert ( did. into ( ) ) {
444
+ return ;
445
+ }
446
+ debug_assert ! ( did. is_local( ) , "build_local_impl called on external impl" ) ;
447
+ let tcx = cx. tcx ;
448
+ let _prof_timer = tcx. sess . prof . generic_activity ( "build_local_impl" ) ;
449
+
450
+ let associated_trait = tcx. impl_trait_ref ( did) . map ( ty:: EarlyBinder :: skip_binder) ;
451
+
452
+ let impl_item = match did. as_local ( ) {
453
+ Some ( did) => match & tcx. hir_expect_item ( did) . kind {
454
+ hir:: ItemKind :: Impl ( impl_) => impl_,
455
+ _ => panic ! ( "`DefID` passed to `build_impl` is not an `impl" ) ,
456
+ } ,
457
+ None => unreachable ! ( "build_local_impl called on external impl" ) ,
458
+ } ;
459
+
460
+ let for_ = clean_ty ( impl_item. self_ty , cx) ;
461
+
462
+ let document_hidden = cx. render_options . document_hidden ;
463
+ let ( trait_items, generics) = (
464
+ impl_item
465
+ . items
466
+ . iter ( )
467
+ . map ( |& item| tcx. hir_impl_item ( item) )
468
+ . filter ( |item| {
469
+ // Filter out impl items whose corresponding trait item has `doc(hidden)`
470
+ // not to document such impl items.
471
+ // For inherent impls, we don't do any filtering, because that's already done in strip_hidden.rs.
472
+
473
+ // When `--document-hidden-items` is passed, we don't
474
+ // do any filtering, too.
475
+ if document_hidden {
476
+ return true ;
477
+ }
478
+ if let Some ( associated_trait) = associated_trait {
479
+ let assoc_tag = match item. kind {
480
+ hir:: ImplItemKind :: Const ( ..) => ty:: AssocTag :: Const ,
481
+ hir:: ImplItemKind :: Fn ( ..) => ty:: AssocTag :: Fn ,
482
+ hir:: ImplItemKind :: Type ( ..) => ty:: AssocTag :: Type ,
483
+ } ;
484
+ let trait_item = tcx
485
+ . associated_items ( associated_trait. def_id )
486
+ . find_by_ident_and_kind ( tcx, item. ident , assoc_tag, associated_trait. def_id )
487
+ . unwrap ( ) ; // SAFETY: For all impl items there exists trait item that has the same name.
488
+ !tcx. is_doc_hidden ( trait_item. def_id )
489
+ } else {
490
+ true
491
+ }
492
+ } )
493
+ . map ( |item| clean_impl_item ( item, cx) )
494
+ . collect :: < Vec < _ > > ( ) ,
495
+ clean_generics ( impl_item. generics , cx) ,
496
+ ) ;
497
+ build_impl_finalize ( cx, did, attrs, ret, associated_trait, for_, trait_items, generics)
498
+ }
499
+
436
500
/// Inline an `impl`, inherent or of a trait. The `did` must be for an `impl`.
437
501
pub ( crate ) fn build_impl (
438
502
cx : & mut DocContext < ' _ > ,
439
503
did : DefId ,
440
504
attrs : Option < ( & [ hir:: Attribute ] , Option < LocalDefId > ) > ,
441
505
ret : & mut Vec < clean:: Item > ,
506
+ ) {
507
+ if did. is_local ( ) {
508
+ build_local_impl ( cx, did, attrs, ret) ;
509
+ } else {
510
+ build_external_impl ( cx, did, attrs, ret) ;
511
+ }
512
+ }
513
+
514
+ /// Inline an `impl`, inherent or of a trait. The `did` must be for an `impl` defined in an external crate.
515
+ pub ( crate ) fn build_external_impl (
516
+ cx : & mut DocContext < ' _ > ,
517
+ did : DefId ,
518
+ attrs : Option < ( & [ hir:: Attribute ] , Option < LocalDefId > ) > ,
519
+ ret : & mut Vec < clean:: Item > ,
442
520
) {
443
521
if !cx. inlined . insert ( did. into ( ) ) {
444
522
return ;
445
523
}
446
524
447
525
let tcx = cx. tcx ;
448
- let _prof_timer = tcx. sess . prof . generic_activity ( "build_impl " ) ;
526
+ let _prof_timer = tcx. sess . prof . generic_activity ( "build_external_impl " ) ;
449
527
450
528
let associated_trait = tcx. impl_trait_ref ( did) . map ( ty:: EarlyBinder :: skip_binder) ;
451
529
@@ -462,30 +540,18 @@ pub(crate) fn build_impl(
462
540
463
541
// Only inline impl if the implemented trait is
464
542
// reachable in rustdoc generated documentation
465
- if !did. is_local ( )
466
- && let Some ( traitref) = associated_trait
543
+ if let Some ( traitref) = associated_trait
467
544
&& !is_directly_public ( cx, traitref. def_id )
468
545
{
469
546
return ;
470
547
}
471
548
472
- let impl_item = match did. as_local ( ) {
473
- Some ( did) => match & tcx. hir_expect_item ( did) . kind {
474
- hir:: ItemKind :: Impl ( impl_) => Some ( impl_) ,
475
- _ => panic ! ( "`DefID` passed to `build_impl` is not an `impl" ) ,
476
- } ,
477
- None => None ,
478
- } ;
479
-
480
- let for_ = match & impl_item {
481
- Some ( impl_) => clean_ty ( impl_. self_ty , cx) ,
482
- None => clean_middle_ty (
483
- ty:: Binder :: dummy ( tcx. type_of ( did) . instantiate_identity ( ) ) ,
484
- cx,
485
- Some ( did) ,
486
- None ,
487
- ) ,
488
- } ;
549
+ let for_ = clean_middle_ty (
550
+ ty:: Binder :: dummy ( tcx. type_of ( did) . instantiate_identity ( ) ) ,
551
+ cx,
552
+ Some ( did) ,
553
+ None ,
554
+ ) ;
489
555
490
556
// Only inline impl if the implementing type is
491
557
// reachable in rustdoc generated documentation
@@ -496,82 +562,57 @@ pub(crate) fn build_impl(
496
562
return ;
497
563
}
498
564
565
+ debug_assert ! ( !did. is_local( ) , "build_external_impl called on local impl" ) ;
566
+
567
+ let document_hidden = cx. render_options . document_hidden ;
568
+ let ( trait_items, generics) = (
569
+ tcx. associated_items ( did)
570
+ . in_definition_order ( )
571
+ . filter ( |item| !item. is_impl_trait_in_trait ( ) )
572
+ . filter ( |item| {
573
+ // If this is a trait impl, filter out associated items whose corresponding item
574
+ // in the associated trait is marked `doc(hidden)`.
575
+ // If this is an inherent impl, filter out private associated items.
576
+ if let Some ( associated_trait) = associated_trait {
577
+ let trait_item = tcx
578
+ . associated_items ( associated_trait. def_id )
579
+ . find_by_ident_and_kind (
580
+ tcx,
581
+ item. ident ( tcx) ,
582
+ item. as_tag ( ) ,
583
+ associated_trait. def_id ,
584
+ )
585
+ . unwrap ( ) ; // corresponding associated item has to exist
586
+ document_hidden || !tcx. is_doc_hidden ( trait_item. def_id )
587
+ } else {
588
+ item. visibility ( tcx) . is_public ( )
589
+ }
590
+ } )
591
+ . map ( |item| clean_middle_assoc_item ( item, cx) )
592
+ . collect :: < Vec < _ > > ( ) ,
593
+ clean:: enter_impl_trait ( cx, |cx| clean_ty_generics ( cx, did) ) ,
594
+ ) ;
595
+ build_impl_finalize ( cx, did, attrs, ret, associated_trait, for_, trait_items, generics)
596
+ }
597
+
598
+ fn build_impl_finalize < ' tcx > (
599
+ cx : & mut DocContext < ' tcx > ,
600
+ did : DefId ,
601
+ attrs : Option < ( & [ rustc_hir:: Attribute ] , Option < LocalDefId > ) > ,
602
+ ret : & mut Vec < Item > ,
603
+ associated_trait : Option < ty:: TraitRef < ' tcx > > ,
604
+ for_ : Type ,
605
+ trait_items : Vec < Item > ,
606
+ generics : clean:: Generics ,
607
+ ) {
608
+ let tcx = cx. tcx ;
499
609
let document_hidden = cx. render_options . document_hidden ;
500
- let ( trait_items, generics) = match impl_item {
501
- Some ( impl_) => (
502
- impl_
503
- . items
504
- . iter ( )
505
- . map ( |& item| tcx. hir_impl_item ( item) )
506
- . filter ( |item| {
507
- // Filter out impl items whose corresponding trait item has `doc(hidden)`
508
- // not to document such impl items.
509
- // For inherent impls, we don't do any filtering, because that's already done in strip_hidden.rs.
510
-
511
- // When `--document-hidden-items` is passed, we don't
512
- // do any filtering, too.
513
- if document_hidden {
514
- return true ;
515
- }
516
- if let Some ( associated_trait) = associated_trait {
517
- let assoc_tag = match item. kind {
518
- hir:: ImplItemKind :: Const ( ..) => ty:: AssocTag :: Const ,
519
- hir:: ImplItemKind :: Fn ( ..) => ty:: AssocTag :: Fn ,
520
- hir:: ImplItemKind :: Type ( ..) => ty:: AssocTag :: Type ,
521
- } ;
522
- let trait_item = tcx
523
- . associated_items ( associated_trait. def_id )
524
- . find_by_ident_and_kind (
525
- tcx,
526
- item. ident ,
527
- assoc_tag,
528
- associated_trait. def_id ,
529
- )
530
- . unwrap ( ) ; // SAFETY: For all impl items there exists trait item that has the same name.
531
- !tcx. is_doc_hidden ( trait_item. def_id )
532
- } else {
533
- true
534
- }
535
- } )
536
- . map ( |item| clean_impl_item ( item, cx) )
537
- . collect :: < Vec < _ > > ( ) ,
538
- clean_generics ( impl_. generics , cx) ,
539
- ) ,
540
- None => (
541
- tcx. associated_items ( did)
542
- . in_definition_order ( )
543
- . filter ( |item| !item. is_impl_trait_in_trait ( ) )
544
- . filter ( |item| {
545
- // If this is a trait impl, filter out associated items whose corresponding item
546
- // in the associated trait is marked `doc(hidden)`.
547
- // If this is an inherent impl, filter out private associated items.
548
- if let Some ( associated_trait) = associated_trait {
549
- let trait_item = tcx
550
- . associated_items ( associated_trait. def_id )
551
- . find_by_ident_and_kind (
552
- tcx,
553
- item. ident ( tcx) ,
554
- item. as_tag ( ) ,
555
- associated_trait. def_id ,
556
- )
557
- . unwrap ( ) ; // corresponding associated item has to exist
558
- document_hidden || !tcx. is_doc_hidden ( trait_item. def_id )
559
- } else {
560
- item. visibility ( tcx) . is_public ( )
561
- }
562
- } )
563
- . map ( |item| clean_middle_assoc_item ( item, cx) )
564
- . collect :: < Vec < _ > > ( ) ,
565
- clean:: enter_impl_trait ( cx, |cx| clean_ty_generics ( cx, did) ) ,
566
- ) ,
567
- } ;
568
610
let polarity = tcx. impl_polarity ( did) ;
569
611
let trait_ = associated_trait
570
612
. map ( |t| clean_trait_ref_with_constraints ( cx, ty:: Binder :: dummy ( t) , ThinVec :: new ( ) ) ) ;
571
613
if trait_. as_ref ( ) . map ( |t| t. def_id ( ) ) == tcx. lang_items ( ) . deref_trait ( ) {
572
614
super :: build_deref_target_impls ( cx, & trait_items, ret) ;
573
615
}
574
-
575
616
if !document_hidden {
576
617
// Return if the trait itself or any types of the generic parameters are doc(hidden).
577
618
let mut stack: Vec < & Type > = vec ! [ & for_] ;
@@ -597,16 +638,13 @@ pub(crate) fn build_impl(
597
638
}
598
639
}
599
640
}
600
-
601
641
if let Some ( did) = trait_. as_ref ( ) . map ( |t| t. def_id ( ) ) {
602
642
cx. with_param_env ( did, |cx| {
603
643
record_extern_trait ( cx, did) ;
604
644
} ) ;
605
645
}
606
-
607
646
let ( merged_attrs, cfg) = merge_attrs ( cx, load_attrs ( cx, did) , attrs) ;
608
647
trace ! ( "merged_attrs={merged_attrs:?}" ) ;
609
-
610
648
trace ! (
611
649
"build_impl: impl {:?} for {:?}" ,
612
650
trait_. as_ref( ) . map( |t| t. def_id( ) ) ,
@@ -620,7 +658,7 @@ pub(crate) fn build_impl(
620
658
generics,
621
659
trait_,
622
660
for_,
623
- items : trait_items,
661
+ items : trait_items. to_vec ( ) ,
624
662
polarity,
625
663
kind : if utils:: has_doc_flag ( tcx, did, sym:: fake_variadic) {
626
664
ImplKind :: FakeVariadic
0 commit comments