@@ -557,17 +557,13 @@ fn lockstep_iter_size(
557557 }
558558 }
559559 TokenTree :: MetaVarExpr ( _, expr) => {
560- let default_rslt = LockstepIterSize :: Unconstrained ;
561- let Some ( ident) = expr. ident ( ) else {
562- return default_rslt;
563- } ;
564- let name = MacroRulesNormalizedIdent :: new ( ident) ;
565- match lookup_cur_matched ( name, interpolations, repeats) {
566- Some ( MatchedSeq ( ads) ) => {
567- default_rslt. with ( LockstepIterSize :: Constraint ( ads. len ( ) , name) )
568- }
569- _ => default_rslt,
570- }
560+ expr. for_each_metavar ( LockstepIterSize :: Unconstrained , |lis, ident| {
561+ lis. with ( lockstep_iter_size (
562+ & TokenTree :: MetaVar ( ident. span , * ident) ,
563+ interpolations,
564+ repeats,
565+ ) )
566+ } )
571567 }
572568 TokenTree :: Token ( ..) => LockstepIterSize :: Unconstrained ,
573569 }
@@ -695,7 +691,23 @@ fn transcribe_metavar_expr<'a>(
695691 let symbol = match element {
696692 MetaVarExprConcatElem :: Ident ( elem) => elem. name ,
697693 MetaVarExprConcatElem :: Literal ( elem) => * elem,
698- MetaVarExprConcatElem :: Var ( elem) => extract_var_symbol ( dcx, * elem, interp) ?,
694+ MetaVarExprConcatElem :: Var ( ident) => {
695+ match matched_from_ident ( dcx, * ident, interp) ? {
696+ NamedMatch :: MatchedSeq ( named_matches) => {
697+ let curr_idx = repeats. last ( ) . unwrap ( ) . 0 ;
698+ match & named_matches[ curr_idx] {
699+ // FIXME(c410-f3r) Nested repetitions are unimplemented
700+ MatchedSeq ( _) => unimplemented ! ( ) ,
701+ MatchedSingle ( pnr) => {
702+ extract_symbol_from_pnr ( dcx, pnr, ident. span ) ?
703+ }
704+ }
705+ }
706+ NamedMatch :: MatchedSingle ( pnr) => {
707+ extract_symbol_from_pnr ( dcx, pnr, ident. span ) ?
708+ }
709+ }
710+ }
699711 } ;
700712 concatenated. push_str ( symbol. as_str ( ) ) ;
701713 }
@@ -752,41 +764,48 @@ fn transcribe_metavar_expr<'a>(
752764}
753765
754766/// Extracts an metavariable symbol that can be an identifier, a token tree or a literal.
755- fn extract_var_symbol < ' a > (
767+ fn extract_symbol_from_pnr < ' a > (
756768 dcx : DiagCtxtHandle < ' a > ,
757- ident : Ident ,
758- interp : & FxHashMap < MacroRulesNormalizedIdent , NamedMatch > ,
769+ pnr : & ParseNtResult ,
770+ span_err : Span ,
759771) -> PResult < ' a , Symbol > {
760- if let NamedMatch :: MatchedSingle ( pnr) = matched_from_ident ( dcx , ident , interp ) ? {
761- if let ParseNtResult :: Ident ( nt_ident, is_raw) = pnr {
772+ match pnr {
773+ ParseNtResult :: Ident ( nt_ident, is_raw) => {
762774 if let IdentIsRaw :: Yes = is_raw {
763- return Err ( dcx. struct_span_err ( ident . span , RAW_IDENT_ERR ) ) ;
775+ return Err ( dcx. struct_span_err ( span_err , RAW_IDENT_ERR ) ) ;
764776 }
765777 return Ok ( nt_ident. name ) ;
766778 }
767-
768- if let ParseNtResult :: Tt ( TokenTree :: Token ( Token { kind, .. } , _) ) = pnr {
769- if let TokenKind :: Ident ( symbol, is_raw) = kind {
770- if let IdentIsRaw :: Yes = is_raw {
771- return Err ( dcx. struct_span_err ( ident. span , RAW_IDENT_ERR ) ) ;
772- }
773- return Ok ( * symbol) ;
774- }
775-
776- if let TokenKind :: Literal ( Lit { kind : LitKind :: Str , symbol, suffix : None } ) = kind {
777- return Ok ( * symbol) ;
779+ ParseNtResult :: Tt ( TokenTree :: Token (
780+ Token { kind : TokenKind :: Ident ( symbol, is_raw) , .. } ,
781+ _,
782+ ) ) => {
783+ if let IdentIsRaw :: Yes = is_raw {
784+ return Err ( dcx. struct_span_err ( span_err, RAW_IDENT_ERR ) ) ;
778785 }
786+ return Ok ( * symbol) ;
779787 }
780-
781- if let ParseNtResult :: Nt ( nt) = pnr
782- && let Nonterminal :: NtLiteral ( expr) = & * * nt
783- && let ExprKind :: Lit ( Lit { kind : LitKind :: Str , symbol, suffix : None } ) = & expr. kind
788+ ParseNtResult :: Tt ( TokenTree :: Token (
789+ Token {
790+ kind : TokenKind :: Literal ( Lit { kind : LitKind :: Str , symbol, suffix : None } ) ,
791+ ..
792+ } ,
793+ _,
794+ ) ) => {
795+ return Ok ( * symbol) ;
796+ }
797+ ParseNtResult :: Nt ( nt)
798+ if let Nonterminal :: NtLiteral ( expr) = & * * nt
799+ && let ExprKind :: Lit ( Lit { kind : LitKind :: Str , symbol, suffix : None } ) =
800+ & expr. kind =>
784801 {
785802 return Ok ( * symbol) ;
786803 }
804+ _ => Err ( dcx
805+ . struct_err (
806+ "metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`" ,
807+ )
808+ . with_note ( "currently only string literals are supported" )
809+ . with_span ( span_err) ) ,
787810 }
788- Err ( dcx
789- . struct_err ( "metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`" )
790- . with_note ( "currently only string literals are supported" )
791- . with_span ( ident. span ) )
792811}
0 commit comments