@@ -450,6 +450,102 @@ pub(super) fn transcribe<'a>(
450450 }
451451}
452452
453+ fn transcribe_metavar_expr < ' a > (
454+ dcx : DiagCtxtHandle < ' a > ,
455+ expr : & MetaVarExpr ,
456+ interp : & FxHashMap < MacroRulesNormalizedIdent , NamedMatch > ,
457+ marker : & mut Marker ,
458+ repeats : & [ ( usize , usize ) ] ,
459+ result : & mut Vec < TokenTree > ,
460+ sp : & DelimSpan ,
461+ symbol_gallery : & SymbolGallery ,
462+ ) -> PResult < ' a , ( ) > {
463+ let mut visited_span = || {
464+ let mut span = sp. entire ( ) ;
465+ marker. mark_span ( & mut span) ;
466+ span
467+ } ;
468+ match * expr {
469+ MetaVarExpr :: Concat ( ref elements) => {
470+ let mut concatenated = String :: new ( ) ;
471+ for element in elements. into_iter ( ) {
472+ let symbol = match element {
473+ MetaVarExprConcatElem :: Ident ( elem) => elem. name ,
474+ MetaVarExprConcatElem :: Literal ( elem) => * elem,
475+ MetaVarExprConcatElem :: Var ( ident) => {
476+ match matched_from_ident ( dcx, * ident, interp) ? {
477+ NamedMatch :: MatchedSeq ( named_matches) => {
478+ let Some ( ( curr_idx, _) ) = repeats. last ( ) else {
479+ return Err ( dcx. struct_span_err ( sp. entire ( ) , "invalid syntax" ) ) ;
480+ } ;
481+ match & named_matches[ * curr_idx] {
482+ // FIXME(c410-f3r) Nested repetitions are unimplemented
483+ MatchedSeq ( _) => unimplemented ! ( ) ,
484+ MatchedSingle ( pnr) => {
485+ extract_symbol_from_pnr ( dcx, pnr, ident. span ) ?
486+ }
487+ }
488+ }
489+ NamedMatch :: MatchedSingle ( pnr) => {
490+ extract_symbol_from_pnr ( dcx, pnr, ident. span ) ?
491+ }
492+ }
493+ }
494+ } ;
495+ concatenated. push_str ( symbol. as_str ( ) ) ;
496+ }
497+ let symbol = nfc_normalize ( & concatenated) ;
498+ let concatenated_span = visited_span ( ) ;
499+ if !rustc_lexer:: is_ident ( symbol. as_str ( ) ) {
500+ return Err ( dcx. struct_span_err (
501+ concatenated_span,
502+ "`${concat(..)}` is not generating a valid identifier" ,
503+ ) ) ;
504+ }
505+ symbol_gallery. insert ( symbol, concatenated_span) ;
506+ // The current implementation marks the span as coming from the macro regardless of
507+ // contexts of the concatenated identifiers but this behavior may change in the
508+ // future.
509+ result. push ( TokenTree :: Token (
510+ Token :: from_ast_ident ( Ident :: new ( symbol, concatenated_span) ) ,
511+ Spacing :: Alone ,
512+ ) ) ;
513+ }
514+ MetaVarExpr :: Count ( original_ident, depth) => {
515+ let matched = matched_from_ident ( dcx, original_ident, interp) ?;
516+ let count = count_repetitions ( dcx, depth, matched, repeats, sp) ?;
517+ let tt = TokenTree :: token_alone (
518+ TokenKind :: lit ( token:: Integer , sym:: integer ( count) , None ) ,
519+ visited_span ( ) ,
520+ ) ;
521+ result. push ( tt) ;
522+ }
523+ MetaVarExpr :: Ignore ( original_ident) => {
524+ // Used to ensure that `original_ident` is present in the LHS
525+ let _ = matched_from_ident ( dcx, original_ident, interp) ?;
526+ }
527+ MetaVarExpr :: Index ( depth) => match repeats. iter ( ) . nth_back ( depth) {
528+ Some ( ( index, _) ) => {
529+ result. push ( TokenTree :: token_alone (
530+ TokenKind :: lit ( token:: Integer , sym:: integer ( * index) , None ) ,
531+ visited_span ( ) ,
532+ ) ) ;
533+ }
534+ None => return Err ( out_of_bounds_err ( dcx, repeats. len ( ) , sp. entire ( ) , "index" ) ) ,
535+ } ,
536+ MetaVarExpr :: Len ( depth) => match repeats. iter ( ) . nth_back ( depth) {
537+ Some ( ( _, length) ) => {
538+ result. push ( TokenTree :: token_alone (
539+ TokenKind :: lit ( token:: Integer , sym:: integer ( * length) , None ) ,
540+ visited_span ( ) ,
541+ ) ) ;
542+ }
543+ None => return Err ( out_of_bounds_err ( dcx, repeats. len ( ) , sp. entire ( ) , "len" ) ) ,
544+ } ,
545+ }
546+ Ok ( ( ) )
547+ }
548+
453549/// Store the metavariable span for this original span into a side table.
454550/// FIXME: Try to put the metavariable span into `SpanData` instead of a side table (#118517).
455551/// An optimal encoding for inlined spans will need to be selected to minimize regressions.
@@ -762,102 +858,6 @@ fn out_of_bounds_err<'a>(dcx: DiagCtxtHandle<'a>, max: usize, span: Span, ty: &s
762858 dcx. struct_span_err ( span, msg)
763859}
764860
765- fn transcribe_metavar_expr < ' a > (
766- dcx : DiagCtxtHandle < ' a > ,
767- expr : & MetaVarExpr ,
768- interp : & FxHashMap < MacroRulesNormalizedIdent , NamedMatch > ,
769- marker : & mut Marker ,
770- repeats : & [ ( usize , usize ) ] ,
771- result : & mut Vec < TokenTree > ,
772- sp : & DelimSpan ,
773- symbol_gallery : & SymbolGallery ,
774- ) -> PResult < ' a , ( ) > {
775- let mut visited_span = || {
776- let mut span = sp. entire ( ) ;
777- marker. mark_span ( & mut span) ;
778- span
779- } ;
780- match * expr {
781- MetaVarExpr :: Concat ( ref elements) => {
782- let mut concatenated = String :: new ( ) ;
783- for element in elements. into_iter ( ) {
784- let symbol = match element {
785- MetaVarExprConcatElem :: Ident ( elem) => elem. name ,
786- MetaVarExprConcatElem :: Literal ( elem) => * elem,
787- MetaVarExprConcatElem :: Var ( ident) => {
788- match matched_from_ident ( dcx, * ident, interp) ? {
789- NamedMatch :: MatchedSeq ( named_matches) => {
790- let Some ( ( curr_idx, _) ) = repeats. last ( ) else {
791- return Err ( dcx. struct_span_err ( sp. entire ( ) , "invalid syntax" ) ) ;
792- } ;
793- match & named_matches[ * curr_idx] {
794- // FIXME(c410-f3r) Nested repetitions are unimplemented
795- MatchedSeq ( _) => unimplemented ! ( ) ,
796- MatchedSingle ( pnr) => {
797- extract_symbol_from_pnr ( dcx, pnr, ident. span ) ?
798- }
799- }
800- }
801- NamedMatch :: MatchedSingle ( pnr) => {
802- extract_symbol_from_pnr ( dcx, pnr, ident. span ) ?
803- }
804- }
805- }
806- } ;
807- concatenated. push_str ( symbol. as_str ( ) ) ;
808- }
809- let symbol = nfc_normalize ( & concatenated) ;
810- let concatenated_span = visited_span ( ) ;
811- if !rustc_lexer:: is_ident ( symbol. as_str ( ) ) {
812- return Err ( dcx. struct_span_err (
813- concatenated_span,
814- "`${concat(..)}` is not generating a valid identifier" ,
815- ) ) ;
816- }
817- symbol_gallery. insert ( symbol, concatenated_span) ;
818- // The current implementation marks the span as coming from the macro regardless of
819- // contexts of the concatenated identifiers but this behavior may change in the
820- // future.
821- result. push ( TokenTree :: Token (
822- Token :: from_ast_ident ( Ident :: new ( symbol, concatenated_span) ) ,
823- Spacing :: Alone ,
824- ) ) ;
825- }
826- MetaVarExpr :: Count ( original_ident, depth) => {
827- let matched = matched_from_ident ( dcx, original_ident, interp) ?;
828- let count = count_repetitions ( dcx, depth, matched, repeats, sp) ?;
829- let tt = TokenTree :: token_alone (
830- TokenKind :: lit ( token:: Integer , sym:: integer ( count) , None ) ,
831- visited_span ( ) ,
832- ) ;
833- result. push ( tt) ;
834- }
835- MetaVarExpr :: Ignore ( original_ident) => {
836- // Used to ensure that `original_ident` is present in the LHS
837- let _ = matched_from_ident ( dcx, original_ident, interp) ?;
838- }
839- MetaVarExpr :: Index ( depth) => match repeats. iter ( ) . nth_back ( depth) {
840- Some ( ( index, _) ) => {
841- result. push ( TokenTree :: token_alone (
842- TokenKind :: lit ( token:: Integer , sym:: integer ( * index) , None ) ,
843- visited_span ( ) ,
844- ) ) ;
845- }
846- None => return Err ( out_of_bounds_err ( dcx, repeats. len ( ) , sp. entire ( ) , "index" ) ) ,
847- } ,
848- MetaVarExpr :: Len ( depth) => match repeats. iter ( ) . nth_back ( depth) {
849- Some ( ( _, length) ) => {
850- result. push ( TokenTree :: token_alone (
851- TokenKind :: lit ( token:: Integer , sym:: integer ( * length) , None ) ,
852- visited_span ( ) ,
853- ) ) ;
854- }
855- None => return Err ( out_of_bounds_err ( dcx, repeats. len ( ) , sp. entire ( ) , "len" ) ) ,
856- } ,
857- }
858- Ok ( ( ) )
859- }
860-
861861/// Extracts an metavariable symbol that can be an identifier, a token tree or a literal.
862862fn extract_symbol_from_pnr < ' a > (
863863 dcx : DiagCtxtHandle < ' a > ,
0 commit comments