@@ -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 ) ?;
@@ -126,6 +87,22 @@ impl MetaVarExpr {
126
87
}
127
88
}
128
89
90
+ // Checks if there are any remaining tokens. For example, `${ignore(ident ... a b c ...)}`
91
+ fn check_trailing_token < ' psess > (
92
+ iter : & mut TokenStreamIter < ' _ > ,
93
+ psess : & ' psess ParseSess ,
94
+ ) -> PResult < ' psess , ( ) > {
95
+ if let Some ( tt) = iter. next ( ) {
96
+ let mut diag = psess
97
+ . dcx ( )
98
+ . struct_span_err ( tt. span ( ) , format ! ( "unexpected token: {}" , pprust:: tt_to_string( tt) ) ) ;
99
+ diag. span_note ( tt. span ( ) , "meta-variable expression must not have trailing tokens" ) ;
100
+ Err ( diag)
101
+ } else {
102
+ Ok ( ( ) )
103
+ }
104
+ }
105
+
129
106
/// Indicates what is placed in a `concat` parameter. For example, literals
130
107
/// (`${concat("foo", "bar")}`) or adhoc identifiers (`${concat(foo, bar)}`).
131
108
#[ derive( Debug , Decodable , Encodable , PartialEq ) ]
@@ -140,20 +117,48 @@ pub(crate) enum MetaVarExprConcatElem {
140
117
Var ( Ident ) ,
141
118
}
142
119
143
- // Checks if there are any remaining tokens. For example, `${ignore( ident ... a b c ...)}`
144
- fn check_trailing_token < ' psess > (
120
+ /// Parse a meta-variable `concat` expression: `concat($metavar, ident, ...)`.
121
+ fn parse_concat < ' psess > (
145
122
iter : & mut TokenStreamIter < ' _ > ,
146
123
psess : & ' psess ParseSess ,
147
- ) -> PResult < ' psess , ( ) > {
148
- if let Some ( tt) = iter. next ( ) {
149
- let mut diag = psess
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
150
158
. dcx ( )
151
- . struct_span_err ( tt. span ( ) , format ! ( "unexpected token: {}" , pprust:: tt_to_string( tt) ) ) ;
152
- diag. span_note ( tt. span ( ) , "meta-variable expression must not have trailing tokens" ) ;
153
- Err ( diag)
154
- } else {
155
- Ok ( ( ) )
159
+ . struct_span_err ( expr_ident_span, "`concat` must have at least two elements" ) ) ;
156
160
}
161
+ Ok ( MetaVarExpr :: Concat ( result. into ( ) ) )
157
162
}
158
163
159
164
/// Parse a meta-variable `count` expression: `count(ident[, depth])`
0 commit comments