@@ -10,6 +10,10 @@ use rustc_span::Span;
1010/// A meta-variable expression, for expansions based on properties of meta-variables.
1111#[ derive( Debug , Clone , PartialEq , Encodable , Decodable ) ]
1212pub ( 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+
1317 /// The number of repetitions of an identifier.
1418 Count ( Ident , usize ) ,
1519
@@ -41,6 +45,16 @@ impl MetaVarExpr {
4145 check_trailing_token ( & mut tts, sess) ?;
4246 let mut iter = args. trees ( ) ;
4347 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+ }
4458 "count" => parse_count ( & mut iter, sess, ident. span ) ?,
4559 "ignore" => {
4660 eat_dollar ( & mut iter, sess, ident. span ) ?;
@@ -67,7 +81,7 @@ impl MetaVarExpr {
6781 pub ( crate ) fn ident ( & self ) -> Option < Ident > {
6882 match * self {
6983 MetaVarExpr :: Count ( ident, _) | MetaVarExpr :: Ignore ( ident) => Some ( ident) ,
70- MetaVarExpr :: Index ( ..) | MetaVarExpr :: Length ( ..) => None ,
84+ MetaVarExpr :: Concat ( .. ) | MetaVarExpr :: Index ( ..) | MetaVarExpr :: Length ( ..) => None ,
7185 }
7286 }
7387}
@@ -170,6 +184,17 @@ fn try_eat_comma(iter: &mut RefTokenTreeCursor<'_>) -> bool {
170184 false
171185}
172186
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+
173198/// Expects that the next item is a dollar sign.
174199fn eat_dollar < ' sess > (
175200 iter : & mut RefTokenTreeCursor < ' _ > ,
0 commit comments