@@ -90,72 +90,88 @@ pub(super) fn parse(
9090/// # Parameters
9191///
9292/// - `tree`: the tree we wish to convert.
93- /// - `trees `: an iterator over trees. We may need to read more tokens from it in order to finish
93+ /// - `outer_trees `: an iterator over trees. We may need to read more tokens from it in order to finish
9494/// converting `tree`
9595/// - `expect_matchers`: same as for `parse` (see above).
9696/// - `sess`: the parsing session. Any errors will be emitted to this session.
9797/// - `features`, `attrs`: language feature flags and attributes so that we know whether to use
9898/// unstable features or not.
9999fn parse_tree (
100100 tree : tokenstream:: TokenTree ,
101- trees : & mut impl Iterator < Item = tokenstream:: TokenTree > ,
101+ outer_trees : & mut impl Iterator < Item = tokenstream:: TokenTree > ,
102102 expect_matchers : bool ,
103103 sess : & ParseSess ,
104104 node_id : NodeId ,
105105) -> TokenTree {
106106 // Depending on what `tree` is, we could be parsing different parts of a macro
107107 match tree {
108108 // `tree` is a `$` token. Look at the next token in `trees`
109- tokenstream:: TokenTree :: Token ( Token { kind : token:: Dollar , span } ) => match trees. next ( ) {
110- // `tree` is followed by a delimited set of token trees. This indicates the beginning
111- // of a repetition sequence in the macro (e.g. `$(pat)*`).
112- Some ( tokenstream:: TokenTree :: Delimited ( span, delim, tts) ) => {
113- // Must have `(` not `{` or `[`
114- if delim != token:: Paren {
115- let tok = pprust:: token_kind_to_string ( & token:: OpenDelim ( delim) ) ;
116- let msg = format ! ( "expected `(`, found `{}`" , tok) ;
117- sess. span_diagnostic . span_err ( span. entire ( ) , & msg) ;
118- }
119- // Parse the contents of the sequence itself
120- let sequence = parse ( tts, expect_matchers, sess, node_id) ;
121- // Get the Kleene operator and optional separator
122- let ( separator, kleene) = parse_sep_and_kleene_op ( trees, span. entire ( ) , sess) ;
123- // Count the number of captured "names" (i.e., named metavars)
124- let name_captures = macro_parser:: count_names ( & sequence) ;
125- TokenTree :: Sequence (
126- span,
127- Lrc :: new ( SequenceRepetition {
128- tts : sequence,
129- separator,
130- kleene,
131- num_captures : name_captures,
132- } ) ,
133- )
109+ tokenstream:: TokenTree :: Token ( Token { kind : token:: Dollar , span } ) => {
110+ // FIXME: Handle `None`-delimited groups in a more systematic way
111+ // during parsing.
112+ let mut next = outer_trees. next ( ) ;
113+ let mut trees: Box < dyn Iterator < Item = tokenstream:: TokenTree > > ;
114+ if let Some ( tokenstream:: TokenTree :: Delimited ( _, token:: NoDelim , tts) ) = next {
115+ trees = Box :: new ( tts. into_trees ( ) ) ;
116+ next = trees. next ( ) ;
117+ } else {
118+ trees = Box :: new ( outer_trees) ;
134119 }
135120
136- // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate` special
137- // metavariable that names the crate of the invocation.
138- Some ( tokenstream:: TokenTree :: Token ( token) ) if token. is_ident ( ) => {
139- let ( ident, is_raw) = token. ident ( ) . unwrap ( ) ;
140- let span = ident. span . with_lo ( span. lo ( ) ) ;
141- if ident. name == kw:: Crate && !is_raw {
142- TokenTree :: token ( token:: Ident ( kw:: DollarCrate , is_raw) , span)
143- } else {
144- TokenTree :: MetaVar ( span, ident)
121+ match next {
122+ // `tree` is followed by a delimited set of token trees. This indicates the beginning
123+ // of a repetition sequence in the macro (e.g. `$(pat)*`).
124+ Some ( tokenstream:: TokenTree :: Delimited ( span, delim, tts) ) => {
125+ // Must have `(` not `{` or `[`
126+ if delim != token:: Paren {
127+ let tok = pprust:: token_kind_to_string ( & token:: OpenDelim ( delim) ) ;
128+ let msg = format ! ( "expected `(`, found `{}`" , tok) ;
129+ sess. span_diagnostic . span_err ( span. entire ( ) , & msg) ;
130+ }
131+ // Parse the contents of the sequence itself
132+ let sequence = parse ( tts, expect_matchers, sess, node_id) ;
133+ // Get the Kleene operator and optional separator
134+ let ( separator, kleene) =
135+ parse_sep_and_kleene_op ( & mut trees, span. entire ( ) , sess) ;
136+ // Count the number of captured "names" (i.e., named metavars)
137+ let name_captures = macro_parser:: count_names ( & sequence) ;
138+ TokenTree :: Sequence (
139+ span,
140+ Lrc :: new ( SequenceRepetition {
141+ tts : sequence,
142+ separator,
143+ kleene,
144+ num_captures : name_captures,
145+ } ) ,
146+ )
145147 }
146- }
147148
148- // `tree` is followed by a random token. This is an error.
149- Some ( tokenstream:: TokenTree :: Token ( token) ) => {
150- let msg =
151- format ! ( "expected identifier, found `{}`" , pprust:: token_to_string( & token) , ) ;
152- sess. span_diagnostic . span_err ( token. span , & msg) ;
153- TokenTree :: MetaVar ( token. span , Ident :: invalid ( ) )
154- }
149+ // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate` special
150+ // metavariable that names the crate of the invocation.
151+ Some ( tokenstream:: TokenTree :: Token ( token) ) if token. is_ident ( ) => {
152+ let ( ident, is_raw) = token. ident ( ) . unwrap ( ) ;
153+ let span = ident. span . with_lo ( span. lo ( ) ) ;
154+ if ident. name == kw:: Crate && !is_raw {
155+ TokenTree :: token ( token:: Ident ( kw:: DollarCrate , is_raw) , span)
156+ } else {
157+ TokenTree :: MetaVar ( span, ident)
158+ }
159+ }
155160
156- // There are no more tokens. Just return the `$` we already have.
157- None => TokenTree :: token ( token:: Dollar , span) ,
158- } ,
161+ // `tree` is followed by a random token. This is an error.
162+ Some ( tokenstream:: TokenTree :: Token ( token) ) => {
163+ let msg = format ! (
164+ "expected identifier, found `{}`" ,
165+ pprust:: token_to_string( & token) ,
166+ ) ;
167+ sess. span_diagnostic . span_err ( token. span , & msg) ;
168+ TokenTree :: MetaVar ( token. span , Ident :: invalid ( ) )
169+ }
170+
171+ // There are no more tokens. Just return the `$` we already have.
172+ None => TokenTree :: token ( token:: Dollar , span) ,
173+ }
174+ }
159175
160176 // `tree` is an arbitrary token. Keep it.
161177 tokenstream:: TokenTree :: Token ( token) => TokenTree :: Token ( token) ,
0 commit comments