@@ -23,7 +23,7 @@ pub use GenericArgs::*;
23
23
pub use UnsafeSource :: * ;
24
24
25
25
use crate :: ptr:: P ;
26
- use crate :: token:: { self , CommentKind , Delimiter , Token } ;
26
+ use crate :: token:: { self , CommentKind , Delimiter , Token , TokenKind } ;
27
27
use crate :: tokenstream:: { DelimSpan , LazyTokenStream , TokenStream , TokenTree } ;
28
28
29
29
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
@@ -1532,7 +1532,7 @@ impl MacCall {
1532
1532
}
1533
1533
1534
1534
/// Arguments passed to an attribute or a function-like macro.
1535
- #[ derive( Clone , Encodable , Decodable , Debug , HashStable_Generic ) ]
1535
+ #[ derive( Clone , Encodable , Decodable , Debug ) ]
1536
1536
pub enum MacArgs {
1537
1537
/// No arguments - `#[attr]`.
1538
1538
Empty ,
@@ -1542,11 +1542,20 @@ pub enum MacArgs {
1542
1542
Eq (
1543
1543
/// Span of the `=` token.
1544
1544
Span ,
1545
- /// "value" as a nonterminal token .
1546
- Token ,
1545
+ /// The "value".
1546
+ MacArgsEq ,
1547
1547
) ,
1548
1548
}
1549
1549
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
+
1550
1559
impl MacArgs {
1551
1560
pub fn delim ( & self ) -> Option < Delimiter > {
1552
1561
match self {
@@ -1559,7 +1568,10 @@ impl MacArgs {
1559
1568
match self {
1560
1569
MacArgs :: Empty => None ,
1561
1570
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
+ }
1563
1575
}
1564
1576
}
1565
1577
@@ -1569,7 +1581,23 @@ impl MacArgs {
1569
1581
match self {
1570
1582
MacArgs :: Empty => TokenStream :: default ( ) ,
1571
1583
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
+ }
1573
1601
}
1574
1602
}
1575
1603
@@ -1580,6 +1608,30 @@ impl MacArgs {
1580
1608
}
1581
1609
}
1582
1610
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
+
1583
1635
#[ derive( Copy , Clone , PartialEq , Eq , Encodable , Decodable , Debug , HashStable_Generic ) ]
1584
1636
pub enum MacDelimiter {
1585
1637
Parenthesis ,
0 commit comments