@@ -47,46 +47,7 @@ impl MetaVarExpr {
47
47
check_trailing_token ( & mut iter, psess) ?;
48
48
let mut iter = args. iter ( ) ;
49
49
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 ) ?,
90
51
"count" => parse_count ( & mut iter, psess, ident. span ) ?,
91
52
"ignore" => {
92
53
eat_dollar ( & mut iter, psess, ident. span ) ?;
@@ -156,6 +117,50 @@ fn check_trailing_token<'psess>(
156
117
}
157
118
}
158
119
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
+
159
164
/// Parse a meta-variable `count` expression: `count(ident[, depth])`
160
165
fn parse_count < ' psess > (
161
166
iter : & mut TokenStreamIter < ' _ > ,
0 commit comments