@@ -391,6 +391,24 @@ pub enum DocFragmentKind {
391
391
/// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
392
392
/// given filename and the file contents.
393
393
Include { filename : String } ,
394
+ /// A doc fragment used to distinguish between documentation in different modules.
395
+ ///
396
+ /// In particular, this prevents `collapse_docs` from turning all documentation comments
397
+ /// into a single giant attributes even when the item is re-exported with documentation on the re-export.
398
+ Divider ,
399
+ }
400
+
401
+ impl DocFragment {
402
+ /// Creates a dummy doc-fragment which divides earlier and later fragments.
403
+ fn divider ( ) -> Self {
404
+ DocFragment {
405
+ line : 0 ,
406
+ span : DUMMY_SP ,
407
+ parent_module : None ,
408
+ doc : String :: new ( ) ,
409
+ kind : DocFragmentKind :: Divider ,
410
+ }
411
+ }
394
412
}
395
413
396
414
impl < ' a > FromIterator < & ' a DocFragment > for String {
@@ -531,68 +549,72 @@ impl Attributes {
531
549
attrs : & [ ast:: Attribute ] ,
532
550
additional_attrs : Option < ( & [ ast:: Attribute ] , DefId ) > ,
533
551
) -> Attributes {
534
- let mut doc_strings = vec ! [ ] ;
552
+ let doc_strings = RefCell :: new ( vec ! [ ] ) ;
535
553
let mut sp = None ;
536
554
let mut cfg = Cfg :: True ;
537
555
let mut doc_line = 0 ;
538
556
539
- // Additional documentation should be shown before the original documentation
540
- let other_attrs = additional_attrs
541
- . into_iter ( )
542
- . map ( |( attrs, id) | attrs. iter ( ) . map ( move |attr| ( attr, Some ( id) ) ) )
543
- . flatten ( )
544
- . chain ( attrs. iter ( ) . map ( |attr| ( attr, None ) ) )
545
- . filter_map ( |( attr, parent_module) | {
546
- if let Some ( value) = attr. doc_str ( ) {
547
- trace ! ( "got doc_str={:?}" , value) ;
548
- let value = beautify_doc_string ( value) ;
549
- let kind = if attr. is_doc_comment ( ) {
550
- DocFragmentKind :: SugaredDoc
551
- } else {
552
- DocFragmentKind :: RawDoc
553
- } ;
554
-
555
- let line = doc_line;
556
- doc_line += value. lines ( ) . count ( ) ;
557
- doc_strings. push ( DocFragment {
558
- line,
559
- span : attr. span ,
560
- doc : value,
561
- kind,
562
- parent_module,
563
- } ) ;
564
-
565
- if sp. is_none ( ) {
566
- sp = Some ( attr. span ) ;
567
- }
568
- None
557
+ let clean_attr = |( attr, parent_module) : ( & ast:: Attribute , _ ) | {
558
+ if let Some ( value) = attr. doc_str ( ) {
559
+ trace ! ( "got doc_str={:?}" , value) ;
560
+ let value = beautify_doc_string ( value) ;
561
+ let kind = if attr. is_doc_comment ( ) {
562
+ DocFragmentKind :: SugaredDoc
569
563
} else {
570
- if attr. has_name ( sym:: doc) {
571
- if let Some ( mi) = attr. meta ( ) {
572
- if let Some ( cfg_mi) = Attributes :: extract_cfg ( & mi) {
573
- // Extracted #[doc(cfg(...))]
574
- match Cfg :: parse ( cfg_mi) {
575
- Ok ( new_cfg) => cfg &= new_cfg,
576
- Err ( e) => diagnostic. span_err ( e. span , e. msg ) ,
577
- }
578
- } else if let Some ( ( filename, contents) ) =
579
- Attributes :: extract_include ( & mi)
580
- {
581
- let line = doc_line;
582
- doc_line += contents. lines ( ) . count ( ) ;
583
- doc_strings. push ( DocFragment {
584
- line,
585
- span : attr. span ,
586
- doc : contents,
587
- kind : DocFragmentKind :: Include { filename } ,
588
- parent_module : parent_module,
589
- } ) ;
564
+ DocFragmentKind :: RawDoc
565
+ } ;
566
+
567
+ let line = doc_line;
568
+ doc_line += value. lines ( ) . count ( ) ;
569
+ doc_strings. borrow_mut ( ) . push ( DocFragment {
570
+ line,
571
+ span : attr. span ,
572
+ doc : value,
573
+ kind,
574
+ parent_module,
575
+ } ) ;
576
+
577
+ if sp. is_none ( ) {
578
+ sp = Some ( attr. span ) ;
579
+ }
580
+ None
581
+ } else {
582
+ if attr. has_name ( sym:: doc) {
583
+ if let Some ( mi) = attr. meta ( ) {
584
+ if let Some ( cfg_mi) = Attributes :: extract_cfg ( & mi) {
585
+ // Extracted #[doc(cfg(...))]
586
+ match Cfg :: parse ( cfg_mi) {
587
+ Ok ( new_cfg) => cfg &= new_cfg,
588
+ Err ( e) => diagnostic. span_err ( e. span , e. msg ) ,
590
589
}
590
+ } else if let Some ( ( filename, contents) ) = Attributes :: extract_include ( & mi)
591
+ {
592
+ let line = doc_line;
593
+ doc_line += contents. lines ( ) . count ( ) ;
594
+ doc_strings. borrow_mut ( ) . push ( DocFragment {
595
+ line,
596
+ span : attr. span ,
597
+ doc : contents,
598
+ kind : DocFragmentKind :: Include { filename } ,
599
+ parent_module : parent_module,
600
+ } ) ;
591
601
}
592
602
}
593
- Some ( attr. clone ( ) )
594
603
}
604
+ Some ( attr. clone ( ) )
605
+ }
606
+ } ;
607
+
608
+ // Additional documentation should be shown before the original documentation
609
+ let other_attrs = additional_attrs
610
+ . into_iter ( )
611
+ . map ( |( attrs, id) | {
612
+ doc_strings. borrow_mut ( ) . push ( DocFragment :: divider ( ) ) ;
613
+ attrs. iter ( ) . map ( move |attr| ( attr, Some ( id) ) )
595
614
} )
615
+ . flatten ( )
616
+ . chain ( attrs. iter ( ) . map ( |attr| ( attr, None ) ) )
617
+ . filter_map ( clean_attr)
596
618
. collect ( ) ;
597
619
598
620
// treat #[target_feature(enable = "feat")] attributes as if they were
@@ -618,7 +640,7 @@ impl Attributes {
618
640
. map_or ( true , |a| a. style == AttrStyle :: Inner ) ;
619
641
620
642
Attributes {
621
- doc_strings,
643
+ doc_strings : doc_strings . into_inner ( ) ,
622
644
other_attrs,
623
645
cfg : if cfg == Cfg :: True { None } else { Some ( Arc :: new ( cfg) ) } ,
624
646
span : sp,
0 commit comments