1
1
use crate :: mbe:: macro_parser;
2
- use crate :: mbe:: { Delimited , KleeneOp , KleeneToken , MetaVarExpr , SequenceRepetition , TokenTree } ;
2
+ use crate :: mbe:: { Delimited , KleeneOp , KleeneToken , SequenceRepetition , TokenTree } ;
3
3
4
4
use rustc_ast:: token:: { self , Token } ;
5
5
use rustc_ast:: tokenstream;
6
6
use rustc_ast:: { NodeId , DUMMY_NODE_ID } ;
7
7
use rustc_ast_pretty:: pprust;
8
8
use rustc_feature:: Features ;
9
- use rustc_session:: parse:: { feature_err , ParseSess } ;
10
- use rustc_span:: symbol:: { kw, sym , Ident } ;
9
+ use rustc_session:: parse:: ParseSess ;
10
+ use rustc_span:: symbol:: { kw, Ident } ;
11
11
12
12
use rustc_span:: edition:: Edition ;
13
13
use rustc_span:: { Span , SyntaxContext } ;
@@ -25,22 +25,22 @@ const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
25
25
/// # Parameters
26
26
///
27
27
/// - `input`: a token stream to read from, the contents of which we are parsing.
28
- /// - `parsing_patterns`: `parse` can be used to parse either the "patterns" or the "body" of a
29
- /// macro. Both take roughly the same form _except_ that:
30
- /// - In a pattern, metavars are declared with their "matcher" type. For example `$var:expr` or
31
- /// `$id:ident`. In this example, `expr` and `ident` are "matchers". They are not present in the
32
- /// body of a macro rule -- just in the pattern.
33
- /// - Metavariable expressions are only valid in the "body", not the "pattern".
28
+ /// - `expect_matchers`: `parse` can be used to parse either the "patterns" or the "body" of a
29
+ /// macro. Both take roughly the same form _except_ that in a pattern, metavars are declared with
30
+ /// their "matcher" type. For example `$var:expr` or `$id:ident`. In this example, `expr` and
31
+ /// `ident` are "matchers". They are not present in the body of a macro rule -- just in the
32
+ /// pattern, so we pass a parameter to indicate whether to expect them or not.
34
33
/// - `sess`: the parsing session. Any errors will be emitted to this session.
35
34
/// - `node_id`: the NodeId of the macro we are parsing.
36
35
/// - `features`: language features so we can do feature gating.
36
+ /// - `edition`: the edition of the crate defining the macro
37
37
///
38
38
/// # Returns
39
39
///
40
40
/// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`.
41
41
pub ( super ) fn parse (
42
42
input : tokenstream:: TokenStream ,
43
- parsing_patterns : bool ,
43
+ expect_matchers : bool ,
44
44
sess : & ParseSess ,
45
45
node_id : NodeId ,
46
46
features : & Features ,
@@ -55,9 +55,9 @@ pub(super) fn parse(
55
55
while let Some ( tree) = trees. next ( ) {
56
56
// Given the parsed tree, if there is a metavar and we are expecting matchers, actually
57
57
// parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`).
58
- let tree = parse_tree ( tree, & mut trees, parsing_patterns , sess, node_id, features, edition) ;
58
+ let tree = parse_tree ( tree, & mut trees, expect_matchers , sess, node_id, features, edition) ;
59
59
match tree {
60
- TokenTree :: MetaVar ( start_sp, ident) if parsing_patterns => {
60
+ TokenTree :: MetaVar ( start_sp, ident) if expect_matchers => {
61
61
let span = match trees. next ( ) {
62
62
Some ( tokenstream:: TokenTree :: Token ( Token { kind : token:: Colon , span } ) ) => {
63
63
match trees. next ( ) {
@@ -118,14 +118,6 @@ pub(super) fn parse(
118
118
result
119
119
}
120
120
121
- /// Asks for the `macro_metavar_expr` feature if it is not already declared
122
- fn maybe_emit_macro_metavar_expr_feature ( features : & Features , sess : & ParseSess , span : Span ) {
123
- if !features. macro_metavar_expr {
124
- let msg = "meta-variable expressions are unstable" ;
125
- feature_err ( & sess, sym:: macro_metavar_expr, span, msg) . emit ( ) ;
126
- }
127
- }
128
-
129
121
/// Takes a `tokenstream::TokenTree` and returns a `self::TokenTree`. Specifically, this takes a
130
122
/// generic `TokenTree`, such as is used in the rest of the compiler, and returns a `TokenTree`
131
123
/// for use in parsing a macro.
@@ -137,13 +129,14 @@ fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &ParseSess,
137
129
/// - `tree`: the tree we wish to convert.
138
130
/// - `outer_trees`: an iterator over trees. We may need to read more tokens from it in order to finish
139
131
/// converting `tree`
140
- /// - `parsing_patterns `: same as [ parse] .
132
+ /// - `expect_matchers `: same as for ` parse` (see above) .
141
133
/// - `sess`: the parsing session. Any errors will be emitted to this session.
142
134
/// - `features`: language features so we can do feature gating.
135
+ /// - `edition` - the edition of the crate defining the macro
143
136
fn parse_tree (
144
137
tree : tokenstream:: TokenTree ,
145
138
outer_trees : & mut impl Iterator < Item = tokenstream:: TokenTree > ,
146
- parsing_patterns : bool ,
139
+ expect_matchers : bool ,
147
140
sess : & ParseSess ,
148
141
node_id : NodeId ,
149
142
features : & Features ,
@@ -165,57 +158,24 @@ fn parse_tree(
165
158
}
166
159
167
160
match next {
168
- // `tree` is followed by a delimited set of token trees.
169
- Some ( tokenstream:: TokenTree :: Delimited ( delim_span, delim, tts) ) => {
170
- if parsing_patterns {
171
- if delim != token:: Paren {
172
- span_dollar_dollar_or_metavar_in_the_lhs_err (
173
- sess,
174
- & Token { kind : token:: OpenDelim ( delim) , span : delim_span. entire ( ) } ,
175
- ) ;
176
- }
177
- } else {
178
- match delim {
179
- token:: Brace => {
180
- // The delimiter is `{`. This indicates the beginning
181
- // of a meta-variable expression (e.g. `${count(ident)}`).
182
- // Try to parse the meta-variable expression.
183
- match MetaVarExpr :: parse ( & tts, delim_span. entire ( ) , sess) {
184
- Err ( mut err) => {
185
- err. emit ( ) ;
186
- // Returns early the same read `$` to avoid spanning
187
- // unrelated diagnostics that could be performed afterwards
188
- return TokenTree :: token ( token:: Dollar , span) ;
189
- }
190
- Ok ( elem) => {
191
- maybe_emit_macro_metavar_expr_feature (
192
- features,
193
- sess,
194
- delim_span. entire ( ) ,
195
- ) ;
196
- return TokenTree :: MetaVarExpr ( delim_span, elem) ;
197
- }
198
- }
199
- }
200
- token:: Paren => { }
201
- _ => {
202
- let tok = pprust:: token_kind_to_string ( & token:: OpenDelim ( delim) ) ;
203
- let msg = format ! ( "expected `(` or `{{`, found `{}`" , tok) ;
204
- sess. span_diagnostic . span_err ( delim_span. entire ( ) , & msg) ;
205
- }
206
- }
161
+ // `tree` is followed by a delimited set of token trees. This indicates the beginning
162
+ // of a repetition sequence in the macro (e.g. `$(pat)*`).
163
+ Some ( tokenstream:: TokenTree :: Delimited ( span, delim, tts) ) => {
164
+ // Must have `(` not `{` or `[`
165
+ if delim != token:: Paren {
166
+ let tok = pprust:: token_kind_to_string ( & token:: OpenDelim ( delim) ) ;
167
+ let msg = format ! ( "expected `(`, found `{}`" , tok) ;
168
+ sess. span_diagnostic . span_err ( span. entire ( ) , & msg) ;
207
169
}
208
- // If we didn't find a metavar expression above, then we must have a
209
- // repetition sequence in the macro (e.g. `$(pat)*`). Parse the
210
- // contents of the sequence itself
211
- let sequence = parse ( tts, parsing_patterns, sess, node_id, features, edition) ;
170
+ // Parse the contents of the sequence itself
171
+ let sequence = parse ( tts, expect_matchers, sess, node_id, features, edition) ;
212
172
// Get the Kleene operator and optional separator
213
173
let ( separator, kleene) =
214
- parse_sep_and_kleene_op ( & mut trees, delim_span . entire ( ) , sess) ;
174
+ parse_sep_and_kleene_op ( & mut trees, span . entire ( ) , sess) ;
215
175
// Count the number of captured "names" (i.e., named metavars)
216
176
let name_captures = macro_parser:: count_names ( & sequence) ;
217
177
TokenTree :: Sequence (
218
- delim_span ,
178
+ span ,
219
179
Lrc :: new ( SequenceRepetition {
220
180
tts : sequence,
221
181
separator,
@@ -237,20 +197,7 @@ fn parse_tree(
237
197
}
238
198
}
239
199
240
- // `tree` is followed by another `$`. This is an escaped `$`.
241
- Some ( tokenstream:: TokenTree :: Token ( Token { kind : token:: Dollar , span } ) ) => {
242
- if parsing_patterns {
243
- span_dollar_dollar_or_metavar_in_the_lhs_err (
244
- sess,
245
- & Token { kind : token:: Dollar , span } ,
246
- ) ;
247
- } else {
248
- maybe_emit_macro_metavar_expr_feature ( features, sess, span) ;
249
- }
250
- TokenTree :: token ( token:: Dollar , span)
251
- }
252
-
253
- // `tree` is followed by some other token. This is an error.
200
+ // `tree` is followed by a random token. This is an error.
254
201
Some ( tokenstream:: TokenTree :: Token ( token) ) => {
255
202
let msg = format ! (
256
203
"expected identifier, found `{}`" ,
@@ -274,7 +221,7 @@ fn parse_tree(
274
221
span,
275
222
Lrc :: new ( Delimited {
276
223
delim,
277
- tts : parse ( tts, parsing_patterns , sess, node_id, features, edition) ,
224
+ tts : parse ( tts, expect_matchers , sess, node_id, features, edition) ,
278
225
} ) ,
279
226
) ,
280
227
}
@@ -362,15 +309,3 @@ fn parse_sep_and_kleene_op(
362
309
// Return a dummy
363
310
( None , KleeneToken :: new ( KleeneOp :: ZeroOrMore , span) )
364
311
}
365
-
366
- // `$$` or a meta-variable is the lhs of a macro but shouldn't.
367
- //
368
- // For example, `macro_rules! foo { ( ${length()} ) => {} }`
369
- fn span_dollar_dollar_or_metavar_in_the_lhs_err < ' sess > ( sess : & ' sess ParseSess , token : & Token ) {
370
- sess. span_diagnostic
371
- . span_err ( token. span , & format ! ( "unexpected token: {}" , pprust:: token_to_string( token) ) ) ;
372
- sess. span_diagnostic . span_note_without_error (
373
- token. span ,
374
- "`$$` and meta-variable expressions are not allowed inside macro parameter definitions" ,
375
- ) ;
376
- }
0 commit comments