@@ -23,7 +23,7 @@ pub use GenericArgs::*;
2323pub use UnsafeSource :: * ;
2424
2525use crate :: ptr:: P ;
26- use crate :: token:: { self , CommentKind , Delimiter , Token } ;
26+ use crate :: token:: { self , CommentKind , Delimiter , Token , TokenKind } ;
2727use crate :: tokenstream:: { DelimSpan , LazyTokenStream , TokenStream , TokenTree } ;
2828
2929use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
@@ -1532,7 +1532,7 @@ impl MacCall {
15321532}
15331533
15341534/// Arguments passed to an attribute or a function-like macro.
1535- #[ derive( Clone , Encodable , Decodable , Debug , HashStable_Generic ) ]
1535+ #[ derive( Clone , Encodable , Decodable , Debug ) ]
15361536pub enum MacArgs {
15371537 /// No arguments - `#[attr]`.
15381538 Empty ,
@@ -1542,11 +1542,20 @@ pub enum MacArgs {
15421542 Eq (
15431543 /// Span of the `=` token.
15441544 Span ,
1545- /// "value" as a nonterminal token .
1546- Token ,
1545+ /// The "value".
1546+ MacArgsEq ,
15471547 ) ,
15481548}
15491549
1550+ // The RHS of a `MacArgs::Eq` starts out as an expression. Once macro expansion
1551+ // is completed, all cases end up either as a literal, which is the form used
1552+ // after lowering to HIR, or as an error.
1553+ #[ derive( Clone , Encodable , Decodable , Debug ) ]
1554+ pub enum MacArgsEq {
1555+ Ast ( P < Expr > ) ,
1556+ Hir ( Lit ) ,
1557+ }
1558+
15501559impl MacArgs {
15511560 pub fn delim ( & self ) -> Option < Delimiter > {
15521561 match self {
@@ -1559,7 +1568,10 @@ impl MacArgs {
15591568 match self {
15601569 MacArgs :: Empty => None ,
15611570 MacArgs :: Delimited ( dspan, ..) => Some ( dspan. entire ( ) ) ,
1562- MacArgs :: Eq ( eq_span, token) => Some ( eq_span. to ( token. span ) ) ,
1571+ MacArgs :: Eq ( eq_span, MacArgsEq :: Ast ( expr) ) => Some ( eq_span. to ( expr. span ) ) ,
1572+ MacArgs :: Eq ( _, MacArgsEq :: Hir ( lit) ) => {
1573+ unreachable ! ( "in literal form when getting span: {:?}" , lit) ;
1574+ }
15631575 }
15641576 }
15651577
@@ -1569,7 +1581,23 @@ impl MacArgs {
15691581 match self {
15701582 MacArgs :: Empty => TokenStream :: default ( ) ,
15711583 MacArgs :: Delimited ( .., tokens) => tokens. clone ( ) ,
1572- MacArgs :: Eq ( .., token) => TokenTree :: Token ( token. clone ( ) ) . into ( ) ,
1584+ MacArgs :: Eq ( _, MacArgsEq :: Ast ( expr) ) => {
1585+ // Currently only literals are allowed here. If more complex expression kinds are
1586+ // allowed in the future, then `nt_to_tokenstream` should be used to extract the
1587+ // token stream. This will require some cleverness, perhaps with a function
1588+ // pointer, because `nt_to_tokenstream` is not directly usable from this crate.
1589+ // It will also require changing the `parse_expr` call in `parse_mac_args_common`
1590+ // to `parse_expr_force_collect`.
1591+ if let ExprKind :: Lit ( lit) = & expr. kind {
1592+ let token = Token :: new ( TokenKind :: Literal ( lit. token ) , lit. span ) ;
1593+ TokenTree :: Token ( token) . into ( )
1594+ } else {
1595+ unreachable ! ( "couldn't extract literal when getting inner tokens: {:?}" , expr)
1596+ }
1597+ }
1598+ MacArgs :: Eq ( _, MacArgsEq :: Hir ( lit) ) => {
1599+ unreachable ! ( "in literal form when getting inner tokens: {:?}" , lit)
1600+ }
15731601 }
15741602 }
15751603
@@ -1580,6 +1608,30 @@ impl MacArgs {
15801608 }
15811609}
15821610
1611+ impl < CTX > HashStable < CTX > for MacArgs
1612+ where
1613+ CTX : crate :: HashStableContext ,
1614+ {
1615+ fn hash_stable ( & self , ctx : & mut CTX , hasher : & mut StableHasher ) {
1616+ mem:: discriminant ( self ) . hash_stable ( ctx, hasher) ;
1617+ match self {
1618+ MacArgs :: Empty => { }
1619+ MacArgs :: Delimited ( dspan, delim, tokens) => {
1620+ dspan. hash_stable ( ctx, hasher) ;
1621+ delim. hash_stable ( ctx, hasher) ;
1622+ tokens. hash_stable ( ctx, hasher) ;
1623+ }
1624+ MacArgs :: Eq ( _eq_span, MacArgsEq :: Ast ( expr) ) => {
1625+ unreachable ! ( "hash_stable {:?}" , expr) ;
1626+ }
1627+ MacArgs :: Eq ( eq_span, MacArgsEq :: Hir ( lit) ) => {
1628+ eq_span. hash_stable ( ctx, hasher) ;
1629+ lit. hash_stable ( ctx, hasher) ;
1630+ }
1631+ }
1632+ }
1633+ }
1634+
15831635#[ derive( Copy , Clone , PartialEq , Eq , Encodable , Decodable , Debug , HashStable_Generic ) ]
15841636pub enum MacDelimiter {
15851637 Parenthesis ,
0 commit comments