about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-04-07 11:08:21 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-04-07 17:54:34 -0700
commit0f3183f42b02aee06e920dec18b0f4d1c93e6a77 (patch)
tree56ccbe0bb41163c2300892f8131f00ab0c9b40c1
parentec412c2a94cec88f7c9d4bbdd793c3407c6871f7 (diff)
downloadrust-0f3183f42b02aee06e920dec18b0f4d1c93e6a77.tar.gz
rust-0f3183f42b02aee06e920dec18b0f4d1c93e6a77.zip
rustdoc: Don't duplicate inlined impl blocks
Closes #21474
-rw-r--r--src/librustdoc/visit_ast.rs16
-rw-r--r--src/test/rustdoc/issue-21474.rs21
2 files changed, 35 insertions, 2 deletions
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 3f813b30ecc..6ed6626d64c 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -12,6 +12,7 @@
 //! usable for clean
 
 use std::collections::HashSet;
+use std::mem;
 
 use syntax::abi;
 use syntax::ast;
@@ -40,6 +41,7 @@ pub struct RustdocVisitor<'a, 'tcx: 'a> {
     pub cx: &'a core::DocContext<'tcx>,
     pub analysis: Option<&'a core::CrateAnalysis>,
     view_item_stack: HashSet<ast::NodeId>,
+    inlining_from_glob: bool,
 }
 
 impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
@@ -54,6 +56,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             cx: cx,
             analysis: analysis,
             view_item_stack: stack,
+            inlining_from_glob: false,
         }
     }
 
@@ -209,6 +212,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         let ret = match tcx.map.get(def.node) {
             ast_map::NodeItem(it) => {
                 if glob {
+                    let prev = mem::replace(&mut self.inlining_from_glob, true);
                     match it.node {
                         ast::ItemMod(ref m) => {
                             for i in &m.items {
@@ -218,6 +222,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                         ast::ItemEnum(..) => {}
                         _ => { panic!("glob not mapped to a module or enum"); }
                     }
+                    self.inlining_from_glob = prev;
                 } else {
                     self.visit_item(it, renamed, om);
                 }
@@ -356,7 +361,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     vis: item.vis,
                     stab: self.stability(item.id),
                 };
-                om.impls.push(i);
+                // Don't duplicate impls when inlining glob imports, we'll pick
+                // them up regardless of where they're located.
+                if !self.inlining_from_glob {
+                    om.impls.push(i);
+                }
             },
             ast::ItemDefaultImpl(unsafety, ref trait_ref) => {
                 let i = DefaultImpl {
@@ -366,7 +375,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     attrs: item.attrs.clone(),
                     whence: item.span,
                 };
-                om.def_traits.push(i);
+                // see comment above about ItemImpl
+                if !self.inlining_from_glob {
+                    om.def_traits.push(i);
+                }
             }
             ast::ItemForeignMod(ref fm) => {
                 om.foreigns.push(fm.clone());
diff --git a/src/test/rustdoc/issue-21474.rs b/src/test/rustdoc/issue-21474.rs
new file mode 100644
index 00000000000..36f160acf1c
--- /dev/null
+++ b/src/test/rustdoc/issue-21474.rs
@@ -0,0 +1,21 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub use inner::*;
+
+mod inner {
+    impl super::Blah for super::What { }
+}
+
+pub trait Blah { }
+
+// @count issue_21474/struct.What.html \
+//        '//*[@class="impl"]' 1
+pub struct What;