Skip to content

Commit 546eb6b

Browse files
committed
Test macros doing edition dependent parsing
1 parent 2c32ee7 commit 546eb6b

File tree

8 files changed

+92
-62
lines changed

8 files changed

+92
-62
lines changed

crates/hir-def/src/macro_expansion_tests/mbe.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,3 +1921,59 @@ fn f() {
19211921
"#]],
19221922
);
19231923
}
1924+
1925+
#[test]
1926+
fn test_edition_handling_out() {
1927+
check(
1928+
r#"
1929+
//- /main.rs crate:main deps:old edition:2021
1930+
macro_rules! r#try {
1931+
($it:expr) => {
1932+
$it?
1933+
};
1934+
}
1935+
fn f() {
1936+
old::invoke_bare_try!(0);
1937+
}
1938+
//- /old.rs crate:old edition:2015
1939+
#[macro_export]
1940+
macro_rules! invoke_bare_try {
1941+
($it:expr) => {
1942+
try!($it)
1943+
};
1944+
}
1945+
"#,
1946+
expect![[r#"
1947+
macro_rules! r#try {
1948+
($it:expr) => {
1949+
$it?
1950+
};
1951+
}
1952+
fn f() {
1953+
try!(0);
1954+
}
1955+
"#]],
1956+
);
1957+
}
1958+
1959+
#[test]
1960+
fn test_edition_handling_in() {
1961+
check(
1962+
r#"
1963+
//- /main.rs crate:main deps:old edition:2021
1964+
fn f() {
1965+
old::parse_try_old!(try!{});
1966+
}
1967+
//- /old.rs crate:old edition:2015
1968+
#[macro_export]
1969+
macro_rules! parse_try_old {
1970+
($it:expr) => {};
1971+
}
1972+
"#,
1973+
expect![[r#"
1974+
fn f() {
1975+
;
1976+
}
1977+
"#]],
1978+
);
1979+
}

crates/hir-expand/src/db.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ fn parse_macro_expansion(
348348
) -> ExpandResult<(Parse<SyntaxNode>, Arc<ExpansionSpanMap>)> {
349349
let _p = tracing::info_span!("parse_macro_expansion").entered();
350350
let loc = db.lookup_intern_macro_call(macro_file.macro_call_id);
351-
let edition = loc.def.edition;
351+
let def_edition = loc.def.edition;
352352
let expand_to = loc.expand_to();
353353
let mbe::ValueResult { value: (tt, matched_arm), err } =
354354
macro_expand(db, macro_file.macro_call_id, loc);
@@ -359,7 +359,7 @@ fn parse_macro_expansion(
359359
CowArc::Owned(it) => it,
360360
},
361361
expand_to,
362-
edition,
362+
def_edition,
363363
);
364364
rev_token_map.matched_arm = matched_arm;
365365

crates/hir-expand/src/declarative.rs

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,7 @@ impl DeclarativeMacroExpander {
129129
_ => None,
130130
}
131131
};
132-
let toolchain = db.toolchain(def_crate);
133-
let new_meta_vars = toolchain.as_ref().map_or(false, |version| {
134-
REQUIREMENT.get_or_init(|| VersionReq::parse(">=1.76").unwrap()).matches(
135-
&base_db::Version {
136-
pre: base_db::Prerelease::EMPTY,
137-
build: base_db::BuildMetadata::EMPTY,
138-
major: version.major,
139-
minor: version.minor,
140-
patch: version.patch,
141-
},
142-
)
143-
});
144-
145-
let edition = |ctx: SyntaxContextId| {
132+
let ctx_edition = |ctx: SyntaxContextId| {
146133
let crate_graph = db.crate_graph();
147134
if ctx.is_root() {
148135
crate_graph[def_crate].edition
@@ -165,7 +152,7 @@ impl DeclarativeMacroExpander {
165152
DocCommentDesugarMode::Mbe,
166153
);
167154

168-
mbe::DeclarativeMacro::parse_macro_rules(&tt, edition, new_meta_vars)
155+
mbe::DeclarativeMacro::parse_macro_rules(&tt, ctx_edition)
169156
}
170157
None => mbe::DeclarativeMacro::from_err(mbe::ParseError::Expected(
171158
"expected a token tree".into(),
@@ -193,12 +180,7 @@ impl DeclarativeMacroExpander {
193180
DocCommentDesugarMode::Mbe,
194181
);
195182

196-
mbe::DeclarativeMacro::parse_macro2(
197-
args.as_ref(),
198-
&body,
199-
edition,
200-
new_meta_vars,
201-
)
183+
mbe::DeclarativeMacro::parse_macro2(args.as_ref(), &body, ctx_edition)
202184
}
203185
None => mbe::DeclarativeMacro::from_err(mbe::ParseError::Expected(
204186
"expected a token tree".into(),

crates/mbe/src/benchmark.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ fn benchmark_parse_macro_rules() {
2525
rules
2626
.values()
2727
.map(|it| {
28-
DeclarativeMacro::parse_macro_rules(it, |_| span::Edition::CURRENT, true)
29-
.rules
30-
.len()
28+
DeclarativeMacro::parse_macro_rules(it, |_| span::Edition::CURRENT).rules.len()
3129
})
3230
.sum()
3331
};
@@ -59,9 +57,7 @@ fn benchmark_expand_macro_rules() {
5957
fn macro_rules_fixtures() -> FxHashMap<String, DeclarativeMacro> {
6058
macro_rules_fixtures_tt()
6159
.into_iter()
62-
.map(|(id, tt)| {
63-
(id, DeclarativeMacro::parse_macro_rules(&tt, |_| span::Edition::CURRENT, true))
64-
})
60+
.map(|(id, tt)| (id, DeclarativeMacro::parse_macro_rules(&tt, |_| span::Edition::CURRENT)))
6561
.collect()
6662
}
6763

crates/mbe/src/lib.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,7 @@ impl DeclarativeMacro {
144144
/// The old, `macro_rules! m {}` flavor.
145145
pub fn parse_macro_rules(
146146
tt: &tt::Subtree<Span>,
147-
edition: impl Copy + Fn(SyntaxContextId) -> Edition,
148-
// FIXME: Remove this once we drop support for rust 1.76 (defaults to true then)
149-
new_meta_vars: bool,
147+
ctx_edition: impl Copy + Fn(SyntaxContextId) -> Edition,
150148
) -> DeclarativeMacro {
151149
// Note: this parsing can be implemented using mbe machinery itself, by
152150
// matching against `$($lhs:tt => $rhs:tt);*` pattern, but implementing
@@ -156,7 +154,7 @@ impl DeclarativeMacro {
156154
let mut err = None;
157155

158156
while src.len() > 0 {
159-
let rule = match Rule::parse(edition, &mut src, new_meta_vars) {
157+
let rule = match Rule::parse(ctx_edition, &mut src) {
160158
Ok(it) => it,
161159
Err(e) => {
162160
err = Some(Box::new(e));
@@ -186,9 +184,7 @@ impl DeclarativeMacro {
186184
pub fn parse_macro2(
187185
args: Option<&tt::Subtree<Span>>,
188186
body: &tt::Subtree<Span>,
189-
edition: impl Copy + Fn(SyntaxContextId) -> Edition,
190-
// FIXME: Remove this once we drop support for rust 1.76 (defaults to true then)
191-
new_meta_vars: bool,
187+
ctx_edition: impl Copy + Fn(SyntaxContextId) -> Edition,
192188
) -> DeclarativeMacro {
193189
let mut rules = Vec::new();
194190
let mut err = None;
@@ -197,8 +193,8 @@ impl DeclarativeMacro {
197193
cov_mark::hit!(parse_macro_def_simple);
198194

199195
let rule = (|| {
200-
let lhs = MetaTemplate::parse_pattern(edition, args)?;
201-
let rhs = MetaTemplate::parse_template(edition, body, new_meta_vars)?;
196+
let lhs = MetaTemplate::parse_pattern(ctx_edition, args)?;
197+
let rhs = MetaTemplate::parse_template(ctx_edition, body)?;
202198

203199
Ok(crate::Rule { lhs, rhs })
204200
})();
@@ -211,7 +207,7 @@ impl DeclarativeMacro {
211207
cov_mark::hit!(parse_macro_def_rules);
212208
let mut src = TtIter::new(body);
213209
while src.len() > 0 {
214-
let rule = match Rule::parse(edition, &mut src, new_meta_vars) {
210+
let rule = match Rule::parse(ctx_edition, &mut src) {
215211
Ok(it) => it,
216212
Err(e) => {
217213
err = Some(Box::new(e));
@@ -264,15 +260,14 @@ impl Rule {
264260
fn parse(
265261
edition: impl Copy + Fn(SyntaxContextId) -> Edition,
266262
src: &mut TtIter<'_, Span>,
267-
new_meta_vars: bool,
268263
) -> Result<Self, ParseError> {
269264
let lhs = src.expect_subtree().map_err(|()| ParseError::expected("expected subtree"))?;
270265
src.expect_char('=').map_err(|()| ParseError::expected("expected `=`"))?;
271266
src.expect_char('>').map_err(|()| ParseError::expected("expected `>`"))?;
272267
let rhs = src.expect_subtree().map_err(|()| ParseError::expected("expected subtree"))?;
273268

274269
let lhs = MetaTemplate::parse_pattern(edition, lhs)?;
275-
let rhs = MetaTemplate::parse_template(edition, rhs, new_meta_vars)?;
270+
let rhs = MetaTemplate::parse_template(edition, rhs)?;
276271

277272
Ok(crate::Rule { lhs, rhs })
278273
}
@@ -367,7 +362,7 @@ fn expect_fragment<S: Copy + fmt::Debug>(
367362
) -> ExpandResult<Option<tt::TokenTree<S>>> {
368363
use ::parser;
369364
let buffer = tt::buffer::TokenBuffer::from_tokens(tt_iter.as_slice());
370-
let parser_input = to_parser_input::to_parser_input(&buffer);
365+
let parser_input = to_parser_input::to_parser_input(edition, &buffer);
371366
let tree_traversal = entry_point.parse(&parser_input, edition);
372367
let mut cursor = buffer.begin();
373368
let mut error = false;

crates/mbe/src/parser.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,14 @@ impl MetaTemplate {
3131
edition: impl Copy + Fn(SyntaxContextId) -> Edition,
3232
pattern: &tt::Subtree<Span>,
3333
) -> Result<Self, ParseError> {
34-
MetaTemplate::parse(edition, pattern, Mode::Pattern, false)
34+
MetaTemplate::parse(edition, pattern, Mode::Pattern)
3535
}
3636

3737
pub(crate) fn parse_template(
3838
edition: impl Copy + Fn(SyntaxContextId) -> Edition,
3939
template: &tt::Subtree<Span>,
40-
new_meta_vars: bool,
4140
) -> Result<Self, ParseError> {
42-
MetaTemplate::parse(edition, template, Mode::Template, new_meta_vars)
41+
MetaTemplate::parse(edition, template, Mode::Template)
4342
}
4443

4544
pub(crate) fn iter(&self) -> impl Iterator<Item = &Op> {
@@ -50,13 +49,12 @@ impl MetaTemplate {
5049
edition: impl Copy + Fn(SyntaxContextId) -> Edition,
5150
tt: &tt::Subtree<Span>,
5251
mode: Mode,
53-
new_meta_vars: bool,
5452
) -> Result<Self, ParseError> {
5553
let mut src = TtIter::new(tt);
5654

5755
let mut res = Vec::new();
5856
while let Some(first) = src.peek_n(0) {
59-
let op = next_op(edition, first, &mut src, mode, new_meta_vars)?;
57+
let op = next_op(edition, first, &mut src, mode)?;
6058
res.push(op);
6159
}
6260

@@ -161,7 +159,6 @@ fn next_op(
161159
first_peeked: &tt::TokenTree<Span>,
162160
src: &mut TtIter<'_, Span>,
163161
mode: Mode,
164-
new_meta_vars: bool,
165162
) -> Result<Op, ParseError> {
166163
let res = match first_peeked {
167164
tt::TokenTree::Leaf(tt::Leaf::Punct(p @ tt::Punct { char: '$', .. })) => {
@@ -181,14 +178,14 @@ fn next_op(
181178
tt::TokenTree::Subtree(subtree) => match subtree.delimiter.kind {
182179
tt::DelimiterKind::Parenthesis => {
183180
let (separator, kind) = parse_repeat(src)?;
184-
let tokens = MetaTemplate::parse(edition, subtree, mode, new_meta_vars)?;
181+
let tokens = MetaTemplate::parse(edition, subtree, mode)?;
185182
Op::Repeat { tokens, separator: separator.map(Arc::new), kind }
186183
}
187184
tt::DelimiterKind::Brace => match mode {
188185
Mode::Template => {
189-
parse_metavar_expr(new_meta_vars, &mut TtIter::new(subtree)).map_err(
190-
|()| ParseError::unexpected("invalid metavariable expression"),
191-
)?
186+
parse_metavar_expr(&mut TtIter::new(subtree)).map_err(|()| {
187+
ParseError::unexpected("invalid metavariable expression")
188+
})?
192189
}
193190
Mode::Pattern => {
194191
return Err(ParseError::unexpected(
@@ -260,7 +257,7 @@ fn next_op(
260257

261258
tt::TokenTree::Subtree(subtree) => {
262259
src.next().expect("first token already peeked");
263-
let tokens = MetaTemplate::parse(edition, subtree, mode, new_meta_vars)?;
260+
let tokens = MetaTemplate::parse(edition, subtree, mode)?;
264261
Op::Subtree { tokens, delimiter: subtree.delimiter }
265262
}
266263
};
@@ -343,7 +340,7 @@ fn parse_repeat(src: &mut TtIter<'_, Span>) -> Result<(Option<Separator>, Repeat
343340
Err(ParseError::InvalidRepeat)
344341
}
345342

346-
fn parse_metavar_expr(new_meta_vars: bool, src: &mut TtIter<'_, Span>) -> Result<Op, ()> {
343+
fn parse_metavar_expr(src: &mut TtIter<'_, Span>) -> Result<Op, ()> {
347344
let func = src.expect_ident()?;
348345
let args = src.expect_subtree()?;
349346

@@ -355,18 +352,14 @@ fn parse_metavar_expr(new_meta_vars: bool, src: &mut TtIter<'_, Span>) -> Result
355352

356353
let op = match &func.sym {
357354
s if sym::ignore == *s => {
358-
if new_meta_vars {
359-
args.expect_dollar()?;
360-
}
355+
args.expect_dollar()?;
361356
let ident = args.expect_ident()?;
362357
Op::Ignore { name: ident.sym.clone(), id: ident.span }
363358
}
364359
s if sym::index == *s => Op::Index { depth: parse_depth(&mut args)? },
365360
s if sym::len == *s => Op::Len { depth: parse_depth(&mut args)? },
366361
s if sym::count == *s => {
367-
if new_meta_vars {
368-
args.expect_dollar()?;
369-
}
362+
args.expect_dollar()?;
370363
let ident = args.expect_ident()?;
371364
let depth = if try_eat_comma(&mut args) { Some(parse_depth(&mut args)?) } else { None };
372365
Op::Count { name: ident.sym.clone(), depth }

crates/mbe/src/syntax_bridge.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ where
153153
} => TokenBuffer::from_tokens(token_trees),
154154
_ => TokenBuffer::from_subtree(tt),
155155
};
156-
let parser_input = to_parser_input(&buffer);
156+
let parser_input = to_parser_input(edition, &buffer);
157157
let parser_output = entry_point.parse(&parser_input, edition);
158158
let mut tree_sink = TtTreeSink::new(buffer.begin());
159159
for event in parser_output.iter() {

crates/mbe/src/to_parser_input.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
44
use std::fmt;
55

6+
use span::Edition;
67
use syntax::{SyntaxKind, SyntaxKind::*, T};
78

89
use tt::buffer::TokenBuffer;
910

10-
pub(crate) fn to_parser_input<S: Copy + fmt::Debug>(buffer: &TokenBuffer<'_, S>) -> parser::Input {
11+
pub(crate) fn to_parser_input<S: Copy + fmt::Debug>(
12+
edition: Edition,
13+
buffer: &TokenBuffer<'_, S>,
14+
) -> parser::Input {
1115
let mut res = parser::Input::default();
1216

1317
let mut current = buffer.begin();
@@ -60,6 +64,10 @@ pub(crate) fn to_parser_input<S: Copy + fmt::Debug>(buffer: &TokenBuffer<'_, S>)
6064
"_" => res.push(T![_]),
6165
i if i.starts_with('\'') => res.push(LIFETIME_IDENT),
6266
_ if ident.is_raw.yes() => res.push(IDENT),
67+
"gen" if !edition.at_least_2024() => res.push(IDENT),
68+
"async" | "await" | "dyn" | "try" if !edition.at_least_2018() => {
69+
res.push(IDENT)
70+
}
6371
text => match SyntaxKind::from_keyword(text) {
6472
Some(kind) => res.push(kind),
6573
None => {

0 commit comments

Comments
 (0)