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.
220
321pub use GenericArgs :: * ;
422pub use UnsafeSource :: * ;
523pub use crate :: util:: parser:: ExprPrecedence ;
624
25+ pub use rustc_target:: abi:: FloatTy ;
26+ pub use syntax_pos:: symbol:: { Ident , Symbol as Name } ;
27+
728use crate :: parse:: token:: { self , DelimToken } ;
829use crate :: ptr:: P ;
930use crate :: source_map:: { dummy_spanned, respan, Spanned } ;
1031use crate :: tokenstream:: TokenStream ;
1132
12- use rustc_target:: spec:: abi:: Abi ;
13- pub use rustc_target:: abi:: FloatTy ;
14-
15- use syntax_pos:: { Span , DUMMY_SP , ExpnId } ;
1633use syntax_pos:: symbol:: { kw, sym, Symbol } ;
17- pub use syntax_pos:: symbol :: { Ident , Symbol as Name } ;
34+ use syntax_pos:: { Span , DUMMY_SP , ExpnId } ;
1835
19- use rustc_index:: vec:: Idx ;
20- #[ cfg( target_arch = "x86_64" ) ]
21- use rustc_data_structures:: static_assert_size;
2236use rustc_data_structures:: fx:: FxHashSet ;
2337use rustc_data_structures:: sync:: Lrc ;
2438use rustc_data_structures:: thin_vec:: ThinVec ;
39+ use rustc_index:: vec:: Idx ;
2540use 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+
2646use std:: fmt;
2747
2848#[ cfg( test) ]
2949mod tests;
3050
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.
3161#[ derive( Clone , RustcEncodable , RustcDecodable , Copy ) ]
3262pub struct Label {
3363 pub ident : Ident ,
@@ -39,6 +69,8 @@ impl fmt::Debug for Label {
3969 }
4070}
4171
72+ /// A "Lifetime" is an annotation of the scope in which variable
73+ /// can be used, e.g. `'a` in `&'a i32`.
4274#[ derive( Clone , RustcEncodable , RustcDecodable , Copy ) ]
4375pub struct Lifetime {
4476 pub id : NodeId ,
@@ -161,10 +193,14 @@ impl GenericArgs {
161193 }
162194}
163195
196+ /// Concrete argument in the sequence of generic args.
164197#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
165198pub enum GenericArg {
199+ /// `'a` in `Foo<'a>`
166200 Lifetime ( Lifetime ) ,
201+ /// `Bar` in `Foo<Bar>`
167202 Type ( P < Ty > ) ,
203+ /// `1` in `Foo<1>`
168204 Const ( AnonConst ) ,
169205}
170206
@@ -549,15 +585,24 @@ impl Pat {
549585 }
550586
551587 match & self . kind {
588+ // Walk into the pattern associated with `Ident` (if any).
552589 PatKind :: Ident ( _, _, Some ( p) ) => p. walk ( it) ,
590+
591+ // Walk into each field of struct.
553592 PatKind :: Struct ( _, fields, _) => fields. iter ( ) . for_each ( |field| field. pat . walk ( it) ) ,
593+
594+ // Sequence of patterns.
554595 PatKind :: TupleStruct ( _, s)
555596 | PatKind :: Tuple ( s)
556597 | PatKind :: Slice ( s)
557598 | PatKind :: Or ( s) => s. iter ( ) . for_each ( |p| p. walk ( it) ) ,
599+
600+ // Trivial wrappers over inner patterns.
558601 PatKind :: Box ( s)
559602 | PatKind :: Ref ( s, _)
560603 | PatKind :: Paren ( s) => s. walk ( it) ,
604+
605+ // These patterns do not contain subpatterns, skip.
561606 PatKind :: Wild
562607 | PatKind :: Rest
563608 | PatKind :: Lit ( _)
@@ -609,7 +654,9 @@ pub enum RangeEnd {
609654
610655#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
611656pub enum RangeSyntax {
657+ /// `...`
612658 DotDotDot ,
659+ /// `..=`
613660 DotDotEq ,
614661}
615662
@@ -768,6 +815,8 @@ impl BinOpKind {
768815
769816 pub fn is_comparison ( & self ) -> bool {
770817 use BinOpKind :: * ;
818+ // Note for developers: please keep this as is;
819+ // we want compilation to fail if another variant is added.
771820 match * self {
772821 Eq | Lt | Le | Ne | Gt | Ge => true ,
773822 And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false ,
@@ -782,6 +831,9 @@ impl BinOpKind {
782831
783832pub type BinOp = Spanned < BinOpKind > ;
784833
834+ /// Unary operator.
835+ ///
836+ /// Note that `&data` is not an operator, it's an `AddrOf` expression.
785837#[ derive( Clone , RustcEncodable , RustcDecodable , Debug , Copy ) ]
786838pub enum UnOp {
787839 /// The `*` operator for dereferencing
@@ -849,10 +901,8 @@ impl Stmt {
849901pub enum StmtKind {
850902 /// A local (let) binding.
851903 Local ( P < Local > ) ,
852-
853904 /// An item definition.
854905 Item ( P < Item > ) ,
855-
856906 /// Expr without trailing semi-colon.
857907 Expr ( P < Expr > ) ,
858908 /// Expr with a trailing semi-colon.
@@ -899,14 +949,18 @@ pub struct Local {
899949#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
900950pub struct Arm {
901951 pub attrs : Vec < Attribute > ,
952+ /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`
902953 pub pat : P < Pat > ,
954+ /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`
903955 pub guard : Option < P < Expr > > ,
956+ /// Match arm body.
904957 pub body : P < Expr > ,
905958 pub span : Span ,
906959 pub id : NodeId ,
907960 pub is_placeholder : bool ,
908961}
909962
963+ /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
910964#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
911965pub struct Field {
912966 pub ident : Ident ,
@@ -989,32 +1043,45 @@ impl Expr {
9891043 }
9901044 }
9911045
1046+ /// Attempts to reparse as `Ty` (for diagnostic purposes).
9921047 pub ( super ) fn to_ty ( & self ) -> Option < P < Ty > > {
9931048 let kind = match & self . kind {
1049+ // Trivial conversions.
9941050 ExprKind :: Path ( qself, path) => TyKind :: Path ( qself. clone ( ) , path. clone ( ) ) ,
9951051 ExprKind :: Mac ( mac) => TyKind :: Mac ( mac. clone ( ) ) ,
1052+
9961053 ExprKind :: Paren ( expr) => expr. to_ty ( ) . map ( TyKind :: Paren ) ?,
1054+
9971055 ExprKind :: AddrOf ( mutbl, expr) => expr
9981056 . to_ty ( )
9991057 . map ( |ty| TyKind :: Rptr ( None , MutTy { ty, mutbl : * mutbl } ) ) ?,
1058+
10001059 ExprKind :: Repeat ( expr, expr_len) => {
10011060 expr. to_ty ( ) . map ( |ty| TyKind :: Array ( ty, expr_len. clone ( ) ) ) ?
10021061 }
1062+
10031063 ExprKind :: Array ( exprs) if exprs. len ( ) == 1 => exprs[ 0 ] . to_ty ( ) . map ( TyKind :: Slice ) ?,
1064+
10041065 ExprKind :: Tup ( exprs) => {
10051066 let tys = exprs
10061067 . iter ( )
10071068 . map ( |expr| expr. to_ty ( ) )
10081069 . collect :: < Option < Vec < _ > > > ( ) ?;
10091070 TyKind :: Tup ( tys)
10101071 }
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.
10111076 ExprKind :: Binary ( binop, lhs, rhs) if binop. node == BinOpKind :: Add => {
10121077 if let ( Some ( lhs) , Some ( rhs) ) = ( lhs. to_bound ( ) , rhs. to_bound ( ) ) {
10131078 TyKind :: TraitObject ( vec ! [ lhs, rhs] , TraitObjectSyntax :: None )
10141079 } else {
10151080 return None ;
10161081 }
10171082 }
1083+
1084+ // This expression doesn't look like a type syntactically.
10181085 _ => return None ,
10191086 } ;
10201087
@@ -1241,10 +1308,12 @@ pub struct QSelf {
12411308 pub position : usize ,
12421309}
12431310
1244- /// A capture clause.
1311+ /// A capture clause used in closures and `async` blocks .
12451312#[ derive( Clone , Copy , PartialEq , RustcEncodable , RustcDecodable , Debug ) ]
12461313pub enum CaptureBy {
1314+ /// `move |x| y + x`.
12471315 Value ,
1316+ /// `move` keyword was not specified.
12481317 Ref ,
12491318}
12501319
@@ -1293,9 +1362,11 @@ impl MacDelimiter {
12931362 }
12941363}
12951364
1365+ /// Represents a macro definition.
12961366#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
12971367pub struct MacroDef {
12981368 pub tokens : TokenStream ,
1369+ /// `true` if macro was defined with `macro_rules`.
12991370 pub legacy : bool ,
13001371}
13011372
@@ -1329,10 +1400,14 @@ pub struct Lit {
13291400}
13301401
13311402// Clippy uses Hash and PartialEq
1403+ /// Type of the integer literal based on provided suffix.
13321404#[ derive( Clone , RustcEncodable , RustcDecodable , Debug , Copy , Hash , PartialEq ) ]
13331405pub enum LitIntType {
1406+ /// e.g. `42_i32`.
13341407 Signed ( IntTy ) ,
1408+ /// e.g. `42_u32`.
13351409 Unsigned ( UintTy ) ,
1410+ /// e.g. `42`.
13361411 Unsuffixed ,
13371412}
13381413
@@ -1390,7 +1465,16 @@ impl LitKind {
13901465 /// Returns `true` if this literal has no suffix.
13911466 /// Note: this will return true for literals with prefixes such as raw strings and byte strings.
13921467 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 {
13931473 match * self {
1474+ // suffixed variants
1475+ LitKind :: Int ( _, LitIntType :: Signed ( ..) )
1476+ | LitKind :: Int ( _, LitIntType :: Unsigned ( ..) )
1477+ | LitKind :: Float ( ..) => true ,
13941478 // unsuffixed variants
13951479 LitKind :: Str ( ..)
13961480 | LitKind :: ByteStr ( ..)
@@ -1399,18 +1483,9 @@ impl LitKind {
13991483 | LitKind :: Int ( _, LitIntType :: Unsuffixed )
14001484 | LitKind :: FloatUnsuffixed ( ..)
14011485 | 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 ,
14071487 }
14081488 }
1409-
1410- /// Returns `true` if this literal has a suffix.
1411- pub fn is_suffixed ( & self ) -> bool {
1412- !self . is_unsuffixed ( )
1413- }
14141489}
14151490
14161491// N.B., If you change this, you'll probably want to change the corresponding
@@ -1779,6 +1854,7 @@ pub enum SelfKind {
17791854pub type ExplicitSelf = Spanned < SelfKind > ;
17801855
17811856impl Param {
1857+ /// Attempts to cast parameter to `ExplicitSelf`.
17821858 pub fn to_self ( & self ) -> Option < ExplicitSelf > {
17831859 if let PatKind :: Ident ( BindingMode :: ByValue ( mutbl) , ident, _) = self . pat . kind {
17841860 if ident. name == kw:: SelfLower {
@@ -1797,6 +1873,7 @@ impl Param {
17971873 None
17981874 }
17991875
1876+ /// Returns `true` if parameter is `self`.
18001877 pub fn is_self ( & self ) -> bool {
18011878 if let PatKind :: Ident ( _, ident, _) = self . pat . kind {
18021879 ident. name == kw:: SelfLower
@@ -1805,6 +1882,7 @@ impl Param {
18051882 }
18061883 }
18071884
1885+ /// Builds a `Param` object from `ExplicitSelf`.
18081886 pub fn from_self ( attrs : ThinVec < Attribute > , eself : ExplicitSelf , eself_ident : Ident ) -> Param {
18091887 let span = eself. span . to ( eself_ident. span ) ;
18101888 let infer_ty = P ( Ty {
@@ -1845,9 +1923,12 @@ impl Param {
18451923 }
18461924}
18471925
1848- /// A header (not the body) of a function declaration.
1926+ /// A signature (not the body) of a function declaration.
18491927///
18501928/// 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.
18511932#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
18521933pub struct FnDecl {
18531934 pub inputs : Vec < Param > ,
@@ -1859,13 +1940,13 @@ impl FnDecl {
18591940 self . inputs . get ( 0 ) . and_then ( Param :: to_self)
18601941 }
18611942 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)
18631944 }
18641945 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 {
18661947 TyKind :: CVarArgs => true ,
18671948 _ => false ,
1868- } ) . unwrap_or ( false )
1949+ } )
18691950 }
18701951}
18711952
@@ -1918,6 +1999,8 @@ pub enum Constness {
19181999 NotConst ,
19192000}
19202001
2002+ /// Item defaultness.
2003+ /// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532).
19212004#[ derive( Copy , Clone , PartialEq , RustcEncodable , RustcDecodable , Debug ) ]
19222005pub enum Defaultness {
19232006 Default ,
@@ -2009,6 +2092,7 @@ pub struct EnumDef {
20092092 pub variants : Vec < Variant > ,
20102093}
20112094
2095+ /// Enum variant.
20122096#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
20132097pub struct Variant {
20142098 /// Name of the variant.
@@ -2111,6 +2195,8 @@ pub struct AttrItem {
21112195pub struct Attribute {
21122196 pub item : AttrItem ,
21132197 pub id : AttrId ,
2198+ /// Denotes if the attribute decorates the following construct (outer)
2199+ /// or the construct this attribute is contained within (inner).
21142200 pub style : AttrStyle ,
21152201 pub is_sugared_doc : bool ,
21162202 pub span : Span ,
0 commit comments