@@ -54,66 +54,71 @@ pub(super) fn parse(
5454 // Given the parsed tree, if there is a metavar and we are expecting matchers, actually
5555 // parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`).
5656 let tree = parse_tree ( tree, & mut iter, parsing_patterns, sess, node_id, features, edition) ;
57- match tree {
58- TokenTree :: MetaVar ( start_sp, ident) if parsing_patterns => {
59- // Not consuming the next token immediately, as it may not be a colon
60- let span = match iter. peek ( ) {
61- Some ( & tokenstream:: TokenTree :: Token (
62- Token { kind : token:: Colon , span : colon_span } ,
63- _,
64- ) ) => {
65- // Consume the colon first
66- iter. next ( ) ;
67-
68- // It's ok to consume the next tree no matter how,
69- // since if it's not a token then it will be an invalid declaration.
70- match iter. next ( ) {
71- Some ( tokenstream:: TokenTree :: Token ( token, _) ) => match token. ident ( ) {
72- Some ( ( fragment, _) ) => {
73- let span = token. span . with_lo ( start_sp. lo ( ) ) ;
74- let edition = || {
75- // FIXME(#85708) - once we properly decode a foreign
76- // crate's `SyntaxContext::root`, then we can replace
77- // this with just `span.edition()`. A
78- // `SyntaxContext::root()` from the current crate will
79- // have the edition of the current crate, and a
80- // `SyntaxContext::root()` from a foreign crate will
81- // have the edition of that crate (which we manually
82- // retrieve via the `edition` parameter).
83- if !span. from_expansion ( ) {
84- edition
85- } else {
86- span. edition ( )
87- }
88- } ;
89- let kind = NonterminalKind :: from_symbol ( fragment. name , edition)
90- . unwrap_or_else ( || {
91- sess. dcx ( ) . emit_err ( errors:: InvalidFragmentSpecifier {
92- span,
93- fragment,
94- help : VALID_FRAGMENT_NAMES_MSG . into ( ) ,
95- } ) ;
96- NonterminalKind :: Ident
97- } ) ;
98- result. push ( TokenTree :: MetaVarDecl ( span, ident, Some ( kind) ) ) ;
99- continue ;
100- }
101- _ => token. span ,
102- } ,
103- // Invalid, return a nice source location
104- _ => colon_span. with_lo ( start_sp. lo ( ) ) ,
105- }
106- }
107- // Whether it's none or some other tree, it doesn't belong to
108- // the current meta variable, returning the original span.
109- _ => start_sp,
110- } ;
11157
112- result. push ( TokenTree :: MetaVarDecl ( span, ident, None ) ) ;
113- }
58+ if !parsing_patterns {
59+ // No matchers allowed, nothing to process here
60+ result. push ( tree) ;
61+ continue ;
62+ }
63+
64+ let TokenTree :: MetaVar ( start_sp, ident) = tree else {
65+ // Not a metavariable, just return the tree
66+ result. push ( tree) ;
67+ continue ;
68+ } ;
11469
115- // Not a metavar or no matchers allowed, so just return the tree
116- _ => result. push ( tree) ,
70+ // Push a metavariable with no fragment specifier at the given span
71+ let mut push_empty_metavar = |span| {
72+ result. push ( TokenTree :: MetaVarDecl ( span, ident, None ) ) ;
73+ } ;
74+
75+ // Not consuming the next token immediately, as it may not be a colon
76+ if let Some ( peek) = iter. peek ( )
77+ && let tokenstream:: TokenTree :: Token ( token, _spacing) = peek
78+ && let Token { kind : token:: Colon , span : colon_span } = token
79+ {
80+ // Next token is a colon; consume it
81+ iter. next ( ) ;
82+
83+ // It's ok to consume the next tree no matter how,
84+ // since if it's not a token then it will be an invalid declaration.
85+ let Some ( tokenstream:: TokenTree :: Token ( token, _) ) = iter. next ( ) else {
86+ // Invalid, return a nice source location as `var:`
87+ push_empty_metavar ( colon_span. with_lo ( start_sp. lo ( ) ) ) ;
88+ continue ;
89+ } ;
90+
91+ let Some ( ( fragment, _) ) = token. ident ( ) else {
92+ // No identifier for the fragment specifier;
93+ push_empty_metavar ( token. span ) ;
94+ continue ;
95+ } ;
96+
97+ let span = token. span . with_lo ( start_sp. lo ( ) ) ;
98+ let edition = || {
99+ // FIXME(#85708) - once we properly decode a foreign
100+ // crate's `SyntaxContext::root`, then we can replace
101+ // this with just `span.edition()`. A
102+ // `SyntaxContext::root()` from the current crate will
103+ // have the edition of the current crate, and a
104+ // `SyntaxContext::root()` from a foreign crate will
105+ // have the edition of that crate (which we manually
106+ // retrieve via the `edition` parameter).
107+ if !span. from_expansion ( ) { edition } else { span. edition ( ) }
108+ } ;
109+ let kind = NonterminalKind :: from_symbol ( fragment. name , edition) . unwrap_or_else ( || {
110+ sess. dcx ( ) . emit_err ( errors:: InvalidFragmentSpecifier {
111+ span,
112+ fragment,
113+ help : VALID_FRAGMENT_NAMES_MSG . into ( ) ,
114+ } ) ;
115+ NonterminalKind :: Ident
116+ } ) ;
117+ result. push ( TokenTree :: MetaVarDecl ( span, ident, Some ( kind) ) ) ;
118+ } else {
119+ // Whether it's none or some other tree, it doesn't belong to
120+ // the current meta variable, returning the original span.
121+ push_empty_metavar ( start_sp) ;
117122 }
118123 }
119124 result
0 commit comments