Skip to content

Commit d51a842

Browse files
authored
Rollup merge of #65761 - popzxc:document-ast, r=petrochenkov
libsyntax: Enhance documentation of the AST module This PR enhances documentation state to the `libsyntax/ast.rs` (as initiative caused by [rustc-guide#474](rust-lang/rustc-dev-guide#474)), by adding: - Module documentation. - Doc-comments (and a bit of usual comments) in non-obvious (as for me) places. - Minor style fixes to improve module readability.
2 parents 4f43352 + ae5203a commit d51a842

File tree

1 file changed

+112
-26
lines changed

1 file changed

+112
-26
lines changed

src/libsyntax/ast.rs

+112-26
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,63 @@
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
321
pub use GenericArgs::*;
422
pub use UnsafeSource::*;
523
pub use crate::util::parser::ExprPrecedence;
624

25+
pub use rustc_target::abi::FloatTy;
26+
pub use syntax_pos::symbol::{Ident, Symbol as Name};
27+
728
use crate::parse::token::{self, DelimToken};
829
use crate::ptr::P;
930
use crate::source_map::{dummy_spanned, respan, Spanned};
1031
use 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};
1633
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};
1835

19-
use rustc_index::vec::Idx;
20-
#[cfg(target_arch = "x86_64")]
21-
use rustc_data_structures::static_assert_size;
2236
use rustc_data_structures::fx::FxHashSet;
2337
use rustc_data_structures::sync::Lrc;
2438
use rustc_data_structures::thin_vec::ThinVec;
39+
use rustc_index::vec::Idx;
2540
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+
2646
use std::fmt;
2747

2848
#[cfg(test)]
2949
mod 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)]
3262
pub 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)]
4375
pub 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)]
165198
pub 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)]
611656
pub 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

783832
pub 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)]
786838
pub enum UnOp {
787839
/// The `*` operator for dereferencing
@@ -849,10 +901,8 @@ impl Stmt {
849901
pub 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)]
900950
pub 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)]
911965
pub 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)]
12461313
pub 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)]
12971367
pub 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)]
13331405
pub 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 {
17791854
pub type ExplicitSelf = Spanned<SelfKind>;
17801855

17811856
impl 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)]
18521933
pub 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)]
19222005
pub 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)]
20132097
pub struct Variant {
20142098
/// Name of the variant.
@@ -2111,6 +2195,8 @@ pub struct AttrItem {
21112195
pub 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

Comments
 (0)