Skip to content

Commit 7b3585d

Browse files
authored
Unrolled build for rust-lang#120218
Rollup merge of rust-lang#120218 - compiler-errors:parse_macro_arg, r=calebcartwright,ytmimi rustfmt: Check that a token can begin a nonterminal kind before parsing it as a macro arg r? ``@ytmimi`` and/or ``@calebcartwright`` cc ``@fmease`` I'm putting this on r-l/rust since it should fix the nightly rustfmt version. If you don't care about having this regression until the next rustfmt->rust sync, then I can move that PR over to r-l/rustfmt. --- > Any idea why the formatting would have changed [from rust-lang#119099]? **Copied over explanation:** This has to do with the weirdness of the way that `parse_macro_arg` works. Unlike parsing nonterminal args in a macro-by-example, it eagerly tries, for example, to parse a type without checking that the beginning token may begin a type: https://github.com/rust-lang/rustfmt/blob/bf967319e258acb9b1648a952bba52665eceaf52/src/parse/macros/mod.rs#L54 Contrast this to the nonterminal parsing code, which first checks that the nonterminal may begin with a given token: https://github.com/rust-lang/rust/blob/ef71f1047e04438181d7cb925a833e2ada6ab390/compiler/rustc_parse/src/parser/nonterminal.rs#L47 In rust-lang#119099, ``@fmease`` implemented a change so that `const Tr` would be parsed as `dyn const Tr` (a trait object to a const trait) in edition 2015. This is okay for the purposes of macros, because he explicitly made sure that `const` did not get added to the list of tokens that may begin a `:ty` nonterminal kind: rust-lang#119099 (comment) However, since rustfmt is not so careful about eagerly parsing macro args before checking that they're legal in macro position, this changed the way that the string of tokens is being parsed into macro args.
2 parents 021861a + 5297433 commit 7b3585d

File tree

3 files changed

+29
-19
lines changed

3 files changed

+29
-19
lines changed

src/tools/rustfmt/src/parse/macros/mod.rs

+25-19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use rustc_ast::token::{Delimiter, TokenKind};
1+
use rustc_ast::token::{Delimiter, NonterminalKind, TokenKind};
22
use rustc_ast::tokenstream::TokenStream;
33
use rustc_ast::{ast, ptr};
4-
use rustc_parse::parser::{ForceCollect, Parser};
4+
use rustc_parse::parser::{ForceCollect, Parser, Recovery};
55
use rustc_parse::{stream_to_parser, MACRO_ARGUMENTS};
66
use rustc_session::parse::ParseSess;
77
use rustc_span::symbol::{self, kw};
@@ -15,7 +15,7 @@ pub(crate) mod cfg_if;
1515
pub(crate) mod lazy_static;
1616

1717
fn build_stream_parser<'a>(sess: &'a ParseSess, tokens: TokenStream) -> Parser<'a> {
18-
stream_to_parser(sess, tokens, MACRO_ARGUMENTS)
18+
stream_to_parser(sess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden)
1919
}
2020

2121
fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> {
@@ -24,45 +24,51 @@ fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser
2424

2525
fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> {
2626
macro_rules! parse_macro_arg {
27-
($macro_arg:ident, $parser:expr, $f:expr) => {
27+
($macro_arg:ident, $nt_kind:expr, $try_parse:expr, $then:expr) => {
2828
let mut cloned_parser = (*parser).clone();
29-
match $parser(&mut cloned_parser) {
30-
Ok(x) => {
31-
if parser.sess.dcx.has_errors().is_some() {
29+
if Parser::nonterminal_may_begin_with($nt_kind, &cloned_parser.token) {
30+
match $try_parse(&mut cloned_parser) {
31+
Ok(x) => {
32+
if parser.sess.dcx.has_errors().is_some() {
33+
parser.sess.dcx.reset_err_count();
34+
} else {
35+
// Parsing succeeded.
36+
*parser = cloned_parser;
37+
return Some(MacroArg::$macro_arg($then(x)?));
38+
}
39+
}
40+
Err(e) => {
41+
e.cancel();
3242
parser.sess.dcx.reset_err_count();
33-
} else {
34-
// Parsing succeeded.
35-
*parser = cloned_parser;
36-
return Some(MacroArg::$macro_arg($f(x)?));
3743
}
3844
}
39-
Err(e) => {
40-
e.cancel();
41-
parser.sess.dcx.reset_err_count();
42-
}
4345
}
4446
};
4547
}
4648

4749
parse_macro_arg!(
4850
Expr,
49-
|parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_expr(),
51+
NonterminalKind::Expr,
52+
|parser: &mut Parser<'b>| parser.parse_expr(),
5053
|x: ptr::P<ast::Expr>| Some(x)
5154
);
5255
parse_macro_arg!(
5356
Ty,
54-
|parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_ty(),
57+
NonterminalKind::Ty,
58+
|parser: &mut Parser<'b>| parser.parse_ty(),
5559
|x: ptr::P<ast::Ty>| Some(x)
5660
);
5761
parse_macro_arg!(
5862
Pat,
59-
|parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_pat_no_top_alt(None, None),
63+
NonterminalKind::PatParam { inferred: false },
64+
|parser: &mut Parser<'b>| parser.parse_pat_no_top_alt(None, None),
6065
|x: ptr::P<ast::Pat>| Some(x)
6166
);
6267
// `parse_item` returns `Option<ptr::P<ast::Item>>`.
6368
parse_macro_arg!(
6469
Item,
65-
|parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_item(ForceCollect::No),
70+
NonterminalKind::Item,
71+
|parser: &mut Parser<'b>| parser.parse_item(ForceCollect::No),
6672
|x: Option<ptr::P<ast::Item>>| x
6773
);
6874

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
m!(const N: usize = 0;);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
m!(
2+
const N: usize = 0;
3+
);

0 commit comments

Comments
 (0)