@@ -10,6 +10,10 @@ use rustc_span::Span;
10
10
/// A meta-variable expression, for expansions based on properties of meta-variables.
11
11
#[ derive( Debug , Clone , PartialEq , Encodable , Decodable ) ]
12
12
pub ( crate ) enum MetaVarExpr {
13
+ /// Unification of two identifiers. The `bool` of each element indicates if there is a
14
+ /// preceding dollar sign.
15
+ Concat ( ( Ident , bool ) , ( Ident , bool ) ) ,
16
+
13
17
/// The number of repetitions of an identifier.
14
18
Count ( Ident , usize ) ,
15
19
@@ -41,6 +45,16 @@ impl MetaVarExpr {
41
45
check_trailing_token ( & mut tts, sess) ?;
42
46
let mut iter = args. trees ( ) ;
43
47
let rslt = match ident. as_str ( ) {
48
+ "concat" => {
49
+ let lhs_sign = try_eat_dollar ( & mut iter) ;
50
+ let lhs = parse_ident ( & mut iter, sess, ident. span ) ?;
51
+ if !try_eat_comma ( & mut iter) {
52
+ return Err ( sess. span_diagnostic . struct_span_err ( ident. span , "expected comma" ) ) ;
53
+ }
54
+ let rhs_sign = try_eat_dollar ( & mut iter) ;
55
+ let rhs = parse_ident ( & mut iter, sess, ident. span ) ?;
56
+ MetaVarExpr :: Concat ( ( lhs, lhs_sign) , ( rhs, rhs_sign) )
57
+ }
44
58
"count" => parse_count ( & mut iter, sess, ident. span ) ?,
45
59
"ignore" => {
46
60
eat_dollar ( & mut iter, sess, ident. span ) ?;
@@ -67,7 +81,7 @@ impl MetaVarExpr {
67
81
pub ( crate ) fn ident ( & self ) -> Option < Ident > {
68
82
match * self {
69
83
MetaVarExpr :: Count ( ident, _) | MetaVarExpr :: Ignore ( ident) => Some ( ident) ,
70
- MetaVarExpr :: Index ( ..) | MetaVarExpr :: Length ( ..) => None ,
84
+ MetaVarExpr :: Concat ( .. ) | MetaVarExpr :: Index ( ..) | MetaVarExpr :: Length ( ..) => None ,
71
85
}
72
86
}
73
87
}
@@ -170,6 +184,17 @@ fn try_eat_comma(iter: &mut RefTokenTreeCursor<'_>) -> bool {
170
184
false
171
185
}
172
186
187
+ /// Tries to move the iterator forward returning `true` if there is a dollar sign. If not, then the
188
+ /// iterator is not modified and the result is `false`.
189
+ fn try_eat_dollar ( iter : & mut RefTokenTreeCursor < ' _ > ) -> bool {
190
+ if let Some ( TokenTree :: Token ( token:: Token { kind : token:: Dollar , .. } , _) ) = iter. look_ahead ( 0 )
191
+ {
192
+ let _ = iter. next ( ) ;
193
+ return true ;
194
+ }
195
+ false
196
+ }
197
+
173
198
/// Expects that the next item is a dollar sign.
174
199
fn eat_dollar < ' sess > (
175
200
iter : & mut RefTokenTreeCursor < ' _ > ,
0 commit comments