1
- // The Rust abstract syntax tree.
1
+ //! The Rust abstract syntax tree module.
2
+ //!
3
+ //! This module contains common structures forming the language AST.
4
+ //! Two main entities in the module are [`Item`] (which represents an AST element with
5
+ //! additional metadata), and [`ItemKind`] (which represents a concrete type and contains
6
+ //! information specific to the type of the item).
7
+ //!
8
+ //! Other module items that worth mentioning:
9
+ //! - [`Ty`] and [`TyKind`]: A parsed Rust type.
10
+ //! - [`Expr`] and [`ExprKind`]: A parsed Rust expression.
11
+ //! - [`Pat`] and [`PatKind`]: A parsed Rust pattern. Patterns are often dual to expressions.
12
+ //! - [`Stmt`] and [`StmtKind`]: An executable action that does not return a value.
13
+ //! - [`FnDecl`], [`FnHeader`] and [`Param`]: Metadata associated with a function declaration.
14
+ //! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters.
15
+ //! - [`EnumDef`] and [`Variant`]: Enum declaration.
16
+ //! - [`Lit`] and [`LitKind`]: Literal expressions.
17
+ //! - [`MacroDef`], [`MacStmtStyle`], [`Mac`], [`MacDelimeter`]: Macro definition and invocation.
18
+ //! - [`Attribute`]: Metadata associated with item.
19
+ //! - [`UnOp`], [`UnOpKind`], [`BinOp`], [`BinOpKind`]: Unary and binary operators.
2
20
3
21
pub use GenericArgs :: * ;
4
22
pub use UnsafeSource :: * ;
5
23
pub use crate :: util:: parser:: ExprPrecedence ;
6
24
25
+ pub use rustc_target:: abi:: FloatTy ;
26
+ pub use syntax_pos:: symbol:: { Ident , Symbol as Name } ;
27
+
7
28
use crate :: parse:: token:: { self , DelimToken } ;
8
29
use crate :: ptr:: P ;
9
30
use crate :: source_map:: { dummy_spanned, respan, Spanned } ;
10
31
use crate :: tokenstream:: TokenStream ;
11
32
12
- use rustc_target:: spec:: abi:: Abi ;
13
- pub use rustc_target:: abi:: FloatTy ;
14
-
15
- use syntax_pos:: { Span , DUMMY_SP , ExpnId } ;
16
33
use syntax_pos:: symbol:: { kw, sym, Symbol } ;
17
- pub use syntax_pos:: symbol :: { Ident , Symbol as Name } ;
34
+ use syntax_pos:: { Span , DUMMY_SP , ExpnId } ;
18
35
19
- use rustc_index:: vec:: Idx ;
20
- #[ cfg( target_arch = "x86_64" ) ]
21
- use rustc_data_structures:: static_assert_size;
22
36
use rustc_data_structures:: fx:: FxHashSet ;
23
37
use rustc_data_structures:: sync:: Lrc ;
24
38
use rustc_data_structures:: thin_vec:: ThinVec ;
39
+ use rustc_index:: vec:: Idx ;
25
40
use rustc_serialize:: { self , Decoder , Encoder } ;
41
+ use rustc_target:: spec:: abi:: Abi ;
42
+
43
+ #[ cfg( target_arch = "x86_64" ) ]
44
+ use rustc_data_structures:: static_assert_size;
45
+
26
46
use std:: fmt;
27
47
28
48
#[ cfg( test) ]
29
49
mod tests;
30
50
51
+ /// A "Label" is an identifier of some point in sources,
52
+ /// e.g. in the following code:
53
+ ///
54
+ /// ```rust
55
+ /// 'outer: loop {
56
+ /// break 'outer;
57
+ /// }
58
+ /// ```
59
+ ///
60
+ /// `'outer` is a label.
31
61
#[ derive( Clone , RustcEncodable , RustcDecodable , Copy ) ]
32
62
pub struct Label {
33
63
pub ident : Ident ,
@@ -39,6 +69,8 @@ impl fmt::Debug for Label {
39
69
}
40
70
}
41
71
72
+ /// A "Lifetime" is an annotation of the scope in which variable
73
+ /// can be used, e.g. `'a` in `&'a i32`.
42
74
#[ derive( Clone , RustcEncodable , RustcDecodable , Copy ) ]
43
75
pub struct Lifetime {
44
76
pub id : NodeId ,
@@ -161,10 +193,14 @@ impl GenericArgs {
161
193
}
162
194
}
163
195
196
+ /// Concrete argument in the sequence of generic args.
164
197
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
165
198
pub enum GenericArg {
199
+ /// `'a` in `Foo<'a>`
166
200
Lifetime ( Lifetime ) ,
201
+ /// `Bar` in `Foo<Bar>`
167
202
Type ( P < Ty > ) ,
203
+ /// `1` in `Foo<1>`
168
204
Const ( AnonConst ) ,
169
205
}
170
206
@@ -549,15 +585,24 @@ impl Pat {
549
585
}
550
586
551
587
match & self . kind {
588
+ // Walk into the pattern associated with `Ident` (if any).
552
589
PatKind :: Ident ( _, _, Some ( p) ) => p. walk ( it) ,
590
+
591
+ // Walk into each field of struct.
553
592
PatKind :: Struct ( _, fields, _) => fields. iter ( ) . for_each ( |field| field. pat . walk ( it) ) ,
593
+
594
+ // Sequence of patterns.
554
595
PatKind :: TupleStruct ( _, s)
555
596
| PatKind :: Tuple ( s)
556
597
| PatKind :: Slice ( s)
557
598
| PatKind :: Or ( s) => s. iter ( ) . for_each ( |p| p. walk ( it) ) ,
599
+
600
+ // Trivial wrappers over inner patterns.
558
601
PatKind :: Box ( s)
559
602
| PatKind :: Ref ( s, _)
560
603
| PatKind :: Paren ( s) => s. walk ( it) ,
604
+
605
+ // These patterns do not contain subpatterns, skip.
561
606
PatKind :: Wild
562
607
| PatKind :: Rest
563
608
| PatKind :: Lit ( _)
@@ -609,7 +654,9 @@ pub enum RangeEnd {
609
654
610
655
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
611
656
pub enum RangeSyntax {
657
+ /// `...`
612
658
DotDotDot ,
659
+ /// `..=`
613
660
DotDotEq ,
614
661
}
615
662
@@ -768,6 +815,8 @@ impl BinOpKind {
768
815
769
816
pub fn is_comparison ( & self ) -> bool {
770
817
use BinOpKind :: * ;
818
+ // Note for developers: please keep this as is;
819
+ // we want compilation to fail if another variant is added.
771
820
match * self {
772
821
Eq | Lt | Le | Ne | Gt | Ge => true ,
773
822
And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false ,
@@ -782,6 +831,9 @@ impl BinOpKind {
782
831
783
832
pub type BinOp = Spanned < BinOpKind > ;
784
833
834
+ /// Unary operator.
835
+ ///
836
+ /// Note that `&data` is not an operator, it's an `AddrOf` expression.
785
837
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug , Copy ) ]
786
838
pub enum UnOp {
787
839
/// The `*` operator for dereferencing
@@ -849,10 +901,8 @@ impl Stmt {
849
901
pub enum StmtKind {
850
902
/// A local (let) binding.
851
903
Local ( P < Local > ) ,
852
-
853
904
/// An item definition.
854
905
Item ( P < Item > ) ,
855
-
856
906
/// Expr without trailing semi-colon.
857
907
Expr ( P < Expr > ) ,
858
908
/// Expr with a trailing semi-colon.
@@ -899,14 +949,18 @@ pub struct Local {
899
949
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
900
950
pub struct Arm {
901
951
pub attrs : Vec < Attribute > ,
952
+ /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`
902
953
pub pat : P < Pat > ,
954
+ /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`
903
955
pub guard : Option < P < Expr > > ,
956
+ /// Match arm body.
904
957
pub body : P < Expr > ,
905
958
pub span : Span ,
906
959
pub id : NodeId ,
907
960
pub is_placeholder : bool ,
908
961
}
909
962
963
+ /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
910
964
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
911
965
pub struct Field {
912
966
pub ident : Ident ,
@@ -989,32 +1043,45 @@ impl Expr {
989
1043
}
990
1044
}
991
1045
1046
+ /// Attempts to reparse as `Ty` (for diagnostic purposes).
992
1047
pub ( super ) fn to_ty ( & self ) -> Option < P < Ty > > {
993
1048
let kind = match & self . kind {
1049
+ // Trivial conversions.
994
1050
ExprKind :: Path ( qself, path) => TyKind :: Path ( qself. clone ( ) , path. clone ( ) ) ,
995
1051
ExprKind :: Mac ( mac) => TyKind :: Mac ( mac. clone ( ) ) ,
1052
+
996
1053
ExprKind :: Paren ( expr) => expr. to_ty ( ) . map ( TyKind :: Paren ) ?,
1054
+
997
1055
ExprKind :: AddrOf ( mutbl, expr) => expr
998
1056
. to_ty ( )
999
1057
. map ( |ty| TyKind :: Rptr ( None , MutTy { ty, mutbl : * mutbl } ) ) ?,
1058
+
1000
1059
ExprKind :: Repeat ( expr, expr_len) => {
1001
1060
expr. to_ty ( ) . map ( |ty| TyKind :: Array ( ty, expr_len. clone ( ) ) ) ?
1002
1061
}
1062
+
1003
1063
ExprKind :: Array ( exprs) if exprs. len ( ) == 1 => exprs[ 0 ] . to_ty ( ) . map ( TyKind :: Slice ) ?,
1064
+
1004
1065
ExprKind :: Tup ( exprs) => {
1005
1066
let tys = exprs
1006
1067
. iter ( )
1007
1068
. map ( |expr| expr. to_ty ( ) )
1008
1069
. collect :: < Option < Vec < _ > > > ( ) ?;
1009
1070
TyKind :: Tup ( tys)
1010
1071
}
1072
+
1073
+ // If binary operator is `Add` and both `lhs` and `rhs` are trait bounds,
1074
+ // then type of result is trait object.
1075
+ // Othewise we don't assume the result type.
1011
1076
ExprKind :: Binary ( binop, lhs, rhs) if binop. node == BinOpKind :: Add => {
1012
1077
if let ( Some ( lhs) , Some ( rhs) ) = ( lhs. to_bound ( ) , rhs. to_bound ( ) ) {
1013
1078
TyKind :: TraitObject ( vec ! [ lhs, rhs] , TraitObjectSyntax :: None )
1014
1079
} else {
1015
1080
return None ;
1016
1081
}
1017
1082
}
1083
+
1084
+ // This expression doesn't look like a type syntactically.
1018
1085
_ => return None ,
1019
1086
} ;
1020
1087
@@ -1241,10 +1308,12 @@ pub struct QSelf {
1241
1308
pub position : usize ,
1242
1309
}
1243
1310
1244
- /// A capture clause.
1311
+ /// A capture clause used in closures and `async` blocks .
1245
1312
#[ derive( Clone , Copy , PartialEq , RustcEncodable , RustcDecodable , Debug ) ]
1246
1313
pub enum CaptureBy {
1314
+ /// `move |x| y + x`.
1247
1315
Value ,
1316
+ /// `move` keyword was not specified.
1248
1317
Ref ,
1249
1318
}
1250
1319
@@ -1293,9 +1362,11 @@ impl MacDelimiter {
1293
1362
}
1294
1363
}
1295
1364
1365
+ /// Represents a macro definition.
1296
1366
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
1297
1367
pub struct MacroDef {
1298
1368
pub tokens : TokenStream ,
1369
+ /// `true` if macro was defined with `macro_rules`.
1299
1370
pub legacy : bool ,
1300
1371
}
1301
1372
@@ -1329,10 +1400,14 @@ pub struct Lit {
1329
1400
}
1330
1401
1331
1402
// Clippy uses Hash and PartialEq
1403
+ /// Type of the integer literal based on provided suffix.
1332
1404
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug , Copy , Hash , PartialEq ) ]
1333
1405
pub enum LitIntType {
1406
+ /// e.g. `42_i32`.
1334
1407
Signed ( IntTy ) ,
1408
+ /// e.g. `42_u32`.
1335
1409
Unsigned ( UintTy ) ,
1410
+ /// e.g. `42`.
1336
1411
Unsuffixed ,
1337
1412
}
1338
1413
@@ -1390,7 +1465,16 @@ impl LitKind {
1390
1465
/// Returns `true` if this literal has no suffix.
1391
1466
/// Note: this will return true for literals with prefixes such as raw strings and byte strings.
1392
1467
pub fn is_unsuffixed ( & self ) -> bool {
1468
+ !self . is_suffixed ( )
1469
+ }
1470
+
1471
+ /// Returns `true` if this literal has a suffix.
1472
+ pub fn is_suffixed ( & self ) -> bool {
1393
1473
match * self {
1474
+ // suffixed variants
1475
+ LitKind :: Int ( _, LitIntType :: Signed ( ..) )
1476
+ | LitKind :: Int ( _, LitIntType :: Unsigned ( ..) )
1477
+ | LitKind :: Float ( ..) => true ,
1394
1478
// unsuffixed variants
1395
1479
LitKind :: Str ( ..)
1396
1480
| LitKind :: ByteStr ( ..)
@@ -1399,18 +1483,9 @@ impl LitKind {
1399
1483
| LitKind :: Int ( _, LitIntType :: Unsuffixed )
1400
1484
| LitKind :: FloatUnsuffixed ( ..)
1401
1485
| LitKind :: Bool ( ..)
1402
- | LitKind :: Err ( ..) => true ,
1403
- // suffixed variants
1404
- LitKind :: Int ( _, LitIntType :: Signed ( ..) )
1405
- | LitKind :: Int ( _, LitIntType :: Unsigned ( ..) )
1406
- | LitKind :: Float ( ..) => false ,
1486
+ | LitKind :: Err ( ..) => false ,
1407
1487
}
1408
1488
}
1409
-
1410
- /// Returns `true` if this literal has a suffix.
1411
- pub fn is_suffixed ( & self ) -> bool {
1412
- !self . is_unsuffixed ( )
1413
- }
1414
1489
}
1415
1490
1416
1491
// N.B., If you change this, you'll probably want to change the corresponding
@@ -1779,6 +1854,7 @@ pub enum SelfKind {
1779
1854
pub type ExplicitSelf = Spanned < SelfKind > ;
1780
1855
1781
1856
impl Param {
1857
+ /// Attempts to cast parameter to `ExplicitSelf`.
1782
1858
pub fn to_self ( & self ) -> Option < ExplicitSelf > {
1783
1859
if let PatKind :: Ident ( BindingMode :: ByValue ( mutbl) , ident, _) = self . pat . kind {
1784
1860
if ident. name == kw:: SelfLower {
@@ -1797,6 +1873,7 @@ impl Param {
1797
1873
None
1798
1874
}
1799
1875
1876
+ /// Returns `true` if parameter is `self`.
1800
1877
pub fn is_self ( & self ) -> bool {
1801
1878
if let PatKind :: Ident ( _, ident, _) = self . pat . kind {
1802
1879
ident. name == kw:: SelfLower
@@ -1805,6 +1882,7 @@ impl Param {
1805
1882
}
1806
1883
}
1807
1884
1885
+ /// Builds a `Param` object from `ExplicitSelf`.
1808
1886
pub fn from_self ( attrs : ThinVec < Attribute > , eself : ExplicitSelf , eself_ident : Ident ) -> Param {
1809
1887
let span = eself. span . to ( eself_ident. span ) ;
1810
1888
let infer_ty = P ( Ty {
@@ -1845,9 +1923,12 @@ impl Param {
1845
1923
}
1846
1924
}
1847
1925
1848
- /// A header (not the body) of a function declaration.
1926
+ /// A signature (not the body) of a function declaration.
1849
1927
///
1850
1928
/// E.g., `fn foo(bar: baz)`.
1929
+ ///
1930
+ /// Please note that it's different from `FnHeader` structure
1931
+ /// which contains metadata about function safety, asyncness, constness and ABI.
1851
1932
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
1852
1933
pub struct FnDecl {
1853
1934
pub inputs : Vec < Param > ,
@@ -1859,13 +1940,13 @@ impl FnDecl {
1859
1940
self . inputs . get ( 0 ) . and_then ( Param :: to_self)
1860
1941
}
1861
1942
pub fn has_self ( & self ) -> bool {
1862
- self . inputs . get ( 0 ) . map ( Param :: is_self) . unwrap_or ( false )
1943
+ self . inputs . get ( 0 ) . map_or ( false , Param :: is_self)
1863
1944
}
1864
1945
pub fn c_variadic ( & self ) -> bool {
1865
- self . inputs . last ( ) . map ( |arg| match arg. ty . kind {
1946
+ self . inputs . last ( ) . map_or ( false , |arg| match arg. ty . kind {
1866
1947
TyKind :: CVarArgs => true ,
1867
1948
_ => false ,
1868
- } ) . unwrap_or ( false )
1949
+ } )
1869
1950
}
1870
1951
}
1871
1952
@@ -1918,6 +1999,8 @@ pub enum Constness {
1918
1999
NotConst ,
1919
2000
}
1920
2001
2002
+ /// Item defaultness.
2003
+ /// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532).
1921
2004
#[ derive( Copy , Clone , PartialEq , RustcEncodable , RustcDecodable , Debug ) ]
1922
2005
pub enum Defaultness {
1923
2006
Default ,
@@ -2009,6 +2092,7 @@ pub struct EnumDef {
2009
2092
pub variants : Vec < Variant > ,
2010
2093
}
2011
2094
2095
+ /// Enum variant.
2012
2096
#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
2013
2097
pub struct Variant {
2014
2098
/// Name of the variant.
@@ -2111,6 +2195,8 @@ pub struct AttrItem {
2111
2195
pub struct Attribute {
2112
2196
pub item : AttrItem ,
2113
2197
pub id : AttrId ,
2198
+ /// Denotes if the attribute decorates the following construct (outer)
2199
+ /// or the construct this attribute is contained within (inner).
2114
2200
pub style : AttrStyle ,
2115
2201
pub is_sugared_doc : bool ,
2116
2202
pub span : Span ,
0 commit comments