Skip to content

Commit b92320c

Browse files
committedJan 22, 2024
Check that a token can begin a nonterminal kind before parsing it as a macro arg in rustfmt
1 parent 255d2cf commit b92320c

File tree

3 files changed

+28
-17
lines changed

3 files changed

+28
-17
lines changed
 

‎src/parse/macros/mod.rs

+24-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_ast::token::{Delimiter, 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};
@@ -24,45 +24,52 @@ 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, $can_begin: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 $can_begin(&mut cloned_parser) {
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+
|parser: &mut Parser<'b>| parser.token.can_begin_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+
|parser: &mut Parser<'b>| parser.token.can_begin_type(),
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+
// FIXME: This isn't right
64+
|_| true,
65+
|parser: &mut Parser<'b>| parser.parse_pat_no_top_alt(None, None),
6066
|x: ptr::P<ast::Pat>| Some(x)
6167
);
6268
// `parse_item` returns `Option<ptr::P<ast::Item>>`.
6369
parse_macro_arg!(
6470
Item,
65-
|parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_item(ForceCollect::No),
71+
|_| true,
72+
|parser: &mut Parser<'b>| parser.parse_item(ForceCollect::No),
6673
|x: Option<ptr::P<ast::Item>>| x
6774
);
6875

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)