Skip to content

Commit 770f532

Browse files
authored
Rollup merge of rust-lang#92334 - dtolnay:rustdocmatcher, r=camelid,GuillaumeGomez
rustdoc: Preserve rendering of macro_rules matchers when possible Fixes rust-lang#92331. This approach restores the behavior prior to rust-lang#86282 **if** the matcher token held by the compiler **and** the matcher token found in the source code are identical TokenTrees. Thus rust-lang#86208 remains fixed, but without regressing formatting for the vast majority of macros which are not macro-generated.
2 parents 801a3b6 + 0f8415b commit 770f532

File tree

6 files changed

+85
-22
lines changed

6 files changed

+85
-22
lines changed

src/librustdoc/clean/utils.rs

+55-6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1717
use rustc_middle::mir::interpret::ConstValue;
1818
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
1919
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
20+
use rustc_session::parse::ParseSess;
21+
use rustc_span::source_map::FilePathMapping;
2022
use rustc_span::symbol::{kw, sym, Symbol};
2123
use std::fmt::Write as _;
2224
use std::mem;
@@ -486,20 +488,67 @@ crate const DOC_RUST_LANG_ORG_CHANNEL: &str = env!("DOC_RUST_LANG_ORG_CHANNEL");
486488
/// Render a sequence of macro arms in a format suitable for displaying to the user
487489
/// as part of an item declaration.
488490
pub(super) fn render_macro_arms<'a>(
491+
tcx: TyCtxt<'_>,
489492
matchers: impl Iterator<Item = &'a TokenTree>,
490493
arm_delim: &str,
491494
) -> String {
492495
let mut out = String::new();
493496
for matcher in matchers {
494-
writeln!(out, " {} => {{ ... }}{}", render_macro_matcher(matcher), arm_delim).unwrap();
497+
writeln!(out, " {} => {{ ... }}{}", render_macro_matcher(tcx, matcher), arm_delim)
498+
.unwrap();
495499
}
496500
out
497501
}
498502

499503
/// Render a macro matcher in a format suitable for displaying to the user
500504
/// as part of an item declaration.
501-
pub(super) fn render_macro_matcher(matcher: &TokenTree) -> String {
502-
rustc_ast_pretty::pprust::tt_to_string(matcher)
505+
pub(super) fn render_macro_matcher(tcx: TyCtxt<'_>, matcher: &TokenTree) -> String {
506+
if let Some(snippet) = snippet_equal_to_token(tcx, matcher) {
507+
snippet
508+
} else {
509+
rustc_ast_pretty::pprust::tt_to_string(matcher)
510+
}
511+
}
512+
513+
/// Find the source snippet for this token's Span, reparse it, and return the
514+
/// snippet if the reparsed TokenTree matches the argument TokenTree.
515+
fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String> {
516+
// Find what rustc thinks is the source snippet.
517+
// This may not actually be anything meaningful if this matcher was itself
518+
// generated by a macro.
519+
let source_map = tcx.sess.source_map();
520+
let span = matcher.span();
521+
let snippet = source_map.span_to_snippet(span).ok()?;
522+
523+
// Create a Parser.
524+
let sess = ParseSess::new(FilePathMapping::empty());
525+
let file_name = source_map.span_to_filename(span);
526+
let mut parser =
527+
match rustc_parse::maybe_new_parser_from_source_str(&sess, file_name, snippet.clone()) {
528+
Ok(parser) => parser,
529+
Err(diagnostics) => {
530+
for mut diagnostic in diagnostics {
531+
diagnostic.cancel();
532+
}
533+
return None;
534+
}
535+
};
536+
537+
// Reparse a single token tree.
538+
let mut reparsed_trees = match parser.parse_all_token_trees() {
539+
Ok(reparsed_trees) => reparsed_trees,
540+
Err(mut diagnostic) => {
541+
diagnostic.cancel();
542+
return None;
543+
}
544+
};
545+
if reparsed_trees.len() != 1 {
546+
return None;
547+
}
548+
let reparsed_tree = reparsed_trees.pop().unwrap();
549+
550+
// Compare against the original tree.
551+
if reparsed_tree.eq_unspanned(matcher) { Some(snippet) } else { None }
503552
}
504553

505554
pub(super) fn display_macro_source(
@@ -514,21 +563,21 @@ pub(super) fn display_macro_source(
514563
let matchers = tts.chunks(4).map(|arm| &arm[0]);
515564

516565
if def.macro_rules {
517-
format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";"))
566+
format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(cx.tcx, matchers, ";"))
518567
} else {
519568
if matchers.len() <= 1 {
520569
format!(
521570
"{}macro {}{} {{\n ...\n}}",
522571
vis.to_src_with_space(cx.tcx, def_id),
523572
name,
524-
matchers.map(render_macro_matcher).collect::<String>(),
573+
matchers.map(|matcher| render_macro_matcher(cx.tcx, matcher)).collect::<String>(),
525574
)
526575
} else {
527576
format!(
528577
"{}macro {} {{\n{}}}",
529578
vis.to_src_with_space(cx.tcx, def_id),
530579
name,
531-
render_macro_arms(matchers, ","),
580+
render_macro_arms(cx.tcx, matchers, ","),
532581
)
533582
}
534583
}

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
}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
macro_rules! outer {
2+
($($matcher:tt)*) => {
3+
#[macro_export]
4+
macro_rules! inner {
5+
(<= $($matcher)* =>) => {};
6+
}
7+
}
8+
}
9+
10+
// @has macro_generated_macro/macro.inner.html //pre 'macro_rules! inner {'
11+
// @has - //pre '(<= type $($i : ident) :: * + $e : expr =>) => { ... };'
12+
outer!(type $($i:ident)::* + $e:expr);
13+
14+
inner!(<= type foo::bar + x.sort() =>);

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 {

src/test/rustdoc/reexports-priv.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
extern crate reexports;
77

8-
// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
8+
// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place:expr) {'
99
pub use reexports::addr_of;
1010
// @!has 'foo/macro.addr_of_crate.html'
1111
pub(crate) use reexports::addr_of_crate;
@@ -61,11 +61,11 @@ use reexports::UnionLocal;
6161

6262
pub mod outer {
6363
pub mod inner {
64-
// @has 'foo/outer/inner/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
64+
// @has 'foo/outer/inner/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place:expr) {'
6565
pub use reexports::addr_of;
66-
// @has 'foo/outer/inner/macro.addr_of_crate.html' '//*[@class="docblock item-decl"]' 'pub(crate) macro addr_of_crate($place : expr) {'
66+
// @has 'foo/outer/inner/macro.addr_of_crate.html' '//*[@class="docblock item-decl"]' 'pub(crate) macro addr_of_crate($place:expr) {'
6767
pub(crate) use reexports::addr_of_crate;
68-
// @has 'foo/outer/inner/macro.addr_of_super.html' '//*[@class="docblock item-decl"]' 'pub(in outer) macro addr_of_super($place : expr) {'
68+
// @has 'foo/outer/inner/macro.addr_of_super.html' '//*[@class="docblock item-decl"]' 'pub(in outer) macro addr_of_super($place:expr) {'
6969
pub(super) use reexports::addr_of_super;
7070
// @!has 'foo/outer/inner/macro.addr_of_self.html'
7171
pub(self) use reexports::addr_of_self;

src/test/rustdoc/reexports.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
extern crate reexports;
66

7-
// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
7+
// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place:expr) {'
88
pub use reexports::addr_of;
99
// @!has 'foo/macro.addr_of_crate.html'
1010
pub(crate) use reexports::addr_of_crate;
@@ -60,7 +60,7 @@ use reexports::UnionLocal;
6060

6161
pub mod outer {
6262
pub mod inner {
63-
// @has 'foo/outer/inner/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
63+
// @has 'foo/outer/inner/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place:expr) {'
6464
pub use reexports::addr_of;
6565
// @!has 'foo/outer/inner/macro.addr_of_crate.html'
6666
pub(crate) use reexports::addr_of_crate;

0 commit comments

Comments
 (0)