about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJoshua Nelson <jyn514@gmail.com>2020-10-04 11:15:45 -0400
committerJoshua Nelson <jyn514@gmail.com>2020-10-08 00:29:38 -0400
commit8fbfdc548aa8f0f7b9e7bbd54d6916eb5ed53e23 (patch)
treeb47f63c71f0513dfcb400b7de7e0458760cde6c4 /src
parentfa1b15f6279a95923b8a19046f45f27f243d49d2 (diff)
downloadrust-8fbfdc548aa8f0f7b9e7bbd54d6916eb5ed53e23.tar.gz
rust-8fbfdc548aa8f0f7b9e7bbd54d6916eb5ed53e23.zip
Introduce `Divider`
This distinguishes between documentation on the original from docs on
the re-export
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/clean/types.rs128
1 files changed, 75 insertions, 53 deletions
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index cd20e241c8f..179cf248846 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -391,6 +391,24 @@ pub enum DocFragmentKind {
     /// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
     /// given filename and the file contents.
     Include { filename: String },
+    /// A doc fragment used to distinguish between documentation in different modules.
+    ///
+    /// In particular, this prevents `collapse_docs` from turning all documentation comments
+    /// into a single giant attributes even when the item is re-exported with documentation on the re-export.
+    Divider,
+}
+
+impl DocFragment {
+    /// Creates a dummy doc-fragment which divides earlier and later fragments.
+    fn divider() -> Self {
+        DocFragment {
+            line: 0,
+            span: DUMMY_SP,
+            parent_module: None,
+            doc: String::new(),
+            kind: DocFragmentKind::Divider,
+        }
+    }
 }
 
 impl<'a> FromIterator<&'a DocFragment> for String {
@@ -531,68 +549,72 @@ impl Attributes {
         attrs: &[ast::Attribute],
         additional_attrs: Option<(&[ast::Attribute], DefId)>,
     ) -> Attributes {
-        let mut doc_strings = vec![];
+        let doc_strings = RefCell::new(vec![]);
         let mut sp = None;
         let mut cfg = Cfg::True;
         let mut doc_line = 0;
 
-        // Additional documentation should be shown before the original documentation
-        let other_attrs = additional_attrs
-            .into_iter()
-            .map(|(attrs, id)| attrs.iter().map(move |attr| (attr, Some(id))))
-            .flatten()
-            .chain(attrs.iter().map(|attr| (attr, None)))
-            .filter_map(|(attr, parent_module)| {
-                if let Some(value) = attr.doc_str() {
-                    trace!("got doc_str={:?}", value);
-                    let value = beautify_doc_string(value);
-                    let kind = if attr.is_doc_comment() {
-                        DocFragmentKind::SugaredDoc
-                    } else {
-                        DocFragmentKind::RawDoc
-                    };
-
-                    let line = doc_line;
-                    doc_line += value.lines().count();
-                    doc_strings.push(DocFragment {
-                        line,
-                        span: attr.span,
-                        doc: value,
-                        kind,
-                        parent_module,
-                    });
-
-                    if sp.is_none() {
-                        sp = Some(attr.span);
-                    }
-                    None
+        let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| {
+            if let Some(value) = attr.doc_str() {
+                trace!("got doc_str={:?}", value);
+                let value = beautify_doc_string(value);
+                let kind = if attr.is_doc_comment() {
+                    DocFragmentKind::SugaredDoc
                 } else {
-                    if attr.has_name(sym::doc) {
-                        if let Some(mi) = attr.meta() {
-                            if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
-                                // Extracted #[doc(cfg(...))]
-                                match Cfg::parse(cfg_mi) {
-                                    Ok(new_cfg) => cfg &= new_cfg,
-                                    Err(e) => diagnostic.span_err(e.span, e.msg),
-                                }
-                            } else if let Some((filename, contents)) =
-                                Attributes::extract_include(&mi)
-                            {
-                                let line = doc_line;
-                                doc_line += contents.lines().count();
-                                doc_strings.push(DocFragment {
-                                    line,
-                                    span: attr.span,
-                                    doc: contents,
-                                    kind: DocFragmentKind::Include { filename },
-                                    parent_module: parent_module,
-                                });
+                    DocFragmentKind::RawDoc
+                };
+
+                let line = doc_line;
+                doc_line += value.lines().count();
+                doc_strings.borrow_mut().push(DocFragment {
+                    line,
+                    span: attr.span,
+                    doc: value,
+                    kind,
+                    parent_module,
+                });
+
+                if sp.is_none() {
+                    sp = Some(attr.span);
+                }
+                None
+            } else {
+                if attr.has_name(sym::doc) {
+                    if let Some(mi) = attr.meta() {
+                        if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
+                            // Extracted #[doc(cfg(...))]
+                            match Cfg::parse(cfg_mi) {
+                                Ok(new_cfg) => cfg &= new_cfg,
+                                Err(e) => diagnostic.span_err(e.span, e.msg),
                             }
+                        } else if let Some((filename, contents)) = Attributes::extract_include(&mi)
+                        {
+                            let line = doc_line;
+                            doc_line += contents.lines().count();
+                            doc_strings.borrow_mut().push(DocFragment {
+                                line,
+                                span: attr.span,
+                                doc: contents,
+                                kind: DocFragmentKind::Include { filename },
+                                parent_module: parent_module,
+                            });
                         }
                     }
-                    Some(attr.clone())
                 }
+                Some(attr.clone())
+            }
+        };
+
+        // Additional documentation should be shown before the original documentation
+        let other_attrs = additional_attrs
+            .into_iter()
+            .map(|(attrs, id)| {
+                doc_strings.borrow_mut().push(DocFragment::divider());
+                attrs.iter().map(move |attr| (attr, Some(id)))
             })
+            .flatten()
+            .chain(attrs.iter().map(|attr| (attr, None)))
+            .filter_map(clean_attr)
             .collect();
 
         // treat #[target_feature(enable = "feat")] attributes as if they were
@@ -618,7 +640,7 @@ impl Attributes {
             .map_or(true, |a| a.style == AttrStyle::Inner);
 
         Attributes {
-            doc_strings,
+            doc_strings: doc_strings.into_inner(),
             other_attrs,
             cfg: if cfg == Cfg::True { None } else { Some(Arc::new(cfg)) },
             span: sp,