@@ -2,6 +2,7 @@ use crate::mbe::macro_parser::count_metavar_decls;
2
2
use crate :: mbe:: { Delimited , KleeneOp , KleeneToken , MetaVarExpr , SequenceRepetition , TokenTree } ;
3
3
4
4
use rustc_ast:: token:: { self , Delimiter , Token } ;
5
+ use rustc_ast:: tokenstream:: Cursor ;
5
6
use rustc_ast:: { tokenstream, NodeId } ;
6
7
use rustc_ast_pretty:: pprust;
7
8
use rustc_feature:: Features ;
@@ -136,7 +137,7 @@ fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &ParseSess,
136
137
/// - `features`: language features so we can do feature gating.
137
138
fn parse_tree (
138
139
tree : tokenstream:: TokenTree ,
139
- outer_trees : & mut impl Iterator < Item = tokenstream :: TokenTree > ,
140
+ outer_trees : & mut Cursor ,
140
141
parsing_patterns : bool ,
141
142
sess : & ParseSess ,
142
143
node_id : NodeId ,
@@ -150,13 +151,13 @@ fn parse_tree(
150
151
// FIXME: Handle `Invisible`-delimited groups in a more systematic way
151
152
// during parsing.
152
153
let mut next = outer_trees. next ( ) ;
153
- let mut trees : Box < dyn Iterator < Item = tokenstream :: TokenTree > > ;
154
+ let mut trees_owned = None ;
154
155
if let Some ( tokenstream:: TokenTree :: Delimited ( _, Delimiter :: Invisible , tts) ) = next {
155
- trees = Box :: new ( tts. into_trees ( ) ) ;
156
- next = trees. next ( ) ;
157
- } else {
158
- trees = Box :: new ( outer_trees) ;
156
+ let mut local_trees = tts. into_trees ( ) ;
157
+ next = local_trees. next ( ) ;
158
+ trees_owned = Some ( local_trees) ;
159
159
}
160
+ let trees = if let Some ( ref mut elem) = trees_owned { elem } else { outer_trees } ;
160
161
161
162
match next {
162
163
// `tree` is followed by a delimited set of token trees.
@@ -205,7 +206,7 @@ fn parse_tree(
205
206
let sequence = parse ( tts, parsing_patterns, sess, node_id, features, edition) ;
206
207
// Get the Kleene operator and optional separator
207
208
let ( separator, kleene) =
208
- parse_sep_and_kleene_op ( & mut trees, delim_span. entire ( ) , sess) ;
209
+ parse_sep_and_kleene_op ( trees, delim_span. entire ( ) , sess) ;
209
210
// Count the number of captured "names" (i.e., named metavars)
210
211
let num_captures =
211
212
if parsing_patterns { count_metavar_decls ( & sequence) } else { 0 } ;
@@ -235,9 +236,18 @@ fn parse_tree(
235
236
& Token { kind : token:: Dollar , span } ,
236
237
) ;
237
238
}
239
+ if let Some ( tokenstream:: TokenTree :: Token ( ref token) ) = trees. look_ahead ( 0 )
240
+ && let Some ( ( ident, is_raw) ) = token. ident ( )
241
+ && ident. name == kw:: Crate && !is_raw
242
+ {
243
+ sess. span_diagnostic . span_err (
244
+ token. span ,
245
+ & format ! ( "unexpected token: {}" , pprust:: token_to_string( token) )
246
+ ) ;
247
+ sess. span_diagnostic . note_without_error ( "`$$crate` is not allowed in any context" ) ;
248
+ }
238
249
TokenTree :: token ( token:: Dollar , span)
239
250
}
240
-
241
251
// `tree` is followed by some other token. This is an error.
242
252
Some ( tokenstream:: TokenTree :: Token ( token) ) => {
243
253
let msg = format ! (
0 commit comments