@@ -557,17 +557,13 @@ fn lockstep_iter_size(
557
557
}
558
558
}
559
559
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
+ } )
571
567
}
572
568
TokenTree :: Token ( ..) => LockstepIterSize :: Unconstrained ,
573
569
}
@@ -695,7 +691,23 @@ fn transcribe_metavar_expr<'a>(
695
691
let symbol = match element {
696
692
MetaVarExprConcatElem :: Ident ( elem) => elem. name ,
697
693
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
+ }
699
711
} ;
700
712
concatenated. push_str ( symbol. as_str ( ) ) ;
701
713
}
@@ -752,41 +764,48 @@ fn transcribe_metavar_expr<'a>(
752
764
}
753
765
754
766
/// 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 > (
756
768
dcx : DiagCtxtHandle < ' a > ,
757
- ident : Ident ,
758
- interp : & FxHashMap < MacroRulesNormalizedIdent , NamedMatch > ,
769
+ pnr : & ParseNtResult ,
770
+ span_err : Span ,
759
771
) -> 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) => {
762
774
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 ) ) ;
764
776
}
765
777
return Ok ( nt_ident. name ) ;
766
778
}
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 ) ) ;
778
785
}
786
+ return Ok ( * symbol) ;
779
787
}
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 =>
784
801
{
785
802
return Ok ( * symbol) ;
786
803
}
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) ) ,
787
810
}
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 ) )
792
811
}
0 commit comments