Skip to content

Commit ebda376

Browse files
Pass the correct per-token (not global) edition when expanding macro_rules
This was hard to do because of the separation between `mbe` and `hir-expand`, but became possible by the Salsa migration, as now `SyntaxContext` doesn't require `ExpandDatabase`, `salsa::Database` is enough.
1 parent 3e42012 commit ebda376

File tree

11 files changed

+64
-34
lines changed

11 files changed

+64
-34
lines changed

src/tools/rust-analyzer/Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,7 @@ dependencies = [
14751475
"parser",
14761476
"ra-ap-rustc_lexer",
14771477
"rustc-hash 2.1.1",
1478+
"salsa",
14781479
"smallvec",
14791480
"span",
14801481
"stdx",

src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,3 +2051,33 @@ fn f() {
20512051
"#]],
20522052
);
20532053
}
2054+
2055+
#[test]
2056+
fn per_token_edition() {
2057+
check(
2058+
r#"
2059+
//- /foo.rs crate:foo edition:2024
2060+
#[macro_export]
2061+
macro_rules! m {
2062+
($e:expr) => {};
2063+
}
2064+
//- /bar.rs crate:bar deps:foo edition:2021
2065+
fn gen() -> usize {
2066+
0
2067+
}
2068+
2069+
fn foo() {
2070+
foo::m!(gen());
2071+
}
2072+
"#,
2073+
expect![[r#"
2074+
fn gen() -> usize {
2075+
0
2076+
}
2077+
2078+
fn foo() {
2079+
;
2080+
}
2081+
"#]],
2082+
);
2083+
}

src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use syntax::{
1818
use syntax_bridge::syntax_node_to_token_tree;
1919

2020
use crate::{
21-
EditionedFileId, ExpandError, ExpandResult, Lookup as _, MacroCallId,
21+
EditionedFileId, ExpandError, ExpandResult, MacroCallId,
2222
builtin::quote::{WithDelimiter, dollar_crate},
2323
db::ExpandDatabase,
2424
hygiene::{span_with_call_site_ctxt, span_with_def_site_ctxt},
@@ -230,9 +230,9 @@ fn assert_expand(
230230
let mut iter = tt.iter();
231231

232232
let cond = expect_fragment(
233+
db,
233234
&mut iter,
234235
parser::PrefixEntryPoint::Expr,
235-
id.lookup(db).krate.data(db).edition,
236236
tt.top_subtree().delimiter.delim_span(),
237237
);
238238
_ = iter.expect_char(',');

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ pub fn expand_speculative(
299299
}
300300
MacroDefKind::Declarative(it, _) => db
301301
.decl_macro_expander(loc.krate, it)
302-
.expand_unhygienic(tt, loc.kind.call_style(), span, loc.def.edition),
302+
.expand_unhygienic(db, tt, loc.kind.call_style(), span),
303303
MacroDefKind::BuiltIn(_, it) => {
304304
it.expand(db, actual_macro_call, &tt, span).map_err(Into::into)
305305
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,25 @@ impl DeclarativeMacroExpander {
4242
None => self
4343
.mac
4444
.expand(
45+
db,
4546
&tt,
4647
|s| {
4748
s.ctx =
4849
apply_mark(db, s.ctx, call_id.into(), self.transparency, self.edition)
4950
},
5051
loc.kind.call_style(),
5152
span,
52-
loc.def.edition,
5353
)
5454
.map_err(Into::into),
5555
}
5656
}
5757

5858
pub fn expand_unhygienic(
5959
&self,
60+
db: &dyn ExpandDatabase,
6061
tt: tt::TopSubtree,
6162
call_style: MacroCallStyle,
6263
call_site: Span,
63-
def_site_edition: Edition,
6464
) -> ExpandResult<tt::TopSubtree> {
6565
match self.mac.err() {
6666
Some(_) => ExpandResult::new(
@@ -69,7 +69,7 @@ impl DeclarativeMacroExpander {
6969
),
7070
None => self
7171
.mac
72-
.expand(&tt, |_| (), call_style, call_site, def_site_edition)
72+
.expand(db, &tt, |_| (), call_style, call_site)
7373
.map(TupleExt::head)
7474
.map_err(Into::into),
7575
}

src/tools/rust-analyzer/crates/mbe/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ rustc-hash.workspace = true
1818
smallvec.workspace = true
1919
arrayvec.workspace = true
2020
ra-ap-rustc_lexer.workspace = true
21+
salsa.workspace = true
2122
bitflags.workspace = true
2223

2324
# local deps

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use intern::Symbol;
44
use rustc_hash::FxHashMap;
5-
use span::{Edition, Span};
5+
use span::Span;
66
use stdx::itertools::Itertools;
77
use syntax::{
88
AstNode,
@@ -44,16 +44,16 @@ fn benchmark_expand_macro_rules() {
4444
if skip_slow_tests() {
4545
return;
4646
}
47+
let db = salsa::DatabaseImpl::default();
4748
let rules = macro_rules_fixtures();
48-
let invocations = invocation_fixtures(&rules);
49+
let invocations = invocation_fixtures(&db, &rules);
4950

5051
let hash: usize = {
5152
let _pt = bench("mbe expand macro rules");
5253
invocations
5354
.into_iter()
5455
.map(|(id, tt)| {
55-
let res =
56-
rules[&id].expand(&tt, |_| (), MacroCallStyle::FnLike, DUMMY, Edition::CURRENT);
56+
let res = rules[&id].expand(&db, &tt, |_| (), MacroCallStyle::FnLike, DUMMY);
5757
assert!(res.err.is_none());
5858
res.value.0.0.len()
5959
})
@@ -93,6 +93,7 @@ fn macro_rules_fixtures_tt() -> FxHashMap<String, tt::TopSubtree<Span>> {
9393

9494
/// Generate random invocation fixtures from rules
9595
fn invocation_fixtures(
96+
db: &dyn salsa::Database,
9697
rules: &FxHashMap<String, DeclarativeMacro>,
9798
) -> Vec<(String, tt::TopSubtree<Span>)> {
9899
let mut seed = 123456789;
@@ -124,10 +125,7 @@ fn invocation_fixtures(
124125
}
125126
let subtree = builder.build();
126127

127-
if it
128-
.expand(&subtree, |_| (), MacroCallStyle::FnLike, DUMMY, Edition::CURRENT)
129-
.err
130-
.is_none()
128+
if it.expand(db, &subtree, |_| (), MacroCallStyle::FnLike, DUMMY).err.is_none()
131129
{
132130
res.push((name.clone(), subtree));
133131
break;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@ mod transcriber;
77

88
use intern::Symbol;
99
use rustc_hash::FxHashMap;
10-
use span::{Edition, Span};
10+
use span::Span;
1111

1212
use crate::{
1313
ExpandError, ExpandErrorKind, ExpandResult, MacroCallStyle, MatchedArmIndex,
1414
parser::MetaVarKind,
1515
};
1616

1717
pub(crate) fn expand_rules(
18+
db: &dyn salsa::Database,
1819
rules: &[crate::Rule],
1920
input: &tt::TopSubtree<Span>,
2021
marker: impl Fn(&mut Span) + Copy,
2122
call_style: MacroCallStyle,
2223
call_site: Span,
23-
def_site_edition: Edition,
2424
) -> ExpandResult<(tt::TopSubtree<Span>, MatchedArmIndex)> {
2525
let mut match_: Option<(matcher::Match<'_>, &crate::Rule, usize)> = None;
2626
for (idx, rule) in rules.iter().enumerate() {
@@ -29,7 +29,7 @@ pub(crate) fn expand_rules(
2929
continue;
3030
}
3131

32-
let new_match = matcher::match_(&rule.lhs, input, def_site_edition);
32+
let new_match = matcher::match_(db, &rule.lhs, input);
3333

3434
if new_match.err.is_none() {
3535
// If we find a rule that applies without errors, we're done.

src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use std::{rc::Rc, sync::Arc};
6363

6464
use intern::{Symbol, sym};
6565
use smallvec::{SmallVec, smallvec};
66-
use span::{Edition, Span};
66+
use span::Span;
6767
use tt::{
6868
DelimSpan,
6969
iter::{TtElement, TtIter},
@@ -112,11 +112,11 @@ impl Match<'_> {
112112

113113
/// Matching errors are added to the `Match`.
114114
pub(super) fn match_<'t>(
115+
db: &dyn salsa::Database,
115116
pattern: &'t MetaTemplate,
116117
input: &'t tt::TopSubtree<Span>,
117-
edition: Edition,
118118
) -> Match<'t> {
119-
let mut res = match_loop(pattern, input, edition);
119+
let mut res = match_loop(db, pattern, input);
120120
res.bound_count = count(res.bindings.bindings());
121121
return res;
122122

@@ -365,6 +365,7 @@ struct MatchState<'t> {
365365
/// - `error_items`: the set of items in errors, used for error-resilient parsing
366366
#[inline]
367367
fn match_loop_inner<'t>(
368+
db: &dyn salsa::Database,
368369
src: TtIter<'t, Span>,
369370
stack: &[TtIter<'t, Span>],
370371
res: &mut Match<'t>,
@@ -375,7 +376,6 @@ fn match_loop_inner<'t>(
375376
eof_items: &mut SmallVec<[MatchState<'t>; 1]>,
376377
error_items: &mut SmallVec<[MatchState<'t>; 1]>,
377378
delim_span: tt::DelimSpan<Span>,
378-
edition: Edition,
379379
) {
380380
macro_rules! try_push {
381381
($items: expr, $it:expr) => {
@@ -486,7 +486,7 @@ fn match_loop_inner<'t>(
486486
OpDelimited::Op(Op::Var { kind, name, .. }) => {
487487
if let &Some(kind) = kind {
488488
let mut fork = src.clone();
489-
let match_res = match_meta_var(kind, &mut fork, delim_span, edition);
489+
let match_res = match_meta_var(db, kind, &mut fork, delim_span);
490490
match match_res.err {
491491
None => {
492492
// Some meta variables are optional (e.g. vis)
@@ -621,9 +621,9 @@ fn match_loop_inner<'t>(
621621
}
622622

623623
fn match_loop<'t>(
624+
db: &dyn salsa::Database,
624625
pattern: &'t MetaTemplate,
625626
src: &'t tt::TopSubtree<Span>,
626-
edition: Edition,
627627
) -> Match<'t> {
628628
let span = src.top_subtree().delimiter.delim_span();
629629
let mut src = src.iter();
@@ -655,6 +655,7 @@ fn match_loop<'t>(
655655
stdx::always!(next_items.is_empty());
656656

657657
match_loop_inner(
658+
db,
658659
src.clone(),
659660
&stack,
660661
&mut res,
@@ -665,7 +666,6 @@ fn match_loop<'t>(
665666
&mut eof_items,
666667
&mut error_items,
667668
span,
668-
edition,
669669
);
670670
stdx::always!(cur_items.is_empty());
671671

@@ -772,14 +772,14 @@ fn match_loop<'t>(
772772
}
773773

774774
fn match_meta_var<'t>(
775+
db: &dyn salsa::Database,
775776
kind: MetaVarKind,
776777
input: &mut TtIter<'t, Span>,
777778
delim_span: DelimSpan<Span>,
778-
edition: Edition,
779779
) -> ExpandResult<Fragment<'t>> {
780780
let fragment = match kind {
781781
MetaVarKind::Path => {
782-
return expect_fragment(input, parser::PrefixEntryPoint::Path, edition, delim_span)
782+
return expect_fragment(db, input, parser::PrefixEntryPoint::Path, delim_span)
783783
.map(Fragment::Path);
784784
}
785785
MetaVarKind::Expr(expr) => {
@@ -807,7 +807,7 @@ fn match_meta_var<'t>(
807807
}
808808
_ => {}
809809
};
810-
return expect_fragment(input, parser::PrefixEntryPoint::Expr, edition, delim_span)
810+
return expect_fragment(db, input, parser::PrefixEntryPoint::Expr, delim_span)
811811
.map(Fragment::Expr);
812812
}
813813
MetaVarKind::Ident | MetaVarKind::Tt | MetaVarKind::Lifetime | MetaVarKind::Literal => {
@@ -853,7 +853,7 @@ fn match_meta_var<'t>(
853853
MetaVarKind::Item => parser::PrefixEntryPoint::Item,
854854
MetaVarKind::Vis => parser::PrefixEntryPoint::Vis,
855855
};
856-
expect_fragment(input, fragment, edition, delim_span).map(Fragment::Tokens)
856+
expect_fragment(db, input, fragment, delim_span).map(Fragment::Tokens)
857857
}
858858

859859
fn collect_vars(collector_fun: &mut impl FnMut(Symbol), pattern: &MetaTemplate) {

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,13 @@ impl DeclarativeMacro {
275275

276276
pub fn expand(
277277
&self,
278+
db: &dyn salsa::Database,
278279
tt: &tt::TopSubtree<Span>,
279280
marker: impl Fn(&mut Span) + Copy,
280281
call_style: MacroCallStyle,
281282
call_site: Span,
282-
def_site_edition: Edition,
283283
) -> ExpandResult<(tt::TopSubtree<Span>, MatchedArmIndex)> {
284-
expander::expand_rules(&self.rules, tt, marker, call_style, call_site, def_site_edition)
284+
expander::expand_rules(db, &self.rules, tt, marker, call_style, call_site)
285285
}
286286
}
287287

@@ -390,15 +390,14 @@ impl<T: Default, E> From<Result<T, E>> for ValueResult<T, E> {
390390
}
391391

392392
pub fn expect_fragment<'t>(
393+
db: &dyn salsa::Database,
393394
tt_iter: &mut TtIter<'t, Span>,
394395
entry_point: ::parser::PrefixEntryPoint,
395-
edition: ::parser::Edition,
396396
delim_span: DelimSpan<Span>,
397397
) -> ExpandResult<tt::TokenTreesView<'t, Span>> {
398398
use ::parser;
399399
let buffer = tt_iter.remaining();
400-
// FIXME: Pass the correct edition per token. Due to the split between mbe and hir-expand it's complicated.
401-
let parser_input = to_parser_input(buffer, &mut |_ctx| edition);
400+
let parser_input = to_parser_input(buffer, &mut |ctx| ctx.edition(db));
402401
let tree_traversal = entry_point.parse(&parser_input);
403402
let mut cursor = buffer.cursor();
404403
let mut error = false;

0 commit comments

Comments
 (0)