Skip to content

Commit 5e60845

Browse files
committed
Fix up the syntax tree for macro 2.0
1 parent 8f8f440 commit 5e60845

File tree

9 files changed

+218
-161
lines changed

9 files changed

+218
-161
lines changed

src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,30 @@ impl DeclarativeMacroExpander {
172172
),
173173
ast::Macro::MacroDef(macro_def) => (
174174
match macro_def.body() {
175-
Some(arg) => {
176-
let tt = mbe::syntax_node_to_token_tree(
177-
arg.syntax(),
175+
Some(body) => {
176+
let span =
177+
map.span_for_range(macro_def.macro_token().unwrap().text_range());
178+
let args = macro_def.args().map(|args| {
179+
mbe::syntax_node_to_token_tree(
180+
args.syntax(),
181+
map.as_ref(),
182+
span,
183+
DocCommentDesugarMode::Mbe,
184+
)
185+
});
186+
let body = mbe::syntax_node_to_token_tree(
187+
body.syntax(),
178188
map.as_ref(),
179-
map.span_for_range(macro_def.macro_token().unwrap().text_range()),
189+
span,
180190
DocCommentDesugarMode::Mbe,
181191
);
182192

183-
mbe::DeclarativeMacro::parse_macro2(&tt, edition, new_meta_vars)
193+
mbe::DeclarativeMacro::parse_macro2(
194+
args.as_ref(),
195+
&body,
196+
edition,
197+
new_meta_vars,
198+
)
184199
}
185200
None => mbe::DeclarativeMacro::from_err(mbe::ParseError::Expected(
186201
"expected a token tree".into(),

src/tools/rust-analyzer/crates/mbe/src/lib.rs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ impl DeclarativeMacro {
156156
let mut err = None;
157157

158158
while src.len() > 0 {
159-
let rule = match Rule::parse(edition, &mut src, true, new_meta_vars) {
159+
let rule = match Rule::parse(edition, &mut src, new_meta_vars) {
160160
Ok(it) => it,
161161
Err(e) => {
162162
err = Some(Box::new(e));
@@ -184,19 +184,34 @@ impl DeclarativeMacro {
184184

185185
/// The new, unstable `macro m {}` flavor.
186186
pub fn parse_macro2(
187-
tt: &tt::Subtree<Span>,
187+
args: Option<&tt::Subtree<Span>>,
188+
body: &tt::Subtree<Span>,
188189
edition: impl Copy + Fn(SyntaxContextId) -> Edition,
189190
// FIXME: Remove this once we drop support for rust 1.76 (defaults to true then)
190191
new_meta_vars: bool,
191192
) -> DeclarativeMacro {
192-
let mut src = TtIter::new(tt);
193193
let mut rules = Vec::new();
194194
let mut err = None;
195195

196-
if tt::DelimiterKind::Brace == tt.delimiter.kind {
196+
if let Some(args) = args {
197+
cov_mark::hit!(parse_macro_def_simple);
198+
199+
let rule = (|| {
200+
let lhs = MetaTemplate::parse_pattern(edition, args)?;
201+
let rhs = MetaTemplate::parse_template(edition, body, new_meta_vars)?;
202+
203+
Ok(crate::Rule { lhs, rhs })
204+
})();
205+
206+
match rule {
207+
Ok(rule) => rules.push(rule),
208+
Err(e) => err = Some(Box::new(e)),
209+
}
210+
} else {
197211
cov_mark::hit!(parse_macro_def_rules);
212+
let mut src = TtIter::new(body);
198213
while src.len() > 0 {
199-
let rule = match Rule::parse(edition, &mut src, true, new_meta_vars) {
214+
let rule = match Rule::parse(edition, &mut src, new_meta_vars) {
200215
Ok(it) => it,
201216
Err(e) => {
202217
err = Some(Box::new(e));
@@ -213,19 +228,6 @@ impl DeclarativeMacro {
213228
break;
214229
}
215230
}
216-
} else {
217-
cov_mark::hit!(parse_macro_def_simple);
218-
match Rule::parse(edition, &mut src, false, new_meta_vars) {
219-
Ok(rule) => {
220-
if src.len() != 0 {
221-
err = Some(Box::new(ParseError::expected("remaining tokens in macro def")));
222-
}
223-
rules.push(rule);
224-
}
225-
Err(e) => {
226-
err = Some(Box::new(e));
227-
}
228-
}
229231
}
230232

231233
for Rule { lhs, .. } in &rules {
@@ -262,14 +264,11 @@ impl Rule {
262264
fn parse(
263265
edition: impl Copy + Fn(SyntaxContextId) -> Edition,
264266
src: &mut TtIter<'_, Span>,
265-
expect_arrow: bool,
266267
new_meta_vars: bool,
267268
) -> Result<Self, ParseError> {
268269
let lhs = src.expect_subtree().map_err(|()| ParseError::expected("expected subtree"))?;
269-
if expect_arrow {
270-
src.expect_char('=').map_err(|()| ParseError::expected("expected `=`"))?;
271-
src.expect_char('>').map_err(|()| ParseError::expected("expected `>`"))?;
272-
}
270+
src.expect_char('=').map_err(|()| ParseError::expected("expected `=`"))?;
271+
src.expect_char('>').map_err(|()| ParseError::expected("expected `>`"))?;
273272
let rhs = src.expect_subtree().map_err(|()| ParseError::expected("expected subtree"))?;
274273

275274
let lhs = MetaTemplate::parse_pattern(edition, lhs)?;

src/tools/rust-analyzer/crates/parser/src/grammar/items.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,13 +372,11 @@ fn macro_def(p: &mut Parser<'_>, m: Marker) {
372372
// macro m { ($i:ident) => {} }
373373
token_tree(p);
374374
} else if p.at(T!['(']) {
375-
let m = p.start();
376375
token_tree(p);
377376
match p.current() {
378377
T!['{'] | T!['['] | T!['('] => token_tree(p),
379378
_ => p.error("expected `{`, `[`, `(`"),
380379
}
381-
m.complete(p, TOKEN_TREE);
382380
} else {
383381
p.error("unmatched `(`");
384382
}

src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0147_macro_def.rast

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ SOURCE_FILE
55
NAME
66
IDENT "m"
77
TOKEN_TREE
8-
TOKEN_TREE
9-
L_PAREN "("
10-
DOLLAR "$"
11-
IDENT "i"
12-
COLON ":"
13-
IDENT "ident"
14-
R_PAREN ")"
15-
WHITESPACE " "
16-
TOKEN_TREE
17-
L_CURLY "{"
18-
R_CURLY "}"
8+
L_PAREN "("
9+
DOLLAR "$"
10+
IDENT "i"
11+
COLON ":"
12+
IDENT "ident"
13+
R_PAREN ")"
14+
WHITESPACE " "
15+
TOKEN_TREE
16+
L_CURLY "{"
17+
R_CURLY "}"
1918
WHITESPACE "\n"

src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0012_visibility.rast

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,15 @@ SOURCE_FILE
3939
NAME
4040
IDENT "m"
4141
TOKEN_TREE
42-
TOKEN_TREE
43-
L_PAREN "("
44-
DOLLAR "$"
45-
COLON ":"
46-
IDENT "ident"
47-
R_PAREN ")"
48-
WHITESPACE " "
49-
TOKEN_TREE
50-
L_CURLY "{"
51-
R_CURLY "}"
42+
L_PAREN "("
43+
DOLLAR "$"
44+
COLON ":"
45+
IDENT "ident"
46+
R_PAREN ")"
47+
WHITESPACE " "
48+
TOKEN_TREE
49+
L_CURLY "{"
50+
R_CURLY "}"
5251
WHITESPACE "\n"
5352
FN
5453
VISIBILITY

0 commit comments

Comments
 (0)