@@ -6,14 +6,14 @@ use crate::errors::{
6
6
use crate :: mbe:: macro_parser:: { MatchedNonterminal , MatchedSeq , MatchedTokenTree , NamedMatch } ;
7
7
use crate :: mbe:: { self , MetaVarExpr } ;
8
8
use rustc_ast:: mut_visit:: { self , MutVisitor } ;
9
- use rustc_ast:: token:: { self , Delimiter , Token , TokenKind } ;
9
+ use rustc_ast:: token:: { self , Delimiter , Nonterminal , Token , TokenKind } ;
10
10
use rustc_ast:: tokenstream:: { DelimSpacing , DelimSpan , Spacing , TokenStream , TokenTree } ;
11
11
use rustc_data_structures:: fx:: FxHashMap ;
12
12
use rustc_errors:: { pluralize, PResult } ;
13
13
use rustc_errors:: { DiagnosticBuilder , ErrorGuaranteed } ;
14
14
use rustc_span:: hygiene:: { LocalExpnId , Transparency } ;
15
15
use rustc_span:: symbol:: { sym, Ident , MacroRulesNormalizedIdent } ;
16
- use rustc_span:: Span ;
16
+ use rustc_span:: { Span , Symbol } ;
17
17
18
18
use smallvec:: { smallvec, SmallVec } ;
19
19
use std:: mem;
@@ -558,6 +558,43 @@ fn transcribe_metavar_expr<'a>(
558
558
span
559
559
} ;
560
560
match * expr {
561
+ MetaVarExpr :: Concat { lhs_ident, lhs_is_var, rhs_ident, rhs_is_var } => {
562
+ fn manage_element < ' a > (
563
+ cx : & ExtCtxt < ' a > ,
564
+ ident : Ident ,
565
+ interp : & FxHashMap < MacroRulesNormalizedIdent , NamedMatch > ,
566
+ is_var : bool ,
567
+ repeats : & [ ( usize , usize ) ] ,
568
+ ) -> PResult < ' a , String > {
569
+ if !is_var {
570
+ return Ok ( ident. to_string ( ) ) ;
571
+ }
572
+ let span = ident. span ;
573
+ let mrni = MacroRulesNormalizedIdent :: new ( ident) ;
574
+ if let Some ( nm) = lookup_cur_matched ( mrni, interp, & repeats)
575
+ && let MatchedNonterminal ( nt) = nm
576
+ {
577
+ if let Nonterminal :: NtIdent ( nt_ident, _) = & nt. 0 {
578
+ Ok ( nt_ident. to_string ( ) )
579
+ } else {
580
+ Err ( cx. struct_span_err (
581
+ span,
582
+ "`${concat(..)}` currently only accepts identifiers as parameters" ,
583
+ ) )
584
+ }
585
+ } else {
586
+ Ok ( ident. to_string ( ) )
587
+ }
588
+ }
589
+
590
+ let lhs_elem = manage_element ( cx, lhs_ident, interp, lhs_is_var, repeats) ?;
591
+ let rhs_elem = manage_element ( cx, rhs_ident, interp, rhs_is_var, repeats) ?;
592
+ let symbol_string = lhs_elem + & rhs_elem;
593
+ result. push ( TokenTree :: Token (
594
+ Token :: from_ast_ident ( Ident :: new ( Symbol :: intern ( & symbol_string) , visited_span ( ) ) ) ,
595
+ Spacing :: Alone ,
596
+ ) ) ;
597
+ }
561
598
MetaVarExpr :: Count ( original_ident, depth) => {
562
599
let matched = matched_from_ident ( cx, original_ident, interp) ?;
563
600
let count = count_repetitions ( cx, depth, matched, repeats, sp) ?;
0 commit comments