about summary refs log tree commit diff
path: root/src/librustdoc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-07-05 05:09:35 +0000
committerbors <bors@rust-lang.org>2021-07-05 05:09:35 +0000
commit09d9b608d647fdc19a933c661f943a010c8d84a5 (patch)
tree7359a589e6c9ddae2b858fb1ef13b9c5ede1f697 /src/librustdoc
parent44860d13fa866d002a5f29a4684dad29ff268af9 (diff)
parent7ffec7028a54aeed6076f7043734b682fdf68f6e (diff)
Auto merge of #86282 - camelid:macro_rules-matchers, r=jyn514
Pretty-print macro matchers instead of using source code

Fixes #86208.
Diffstat (limited to 'src/librustdoc')
-rw-r--r--src/librustdoc/clean/inline.rs28
-rw-r--r--src/librustdoc/clean/mod.rs21
-rw-r--r--src/librustdoc/clean/utils.rs37
3 files changed, 39 insertions, 47 deletions
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 829b54f1fc1..7b1b23ff8e6 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -13,10 +13,9 @@ use rustc_metadata::creader::LoadedMacro;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
 
 use crate::clean::{
-    self, Attributes, AttributesExt, FakeDefId, GetDefId, NestedAttributesExt, ToSource, Type,
+    self, utils, Attributes, AttributesExt, FakeDefId, GetDefId, NestedAttributesExt, Type,
 };
 use crate::core::DocContext;
 use crate::formats::item_type::ItemType;
@@ -547,23 +546,20 @@ fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::Item
     let imported_from = cx.tcx.crate_name(did.krate);
     match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
         LoadedMacro::MacroDef(def, _) => {
-            let matchers: Vec<Span> = if let ast::ItemKind::MacroDef(ref def) = def.kind {
+            if let ast::ItemKind::MacroDef(ref def) = def.kind {
                 let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
-                tts.chunks(4).map(|arm| arm[0].span()).collect()
-            } else {
-                unreachable!()
-            };
+                let matchers = tts.chunks(4).map(|arm| &arm[0]);
 
-            let source = format!(
-                "macro_rules! {} {{\n{}}}",
-                name.clean(cx),
-                matchers
-                    .iter()
-                    .map(|span| { format!("    {} => {{ ... }};\n", span.to_src(cx)) })
-                    .collect::<String>()
-            );
+                let source = format!(
+                    "macro_rules! {} {{\n{}}}",
+                    name.clean(cx),
+                    utils::render_macro_arms(matchers, ";")
+                );
 
-            clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) })
+                clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) })
+            } else {
+                unreachable!()
+            }
         }
         LoadedMacro::ProcMacro(ext) => clean::ProcMacroItem(clean::ProcMacro {
             kind: ext.macro_kind(),
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 6abe1c7cd61..b0e75493aa4 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2172,17 +2172,11 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
         let (item, renamed) = self;
         let name = renamed.unwrap_or(item.ident.name);
         let tts = item.ast.body.inner_tokens().trees().collect::<Vec<_>>();
-        // Extract the spans of all matchers. They represent the "interface" of the macro.
-        let matchers = tts.chunks(4).map(|arm| arm[0].span()).collect::<Vec<_>>();
+        // Extract the macro's matchers. They represent the "interface" of the macro.
+        let matchers = tts.chunks(4).map(|arm| &arm[0]);
+
         let source = if item.ast.macro_rules {
-            format!(
-                "macro_rules! {} {{\n{}}}",
-                name,
-                matchers
-                    .iter()
-                    .map(|span| { format!("    {} => {{ ... }};\n", span.to_src(cx)) })
-                    .collect::<String>(),
-            )
+            format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";"))
         } else {
             let vis = item.vis.clean(cx);
             let def_id = item.def_id.to_def_id();
@@ -2192,17 +2186,14 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
                     "{}macro {}{} {{\n    ...\n}}",
                     vis.to_src_with_space(cx.tcx, def_id),
                     name,
-                    matchers.iter().map(|span| span.to_src(cx)).collect::<String>(),
+                    matchers.map(render_macro_matcher).collect::<String>(),
                 )
             } else {
                 format!(
                     "{}macro {} {{\n{}}}",
                     vis.to_src_with_space(cx.tcx, def_id),
                     name,
-                    matchers
-                        .iter()
-                        .map(|span| { format!("    {} => {{ ... }},\n", span.to_src(cx)) })
-                        .collect::<String>(),
+                    render_macro_arms(matchers, ","),
                 )
             }
         };
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index f70ccdd63f9..fb46b81102c 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -7,6 +7,7 @@ use crate::clean::{
 use crate::core::DocContext;
 use crate::formats::item_type::ItemType;
 
+use rustc_ast::tokenstream::TokenTree;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
@@ -14,6 +15,7 @@ use rustc_middle::mir::interpret::ConstValue;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
 use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 use rustc_span::symbol::{kw, sym, Symbol};
+use std::fmt::Write as _;
 use std::mem;
 
 #[cfg(test)]
@@ -248,22 +250,6 @@ crate fn build_deref_target_impls(cx: &mut DocContext<'_>, items: &[Item], ret:
     }
 }
 
-crate trait ToSource {
-    fn to_src(&self, cx: &DocContext<'_>) -> String;
-}
-
-impl ToSource for rustc_span::Span {
-    fn to_src(&self, cx: &DocContext<'_>) -> String {
-        debug!("converting span {:?} to snippet", self);
-        let sn = match cx.sess().source_map().span_to_snippet(*self) {
-            Ok(x) => x,
-            Err(_) => String::new(),
-        };
-        debug!("got snippet {}", sn);
-        sn
-    }
-}
-
 crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
     use rustc_hir::*;
     debug!("trying to get a name from pattern: {:?}", p);
@@ -572,3 +558,22 @@ crate fn has_doc_flag(attrs: ty::Attributes<'_>, flag: Symbol) -> bool {
 ///
 /// Set by `bootstrap::Builder::doc_rust_lang_org_channel` in order to keep tests passing on beta/stable.
 crate const DOC_RUST_LANG_ORG_CHANNEL: &'static str = env!("DOC_RUST_LANG_ORG_CHANNEL");
+
+/// Render a sequence of macro arms in a format suitable for displaying to the user
+/// as part of an item declaration.
+pub(super) fn render_macro_arms<'a>(
+    matchers: impl Iterator<Item = &'a TokenTree>,
+    arm_delim: &str,
+) -> String {
+    let mut out = String::new();
+    for matcher in matchers {
+        writeln!(out, "    {} => {{ ... }}{}", render_macro_matcher(matcher), arm_delim).unwrap();
+    }
+    out
+}
+
+/// Render a macro matcher in a format suitable for displaying to the user
+/// as part of an item declaration.
+pub(super) fn render_macro_matcher(matcher: &TokenTree) -> String {
+    rustc_ast_pretty::pprust::tt_to_string(matcher)
+}