@@ -109,6 +109,7 @@ impl ArgParser {
109109 parts : & [ Symbol ] ,
110110 psess : & ' sess ParseSess ,
111111 should_emit : ShouldEmit ,
112+ allow_expr_metavar : bool ,
112113 ) -> Option < Self > {
113114 Some ( match value {
114115 AttrArgs :: Empty => Self :: NoArgs ,
@@ -122,6 +123,7 @@ impl ArgParser {
122123 args. dspan . entire ( ) ,
123124 psess,
124125 ShouldEmit :: ErrorsAndLints { recovery : Recovery :: Forbidden } ,
126+ allow_expr_metavar,
125127 ) {
126128 Ok ( p) => return Some ( ArgParser :: List ( p) ) ,
127129 Err ( e) => {
@@ -147,9 +149,15 @@ impl ArgParser {
147149 }
148150
149151 Self :: List (
150- MetaItemListParser :: new ( & args. tokens , args. dspan . entire ( ) , psess, should_emit)
151- . map_err ( |e| should_emit. emit_err ( e) )
152- . ok ( ) ?,
152+ MetaItemListParser :: new (
153+ & args. tokens ,
154+ args. dspan . entire ( ) ,
155+ psess,
156+ should_emit,
157+ allow_expr_metavar,
158+ )
159+ . map_err ( |e| should_emit. emit_err ( e) )
160+ . ok ( ) ?,
153161 )
154162 }
155163 AttrArgs :: Eq { eq_span, expr } => Self :: NameValue ( NameValueParser {
@@ -217,8 +225,9 @@ impl MetaItemOrLitParser {
217225 pub fn parse_single < ' sess > (
218226 parser : & mut Parser < ' sess > ,
219227 should_emit : ShouldEmit ,
228+ allow_expr_metavar : bool ,
220229 ) -> PResult < ' sess , MetaItemOrLitParser > {
221- let mut this = MetaItemListParserContext { parser, should_emit } ;
230+ let mut this = MetaItemListParserContext { parser, should_emit, allow_expr_metavar } ;
222231 this. parse_meta_item_inner ( )
223232 }
224233
@@ -407,6 +416,7 @@ fn expr_to_lit<'sess>(
407416struct MetaItemListParserContext < ' a , ' sess > {
408417 parser : & ' a mut Parser < ' sess > ,
409418 should_emit : ShouldEmit ,
419+ allow_expr_metavar : bool ,
410420}
411421
412422impl < ' a , ' sess > MetaItemListParserContext < ' a , ' sess > {
@@ -448,19 +458,43 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
448458 }
449459
450460 fn parse_attr_item ( & mut self ) -> PResult < ' sess , MetaItemParser > {
451- if let Some ( MetaVarKind :: Meta { has_meta_form } ) = self . parser . token . is_metavar_seq ( ) {
452- return if has_meta_form {
453- let attr_item = self
454- . parser
455- . eat_metavar_seq ( MetaVarKind :: Meta { has_meta_form : true } , |this| {
456- MetaItemListParserContext { parser : this, should_emit : self . should_emit }
461+ if let Some ( metavar) = self . parser . token . is_metavar_seq ( ) {
462+ match metavar {
463+ kind @ MetaVarKind :: Expr { .. } if self . allow_expr_metavar => {
464+ return self
465+ . parser
466+ . eat_metavar_seq ( kind, |this| {
467+ MetaItemListParserContext {
468+ parser : this,
469+ should_emit : self . should_emit ,
470+ allow_expr_metavar : true ,
471+ }
457472 . parse_attr_item ( )
458- } )
459- . unwrap ( ) ;
460- Ok ( attr_item)
461- } else {
462- self . parser . unexpected_any ( )
463- } ;
473+ } )
474+ . ok_or_else ( || {
475+ self . parser . unexpected_any :: < core:: convert:: Infallible > ( ) . unwrap_err ( )
476+ } ) ;
477+ }
478+ MetaVarKind :: Meta { has_meta_form } => {
479+ return if has_meta_form {
480+ let attr_item = self
481+ . parser
482+ . eat_metavar_seq ( MetaVarKind :: Meta { has_meta_form : true } , |this| {
483+ MetaItemListParserContext {
484+ parser : this,
485+ should_emit : self . should_emit ,
486+ allow_expr_metavar : self . allow_expr_metavar ,
487+ }
488+ . parse_attr_item ( )
489+ } )
490+ . unwrap ( ) ;
491+ Ok ( attr_item)
492+ } else {
493+ self . parser . unexpected_any ( )
494+ } ;
495+ }
496+ _ => { }
497+ }
464498 }
465499
466500 let path = self . parser . parse_path ( PathStyle :: Mod ) ?;
@@ -469,8 +503,12 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
469503 let args = if self . parser . check ( exp ! ( OpenParen ) ) {
470504 let start = self . parser . token . span ;
471505 let ( sub_parsers, _) = self . parser . parse_paren_comma_seq ( |parser| {
472- MetaItemListParserContext { parser, should_emit : self . should_emit }
473- . parse_meta_item_inner ( )
506+ MetaItemListParserContext {
507+ parser,
508+ should_emit : self . should_emit ,
509+ allow_expr_metavar : self . allow_expr_metavar ,
510+ }
511+ . parse_meta_item_inner ( )
474512 } ) ?;
475513 let end = self . parser . prev_token . span ;
476514 ArgParser :: List ( MetaItemListParser { sub_parsers, span : start. with_hi ( end. hi ( ) ) } )
@@ -580,13 +618,15 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
580618 psess : & ' sess ParseSess ,
581619 span : Span ,
582620 should_emit : ShouldEmit ,
621+ allow_expr_metavar : bool ,
583622 ) -> PResult < ' sess , MetaItemListParser > {
584623 let mut parser = Parser :: new ( psess, tokens, None ) ;
585624 if let ShouldEmit :: ErrorsAndLints { recovery } = should_emit {
586625 parser = parser. recovery ( recovery) ;
587626 }
588627
589- let mut this = MetaItemListParserContext { parser : & mut parser, should_emit } ;
628+ let mut this =
629+ MetaItemListParserContext { parser : & mut parser, should_emit, allow_expr_metavar } ;
590630
591631 // Presumably, the majority of the time there will only be one attr.
592632 let mut sub_parsers = ThinVec :: with_capacity ( 1 ) ;
@@ -618,8 +658,15 @@ impl MetaItemListParser {
618658 span : Span ,
619659 psess : & ' sess ParseSess ,
620660 should_emit : ShouldEmit ,
661+ allow_expr_metavar : bool ,
621662 ) -> Result < Self , Diag < ' sess > > {
622- MetaItemListParserContext :: parse ( tokens. clone ( ) , psess, span, should_emit)
663+ MetaItemListParserContext :: parse (
664+ tokens. clone ( ) ,
665+ psess,
666+ span,
667+ should_emit,
668+ allow_expr_metavar,
669+ )
623670 }
624671
625672 /// Lets you pick and choose as what you want to parse each element in the list
0 commit comments