@@ -9,7 +9,8 @@ use rustc_feature::Features;
9
9
use rustc_session:: parse:: ParseSess ;
10
10
use rustc_span:: symbol:: { kw, Ident } ;
11
11
12
- use rustc_span:: Span ;
12
+ use rustc_span:: edition:: Edition ;
13
+ use rustc_span:: { Span , SyntaxContext } ;
13
14
14
15
use rustc_data_structures:: sync:: Lrc ;
15
16
@@ -32,6 +33,7 @@ const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
32
33
/// - `sess`: the parsing session. Any errors will be emitted to this session.
33
34
/// - `node_id`: the NodeId of the macro we are parsing.
34
35
/// - `features`: language features so we can do feature gating.
36
+ /// - `edition`: the edition of the crate defining the macro
35
37
///
36
38
/// # Returns
37
39
///
@@ -42,6 +44,7 @@ pub(super) fn parse(
42
44
sess : & ParseSess ,
43
45
node_id : NodeId ,
44
46
features : & Features ,
47
+ edition : Edition ,
45
48
) -> Vec < TokenTree > {
46
49
// Will contain the final collection of `self::TokenTree`
47
50
let mut result = Vec :: new ( ) ;
@@ -52,7 +55,7 @@ pub(super) fn parse(
52
55
while let Some ( tree) = trees. next ( ) {
53
56
// Given the parsed tree, if there is a metavar and we are expecting matchers, actually
54
57
// parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`).
55
- let tree = parse_tree ( tree, & mut trees, expect_matchers, sess, node_id, features) ;
58
+ let tree = parse_tree ( tree, & mut trees, expect_matchers, sess, node_id, features, edition ) ;
56
59
match tree {
57
60
TokenTree :: MetaVar ( start_sp, ident) if expect_matchers => {
58
61
let span = match trees. next ( ) {
@@ -64,7 +67,19 @@ pub(super) fn parse(
64
67
65
68
let kind =
66
69
token:: NonterminalKind :: from_symbol ( frag. name , || {
67
- span. edition ( )
70
+ // FIXME(#85708) - once we properly decode a foreign
71
+ // crate's `SyntaxContext::root`, then we can replace
72
+ // this with just `span.edition()`. A
73
+ // `SyntaxContext::root()` from the current crate will
74
+ // have the edition of the current crate, and a
75
+ // `SyntaxxContext::root()` from a foreign crate will
76
+ // have the edition of that crate (which we manually
77
+ // retrieve via the `edition` parameter).
78
+ if span. ctxt ( ) == SyntaxContext :: root ( ) {
79
+ edition
80
+ } else {
81
+ span. edition ( )
82
+ }
68
83
} )
69
84
. unwrap_or_else (
70
85
|| {
@@ -117,13 +132,15 @@ pub(super) fn parse(
117
132
/// - `expect_matchers`: same as for `parse` (see above).
118
133
/// - `sess`: the parsing session. Any errors will be emitted to this session.
119
134
/// - `features`: language features so we can do feature gating.
135
+ /// - `edition` - the edition of the crate defining the macro
120
136
fn parse_tree (
121
137
tree : tokenstream:: TokenTree ,
122
138
outer_trees : & mut impl Iterator < Item = tokenstream:: TokenTree > ,
123
139
expect_matchers : bool ,
124
140
sess : & ParseSess ,
125
141
node_id : NodeId ,
126
142
features : & Features ,
143
+ edition : Edition ,
127
144
) -> TokenTree {
128
145
// Depending on what `tree` is, we could be parsing different parts of a macro
129
146
match tree {
@@ -151,7 +168,7 @@ fn parse_tree(
151
168
sess. span_diagnostic . span_err ( span. entire ( ) , & msg) ;
152
169
}
153
170
// Parse the contents of the sequence itself
154
- let sequence = parse ( tts, expect_matchers, sess, node_id, features) ;
171
+ let sequence = parse ( tts, expect_matchers, sess, node_id, features, edition ) ;
155
172
// Get the Kleene operator and optional separator
156
173
let ( separator, kleene) =
157
174
parse_sep_and_kleene_op ( & mut trees, span. entire ( ) , sess) ;
@@ -204,7 +221,7 @@ fn parse_tree(
204
221
span,
205
222
Lrc :: new ( Delimited {
206
223
delim,
207
- tts : parse ( tts, expect_matchers, sess, node_id, features) ,
224
+ tts : parse ( tts, expect_matchers, sess, node_id, features, edition ) ,
208
225
} ) ,
209
226
) ,
210
227
}
0 commit comments