Skip to content

Commit f82d484

Browse files
committed
Pretty-print macro matchers instead of using source code
The output is not quite as nice as it used to be, but it does work.
1 parent f749d97 commit f82d484

File tree

6 files changed

+53
-62
lines changed

6 files changed

+53
-62
lines changed

Diff for: src/librustdoc/clean/inline.rs

+12-16
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ use rustc_metadata::creader::LoadedMacro;
1313
use rustc_middle::ty::{self, TyCtxt};
1414
use rustc_span::hygiene::MacroKind;
1515
use rustc_span::symbol::{kw, sym, Symbol};
16-
use rustc_span::Span;
1716

1817
use crate::clean::{
19-
self, Attributes, AttributesExt, FakeDefId, GetDefId, NestedAttributesExt, ToSource, Type,
18+
self, utils, Attributes, AttributesExt, FakeDefId, GetDefId, NestedAttributesExt, Type,
2019
};
2120
use crate::core::DocContext;
2221
use crate::formats::item_type::ItemType;
@@ -547,23 +546,20 @@ fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::Item
547546
let imported_from = cx.tcx.crate_name(did.krate);
548547
match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
549548
LoadedMacro::MacroDef(def, _) => {
550-
let matchers: Vec<Span> = if let ast::ItemKind::MacroDef(ref def) = def.kind {
549+
if let ast::ItemKind::MacroDef(ref def) = def.kind {
551550
let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
552-
tts.chunks(4).map(|arm| arm[0].span()).collect()
553-
} else {
554-
unreachable!()
555-
};
551+
let matchers = tts.chunks(4).map(|arm| &arm[0]);
556552

557-
let source = format!(
558-
"macro_rules! {} {{\n{}}}",
559-
name.clean(cx),
560-
matchers
561-
.iter()
562-
.map(|span| { format!(" {} => {{ ... }};\n", span.to_src(cx)) })
563-
.collect::<String>()
564-
);
553+
let source = format!(
554+
"macro_rules! {} {{\n{}}}",
555+
name.clean(cx),
556+
utils::render_macro_arms(matchers, ";")
557+
);
565558

566-
clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) })
559+
clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) })
560+
} else {
561+
unreachable!()
562+
}
567563
}
568564
LoadedMacro::ProcMacro(ext) => clean::ProcMacroItem(clean::ProcMacro {
569565
kind: ext.macro_kind(),

Diff for: src/librustdoc/clean/mod.rs

+6-15
Original file line numberDiff line numberDiff line change
@@ -2172,17 +2172,11 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
21722172
let (item, renamed) = self;
21732173
let name = renamed.unwrap_or(item.ident.name);
21742174
let tts = item.ast.body.inner_tokens().trees().collect::<Vec<_>>();
2175-
// Extract the spans of all matchers. They represent the "interface" of the macro.
2176-
let matchers = tts.chunks(4).map(|arm| arm[0].span()).collect::<Vec<_>>();
2175+
// Extract the macro's matchers. They represent the "interface" of the macro.
2176+
let matchers = tts.chunks(4).map(|arm| &arm[0]);
2177+
21772178
let source = if item.ast.macro_rules {
2178-
format!(
2179-
"macro_rules! {} {{\n{}}}",
2180-
name,
2181-
matchers
2182-
.iter()
2183-
.map(|span| { format!(" {} => {{ ... }};\n", span.to_src(cx)) })
2184-
.collect::<String>(),
2185-
)
2179+
format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";"))
21862180
} else {
21872181
let vis = item.vis.clean(cx);
21882182
let def_id = item.def_id.to_def_id();
@@ -2192,17 +2186,14 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
21922186
"{}macro {}{} {{\n ...\n}}",
21932187
vis.to_src_with_space(cx.tcx, def_id),
21942188
name,
2195-
matchers.iter().map(|span| span.to_src(cx)).collect::<String>(),
2189+
matchers.map(render_macro_matcher).collect::<String>(),
21962190
)
21972191
} else {
21982192
format!(
21992193
"{}macro {} {{\n{}}}",
22002194
vis.to_src_with_space(cx.tcx, def_id),
22012195
name,
2202-
matchers
2203-
.iter()
2204-
.map(|span| { format!(" {} => {{ ... }},\n", span.to_src(cx)) })
2205-
.collect::<String>(),
2196+
render_macro_arms(matchers, ","),
22062197
)
22072198
}
22082199
};

Diff for: src/librustdoc/clean/utils.rs

+21-16
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ use crate::clean::{
77
use crate::core::DocContext;
88
use crate::formats::item_type::ItemType;
99

10+
use rustc_ast::tokenstream::TokenTree;
1011
use rustc_hir as hir;
1112
use rustc_hir::def::{DefKind, Res};
1213
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1314
use rustc_middle::mir::interpret::ConstValue;
1415
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
1516
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
1617
use rustc_span::symbol::{kw, sym, Symbol};
18+
use std::fmt::Write as _;
1719
use std::mem;
1820

1921
#[cfg(test)]
@@ -248,22 +250,6 @@ crate fn build_deref_target_impls(cx: &mut DocContext<'_>, items: &[Item], ret:
248250
}
249251
}
250252

251-
crate trait ToSource {
252-
fn to_src(&self, cx: &DocContext<'_>) -> String;
253-
}
254-
255-
impl ToSource for rustc_span::Span {
256-
fn to_src(&self, cx: &DocContext<'_>) -> String {
257-
debug!("converting span {:?} to snippet", self);
258-
let sn = match cx.sess().source_map().span_to_snippet(*self) {
259-
Ok(x) => x,
260-
Err(_) => String::new(),
261-
};
262-
debug!("got snippet {}", sn);
263-
sn
264-
}
265-
}
266-
267253
crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
268254
use rustc_hir::*;
269255
debug!("trying to get a name from pattern: {:?}", p);
@@ -572,3 +558,22 @@ crate fn has_doc_flag(attrs: ty::Attributes<'_>, flag: Symbol) -> bool {
572558
///
573559
/// Set by `bootstrap::Builder::doc_rust_lang_org_channel` in order to keep tests passing on beta/stable.
574560
crate const DOC_RUST_LANG_ORG_CHANNEL: &'static str = env!("DOC_RUST_LANG_ORG_CHANNEL");
561+
562+
/// Render a sequence of macro arms in a format suitable for displaying to the user
563+
/// as part of an item declaration.
564+
pub(super) fn render_macro_arms<'a>(
565+
matchers: impl Iterator<Item = &'a TokenTree>,
566+
arm_delim: &str,
567+
) -> String {
568+
let mut out = String::new();
569+
for matcher in matchers {
570+
writeln!(out, " {} => {{ ... }}{}", render_macro_matcher(matcher), arm_delim).unwrap();
571+
}
572+
out
573+
}
574+
575+
/// Render a macro matcher in a format suitable for displaying to the user
576+
/// as part of an item declaration.
577+
pub(super) fn render_macro_matcher(matcher: &TokenTree) -> String {
578+
rustc_ast_pretty::pprust::tt_to_string(matcher)
579+
}

Diff for: src/test/rustdoc/decl_macro.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub macro my_macro() {
99

1010
}
1111

12-
// @has decl_macro/macro.my_macro_2.html //pre 'pub macro my_macro_2($($tok:tt)*) {'
12+
// @has decl_macro/macro.my_macro_2.html //pre 'pub macro my_macro_2($ ($ tok : tt) *) {'
1313
// @has - //pre '...'
1414
// @has - //pre '}'
1515
pub macro my_macro_2($($tok:tt)*) {
@@ -18,8 +18,8 @@ pub macro my_macro_2($($tok:tt)*) {
1818

1919
// @has decl_macro/macro.my_macro_multi.html //pre 'pub macro my_macro_multi {'
2020
// @has - //pre '(_) => { ... },'
21-
// @has - //pre '($foo:ident . $bar:expr) => { ... },'
22-
// @has - //pre '($($foo:literal),+) => { ... }'
21+
// @has - //pre '($ foo : ident.$ bar : expr) => { ... },'
22+
// @has - //pre '($ ($ foo : literal), +) => { ... },'
2323
// @has - //pre '}'
2424
pub macro my_macro_multi {
2525
(_) => {
@@ -33,7 +33,7 @@ pub macro my_macro_multi {
3333
}
3434
}
3535

36-
// @has decl_macro/macro.by_example_single.html //pre 'pub macro by_example_single($foo:expr) {'
36+
// @has decl_macro/macro.by_example_single.html //pre 'pub macro by_example_single($ foo : expr) {'
3737
// @has - //pre '...'
3838
// @has - //pre '}'
3939
pub macro by_example_single {
@@ -42,12 +42,12 @@ pub macro by_example_single {
4242

4343
mod a {
4444
mod b {
45-
// @has decl_macro/a/b/macro.by_example_vis.html //pre 'pub(super) macro by_example_vis($foo:expr) {'
45+
// @has decl_macro/a/b/macro.by_example_vis.html //pre 'pub(super) macro by_example_vis($ foo : expr) {'
4646
pub(in super) macro by_example_vis {
4747
($foo:expr) => {}
4848
}
4949
mod c {
50-
// @has decl_macro/a/b/c/macro.by_example_vis_named.html //pre 'pub(in a) macro by_example_vis_named($foo:expr) {'
50+
// @has decl_macro/a/b/c/macro.by_example_vis_named.html //pre 'pub(in a) macro by_example_vis_named($ foo : expr) {'
5151
pub(in a) macro by_example_vis_named {
5252
($foo:expr) => {}
5353
}

Diff for: src/test/rustdoc/macro_rules-matchers.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,15 @@
77
// @has - '//span[@class="macro"]' 'macro_rules!'
88
// @has - '//span[@class="ident"]' 'todo'
99
// Note: count = 2 * ('=' + '>') + '+' = 2 * (1 + 1) + 1 = 5
10-
// @count - '//span[@class="op"]' 5
10+
// @count - '//pre[@class="rust macro"]//span[@class="op"]' 5
1111

1212
// @has - '{ ()'
1313
// @has - '//span[@class="op"]' '='
1414
// @has - '//span[@class="op"]' '>'
1515
// @has - '{ ... };'
1616

17-
// @has - '($('
18-
// @has - '//span[@class="macro-nonterminal"]' '$'
19-
// @has - '//span[@class="macro-nonterminal"]' 'arg'
17+
// @has - '($ ($'
18+
// @has - '//span[@class="ident"]' 'arg'
2019
// @has - ':'
2120
// @has - '//span[@class="ident"]' 'tt'
2221
// @has - '//span[@class="op"]' '+'
@@ -28,7 +27,7 @@ mod mod1 {
2827
// @has - 'macro_rules!'
2928
// @has - 'macro1'
3029
// @has - '{ ()'
31-
// @has - '($('
30+
// @has - '($ ('
3231
// @has - 'arg'
3332
// @has - 'expr'
3433
// @has - ','

Diff for: src/test/rustdoc/macros.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @has macros/macro.my_macro.html //pre 'macro_rules! my_macro {'
22
// @has - //pre '() => { ... };'
3-
// @has - //pre '($a:tt) => { ... };'
4-
// @has - //pre '($e:expr) => { ... };'
3+
// @has - //pre '($ a : tt) => { ... };'
4+
// @has - //pre '($ e : expr) => { ... };'
55
#[macro_export]
66
macro_rules! my_macro {
77
() => [];
@@ -12,8 +12,8 @@ macro_rules! my_macro {
1212
// Check that exported macro defined in a module are shown at crate root.
1313
// @has macros/macro.my_sub_macro.html //pre 'macro_rules! my_sub_macro {'
1414
// @has - //pre '() => { ... };'
15-
// @has - //pre '($a:tt) => { ... };'
16-
// @has - //pre '($e:expr) => { ... };'
15+
// @has - //pre '($ a : tt) => { ... };'
16+
// @has - //pre '($ e : expr) => { ... };'
1717
mod sub {
1818
#[macro_export]
1919
macro_rules! my_sub_macro {

0 commit comments

Comments
 (0)