@@ -6,14 +6,14 @@ use crate::errors::{
66use crate :: mbe:: macro_parser:: { MatchedNonterminal , MatchedSeq , MatchedTokenTree , NamedMatch } ;
77use crate :: mbe:: { self , MetaVarExpr } ;
88use 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 } ;
1010use rustc_ast:: tokenstream:: { DelimSpacing , DelimSpan , Spacing , TokenStream , TokenTree } ;
1111use rustc_data_structures:: fx:: FxHashMap ;
1212use rustc_errors:: { pluralize, PResult } ;
1313use rustc_errors:: { DiagnosticBuilder , ErrorGuaranteed } ;
1414use rustc_span:: hygiene:: { LocalExpnId , Transparency } ;
1515use rustc_span:: symbol:: { sym, Ident , MacroRulesNormalizedIdent } ;
16- use rustc_span:: Span ;
16+ use rustc_span:: { Span , Symbol } ;
1717
1818use smallvec:: { smallvec, SmallVec } ;
1919use std:: mem;
@@ -558,6 +558,43 @@ fn transcribe_metavar_expr<'a>(
558558 span
559559 } ;
560560 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+ }
561598 MetaVarExpr :: Count ( original_ident, depth) => {
562599 let matched = matched_from_ident ( cx, original_ident, interp) ?;
563600 let count = count_repetitions ( cx, depth, matched, repeats, sp) ?;
0 commit comments