about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/clean/mod.rs7
-rw-r--r--src/librustdoc/doctree.rs1
-rw-r--r--src/librustdoc/visit_ast.rs4
-rw-r--r--src/test/rustdoc/macros.rs20
4 files changed, 30 insertions, 2 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 4ea834cce2d..f151e663407 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2663,15 +2663,18 @@ pub struct Macro {
 
 impl Clean<Item> for doctree::Macro {
     fn clean(&self, cx: &DocContext) -> Item {
+        let name = format!("{}!", self.name.clean(cx));
         Item {
-            name: Some(format!("{}!", self.name.clean(cx))),
+            name: Some(name.clone()),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
             visibility: hir::Public.clean(cx),
             stability: self.stab.clean(cx),
             def_id: cx.map.local_def_id(self.id),
             inner: MacroItem(Macro {
-                source: self.whence.to_src(cx),
+                source: format!("macro_rules! {} {{\n{}}}",
+                    name.trim_right_matches('!'), self.matchers.iter().map(|span|
+                        format!("    {} => {{ ... }};\n", span.to_src(cx))).collect::<String>()),
                 imported_from: self.imported_from.clean(cx),
             }),
         }
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 9550109fe9f..91da906f56d 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -213,6 +213,7 @@ pub struct Macro {
     pub id: ast::NodeId,
     pub attrs: Vec<ast::Attribute>,
     pub whence: Span,
+    pub matchers: Vec<Span>,
     pub stab: Option<attr::Stability>,
     pub imported_from: Option<Name>,
 }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 150464404a2..17291233e11 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -400,11 +400,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
 
     // convert each exported_macro into a doc item
     fn visit_macro(&self, def: &hir::MacroDef) -> Macro {
+        // Extract the spans of all matchers. They represent the "interface" of the macro.
+        let matchers = def.body.chunks(4).map(|arm| arm[0].get_span()).collect();
+
         Macro {
             id: def.id,
             attrs: def.attrs.clone(),
             name: def.name,
             whence: def.span,
+            matchers: matchers,
             stab: self.stability(def.id),
             imported_from: def.imported_from,
         }
diff --git a/src/test/rustdoc/macros.rs b/src/test/rustdoc/macros.rs
new file mode 100644
index 00000000000..b052ad2da2f
--- /dev/null
+++ b/src/test/rustdoc/macros.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// @has macros/macro.my_macro!.html //pre 'macro_rules! my_macro {'
+// @has - //pre '() => { ... };'
+// @has - //pre '($a:tt) => { ... };'
+// @has - //pre '($e:expr) => { ... };'
+#[macro_export]
+macro_rules! my_macro {
+    () => [];
+    ($a:tt) => ();
+    ($e:expr) => {};
+}