@@ -27,7 +27,7 @@ pub use syntax_pos::symbol::{Ident, Symbol as Name};
27
27
use crate :: ptr:: P ;
28
28
use crate :: source_map:: { dummy_spanned, respan, Spanned } ;
29
29
use crate :: token:: { self , DelimToken } ;
30
- use crate :: tokenstream:: TokenStream ;
30
+ use crate :: tokenstream:: { TokenStream , TokenTree , DelimSpan } ;
31
31
32
32
use syntax_pos:: symbol:: { kw, sym, Symbol } ;
33
33
use syntax_pos:: { Span , DUMMY_SP , ExpnId } ;
@@ -40,6 +40,7 @@ use rustc_index::vec::Idx;
40
40
use rustc_serialize:: { self , Decoder , Encoder } ;
41
41
use rustc_macros:: HashStable_Generic ;
42
42
43
+ use std:: iter;
43
44
use std:: fmt;
44
45
45
46
#[ cfg( test) ]
@@ -1372,34 +1373,78 @@ pub enum Movability {
1372
1373
Movable ,
1373
1374
}
1374
1375
1375
- /// Represents a macro invocation. The `Path` indicates which macro
1376
- /// is being invoked, and the vector of token-trees contains the source
1377
- /// of the macro invocation.
1378
- ///
1379
- /// N.B., the additional ident for a `macro_rules`-style macro is actually
1380
- /// stored in the enclosing item.
1376
+ /// Represents a macro invocation. The `path` indicates which macro
1377
+ /// is being invoked, and the `args` are arguments passed to it.
1381
1378
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
1382
1379
pub struct Mac {
1383
1380
pub path : Path ,
1384
- pub delim : MacDelimiter ,
1385
- pub tts : TokenStream ,
1381
+ pub args : P < MacArgs > ,
1386
1382
pub span : Span ,
1387
1383
pub prior_type_ascription : Option < ( Span , bool ) > ,
1388
1384
}
1389
1385
1390
- #[ derive( Copy , Clone , PartialEq , Eq , RustcEncodable , RustcDecodable , Debug ) ]
1391
- pub enum MacDelimiter {
1392
- Parenthesis ,
1393
- Bracket ,
1394
- Brace ,
1386
+ /// Arguments passed to an attribute or a function-like macro.
1387
+ #[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
1388
+ pub enum MacArgs {
1389
+ /// No arguments - `#[attr]`.
1390
+ Empty ,
1391
+ /// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`.
1392
+ Delimited ( DelimSpan , MacDelimiter , TokenStream ) ,
1393
+ /// Arguments of a key-value attribute - `#[attr = "value"]`.
1394
+ /// Span belongs to the `=` token, token stream is the "value".
1395
+ Eq ( Span , TokenStream ) ,
1396
+ }
1397
+
1398
+ impl MacArgs {
1399
+ pub fn delim ( & self ) -> DelimToken {
1400
+ match self {
1401
+ MacArgs :: Delimited ( _, delim, _) => delim. to_token ( ) ,
1402
+ MacArgs :: Empty | MacArgs :: Eq ( ..) => token:: NoDelim ,
1403
+ }
1404
+ }
1405
+
1406
+ /// Tokens inside the delimiters or after `=`.
1407
+ /// Proc macros see these tokens, for example.
1408
+ pub fn inner_tokens ( & self ) -> TokenStream {
1409
+ match self {
1410
+ MacArgs :: Empty => TokenStream :: default ( ) ,
1411
+ MacArgs :: Delimited ( .., tokens) => tokens. clone ( ) ,
1412
+ MacArgs :: Eq ( .., tokens) => tokens. clone ( ) ,
1413
+ }
1414
+ }
1415
+
1416
+ /// Tokens together with the delimiters or `=`.
1417
+ /// Use of this functions generally means that something suspicious or hacky is happening.
1418
+ pub fn outer_tokens ( & self ) -> TokenStream {
1419
+ match * self {
1420
+ MacArgs :: Empty => TokenStream :: default ( ) ,
1421
+ MacArgs :: Delimited ( dspan, delim, ref tokens) =>
1422
+ TokenTree :: Delimited ( dspan, delim. to_token ( ) , tokens. clone ( ) ) . into ( ) ,
1423
+ MacArgs :: Eq ( eq_span, ref tokens) => iter:: once ( TokenTree :: token ( token:: Eq , eq_span) )
1424
+ . chain ( tokens. trees ( ) ) . collect ( ) ,
1425
+ }
1426
+ }
1427
+
1428
+ /// Whether a macro with these arguments needs a semicolon
1429
+ /// when used as a standalone item or statement.
1430
+ pub fn need_semicolon ( & self ) -> bool {
1431
+ !matches ! ( self , MacArgs :: Delimited ( _, MacDelimiter :: Brace , _) )
1432
+ }
1395
1433
}
1396
1434
1397
1435
impl Mac {
1398
1436
pub fn stream ( & self ) -> TokenStream {
1399
- self . tts . clone ( )
1437
+ self . args . inner_tokens ( )
1400
1438
}
1401
1439
}
1402
1440
1441
+ #[ derive( Copy , Clone , PartialEq , Eq , RustcEncodable , RustcDecodable , Debug ) ]
1442
+ pub enum MacDelimiter {
1443
+ Parenthesis ,
1444
+ Bracket ,
1445
+ Brace ,
1446
+ }
1447
+
1403
1448
impl MacDelimiter {
1404
1449
crate fn to_token ( self ) -> DelimToken {
1405
1450
match self {
@@ -1408,6 +1453,15 @@ impl MacDelimiter {
1408
1453
MacDelimiter :: Brace => DelimToken :: Brace ,
1409
1454
}
1410
1455
}
1456
+
1457
+ pub fn from_token ( delim : DelimToken ) -> MacDelimiter {
1458
+ match delim {
1459
+ token:: Paren => MacDelimiter :: Parenthesis ,
1460
+ token:: Bracket => MacDelimiter :: Bracket ,
1461
+ token:: Brace => MacDelimiter :: Brace ,
1462
+ token:: NoDelim => panic ! ( "expected a delimiter" ) ,
1463
+ }
1464
+ }
1411
1465
}
1412
1466
1413
1467
/// Represents a macro definition.
0 commit comments