@@ -47,46 +47,7 @@ impl MetaVarExpr {
4747 check_trailing_token ( & mut iter, psess) ?;
4848 let mut iter = args. iter ( ) ;
4949 let rslt = match ident. as_str ( ) {
50- "concat" => {
51- let mut result = Vec :: new ( ) ;
52- loop {
53- let is_var = try_eat_dollar ( & mut iter) ;
54- let token = parse_token ( & mut iter, psess, outer_span) ?;
55- let element = if is_var {
56- MetaVarExprConcatElem :: Var ( parse_ident_from_token ( psess, token) ?)
57- } else if let TokenKind :: Literal ( Lit {
58- kind : token:: LitKind :: Str ,
59- symbol,
60- suffix : None ,
61- } ) = token. kind
62- {
63- MetaVarExprConcatElem :: Literal ( symbol)
64- } else {
65- match parse_ident_from_token ( psess, token) {
66- Err ( err) => {
67- err. cancel ( ) ;
68- return Err ( psess
69- . dcx ( )
70- . struct_span_err ( token. span , UNSUPPORTED_CONCAT_ELEM_ERR ) ) ;
71- }
72- Ok ( elem) => MetaVarExprConcatElem :: Ident ( elem) ,
73- }
74- } ;
75- result. push ( element) ;
76- if iter. peek ( ) . is_none ( ) {
77- break ;
78- }
79- if !try_eat_comma ( & mut iter) {
80- return Err ( psess. dcx ( ) . struct_span_err ( outer_span, "expected comma" ) ) ;
81- }
82- }
83- if result. len ( ) < 2 {
84- return Err ( psess
85- . dcx ( )
86- . struct_span_err ( ident. span , "`concat` must have at least two elements" ) ) ;
87- }
88- MetaVarExpr :: Concat ( result. into ( ) )
89- }
50+ "concat" => parse_concat ( & mut iter, psess, outer_span, ident. span ) ?,
9051 "count" => parse_count ( & mut iter, psess, ident. span ) ?,
9152 "ignore" => {
9253 eat_dollar ( & mut iter, psess, ident. span ) ?;
@@ -156,6 +117,50 @@ fn check_trailing_token<'psess>(
156117 }
157118}
158119
120+ /// Parse a meta-variable `concat` expression: `concat($metavar, ident, ...)`.
121+ fn parse_concat < ' psess > (
122+ iter : & mut TokenStreamIter < ' _ > ,
123+ psess : & ' psess ParseSess ,
124+ outer_span : Span ,
125+ expr_ident_span : Span ,
126+ ) -> PResult < ' psess , MetaVarExpr > {
127+ let mut result = Vec :: new ( ) ;
128+ loop {
129+ let is_var = try_eat_dollar ( iter) ;
130+ let token = parse_token ( iter, psess, outer_span) ?;
131+ let element = if is_var {
132+ MetaVarExprConcatElem :: Var ( parse_ident_from_token ( psess, token) ?)
133+ } else if let TokenKind :: Literal ( Lit { kind : token:: LitKind :: Str , symbol, suffix : None } ) =
134+ token. kind
135+ {
136+ MetaVarExprConcatElem :: Literal ( symbol)
137+ } else {
138+ match parse_ident_from_token ( psess, token) {
139+ Err ( err) => {
140+ err. cancel ( ) ;
141+ return Err ( psess
142+ . dcx ( )
143+ . struct_span_err ( token. span , UNSUPPORTED_CONCAT_ELEM_ERR ) ) ;
144+ }
145+ Ok ( elem) => MetaVarExprConcatElem :: Ident ( elem) ,
146+ }
147+ } ;
148+ result. push ( element) ;
149+ if iter. peek ( ) . is_none ( ) {
150+ break ;
151+ }
152+ if !try_eat_comma ( iter) {
153+ return Err ( psess. dcx ( ) . struct_span_err ( outer_span, "expected comma" ) ) ;
154+ }
155+ }
156+ if result. len ( ) < 2 {
157+ return Err ( psess
158+ . dcx ( )
159+ . struct_span_err ( expr_ident_span, "`concat` must have at least two elements" ) ) ;
160+ }
161+ Ok ( MetaVarExpr :: Concat ( result. into ( ) ) )
162+ }
163+
159164/// Parse a meta-variable `count` expression: `count(ident[, depth])`
160165fn parse_count < ' psess > (
161166 iter : & mut TokenStreamIter < ' _ > ,
0 commit comments