1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // The Rust abstract syntax tree.
13 pub use self::Mutability::*;
14 pub use self::Pat_::*;
15 pub use self::PathListItem_::*;
16 pub use self::StrStyle::*;
17 pub use self::StructFieldKind::*;
18 pub use self::TraitItem_::*;
19 pub use self::TyParamBound::*;
20 pub use self::UnsafeSource::*;
21 pub use self::ViewPath_::*;
22 pub use self::Visibility::*;
23 pub use self::PathParameters::*;
25 use attr::ThinAttributes;
26 use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
29 use ext::tt::macro_parser;
30 use parse::token::InternedString;
33 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
40 use std::hash::{Hash, Hasher};
41 use serialize::{Encodable, Decodable, Encoder, Decoder};
43 /// A name is a part of an identifier, representing a string or gensym. It's
44 /// the result of interning.
45 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
46 pub struct Name(pub u32);
48 /// A SyntaxContext represents a chain of macro-expandings
49 /// and renamings. Each macro expansion corresponds to
50 /// a fresh u32. This u32 is a reference to a table stored
51 /// in thread-local storage.
52 /// The special value EMPTY_CTXT is used to indicate an empty
54 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
55 pub struct SyntaxContext(pub u32);
57 /// An identifier contains a Name (index into the interner
58 /// table) and a SyntaxContext to track renaming and
59 /// macro expansion per Flatt et al., "Macros That Work Together"
60 #[derive(Clone, Copy, Eq)]
63 pub ctxt: SyntaxContext
67 pub fn as_str(self) -> token::InternedString {
68 token::InternedString::new_from_name(self)
72 impl fmt::Debug for Name {
73 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74 write!(f, "{}({})", self, self.0)
78 impl fmt::Display for Name {
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80 fmt::Display::fmt(&self.as_str(), f)
84 impl Encodable for Name {
85 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
86 s.emit_str(&self.as_str())
90 impl Decodable for Name {
91 fn decode<D: Decoder>(d: &mut D) -> Result<Name, D::Error> {
92 Ok(token::intern(&try!(d.read_str())[..]))
96 pub const EMPTY_CTXT : SyntaxContext = SyntaxContext(0);
99 pub fn new(name: Name, ctxt: SyntaxContext) -> Ident {
100 Ident {name: name, ctxt: ctxt}
102 pub fn with_empty_ctxt(name: Name) -> Ident {
103 Ident {name: name, ctxt: EMPTY_CTXT}
107 impl PartialEq for Ident {
108 fn eq(&self, other: &Ident) -> bool {
109 if self.ctxt != other.ctxt {
110 // There's no one true way to compare Idents. They can be compared
111 // non-hygienically `id1.name == id2.name`, hygienically
112 // `mtwt::resolve(id1) == mtwt::resolve(id2)`, or even member-wise
113 // `(id1.name, id1.ctxt) == (id2.name, id2.ctxt)` depending on the situation.
114 // Ideally, PartialEq should not be implemented for Ident at all, but that
115 // would be too impractical, because many larger structures (Token, in particular)
116 // including Idents as their parts derive PartialEq and use it for non-hygienic
117 // comparisons. That's why PartialEq is implemented and defaults to non-hygienic
118 // comparison. Hash is implemented too and is consistent with PartialEq, i.e. only
119 // the name of Ident is hashed. Still try to avoid comparing idents in your code
120 // (especially as keys in hash maps), use one of the three methods listed above
123 // If you see this panic, then some idents from different contexts were compared
124 // non-hygienically. It's likely a bug. Use one of the three comparison methods
125 // listed above explicitly.
127 panic!("idents with different contexts are compared with operator `==`: \
128 {:?}, {:?}.", self, other);
131 self.name == other.name
135 impl Hash for Ident {
136 fn hash<H: Hasher>(&self, state: &mut H) {
137 self.name.hash(state)
141 impl fmt::Debug for Ident {
142 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
143 write!(f, "{}#{}", self.name, self.ctxt.0)
147 impl fmt::Display for Ident {
148 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
149 fmt::Display::fmt(&self.name, f)
153 impl Encodable for Ident {
154 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
159 impl Decodable for Ident {
160 fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
161 Ok(Ident::with_empty_ctxt(try!(Name::decode(d))))
165 /// A mark represents a unique id associated with a macro expansion
168 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
169 pub struct Lifetime {
175 impl fmt::Debug for Lifetime {
176 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
177 write!(f, "lifetime({}: {})", self.id, pprust::lifetime_to_string(self))
181 /// A lifetime definition, eg `'a: 'b+'c+'d`
182 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
183 pub struct LifetimeDef {
184 pub lifetime: Lifetime,
185 pub bounds: Vec<Lifetime>
188 /// A "Path" is essentially Rust's notion of a name; for instance:
189 /// std::cmp::PartialEq . It's represented as a sequence of identifiers,
190 /// along with a bunch of supporting information.
191 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
194 /// A `::foo` path, is relative to the crate root rather than current
195 /// module (like paths in an import).
197 /// The segments in the path: the things separated by `::`.
198 pub segments: Vec<PathSegment>,
201 impl fmt::Debug for Path {
202 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203 write!(f, "path({})", pprust::path_to_string(self))
207 impl fmt::Display for Path {
208 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
209 write!(f, "{}", pprust::path_to_string(self))
213 /// A segment of a path: an identifier, an optional lifetime, and a set of
215 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
216 pub struct PathSegment {
217 /// The identifier portion of this path segment.
218 pub identifier: Ident,
220 /// Type/lifetime parameters attached to this path. They come in
221 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
222 /// this is more than just simple syntactic sugar; the use of
223 /// parens affects the region binding rules, so we preserve the
225 pub parameters: PathParameters,
228 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
229 pub enum PathParameters {
230 /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
231 AngleBracketed(AngleBracketedParameterData),
232 /// The `(A,B)` and `C` in `Foo(A,B) -> C`
233 Parenthesized(ParenthesizedParameterData),
236 impl PathParameters {
237 pub fn none() -> PathParameters {
238 PathParameters::AngleBracketed(AngleBracketedParameterData {
239 lifetimes: Vec::new(),
241 bindings: P::empty(),
245 pub fn is_empty(&self) -> bool {
247 PathParameters::AngleBracketed(ref data) => data.is_empty(),
249 // Even if the user supplied no types, something like
250 // `X()` is equivalent to `X<(),()>`.
251 PathParameters::Parenthesized(..) => false,
255 pub fn has_lifetimes(&self) -> bool {
257 PathParameters::AngleBracketed(ref data) => !data.lifetimes.is_empty(),
258 PathParameters::Parenthesized(_) => false,
262 pub fn has_types(&self) -> bool {
264 PathParameters::AngleBracketed(ref data) => !data.types.is_empty(),
265 PathParameters::Parenthesized(..) => true,
269 /// Returns the types that the user wrote. Note that these do not necessarily map to the type
270 /// parameters in the parenthesized case.
271 pub fn types(&self) -> Vec<&P<Ty>> {
273 PathParameters::AngleBracketed(ref data) => {
274 data.types.iter().collect()
276 PathParameters::Parenthesized(ref data) => {
278 .chain(data.output.iter())
284 pub fn lifetimes(&self) -> Vec<&Lifetime> {
286 PathParameters::AngleBracketed(ref data) => {
287 data.lifetimes.iter().collect()
289 PathParameters::Parenthesized(_) => {
295 pub fn bindings(&self) -> Vec<&P<TypeBinding>> {
297 PathParameters::AngleBracketed(ref data) => {
298 data.bindings.iter().collect()
300 PathParameters::Parenthesized(_) => {
307 /// A path like `Foo<'a, T>`
308 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
309 pub struct AngleBracketedParameterData {
310 /// The lifetime parameters for this path segment.
311 pub lifetimes: Vec<Lifetime>,
312 /// The type parameters for this path segment, if present.
313 pub types: P<[P<Ty>]>,
314 /// Bindings (equality constraints) on associated types, if present.
315 /// e.g., `Foo<A=Bar>`.
316 pub bindings: P<[P<TypeBinding>]>,
319 impl AngleBracketedParameterData {
320 fn is_empty(&self) -> bool {
321 self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
325 /// A path like `Foo(A,B) -> C`
326 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
327 pub struct ParenthesizedParameterData {
332 pub inputs: Vec<P<Ty>>,
335 pub output: Option<P<Ty>>,
338 pub type CrateNum = u32;
340 pub type NodeId = u32;
342 /// Node id used to represent the root of the crate.
343 pub const CRATE_NODE_ID: NodeId = 0;
345 /// When parsing and doing expansions, we initially give all AST nodes this AST
346 /// node value. Then later, in the renumber pass, we renumber them to have
347 /// small, positive ids.
348 pub const DUMMY_NODE_ID: NodeId = !0;
350 pub trait NodeIdAssigner {
351 fn next_node_id(&self) -> NodeId;
352 fn peek_node_id(&self) -> NodeId;
355 /// The AST represents all type param bounds as types.
356 /// typeck::collect::compute_bounds matches these against
357 /// the "special" built-in traits (see middle::lang_items) and
358 /// detects Copy, Send and Sync.
359 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
360 pub enum TyParamBound {
361 TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
362 RegionTyParamBound(Lifetime)
365 /// A modifier on a bound, currently this is only used for `?Sized`, where the
366 /// modifier is `Maybe`. Negative bounds should also be handled here.
367 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
368 pub enum TraitBoundModifier {
373 pub type TyParamBounds = P<[TyParamBound]>;
375 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
379 pub bounds: TyParamBounds,
380 pub default: Option<P<Ty>>,
384 /// Represents lifetimes and type parameters attached to a declaration
385 /// of a function, enum, trait, etc.
386 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
387 pub struct Generics {
388 pub lifetimes: Vec<LifetimeDef>,
389 pub ty_params: P<[TyParam]>,
390 pub where_clause: WhereClause,
394 pub fn is_lt_parameterized(&self) -> bool {
395 !self.lifetimes.is_empty()
397 pub fn is_type_parameterized(&self) -> bool {
398 !self.ty_params.is_empty()
400 pub fn is_parameterized(&self) -> bool {
401 self.is_lt_parameterized() || self.is_type_parameterized()
405 impl Default for Generics {
406 fn default() -> Generics {
408 lifetimes: Vec::new(),
409 ty_params: P::empty(),
410 where_clause: WhereClause {
412 predicates: Vec::new(),
418 /// A `where` clause in a definition
419 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
420 pub struct WhereClause {
422 pub predicates: Vec<WherePredicate>,
425 /// A single predicate in a `where` clause
426 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
427 pub enum WherePredicate {
428 /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
429 BoundPredicate(WhereBoundPredicate),
430 /// A lifetime predicate, e.g. `'a: 'b+'c`
431 RegionPredicate(WhereRegionPredicate),
432 /// An equality predicate (unsupported)
433 EqPredicate(WhereEqPredicate),
436 /// A type bound, e.g. `for<'c> Foo: Send+Clone+'c`
437 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
438 pub struct WhereBoundPredicate {
440 /// Any lifetimes from a `for` binding
441 pub bound_lifetimes: Vec<LifetimeDef>,
442 /// The type being bounded
443 pub bounded_ty: P<Ty>,
444 /// Trait and lifetime bounds (`Clone+Send+'static`)
445 pub bounds: TyParamBounds,
448 /// A lifetime predicate, e.g. `'a: 'b+'c`
449 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
450 pub struct WhereRegionPredicate {
452 pub lifetime: Lifetime,
453 pub bounds: Vec<Lifetime>,
456 /// An equality predicate (unsupported), e.g. `T=int`
457 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
458 pub struct WhereEqPredicate {
465 /// The set of MetaItems that define the compilation environment of the crate,
466 /// used to drive conditional compilation
467 pub type CrateConfig = Vec<P<MetaItem>> ;
469 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
472 pub attrs: Vec<Attribute>,
473 pub config: CrateConfig,
475 pub exported_macros: Vec<MacroDef>,
478 pub type MetaItem = Spanned<MetaItemKind>;
480 #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
481 pub enum MetaItemKind {
482 Word(InternedString),
483 List(InternedString, Vec<P<MetaItem>>),
484 NameValue(InternedString, Lit),
487 // can't be derived because the MetaItemKind::List requires an unordered comparison
488 impl PartialEq for MetaItemKind {
489 fn eq(&self, other: &MetaItemKind) -> bool {
490 use self::MetaItemKind::*;
492 Word(ref ns) => match *other {
493 Word(ref no) => (*ns) == (*no),
496 NameValue(ref ns, ref vs) => match *other {
497 NameValue(ref no, ref vo) => {
498 (*ns) == (*no) && vs.node == vo.node
502 List(ref ns, ref miss) => match *other {
503 List(ref no, ref miso) => {
505 miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
513 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
515 /// Statements in a block
516 pub stmts: Vec<P<Stmt>>,
517 /// An expression at the end of the block
518 /// without a semicolon, if any
519 pub expr: Option<P<Expr>>,
521 /// Distinguishes between `unsafe { ... }` and `{ ... }`
522 pub rules: BlockCheckMode,
526 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
533 impl fmt::Debug for Pat {
534 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
535 write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self))
539 /// A single field in a struct pattern
541 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
542 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
543 /// except is_shorthand is true
544 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
545 pub struct FieldPat {
546 /// The identifier for the field
548 /// The pattern the field is destructured to
550 pub is_shorthand: bool,
553 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
554 pub enum BindingMode {
559 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
561 /// Represents a wildcard pattern (`_`)
564 /// A PatIdent may either be a new bound variable,
565 /// or a nullary enum (in which case the third field
568 /// In the nullary enum case, the parser can't determine
569 /// which it is. The resolver determines this, and
570 /// records this pattern's NodeId in an auxiliary
571 /// set (of "PatIdents that refer to nullary enums")
572 PatIdent(BindingMode, SpannedIdent, Option<P<Pat>>),
574 /// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
575 PatEnum(Path, Option<Vec<P<Pat>>>),
577 /// An associated const named using the qualified path `<T>::CONST` or
578 /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
579 /// referred to as simply `T::CONST`, in which case they will end up as
580 /// PatEnum, and the resolver will have to sort that out.
581 PatQPath(QSelf, Path),
583 /// Destructuring of a struct, e.g. `Foo {x, y, ..}`
584 /// The `bool` is `true` in the presence of a `..`
585 PatStruct(Path, Vec<Spanned<FieldPat>>, bool),
586 /// A tuple pattern `(a, b)`
590 /// A reference pattern, e.g. `&mut (a, b)`
591 PatRegion(P<Pat>, Mutability),
594 /// A range pattern, e.g. `1...2`
595 PatRange(P<Expr>, P<Expr>),
596 /// `[a, b, ..i, y, z]` is represented as:
597 /// `PatVec(box [a, b], Some(i), box [y, z])`
598 PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
599 /// A macro pattern; pre-expansion
603 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
604 pub enum Mutability {
609 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
611 /// The `+` operator (addition)
613 /// The `-` operator (subtraction)
615 /// The `*` operator (multiplication)
617 /// The `/` operator (division)
619 /// The `%` operator (modulus)
621 /// The `&&` operator (logical and)
623 /// The `||` operator (logical or)
625 /// The `^` operator (bitwise xor)
627 /// The `&` operator (bitwise and)
629 /// The `|` operator (bitwise or)
631 /// The `<<` operator (shift left)
633 /// The `>>` operator (shift right)
635 /// The `==` operator (equality)
637 /// The `<` operator (less than)
639 /// The `<=` operator (less than or equal to)
641 /// The `!=` operator (not equal to)
643 /// The `>=` operator (greater than or equal to)
645 /// The `>` operator (greater than)
650 pub fn to_string(&self) -> &'static str {
651 use self::BinOpKind::*;
673 pub fn lazy(&self) -> bool {
675 BinOpKind::And | BinOpKind::Or => true,
680 pub fn is_shift(&self) -> bool {
682 BinOpKind::Shl | BinOpKind::Shr => true,
686 pub fn is_comparison(&self) -> bool {
687 use self::BinOpKind::*;
689 Eq | Lt | Le | Ne | Gt | Ge =>
691 And | Or | Add | Sub | Mul | Div | Rem |
692 BitXor | BitAnd | BitOr | Shl | Shr =>
696 /// Returns `true` if the binary operator takes its arguments by value
697 pub fn is_by_value(&self) -> bool {
698 !self.is_comparison()
702 pub type BinOp = Spanned<BinOpKind>;
704 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
706 /// The `*` operator for dereferencing
708 /// The `!` operator for logical inversion
710 /// The `-` operator for negation
715 /// Returns `true` if the unary operator takes its argument by value
716 pub fn is_by_value(u: UnOp) -> bool {
718 UnOp::Neg | UnOp::Not => true,
723 pub fn to_string(op: UnOp) -> &'static str {
733 pub type Stmt = Spanned<StmtKind>;
735 impl fmt::Debug for Stmt {
736 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
737 write!(f, "stmt({}: {})",
739 .map_or(Cow::Borrowed("<macro>"),|id|Cow::Owned(id.to_string())),
740 pprust::stmt_to_string(self))
745 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
747 /// Could be an item or a local (let) binding:
748 Decl(P<Decl>, NodeId),
750 /// Expr without trailing semi-colon (must have unit type):
751 Expr(P<Expr>, NodeId),
753 /// Expr with trailing semi-colon (may have any type):
754 Semi(P<Expr>, NodeId),
756 Mac(P<Mac>, MacStmtStyle, ThinAttributes),
760 pub fn id(&self) -> Option<NodeId> {
762 StmtKind::Decl(_, id) => Some(id),
763 StmtKind::Expr(_, id) => Some(id),
764 StmtKind::Semi(_, id) => Some(id),
765 StmtKind::Mac(..) => None,
769 pub fn attrs(&self) -> &[Attribute] {
771 StmtKind::Decl(ref d, _) => d.attrs(),
772 StmtKind::Expr(ref e, _) |
773 StmtKind::Semi(ref e, _) => e.attrs(),
774 StmtKind::Mac(_, _, Some(ref b)) => b,
775 StmtKind::Mac(_, _, None) => &[],
780 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
781 pub enum MacStmtStyle {
782 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
783 /// `foo!(...);`, `foo![...];`
785 /// The macro statement had braces; e.g. foo! { ... }
787 /// The macro statement had parentheses or brackets and no semicolon; e.g.
788 /// `foo!(...)`. All of these will end up being converted into macro
793 // FIXME (pending discussion of #1697, #2178...): local should really be
794 // a refinement on pat.
795 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
796 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
799 pub ty: Option<P<Ty>>,
800 /// Initializer expression to set the value, if any
801 pub init: Option<P<Expr>>,
804 pub attrs: ThinAttributes,
808 pub fn attrs(&self) -> &[Attribute] {
816 pub type Decl = Spanned<DeclKind>;
818 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
820 /// A local (let) binding:
827 pub fn attrs(&self) -> &[Attribute] {
829 DeclKind::Local(ref l) => l.attrs(),
830 DeclKind::Item(ref i) => i.attrs(),
835 /// represents one arm of a 'match'
836 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
838 pub attrs: Vec<Attribute>,
839 pub pats: Vec<P<Pat>>,
840 pub guard: Option<P<Expr>>,
844 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
846 pub ident: SpannedIdent,
851 pub type SpannedIdent = Spanned<Ident>;
853 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
854 pub enum BlockCheckMode {
856 Unsafe(UnsafeSource),
859 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
860 pub enum UnsafeSource {
866 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash,)]
871 pub attrs: ThinAttributes
875 pub fn attrs(&self) -> &[Attribute] {
883 impl fmt::Debug for Expr {
884 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
885 write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self))
889 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
891 /// A `box x` expression.
893 /// First expr is the place; second expr is the value.
894 InPlace(P<Expr>, P<Expr>),
895 /// An array (`[a, b, c, d]`)
899 /// The first field resolves to the function itself,
900 /// and the second field is the list of arguments
901 Call(P<Expr>, Vec<P<Expr>>),
902 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
904 /// The `SpannedIdent` is the identifier for the method name.
905 /// The vector of `Ty`s are the ascripted type parameters for the method
906 /// (within the angle brackets).
908 /// The first element of the vector of `Expr`s is the expression that evaluates
909 /// to the object on which the method is being called on (the receiver),
910 /// and the remaining elements are the rest of the arguments.
912 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
913 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
914 MethodCall(SpannedIdent, Vec<P<Ty>>, Vec<P<Expr>>),
915 /// A tuple (`(a, b, c ,d)`)
917 /// A binary operation (For example: `a + b`, `a * b`)
918 Binary(BinOp, P<Expr>, P<Expr>),
919 /// A unary operation (For example: `!x`, `*x`)
920 Unary(UnOp, P<Expr>),
921 /// A literal (For example: `1u8`, `"foo"`)
923 /// A cast (`foo as f64`)
924 Cast(P<Expr>, P<Ty>),
925 Type(P<Expr>, P<Ty>),
926 /// An `if` block, with an optional else block
928 /// `if expr { block } else { expr }`
929 If(P<Expr>, P<Block>, Option<P<Expr>>),
930 /// An `if let` expression with an optional else block
932 /// `if let pat = expr { block } else { expr }`
934 /// This is desugared to a `match` expression.
935 IfLet(P<Pat>, P<Expr>, P<Block>, Option<P<Expr>>),
936 /// A while loop, with an optional label
938 /// `'label: while expr { block }`
939 While(P<Expr>, P<Block>, Option<Ident>),
940 /// A while-let loop, with an optional label
942 /// `'label: while let pat = expr { block }`
944 /// This is desugared to a combination of `loop` and `match` expressions.
945 WhileLet(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
946 /// A for loop, with an optional label
948 /// `'label: for pat in expr { block }`
950 /// This is desugared to a combination of `loop` and `match` expressions.
951 ForLoop(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
952 /// Conditionless loop (can be exited with break, continue, or return)
954 /// `'label: loop { block }`
955 Loop(P<Block>, Option<Ident>),
957 Match(P<Expr>, Vec<Arm>),
958 /// A closure (for example, `move |a, b, c| {a + b + c}`)
959 Closure(CaptureBy, P<FnDecl>, P<Block>),
960 /// A block (`{ ... }`)
963 /// An assignment (`a = foo()`)
964 Assign(P<Expr>, P<Expr>),
965 /// An assignment with an operator
967 /// For example, `a += 1`.
968 AssignOp(BinOp, P<Expr>, P<Expr>),
969 /// Access of a named struct field (`obj.foo`)
970 Field(P<Expr>, SpannedIdent),
971 /// Access of an unnamed field of a struct or tuple-struct
973 /// For example, `foo.0`.
974 TupField(P<Expr>, Spanned<usize>),
975 /// An indexing operation (`foo[2]`)
976 Index(P<Expr>, P<Expr>),
977 /// A range (`1..2`, `1..`, or `..2`)
978 Range(Option<P<Expr>>, Option<P<Expr>>),
980 /// Variable reference, possibly containing `::` and/or type
981 /// parameters, e.g. foo::bar::<baz>.
983 /// Optionally "qualified",
984 /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
985 Path(Option<QSelf>, Path),
987 /// A referencing operation (`&a` or `&mut a`)
988 AddrOf(Mutability, P<Expr>),
989 /// A `break`, with an optional label to break
990 Break(Option<SpannedIdent>),
991 /// A `continue`, with an optional label
992 Again(Option<SpannedIdent>),
993 /// A `return`, with an optional value to be returned
994 Ret(Option<P<Expr>>),
996 /// Output of the `asm!()` macro
997 InlineAsm(InlineAsm),
999 /// A macro invocation; pre-expansion
1002 /// A struct literal expression.
1004 /// For example, `Foo {x: 1, y: 2}`, or
1005 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
1006 Struct(Path, Vec<Field>, Option<P<Expr>>),
1008 /// An array literal constructed from one repeated element.
1010 /// For example, `[1u8; 5]`. The first expression is the element
1011 /// to be repeated; the second is the number of times to repeat it.
1012 Repeat(P<Expr>, P<Expr>),
1014 /// No-op: used solely so we can pretty-print faithfully
1018 /// The explicit Self type in a "qualified path". The actual
1019 /// path, including the trait and the associated item, is stored
1020 /// separately. `position` represents the index of the associated
1021 /// item qualified with this Self type.
1024 /// <Vec<T> as a::b::Trait>::AssociatedItem
1025 /// ^~~~~ ~~~~~~~~~~~~~~^
1028 /// <Vec<T>>::AssociatedItem
1032 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1038 /// A capture clause
1039 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1040 pub enum CaptureBy {
1045 /// A delimited sequence of token trees
1046 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1047 pub struct Delimited {
1048 /// The type of delimiter
1049 pub delim: token::DelimToken,
1050 /// The span covering the opening delimiter
1051 pub open_span: Span,
1052 /// The delimited sequence of token trees
1053 pub tts: Vec<TokenTree>,
1054 /// The span covering the closing delimiter
1055 pub close_span: Span,
1059 /// Returns the opening delimiter as a token.
1060 pub fn open_token(&self) -> token::Token {
1061 token::OpenDelim(self.delim)
1064 /// Returns the closing delimiter as a token.
1065 pub fn close_token(&self) -> token::Token {
1066 token::CloseDelim(self.delim)
1069 /// Returns the opening delimiter as a token tree.
1070 pub fn open_tt(&self) -> TokenTree {
1071 TokenTree::Token(self.open_span, self.open_token())
1074 /// Returns the closing delimiter as a token tree.
1075 pub fn close_tt(&self) -> TokenTree {
1076 TokenTree::Token(self.close_span, self.close_token())
1080 /// A sequence of token trees
1081 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1082 pub struct SequenceRepetition {
1083 /// The sequence of token trees
1084 pub tts: Vec<TokenTree>,
1085 /// The optional separator
1086 pub separator: Option<token::Token>,
1087 /// Whether the sequence can be repeated zero (*), or one or more times (+)
1089 /// The number of `MatchNt`s that appear in the sequence (and subsequences)
1090 pub num_captures: usize,
1093 /// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
1094 /// for token sequences.
1095 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1101 /// When the main rust parser encounters a syntax-extension invocation, it
1102 /// parses the arguments to the invocation as a token-tree. This is a very
1103 /// loose structure, such that all sorts of different AST-fragments can
1104 /// be passed to syntax extensions using a uniform type.
1106 /// If the syntax extension is an MBE macro, it will attempt to match its
1107 /// LHS token tree against the provided token tree, and if it finds a
1108 /// match, will transcribe the RHS token tree, splicing in any captured
1109 /// macro_parser::matched_nonterminals into the `SubstNt`s it finds.
1111 /// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
1112 /// Nothing special happens to misnamed or misplaced `SubstNt`s.
1113 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1114 pub enum TokenTree {
1116 Token(Span, token::Token),
1117 /// A delimited sequence of token trees
1118 Delimited(Span, Rc<Delimited>),
1120 // This only makes sense in MBE macros.
1122 /// A kleene-style repetition sequence with a span
1123 // FIXME(eddyb) #12938 Use DST.
1124 Sequence(Span, Rc<SequenceRepetition>),
1128 pub fn len(&self) -> usize {
1130 TokenTree::Token(_, token::DocComment(name)) => {
1131 match doc_comment_style(&name.as_str()) {
1132 AttrStyle::Outer => 2,
1133 AttrStyle::Inner => 3
1136 TokenTree::Token(_, token::SpecialVarNt(..)) => 2,
1137 TokenTree::Token(_, token::MatchNt(..)) => 3,
1138 TokenTree::Delimited(_, ref delimed) => {
1139 delimed.tts.len() + 2
1141 TokenTree::Sequence(_, ref seq) => {
1144 TokenTree::Token(..) => 0
1148 pub fn get_tt(&self, index: usize) -> TokenTree {
1149 match (self, index) {
1150 (&TokenTree::Token(sp, token::DocComment(_)), 0) => {
1151 TokenTree::Token(sp, token::Pound)
1153 (&TokenTree::Token(sp, token::DocComment(name)), 1)
1154 if doc_comment_style(&name.as_str()) == AttrStyle::Inner => {
1155 TokenTree::Token(sp, token::Not)
1157 (&TokenTree::Token(sp, token::DocComment(name)), _) => {
1158 let stripped = strip_doc_comment_decoration(&name.as_str());
1160 // Searches for the occurrences of `"#*` and returns the minimum number of `#`s
1161 // required to wrap the text.
1162 let num_of_hashes = stripped.chars().scan(0, |cnt, x| {
1163 *cnt = if x == '"' {
1165 } else if *cnt != 0 && x == '#' {
1171 }).max().unwrap_or(0);
1173 TokenTree::Delimited(sp, Rc::new(Delimited {
1174 delim: token::Bracket,
1176 tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc"),
1178 TokenTree::Token(sp, token::Eq),
1179 TokenTree::Token(sp, token::Literal(
1180 token::StrRaw(token::intern(&stripped), num_of_hashes), None))],
1184 (&TokenTree::Delimited(_, ref delimed), _) => {
1186 return delimed.open_tt();
1188 if index == delimed.tts.len() + 1 {
1189 return delimed.close_tt();
1191 delimed.tts[index - 1].clone()
1193 (&TokenTree::Token(sp, token::SpecialVarNt(var)), _) => {
1194 let v = [TokenTree::Token(sp, token::Dollar),
1195 TokenTree::Token(sp, token::Ident(token::str_to_ident(var.as_str()),
1199 (&TokenTree::Token(sp, token::MatchNt(name, kind, name_st, kind_st)), _) => {
1200 let v = [TokenTree::Token(sp, token::SubstNt(name, name_st)),
1201 TokenTree::Token(sp, token::Colon),
1202 TokenTree::Token(sp, token::Ident(kind, kind_st))];
1205 (&TokenTree::Sequence(_, ref seq), _) => {
1206 seq.tts[index].clone()
1208 _ => panic!("Cannot expand a token tree")
1212 /// Returns the `Span` corresponding to this token tree.
1213 pub fn get_span(&self) -> Span {
1215 TokenTree::Token(span, _) => span,
1216 TokenTree::Delimited(span, _) => span,
1217 TokenTree::Sequence(span, _) => span,
1221 /// Use this token tree as a matcher to parse given tts.
1222 pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree])
1223 -> macro_parser::NamedParseResult {
1224 // `None` is because we're not interpolating
1225 let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
1228 tts.iter().cloned().collect(),
1230 macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch)
1234 pub type Mac = Spanned<Mac_>;
1236 /// Represents a macro invocation. The Path indicates which macro
1237 /// is being invoked, and the vector of token-trees contains the source
1238 /// of the macro invocation.
1240 /// NB: the additional ident for a macro_rules-style macro is actually
1241 /// stored in the enclosing item. Oog.
1242 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1245 pub tts: Vec<TokenTree>,
1246 pub ctxt: SyntaxContext,
1249 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1251 /// A regular string, like `"foo"`
1253 /// A raw string, like `r##"foo"##`
1255 /// The uint is the number of `#` symbols used
1260 pub type Lit = Spanned<LitKind>;
1262 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1263 pub enum LitIntType {
1269 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1271 /// A string literal (`"foo"`)
1272 Str(InternedString, StrStyle),
1273 /// A byte string (`b"foo"`)
1274 ByteStr(Rc<Vec<u8>>),
1275 /// A byte char (`b'f'`)
1277 /// A character literal (`'a'`)
1279 /// An integer literal (`1u8`)
1280 Int(u64, LitIntType),
1281 /// A float literal (`1f64` or `1E10f64`)
1282 Float(InternedString, FloatTy),
1283 /// A float literal without a suffix (`1.0 or 1.0E10`)
1284 FloatUnsuffixed(InternedString),
1285 /// A boolean literal
1290 /// Returns true if this literal is a string and false otherwise.
1291 pub fn is_str(&self) -> bool {
1293 LitKind::Str(..) => true,
1299 // NB: If you change this, you'll probably want to change the corresponding
1300 // type structure in middle/ty.rs as well.
1301 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1304 pub mutbl: Mutability,
1307 /// Represents a method's signature in a trait declaration,
1308 /// or in an implementation.
1309 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1310 pub struct MethodSig {
1311 pub unsafety: Unsafety,
1312 pub constness: Constness,
1314 pub decl: P<FnDecl>,
1315 pub generics: Generics,
1316 pub explicit_self: ExplicitSelf,
1319 /// Represents a method declaration in a trait declaration, possibly including
1320 /// a default implementation. A trait method is either required (meaning it
1321 /// doesn't have an implementation, just a signature) or provided (meaning it
1322 /// has a default implementation).
1323 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1324 pub struct TraitItem {
1327 pub attrs: Vec<Attribute>,
1328 pub node: TraitItem_,
1332 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1333 pub enum TraitItem_ {
1334 ConstTraitItem(P<Ty>, Option<P<Expr>>),
1335 MethodTraitItem(MethodSig, Option<P<Block>>),
1336 TypeTraitItem(TyParamBounds, Option<P<Ty>>),
1339 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1340 pub struct ImplItem {
1343 pub vis: Visibility,
1344 pub attrs: Vec<Attribute>,
1345 pub node: ImplItemKind,
1349 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1350 pub enum ImplItemKind {
1351 Const(P<Ty>, P<Expr>),
1352 Method(MethodSig, P<Block>),
1357 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1366 impl fmt::Debug for IntTy {
1367 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1368 fmt::Display::fmt(self, f)
1372 impl fmt::Display for IntTy {
1373 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1374 write!(f, "{}", self.ty_to_string())
1379 pub fn ty_to_string(&self) -> &'static str {
1381 IntTy::Is => "isize",
1383 IntTy::I16 => "i16",
1384 IntTy::I32 => "i32",
1389 pub fn val_to_string(&self, val: i64) -> String {
1390 // cast to a u64 so we can correctly print INT64_MIN. All integral types
1391 // are parsed as u64, so we wouldn't want to print an extra negative
1393 format!("{}{}", val as u64, self.ty_to_string())
1396 pub fn ty_max(&self) -> u64 {
1399 IntTy::I16 => 0x8000,
1400 IntTy::Is | IntTy::I32 => 0x80000000, // FIXME: actually ni about Is
1401 IntTy::I64 => 0x8000000000000000
1405 pub fn bit_width(&self) -> Option<usize> {
1407 IntTy::Is => return None,
1416 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1426 pub fn ty_to_string(&self) -> &'static str {
1428 UintTy::Us => "usize",
1430 UintTy::U16 => "u16",
1431 UintTy::U32 => "u32",
1432 UintTy::U64 => "u64"
1436 pub fn val_to_string(&self, val: u64) -> String {
1437 format!("{}{}", val, self.ty_to_string())
1440 pub fn ty_max(&self) -> u64 {
1443 UintTy::U16 => 0xffff,
1444 UintTy::Us | UintTy::U32 => 0xffffffff, // FIXME: actually ni about Us
1445 UintTy::U64 => 0xffffffffffffffff
1449 pub fn bit_width(&self) -> Option<usize> {
1451 UintTy::Us => return None,
1460 impl fmt::Debug for UintTy {
1461 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1462 fmt::Display::fmt(self, f)
1466 impl fmt::Display for UintTy {
1467 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1468 write!(f, "{}", self.ty_to_string())
1472 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1478 impl fmt::Debug for FloatTy {
1479 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1480 fmt::Display::fmt(self, f)
1484 impl fmt::Display for FloatTy {
1485 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1486 write!(f, "{}", self.ty_to_string())
1491 pub fn ty_to_string(&self) -> &'static str {
1493 FloatTy::F32 => "f32",
1494 FloatTy::F64 => "f64",
1498 pub fn bit_width(&self) -> usize {
1506 // Bind a type to an associated type: `A=Foo`.
1507 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1508 pub struct TypeBinding {
1515 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1522 impl fmt::Debug for Ty {
1523 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1524 write!(f, "type({})", pprust::ty_to_string(self))
1528 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1529 pub struct BareFnTy {
1530 pub unsafety: Unsafety,
1532 pub lifetimes: Vec<LifetimeDef>,
1536 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1537 /// The different kinds of types recognized by the compiler
1540 /// A fixed length array (`[T; n]`)
1541 FixedLengthVec(P<Ty>, P<Expr>),
1542 /// A raw pointer (`*const T` or `*mut T`)
1544 /// A reference (`&'a T` or `&'a mut T`)
1545 Rptr(Option<Lifetime>, MutTy),
1546 /// A bare function (e.g. `fn(usize) -> bool`)
1547 BareFn(P<BareFnTy>),
1548 /// A tuple (`(A, B, C, D,...)`)
1550 /// A path (`module::module::...::Type`), optionally
1551 /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
1553 /// Type parameters are stored in the Path itself
1554 Path(Option<QSelf>, Path),
1555 /// Something like `A+B`. Note that `B` must always be a path.
1556 ObjectSum(P<Ty>, TyParamBounds),
1557 /// A type like `for<'a> Foo<&'a Bar>`
1558 PolyTraitRef(TyParamBounds),
1559 /// No-op; kept solely so that we can pretty-print faithfully
1563 /// TyKind::Infer means the type should be inferred instead of it having been
1564 /// specified. This can appear anywhere in a type.
1566 // A macro in the type position.
1570 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1571 pub enum AsmDialect {
1576 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1577 pub struct InlineAsmOutput {
1578 pub constraint: InternedString,
1581 pub is_indirect: bool,
1584 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1585 pub struct InlineAsm {
1586 pub asm: InternedString,
1587 pub asm_str_style: StrStyle,
1588 pub outputs: Vec<InlineAsmOutput>,
1589 pub inputs: Vec<(InternedString, P<Expr>)>,
1590 pub clobbers: Vec<InternedString>,
1592 pub alignstack: bool,
1593 pub dialect: AsmDialect,
1594 pub expn_id: ExpnId,
1597 /// represents an argument in a function header
1598 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1606 pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
1607 let path = Spanned{span:span,node:self_ident};
1609 // HACK(eddyb) fake type for the self argument.
1612 node: TyKind::Infer,
1617 node: PatIdent(BindingMode::ByValue(mutability), path, None),
1625 /// Represents the header (not the body) of a function declaration
1626 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1628 pub inputs: Vec<Arg>,
1629 pub output: FunctionRetTy,
1633 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1639 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1640 pub enum Constness {
1645 impl fmt::Display for Unsafety {
1646 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1647 fmt::Display::fmt(match *self {
1648 Unsafety::Normal => "normal",
1649 Unsafety::Unsafe => "unsafe",
1654 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1655 pub enum ImplPolarity {
1656 /// `impl Trait for Type`
1658 /// `impl !Trait for Type`
1662 impl fmt::Debug for ImplPolarity {
1663 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1665 ImplPolarity::Positive => "positive".fmt(f),
1666 ImplPolarity::Negative => "negative".fmt(f),
1672 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1673 pub enum FunctionRetTy {
1674 /// Functions with return type `!`that always
1675 /// raise an error or exit (i.e. never return to the caller)
1677 /// Return type is not specified.
1679 /// Functions default to `()` and
1680 /// closures default to inference. Span points to where return
1681 /// type would be inserted.
1687 impl FunctionRetTy {
1688 pub fn span(&self) -> Span {
1690 FunctionRetTy::None(span) => span,
1691 FunctionRetTy::Default(span) => span,
1692 FunctionRetTy::Ty(ref ty) => ty.span,
1697 /// Represents the kind of 'self' associated with a method
1698 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1704 /// `&'lt self`, `&'lt mut self`
1705 Region(Option<Lifetime>, Mutability, Ident),
1707 Explicit(P<Ty>, Ident),
1710 pub type ExplicitSelf = Spanned<SelfKind>;
1712 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1714 /// A span from the first token past `{` to the last token until `}`.
1715 /// For `mod foo;`, the inner span ranges from the first token
1716 /// to the last token in the external file.
1718 pub items: Vec<P<Item>>,
1721 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1722 pub struct ForeignMod {
1724 pub items: Vec<P<ForeignItem>>,
1727 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1728 pub struct EnumDef {
1729 pub variants: Vec<P<Variant>>,
1732 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1733 pub struct Variant_ {
1735 pub attrs: Vec<Attribute>,
1736 pub data: VariantData,
1737 /// Explicit discriminant, eg `Foo = 1`
1738 pub disr_expr: Option<P<Expr>>,
1741 pub type Variant = Spanned<Variant_>;
1743 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1744 pub enum PathListItem_ {
1747 /// renamed in list, eg `use foo::{bar as baz};`
1748 rename: Option<Ident>,
1752 /// renamed in list, eg `use foo::{self as baz};`
1753 rename: Option<Ident>,
1758 impl PathListItem_ {
1759 pub fn id(&self) -> NodeId {
1761 PathListIdent { id, .. } | PathListMod { id, .. } => id
1765 pub fn name(&self) -> Option<Ident> {
1767 PathListIdent { name, .. } => Some(name),
1768 PathListMod { .. } => None,
1772 pub fn rename(&self) -> Option<Ident> {
1774 PathListIdent { rename, .. } | PathListMod { rename, .. } => rename
1779 pub type PathListItem = Spanned<PathListItem_>;
1781 pub type ViewPath = Spanned<ViewPath_>;
1783 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1784 pub enum ViewPath_ {
1786 /// `foo::bar::baz as quux`
1790 /// `foo::bar::baz` (with `as baz` implicitly on the right)
1791 ViewPathSimple(Ident, Path),
1796 /// `foo::bar::{a,b,c}`
1797 ViewPathList(Path, Vec<PathListItem>)
1800 /// Meta-data associated with an item
1801 pub type Attribute = Spanned<Attribute_>;
1803 /// Distinguishes between Attributes that decorate items and Attributes that
1804 /// are contained as statements within items. These two cases need to be
1805 /// distinguished for pretty-printing.
1806 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1807 pub enum AttrStyle {
1812 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1813 pub struct AttrId(pub usize);
1815 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
1816 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1817 pub struct Attribute_ {
1819 pub style: AttrStyle,
1820 pub value: P<MetaItem>,
1821 pub is_sugared_doc: bool,
1824 /// TraitRef's appear in impls.
1826 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1827 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1828 /// If this impl is an ItemKind::Impl, the impl_id is redundant (it could be the
1829 /// same as the impl's node id).
1830 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1831 pub struct TraitRef {
1836 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1837 pub struct PolyTraitRef {
1838 /// The `'a` in `<'a> Foo<&'a T>`
1839 pub bound_lifetimes: Vec<LifetimeDef>,
1841 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1842 pub trait_ref: TraitRef,
1847 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1848 pub enum Visibility {
1854 pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1856 Inherited => parent_visibility,
1862 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1863 pub struct StructField_ {
1864 pub kind: StructFieldKind,
1867 pub attrs: Vec<Attribute>,
1871 pub fn ident(&self) -> Option<Ident> {
1873 NamedField(ref ident, _) => Some(ident.clone()),
1874 UnnamedField(_) => None
1879 pub type StructField = Spanned<StructField_>;
1881 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1882 pub enum StructFieldKind {
1883 NamedField(Ident, Visibility),
1884 /// Element of a tuple-like struct
1885 UnnamedField(Visibility),
1888 impl StructFieldKind {
1889 pub fn is_unnamed(&self) -> bool {
1891 UnnamedField(..) => true,
1892 NamedField(..) => false,
1896 pub fn visibility(&self) -> Visibility {
1898 NamedField(_, vis) | UnnamedField(vis) => vis
1903 /// Fields and Ids of enum variants and structs
1905 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1906 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1907 /// One shared Id can be successfully used for these two purposes.
1908 /// Id of the whole enum lives in `Item`.
1910 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
1911 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
1912 /// the variant itself" from enum variants.
1913 /// Id of the whole struct lives in `Item`.
1914 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1915 pub enum VariantData {
1916 Struct(Vec<StructField>, NodeId),
1917 Tuple(Vec<StructField>, NodeId),
1922 pub fn fields(&self) -> &[StructField] {
1924 VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
1928 pub fn id(&self) -> NodeId {
1930 VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id
1933 pub fn is_struct(&self) -> bool {
1934 if let VariantData::Struct(..) = *self { true } else { false }
1936 pub fn is_tuple(&self) -> bool {
1937 if let VariantData::Tuple(..) = *self { true } else { false }
1939 pub fn is_unit(&self) -> bool {
1940 if let VariantData::Unit(..) = *self { true } else { false }
1945 FIXME (#3300): Should allow items to be anonymous. Right now
1946 we just use dummy names for anon items.
1950 /// The name might be a dummy name in case of anonymous items
1951 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1954 pub attrs: Vec<Attribute>,
1957 pub vis: Visibility,
1962 pub fn attrs(&self) -> &[Attribute] {
1967 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1969 /// An`extern crate` item, with optional original crate name,
1971 /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
1972 ExternCrate(Option<Name>),
1973 /// A `use` or `pub use` item
1977 Static(P<Ty>, Mutability, P<Expr>),
1979 Const(P<Ty>, P<Expr>),
1980 /// A function declaration
1981 Fn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
1984 /// An external module
1985 ForeignMod(ForeignMod),
1986 /// A type alias, e.g. `type Foo = Bar<u8>`
1987 Ty(P<Ty>, Generics),
1988 /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
1989 Enum(EnumDef, Generics),
1990 /// A struct definition, e.g. `struct Foo<A> {x: A}`
1991 Struct(VariantData, Generics),
1992 /// Represents a Trait Declaration
1998 // Default trait implementations
2000 // `impl Trait for .. {}`
2001 DefaultImpl(Unsafety, TraitRef),
2002 /// An implementation, eg `impl<A> Trait for Foo { .. }`
2006 Option<TraitRef>, // (optional) trait this impl implements
2009 /// A macro invocation (which includes macro definition)
2014 pub fn descriptive_variant(&self) -> &str {
2016 ItemKind::ExternCrate(..) => "extern crate",
2017 ItemKind::Use(..) => "use",
2018 ItemKind::Static(..) => "static item",
2019 ItemKind::Const(..) => "constant item",
2020 ItemKind::Fn(..) => "function",
2021 ItemKind::Mod(..) => "module",
2022 ItemKind::ForeignMod(..) => "foreign module",
2023 ItemKind::Ty(..) => "type alias",
2024 ItemKind::Enum(..) => "enum",
2025 ItemKind::Struct(..) => "struct",
2026 ItemKind::Trait(..) => "trait",
2028 ItemKind::Impl(..) |
2029 ItemKind::DefaultImpl(..) => "item"
2034 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2035 pub struct ForeignItem {
2037 pub attrs: Vec<Attribute>,
2038 pub node: ForeignItemKind,
2041 pub vis: Visibility,
2044 /// An item within an `extern` block
2045 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2046 pub enum ForeignItemKind {
2047 /// A foreign function
2048 Fn(P<FnDecl>, Generics),
2049 /// A foreign static item (`static ext: u8`), with optional mutability
2050 /// (the boolean is true when mutable)
2051 Static(P<Ty>, bool),
2054 impl ForeignItemKind {
2055 pub fn descriptive_variant(&self) -> &str {
2057 ForeignItemKind::Fn(..) => "foreign function",
2058 ForeignItemKind::Static(..) => "foreign static item"
2063 /// A macro definition, in this crate or imported from another.
2065 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
2066 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2067 pub struct MacroDef {
2069 pub attrs: Vec<Attribute>,
2072 pub imported_from: Option<Ident>,
2074 pub use_locally: bool,
2075 pub allow_internal_unstable: bool,
2076 pub body: Vec<TokenTree>,
2084 // are ASTs encodable?
2086 fn check_asts_encodable() {
2087 fn assert_encodable<T: serialize::Encodable>() {}
2088 assert_encodable::<Crate>();