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::Pat_::*;
14 pub use self::PathListItem_::*;
15 pub use self::StructFieldKind::*;
16 pub use self::TyParamBound::*;
17 pub use self::UnsafeSource::*;
18 pub use self::ViewPath_::*;
19 pub use self::PathParameters::*;
21 use attr::ThinAttributes;
22 use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
25 use ext::tt::macro_parser;
26 use parse::token::InternedString;
29 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
36 use std::hash::{Hash, Hasher};
37 use serialize::{Encodable, Decodable, Encoder, Decoder};
39 /// A name is a part of an identifier, representing a string or gensym. It's
40 /// the result of interning.
41 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
42 pub struct Name(pub u32);
44 /// A SyntaxContext represents a chain of macro-expandings
45 /// and renamings. Each macro expansion corresponds to
46 /// a fresh u32. This u32 is a reference to a table stored
47 /// in thread-local storage.
48 /// The special value EMPTY_CTXT is used to indicate an empty
50 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
51 pub struct SyntaxContext(pub u32);
53 /// An identifier contains a Name (index into the interner
54 /// table) and a SyntaxContext to track renaming and
55 /// macro expansion per Flatt et al., "Macros That Work Together"
56 #[derive(Clone, Copy, Eq)]
59 pub ctxt: SyntaxContext
63 pub fn as_str(self) -> token::InternedString {
64 token::InternedString::new_from_name(self)
68 impl fmt::Debug for Name {
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 write!(f, "{}({})", self, self.0)
74 impl fmt::Display for Name {
75 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76 fmt::Display::fmt(&self.as_str(), f)
80 impl Encodable for Name {
81 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
82 s.emit_str(&self.as_str())
86 impl Decodable for Name {
87 fn decode<D: Decoder>(d: &mut D) -> Result<Name, D::Error> {
88 Ok(token::intern(&try!(d.read_str())[..]))
92 pub const EMPTY_CTXT : SyntaxContext = SyntaxContext(0);
95 pub fn new(name: Name, ctxt: SyntaxContext) -> Ident {
96 Ident {name: name, ctxt: ctxt}
98 pub fn with_empty_ctxt(name: Name) -> Ident {
99 Ident {name: name, ctxt: EMPTY_CTXT}
103 impl PartialEq for Ident {
104 fn eq(&self, other: &Ident) -> bool {
105 if self.ctxt != other.ctxt {
106 // There's no one true way to compare Idents. They can be compared
107 // non-hygienically `id1.name == id2.name`, hygienically
108 // `mtwt::resolve(id1) == mtwt::resolve(id2)`, or even member-wise
109 // `(id1.name, id1.ctxt) == (id2.name, id2.ctxt)` depending on the situation.
110 // Ideally, PartialEq should not be implemented for Ident at all, but that
111 // would be too impractical, because many larger structures (Token, in particular)
112 // including Idents as their parts derive PartialEq and use it for non-hygienic
113 // comparisons. That's why PartialEq is implemented and defaults to non-hygienic
114 // comparison. Hash is implemented too and is consistent with PartialEq, i.e. only
115 // the name of Ident is hashed. Still try to avoid comparing idents in your code
116 // (especially as keys in hash maps), use one of the three methods listed above
119 // If you see this panic, then some idents from different contexts were compared
120 // non-hygienically. It's likely a bug. Use one of the three comparison methods
121 // listed above explicitly.
123 panic!("idents with different contexts are compared with operator `==`: \
124 {:?}, {:?}.", self, other);
127 self.name == other.name
131 impl Hash for Ident {
132 fn hash<H: Hasher>(&self, state: &mut H) {
133 self.name.hash(state)
137 impl fmt::Debug for Ident {
138 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
139 write!(f, "{}#{}", self.name, self.ctxt.0)
143 impl fmt::Display for Ident {
144 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
145 fmt::Display::fmt(&self.name, f)
149 impl Encodable for Ident {
150 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
155 impl Decodable for Ident {
156 fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
157 Ok(Ident::with_empty_ctxt(try!(Name::decode(d))))
161 /// A mark represents a unique id associated with a macro expansion
164 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
165 pub struct Lifetime {
171 impl fmt::Debug for Lifetime {
172 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
173 write!(f, "lifetime({}: {})", self.id, pprust::lifetime_to_string(self))
177 /// A lifetime definition, eg `'a: 'b+'c+'d`
178 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
179 pub struct LifetimeDef {
180 pub lifetime: Lifetime,
181 pub bounds: Vec<Lifetime>
184 /// A "Path" is essentially Rust's notion of a name; for instance:
185 /// std::cmp::PartialEq . It's represented as a sequence of identifiers,
186 /// along with a bunch of supporting information.
187 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
190 /// A `::foo` path, is relative to the crate root rather than current
191 /// module (like paths in an import).
193 /// The segments in the path: the things separated by `::`.
194 pub segments: Vec<PathSegment>,
197 impl fmt::Debug for Path {
198 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
199 write!(f, "path({})", pprust::path_to_string(self))
203 impl fmt::Display for Path {
204 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
205 write!(f, "{}", pprust::path_to_string(self))
209 /// A segment of a path: an identifier, an optional lifetime, and a set of
211 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
212 pub struct PathSegment {
213 /// The identifier portion of this path segment.
214 pub identifier: Ident,
216 /// Type/lifetime parameters attached to this path. They come in
217 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
218 /// this is more than just simple syntactic sugar; the use of
219 /// parens affects the region binding rules, so we preserve the
221 pub parameters: PathParameters,
224 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
225 pub enum PathParameters {
226 /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
227 AngleBracketed(AngleBracketedParameterData),
228 /// The `(A,B)` and `C` in `Foo(A,B) -> C`
229 Parenthesized(ParenthesizedParameterData),
232 impl PathParameters {
233 pub fn none() -> PathParameters {
234 PathParameters::AngleBracketed(AngleBracketedParameterData {
235 lifetimes: Vec::new(),
237 bindings: P::empty(),
241 pub fn is_empty(&self) -> bool {
243 PathParameters::AngleBracketed(ref data) => data.is_empty(),
245 // Even if the user supplied no types, something like
246 // `X()` is equivalent to `X<(),()>`.
247 PathParameters::Parenthesized(..) => false,
251 pub fn has_lifetimes(&self) -> bool {
253 PathParameters::AngleBracketed(ref data) => !data.lifetimes.is_empty(),
254 PathParameters::Parenthesized(_) => false,
258 pub fn has_types(&self) -> bool {
260 PathParameters::AngleBracketed(ref data) => !data.types.is_empty(),
261 PathParameters::Parenthesized(..) => true,
265 /// Returns the types that the user wrote. Note that these do not necessarily map to the type
266 /// parameters in the parenthesized case.
267 pub fn types(&self) -> Vec<&P<Ty>> {
269 PathParameters::AngleBracketed(ref data) => {
270 data.types.iter().collect()
272 PathParameters::Parenthesized(ref data) => {
274 .chain(data.output.iter())
280 pub fn lifetimes(&self) -> Vec<&Lifetime> {
282 PathParameters::AngleBracketed(ref data) => {
283 data.lifetimes.iter().collect()
285 PathParameters::Parenthesized(_) => {
291 pub fn bindings(&self) -> Vec<&P<TypeBinding>> {
293 PathParameters::AngleBracketed(ref data) => {
294 data.bindings.iter().collect()
296 PathParameters::Parenthesized(_) => {
303 /// A path like `Foo<'a, T>`
304 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
305 pub struct AngleBracketedParameterData {
306 /// The lifetime parameters for this path segment.
307 pub lifetimes: Vec<Lifetime>,
308 /// The type parameters for this path segment, if present.
309 pub types: P<[P<Ty>]>,
310 /// Bindings (equality constraints) on associated types, if present.
311 /// e.g., `Foo<A=Bar>`.
312 pub bindings: P<[P<TypeBinding>]>,
315 impl AngleBracketedParameterData {
316 fn is_empty(&self) -> bool {
317 self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
321 /// A path like `Foo(A,B) -> C`
322 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
323 pub struct ParenthesizedParameterData {
328 pub inputs: Vec<P<Ty>>,
331 pub output: Option<P<Ty>>,
334 pub type CrateNum = u32;
336 pub type NodeId = u32;
338 /// Node id used to represent the root of the crate.
339 pub const CRATE_NODE_ID: NodeId = 0;
341 /// When parsing and doing expansions, we initially give all AST nodes this AST
342 /// node value. Then later, in the renumber pass, we renumber them to have
343 /// small, positive ids.
344 pub const DUMMY_NODE_ID: NodeId = !0;
346 pub trait NodeIdAssigner {
347 fn next_node_id(&self) -> NodeId;
348 fn peek_node_id(&self) -> NodeId;
351 /// The AST represents all type param bounds as types.
352 /// typeck::collect::compute_bounds matches these against
353 /// the "special" built-in traits (see middle::lang_items) and
354 /// detects Copy, Send and Sync.
355 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
356 pub enum TyParamBound {
357 TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
358 RegionTyParamBound(Lifetime)
361 /// A modifier on a bound, currently this is only used for `?Sized`, where the
362 /// modifier is `Maybe`. Negative bounds should also be handled here.
363 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
364 pub enum TraitBoundModifier {
369 pub type TyParamBounds = P<[TyParamBound]>;
371 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
375 pub bounds: TyParamBounds,
376 pub default: Option<P<Ty>>,
380 /// Represents lifetimes and type parameters attached to a declaration
381 /// of a function, enum, trait, etc.
382 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
383 pub struct Generics {
384 pub lifetimes: Vec<LifetimeDef>,
385 pub ty_params: P<[TyParam]>,
386 pub where_clause: WhereClause,
390 pub fn is_lt_parameterized(&self) -> bool {
391 !self.lifetimes.is_empty()
393 pub fn is_type_parameterized(&self) -> bool {
394 !self.ty_params.is_empty()
396 pub fn is_parameterized(&self) -> bool {
397 self.is_lt_parameterized() || self.is_type_parameterized()
401 impl Default for Generics {
402 fn default() -> Generics {
404 lifetimes: Vec::new(),
405 ty_params: P::empty(),
406 where_clause: WhereClause {
408 predicates: Vec::new(),
414 /// A `where` clause in a definition
415 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
416 pub struct WhereClause {
418 pub predicates: Vec<WherePredicate>,
421 /// A single predicate in a `where` clause
422 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
423 pub enum WherePredicate {
424 /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
425 BoundPredicate(WhereBoundPredicate),
426 /// A lifetime predicate, e.g. `'a: 'b+'c`
427 RegionPredicate(WhereRegionPredicate),
428 /// An equality predicate (unsupported)
429 EqPredicate(WhereEqPredicate),
432 /// A type bound, e.g. `for<'c> Foo: Send+Clone+'c`
433 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
434 pub struct WhereBoundPredicate {
436 /// Any lifetimes from a `for` binding
437 pub bound_lifetimes: Vec<LifetimeDef>,
438 /// The type being bounded
439 pub bounded_ty: P<Ty>,
440 /// Trait and lifetime bounds (`Clone+Send+'static`)
441 pub bounds: TyParamBounds,
444 /// A lifetime predicate, e.g. `'a: 'b+'c`
445 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
446 pub struct WhereRegionPredicate {
448 pub lifetime: Lifetime,
449 pub bounds: Vec<Lifetime>,
452 /// An equality predicate (unsupported), e.g. `T=int`
453 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
454 pub struct WhereEqPredicate {
461 /// The set of MetaItems that define the compilation environment of the crate,
462 /// used to drive conditional compilation
463 pub type CrateConfig = Vec<P<MetaItem>> ;
465 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
468 pub attrs: Vec<Attribute>,
469 pub config: CrateConfig,
471 pub exported_macros: Vec<MacroDef>,
474 pub type MetaItem = Spanned<MetaItemKind>;
476 #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
477 pub enum MetaItemKind {
478 Word(InternedString),
479 List(InternedString, Vec<P<MetaItem>>),
480 NameValue(InternedString, Lit),
483 // can't be derived because the MetaItemKind::List requires an unordered comparison
484 impl PartialEq for MetaItemKind {
485 fn eq(&self, other: &MetaItemKind) -> bool {
486 use self::MetaItemKind::*;
488 Word(ref ns) => match *other {
489 Word(ref no) => (*ns) == (*no),
492 NameValue(ref ns, ref vs) => match *other {
493 NameValue(ref no, ref vo) => {
494 (*ns) == (*no) && vs.node == vo.node
498 List(ref ns, ref miss) => match *other {
499 List(ref no, ref miso) => {
501 miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
509 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
511 /// Statements in a block
512 pub stmts: Vec<P<Stmt>>,
513 /// An expression at the end of the block
514 /// without a semicolon, if any
515 pub expr: Option<P<Expr>>,
517 /// Distinguishes between `unsafe { ... }` and `{ ... }`
518 pub rules: BlockCheckMode,
522 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
529 impl fmt::Debug for Pat {
530 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
531 write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self))
535 /// A single field in a struct pattern
537 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
538 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
539 /// except is_shorthand is true
540 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
541 pub struct FieldPat {
542 /// The identifier for the field
544 /// The pattern the field is destructured to
546 pub is_shorthand: bool,
549 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
550 pub enum BindingMode {
555 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
557 /// Represents a wildcard pattern (`_`)
560 /// A PatIdent may either be a new bound variable,
561 /// or a nullary enum (in which case the third field
564 /// In the nullary enum case, the parser can't determine
565 /// which it is. The resolver determines this, and
566 /// records this pattern's NodeId in an auxiliary
567 /// set (of "PatIdents that refer to nullary enums")
568 PatIdent(BindingMode, SpannedIdent, Option<P<Pat>>),
570 /// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
571 PatEnum(Path, Option<Vec<P<Pat>>>),
573 /// An associated const named using the qualified path `<T>::CONST` or
574 /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
575 /// referred to as simply `T::CONST`, in which case they will end up as
576 /// PatEnum, and the resolver will have to sort that out.
577 PatQPath(QSelf, Path),
579 /// Destructuring of a struct, e.g. `Foo {x, y, ..}`
580 /// The `bool` is `true` in the presence of a `..`
581 PatStruct(Path, Vec<Spanned<FieldPat>>, bool),
582 /// A tuple pattern `(a, b)`
586 /// A reference pattern, e.g. `&mut (a, b)`
587 PatRegion(P<Pat>, Mutability),
590 /// A range pattern, e.g. `1...2`
591 PatRange(P<Expr>, P<Expr>),
592 /// `[a, b, ..i, y, z]` is represented as:
593 /// `PatVec(box [a, b], Some(i), box [y, z])`
594 PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
595 /// A macro pattern; pre-expansion
599 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
600 pub enum Mutability {
605 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
607 /// The `+` operator (addition)
609 /// The `-` operator (subtraction)
611 /// The `*` operator (multiplication)
613 /// The `/` operator (division)
615 /// The `%` operator (modulus)
617 /// The `&&` operator (logical and)
619 /// The `||` operator (logical or)
621 /// The `^` operator (bitwise xor)
623 /// The `&` operator (bitwise and)
625 /// The `|` operator (bitwise or)
627 /// The `<<` operator (shift left)
629 /// The `>>` operator (shift right)
631 /// The `==` operator (equality)
633 /// The `<` operator (less than)
635 /// The `<=` operator (less than or equal to)
637 /// The `!=` operator (not equal to)
639 /// The `>=` operator (greater than or equal to)
641 /// The `>` operator (greater than)
646 pub fn to_string(&self) -> &'static str {
647 use self::BinOpKind::*;
669 pub fn lazy(&self) -> bool {
671 BinOpKind::And | BinOpKind::Or => true,
676 pub fn is_shift(&self) -> bool {
678 BinOpKind::Shl | BinOpKind::Shr => true,
682 pub fn is_comparison(&self) -> bool {
683 use self::BinOpKind::*;
685 Eq | Lt | Le | Ne | Gt | Ge =>
687 And | Or | Add | Sub | Mul | Div | Rem |
688 BitXor | BitAnd | BitOr | Shl | Shr =>
692 /// Returns `true` if the binary operator takes its arguments by value
693 pub fn is_by_value(&self) -> bool {
694 !self.is_comparison()
698 pub type BinOp = Spanned<BinOpKind>;
700 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
702 /// The `*` operator for dereferencing
704 /// The `!` operator for logical inversion
706 /// The `-` operator for negation
711 /// Returns `true` if the unary operator takes its argument by value
712 pub fn is_by_value(u: UnOp) -> bool {
714 UnOp::Neg | UnOp::Not => true,
719 pub fn to_string(op: UnOp) -> &'static str {
729 pub type Stmt = Spanned<StmtKind>;
731 impl fmt::Debug for Stmt {
732 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
733 write!(f, "stmt({}: {})",
735 .map_or(Cow::Borrowed("<macro>"),|id|Cow::Owned(id.to_string())),
736 pprust::stmt_to_string(self))
741 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
743 /// Could be an item or a local (let) binding:
744 Decl(P<Decl>, NodeId),
746 /// Expr without trailing semi-colon (must have unit type):
747 Expr(P<Expr>, NodeId),
749 /// Expr with trailing semi-colon (may have any type):
750 Semi(P<Expr>, NodeId),
752 Mac(P<Mac>, MacStmtStyle, ThinAttributes),
756 pub fn id(&self) -> Option<NodeId> {
758 StmtKind::Decl(_, id) => Some(id),
759 StmtKind::Expr(_, id) => Some(id),
760 StmtKind::Semi(_, id) => Some(id),
761 StmtKind::Mac(..) => None,
765 pub fn attrs(&self) -> &[Attribute] {
767 StmtKind::Decl(ref d, _) => d.attrs(),
768 StmtKind::Expr(ref e, _) |
769 StmtKind::Semi(ref e, _) => e.attrs(),
770 StmtKind::Mac(_, _, Some(ref b)) => b,
771 StmtKind::Mac(_, _, None) => &[],
776 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
777 pub enum MacStmtStyle {
778 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
779 /// `foo!(...);`, `foo![...];`
781 /// The macro statement had braces; e.g. foo! { ... }
783 /// The macro statement had parentheses or brackets and no semicolon; e.g.
784 /// `foo!(...)`. All of these will end up being converted into macro
789 // FIXME (pending discussion of #1697, #2178...): local should really be
790 // a refinement on pat.
791 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
792 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
795 pub ty: Option<P<Ty>>,
796 /// Initializer expression to set the value, if any
797 pub init: Option<P<Expr>>,
800 pub attrs: ThinAttributes,
804 pub fn attrs(&self) -> &[Attribute] {
812 pub type Decl = Spanned<DeclKind>;
814 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
816 /// A local (let) binding:
823 pub fn attrs(&self) -> &[Attribute] {
825 DeclKind::Local(ref l) => l.attrs(),
826 DeclKind::Item(ref i) => i.attrs(),
831 /// represents one arm of a 'match'
832 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
834 pub attrs: Vec<Attribute>,
835 pub pats: Vec<P<Pat>>,
836 pub guard: Option<P<Expr>>,
840 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
842 pub ident: SpannedIdent,
847 pub type SpannedIdent = Spanned<Ident>;
849 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
850 pub enum BlockCheckMode {
852 Unsafe(UnsafeSource),
855 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
856 pub enum UnsafeSource {
862 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash,)]
867 pub attrs: ThinAttributes
871 pub fn attrs(&self) -> &[Attribute] {
879 impl fmt::Debug for Expr {
880 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
881 write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self))
885 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
887 /// A `box x` expression.
889 /// First expr is the place; second expr is the value.
890 InPlace(P<Expr>, P<Expr>),
891 /// An array (`[a, b, c, d]`)
895 /// The first field resolves to the function itself,
896 /// and the second field is the list of arguments
897 Call(P<Expr>, Vec<P<Expr>>),
898 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
900 /// The `SpannedIdent` is the identifier for the method name.
901 /// The vector of `Ty`s are the ascripted type parameters for the method
902 /// (within the angle brackets).
904 /// The first element of the vector of `Expr`s is the expression that evaluates
905 /// to the object on which the method is being called on (the receiver),
906 /// and the remaining elements are the rest of the arguments.
908 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
909 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
910 MethodCall(SpannedIdent, Vec<P<Ty>>, Vec<P<Expr>>),
911 /// A tuple (`(a, b, c ,d)`)
913 /// A binary operation (For example: `a + b`, `a * b`)
914 Binary(BinOp, P<Expr>, P<Expr>),
915 /// A unary operation (For example: `!x`, `*x`)
916 Unary(UnOp, P<Expr>),
917 /// A literal (For example: `1u8`, `"foo"`)
919 /// A cast (`foo as f64`)
920 Cast(P<Expr>, P<Ty>),
921 Type(P<Expr>, P<Ty>),
922 /// An `if` block, with an optional else block
924 /// `if expr { block } else { expr }`
925 If(P<Expr>, P<Block>, Option<P<Expr>>),
926 /// An `if let` expression with an optional else block
928 /// `if let pat = expr { block } else { expr }`
930 /// This is desugared to a `match` expression.
931 IfLet(P<Pat>, P<Expr>, P<Block>, Option<P<Expr>>),
932 /// A while loop, with an optional label
934 /// `'label: while expr { block }`
935 While(P<Expr>, P<Block>, Option<Ident>),
936 /// A while-let loop, with an optional label
938 /// `'label: while let pat = expr { block }`
940 /// This is desugared to a combination of `loop` and `match` expressions.
941 WhileLet(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
942 /// A for loop, with an optional label
944 /// `'label: for pat in expr { block }`
946 /// This is desugared to a combination of `loop` and `match` expressions.
947 ForLoop(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
948 /// Conditionless loop (can be exited with break, continue, or return)
950 /// `'label: loop { block }`
951 Loop(P<Block>, Option<Ident>),
953 Match(P<Expr>, Vec<Arm>),
954 /// A closure (for example, `move |a, b, c| {a + b + c}`)
955 Closure(CaptureBy, P<FnDecl>, P<Block>),
956 /// A block (`{ ... }`)
959 /// An assignment (`a = foo()`)
960 Assign(P<Expr>, P<Expr>),
961 /// An assignment with an operator
963 /// For example, `a += 1`.
964 AssignOp(BinOp, P<Expr>, P<Expr>),
965 /// Access of a named struct field (`obj.foo`)
966 Field(P<Expr>, SpannedIdent),
967 /// Access of an unnamed field of a struct or tuple-struct
969 /// For example, `foo.0`.
970 TupField(P<Expr>, Spanned<usize>),
971 /// An indexing operation (`foo[2]`)
972 Index(P<Expr>, P<Expr>),
973 /// A range (`1..2`, `1..`, or `..2`)
974 Range(Option<P<Expr>>, Option<P<Expr>>),
976 /// Variable reference, possibly containing `::` and/or type
977 /// parameters, e.g. foo::bar::<baz>.
979 /// Optionally "qualified",
980 /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
981 Path(Option<QSelf>, Path),
983 /// A referencing operation (`&a` or `&mut a`)
984 AddrOf(Mutability, P<Expr>),
985 /// A `break`, with an optional label to break
986 Break(Option<SpannedIdent>),
987 /// A `continue`, with an optional label
988 Again(Option<SpannedIdent>),
989 /// A `return`, with an optional value to be returned
990 Ret(Option<P<Expr>>),
992 /// Output of the `asm!()` macro
993 InlineAsm(InlineAsm),
995 /// A macro invocation; pre-expansion
998 /// A struct literal expression.
1000 /// For example, `Foo {x: 1, y: 2}`, or
1001 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
1002 Struct(Path, Vec<Field>, Option<P<Expr>>),
1004 /// An array literal constructed from one repeated element.
1006 /// For example, `[1u8; 5]`. The first expression is the element
1007 /// to be repeated; the second is the number of times to repeat it.
1008 Repeat(P<Expr>, P<Expr>),
1010 /// No-op: used solely so we can pretty-print faithfully
1014 /// The explicit Self type in a "qualified path". The actual
1015 /// path, including the trait and the associated item, is stored
1016 /// separately. `position` represents the index of the associated
1017 /// item qualified with this Self type.
1020 /// <Vec<T> as a::b::Trait>::AssociatedItem
1021 /// ^~~~~ ~~~~~~~~~~~~~~^
1024 /// <Vec<T>>::AssociatedItem
1028 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1034 /// A capture clause
1035 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1036 pub enum CaptureBy {
1041 /// A delimited sequence of token trees
1042 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1043 pub struct Delimited {
1044 /// The type of delimiter
1045 pub delim: token::DelimToken,
1046 /// The span covering the opening delimiter
1047 pub open_span: Span,
1048 /// The delimited sequence of token trees
1049 pub tts: Vec<TokenTree>,
1050 /// The span covering the closing delimiter
1051 pub close_span: Span,
1055 /// Returns the opening delimiter as a token.
1056 pub fn open_token(&self) -> token::Token {
1057 token::OpenDelim(self.delim)
1060 /// Returns the closing delimiter as a token.
1061 pub fn close_token(&self) -> token::Token {
1062 token::CloseDelim(self.delim)
1065 /// Returns the opening delimiter as a token tree.
1066 pub fn open_tt(&self) -> TokenTree {
1067 TokenTree::Token(self.open_span, self.open_token())
1070 /// Returns the closing delimiter as a token tree.
1071 pub fn close_tt(&self) -> TokenTree {
1072 TokenTree::Token(self.close_span, self.close_token())
1076 /// A sequence of token trees
1077 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1078 pub struct SequenceRepetition {
1079 /// The sequence of token trees
1080 pub tts: Vec<TokenTree>,
1081 /// The optional separator
1082 pub separator: Option<token::Token>,
1083 /// Whether the sequence can be repeated zero (*), or one or more times (+)
1085 /// The number of `MatchNt`s that appear in the sequence (and subsequences)
1086 pub num_captures: usize,
1089 /// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
1090 /// for token sequences.
1091 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1097 /// When the main rust parser encounters a syntax-extension invocation, it
1098 /// parses the arguments to the invocation as a token-tree. This is a very
1099 /// loose structure, such that all sorts of different AST-fragments can
1100 /// be passed to syntax extensions using a uniform type.
1102 /// If the syntax extension is an MBE macro, it will attempt to match its
1103 /// LHS token tree against the provided token tree, and if it finds a
1104 /// match, will transcribe the RHS token tree, splicing in any captured
1105 /// macro_parser::matched_nonterminals into the `SubstNt`s it finds.
1107 /// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
1108 /// Nothing special happens to misnamed or misplaced `SubstNt`s.
1109 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1110 pub enum TokenTree {
1112 Token(Span, token::Token),
1113 /// A delimited sequence of token trees
1114 Delimited(Span, Rc<Delimited>),
1116 // This only makes sense in MBE macros.
1118 /// A kleene-style repetition sequence with a span
1119 // FIXME(eddyb) #12938 Use DST.
1120 Sequence(Span, Rc<SequenceRepetition>),
1124 pub fn len(&self) -> usize {
1126 TokenTree::Token(_, token::DocComment(name)) => {
1127 match doc_comment_style(&name.as_str()) {
1128 AttrStyle::Outer => 2,
1129 AttrStyle::Inner => 3
1132 TokenTree::Token(_, token::SpecialVarNt(..)) => 2,
1133 TokenTree::Token(_, token::MatchNt(..)) => 3,
1134 TokenTree::Delimited(_, ref delimed) => {
1135 delimed.tts.len() + 2
1137 TokenTree::Sequence(_, ref seq) => {
1140 TokenTree::Token(..) => 0
1144 pub fn get_tt(&self, index: usize) -> TokenTree {
1145 match (self, index) {
1146 (&TokenTree::Token(sp, token::DocComment(_)), 0) => {
1147 TokenTree::Token(sp, token::Pound)
1149 (&TokenTree::Token(sp, token::DocComment(name)), 1)
1150 if doc_comment_style(&name.as_str()) == AttrStyle::Inner => {
1151 TokenTree::Token(sp, token::Not)
1153 (&TokenTree::Token(sp, token::DocComment(name)), _) => {
1154 let stripped = strip_doc_comment_decoration(&name.as_str());
1156 // Searches for the occurrences of `"#*` and returns the minimum number of `#`s
1157 // required to wrap the text.
1158 let num_of_hashes = stripped.chars().scan(0, |cnt, x| {
1159 *cnt = if x == '"' {
1161 } else if *cnt != 0 && x == '#' {
1167 }).max().unwrap_or(0);
1169 TokenTree::Delimited(sp, Rc::new(Delimited {
1170 delim: token::Bracket,
1172 tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc"),
1174 TokenTree::Token(sp, token::Eq),
1175 TokenTree::Token(sp, token::Literal(
1176 token::StrRaw(token::intern(&stripped), num_of_hashes), None))],
1180 (&TokenTree::Delimited(_, ref delimed), _) => {
1182 return delimed.open_tt();
1184 if index == delimed.tts.len() + 1 {
1185 return delimed.close_tt();
1187 delimed.tts[index - 1].clone()
1189 (&TokenTree::Token(sp, token::SpecialVarNt(var)), _) => {
1190 let v = [TokenTree::Token(sp, token::Dollar),
1191 TokenTree::Token(sp, token::Ident(token::str_to_ident(var.as_str()),
1195 (&TokenTree::Token(sp, token::MatchNt(name, kind, name_st, kind_st)), _) => {
1196 let v = [TokenTree::Token(sp, token::SubstNt(name, name_st)),
1197 TokenTree::Token(sp, token::Colon),
1198 TokenTree::Token(sp, token::Ident(kind, kind_st))];
1201 (&TokenTree::Sequence(_, ref seq), _) => {
1202 seq.tts[index].clone()
1204 _ => panic!("Cannot expand a token tree")
1208 /// Returns the `Span` corresponding to this token tree.
1209 pub fn get_span(&self) -> Span {
1211 TokenTree::Token(span, _) => span,
1212 TokenTree::Delimited(span, _) => span,
1213 TokenTree::Sequence(span, _) => span,
1217 /// Use this token tree as a matcher to parse given tts.
1218 pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree])
1219 -> macro_parser::NamedParseResult {
1220 // `None` is because we're not interpolating
1221 let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
1224 tts.iter().cloned().collect(),
1226 macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch)
1230 pub type Mac = Spanned<Mac_>;
1232 /// Represents a macro invocation. The Path indicates which macro
1233 /// is being invoked, and the vector of token-trees contains the source
1234 /// of the macro invocation.
1236 /// NB: the additional ident for a macro_rules-style macro is actually
1237 /// stored in the enclosing item. Oog.
1238 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1241 pub tts: Vec<TokenTree>,
1242 pub ctxt: SyntaxContext,
1245 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1247 /// A regular string, like `"foo"`
1249 /// A raw string, like `r##"foo"##`
1251 /// The uint is the number of `#` symbols used
1256 pub type Lit = Spanned<LitKind>;
1258 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1259 pub enum LitIntType {
1265 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1267 /// A string literal (`"foo"`)
1268 Str(InternedString, StrStyle),
1269 /// A byte string (`b"foo"`)
1270 ByteStr(Rc<Vec<u8>>),
1271 /// A byte char (`b'f'`)
1273 /// A character literal (`'a'`)
1275 /// An integer literal (`1u8`)
1276 Int(u64, LitIntType),
1277 /// A float literal (`1f64` or `1E10f64`)
1278 Float(InternedString, FloatTy),
1279 /// A float literal without a suffix (`1.0 or 1.0E10`)
1280 FloatUnsuffixed(InternedString),
1281 /// A boolean literal
1286 /// Returns true if this literal is a string and false otherwise.
1287 pub fn is_str(&self) -> bool {
1289 LitKind::Str(..) => true,
1295 // NB: If you change this, you'll probably want to change the corresponding
1296 // type structure in middle/ty.rs as well.
1297 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1300 pub mutbl: Mutability,
1303 /// Represents a method's signature in a trait declaration,
1304 /// or in an implementation.
1305 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1306 pub struct MethodSig {
1307 pub unsafety: Unsafety,
1308 pub constness: Constness,
1310 pub decl: P<FnDecl>,
1311 pub generics: Generics,
1312 pub explicit_self: ExplicitSelf,
1315 /// Represents a method declaration in a trait declaration, possibly including
1316 /// a default implementation. A trait method is either required (meaning it
1317 /// doesn't have an implementation, just a signature) or provided (meaning it
1318 /// has a default implementation).
1319 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1320 pub struct TraitItem {
1323 pub attrs: Vec<Attribute>,
1324 pub node: TraitItemKind,
1328 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1329 pub enum TraitItemKind {
1330 Const(P<Ty>, Option<P<Expr>>),
1331 Method(MethodSig, Option<P<Block>>),
1332 Type(TyParamBounds, Option<P<Ty>>),
1335 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1336 pub struct ImplItem {
1339 pub vis: Visibility,
1340 pub attrs: Vec<Attribute>,
1341 pub node: ImplItemKind,
1345 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1346 pub enum ImplItemKind {
1347 Const(P<Ty>, P<Expr>),
1348 Method(MethodSig, P<Block>),
1353 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1362 impl fmt::Debug for IntTy {
1363 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1364 fmt::Display::fmt(self, f)
1368 impl fmt::Display for IntTy {
1369 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1370 write!(f, "{}", self.ty_to_string())
1375 pub fn ty_to_string(&self) -> &'static str {
1377 IntTy::Is => "isize",
1379 IntTy::I16 => "i16",
1380 IntTy::I32 => "i32",
1385 pub fn val_to_string(&self, val: i64) -> String {
1386 // cast to a u64 so we can correctly print INT64_MIN. All integral types
1387 // are parsed as u64, so we wouldn't want to print an extra negative
1389 format!("{}{}", val as u64, self.ty_to_string())
1392 pub fn ty_max(&self) -> u64 {
1395 IntTy::I16 => 0x8000,
1396 IntTy::Is | IntTy::I32 => 0x80000000, // FIXME: actually ni about Is
1397 IntTy::I64 => 0x8000000000000000
1401 pub fn bit_width(&self) -> Option<usize> {
1403 IntTy::Is => return None,
1412 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1422 pub fn ty_to_string(&self) -> &'static str {
1424 UintTy::Us => "usize",
1426 UintTy::U16 => "u16",
1427 UintTy::U32 => "u32",
1428 UintTy::U64 => "u64"
1432 pub fn val_to_string(&self, val: u64) -> String {
1433 format!("{}{}", val, self.ty_to_string())
1436 pub fn ty_max(&self) -> u64 {
1439 UintTy::U16 => 0xffff,
1440 UintTy::Us | UintTy::U32 => 0xffffffff, // FIXME: actually ni about Us
1441 UintTy::U64 => 0xffffffffffffffff
1445 pub fn bit_width(&self) -> Option<usize> {
1447 UintTy::Us => return None,
1456 impl fmt::Debug for UintTy {
1457 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1458 fmt::Display::fmt(self, f)
1462 impl fmt::Display for UintTy {
1463 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1464 write!(f, "{}", self.ty_to_string())
1468 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1474 impl fmt::Debug for FloatTy {
1475 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1476 fmt::Display::fmt(self, f)
1480 impl fmt::Display for FloatTy {
1481 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1482 write!(f, "{}", self.ty_to_string())
1487 pub fn ty_to_string(&self) -> &'static str {
1489 FloatTy::F32 => "f32",
1490 FloatTy::F64 => "f64",
1494 pub fn bit_width(&self) -> usize {
1502 // Bind a type to an associated type: `A=Foo`.
1503 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1504 pub struct TypeBinding {
1511 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1518 impl fmt::Debug for Ty {
1519 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1520 write!(f, "type({})", pprust::ty_to_string(self))
1524 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1525 pub struct BareFnTy {
1526 pub unsafety: Unsafety,
1528 pub lifetimes: Vec<LifetimeDef>,
1532 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1533 /// The different kinds of types recognized by the compiler
1536 /// A fixed length array (`[T; n]`)
1537 FixedLengthVec(P<Ty>, P<Expr>),
1538 /// A raw pointer (`*const T` or `*mut T`)
1540 /// A reference (`&'a T` or `&'a mut T`)
1541 Rptr(Option<Lifetime>, MutTy),
1542 /// A bare function (e.g. `fn(usize) -> bool`)
1543 BareFn(P<BareFnTy>),
1544 /// A tuple (`(A, B, C, D,...)`)
1546 /// A path (`module::module::...::Type`), optionally
1547 /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
1549 /// Type parameters are stored in the Path itself
1550 Path(Option<QSelf>, Path),
1551 /// Something like `A+B`. Note that `B` must always be a path.
1552 ObjectSum(P<Ty>, TyParamBounds),
1553 /// A type like `for<'a> Foo<&'a Bar>`
1554 PolyTraitRef(TyParamBounds),
1555 /// No-op; kept solely so that we can pretty-print faithfully
1559 /// TyKind::Infer means the type should be inferred instead of it having been
1560 /// specified. This can appear anywhere in a type.
1562 // A macro in the type position.
1566 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1567 pub enum AsmDialect {
1572 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1573 pub struct InlineAsmOutput {
1574 pub constraint: InternedString,
1577 pub is_indirect: bool,
1580 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1581 pub struct InlineAsm {
1582 pub asm: InternedString,
1583 pub asm_str_style: StrStyle,
1584 pub outputs: Vec<InlineAsmOutput>,
1585 pub inputs: Vec<(InternedString, P<Expr>)>,
1586 pub clobbers: Vec<InternedString>,
1588 pub alignstack: bool,
1589 pub dialect: AsmDialect,
1590 pub expn_id: ExpnId,
1593 /// represents an argument in a function header
1594 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1602 pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
1603 let path = Spanned{span:span,node:self_ident};
1605 // HACK(eddyb) fake type for the self argument.
1608 node: TyKind::Infer,
1613 node: PatIdent(BindingMode::ByValue(mutability), path, None),
1621 /// Represents the header (not the body) of a function declaration
1622 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1624 pub inputs: Vec<Arg>,
1625 pub output: FunctionRetTy,
1629 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1635 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1636 pub enum Constness {
1641 impl fmt::Display for Unsafety {
1642 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1643 fmt::Display::fmt(match *self {
1644 Unsafety::Normal => "normal",
1645 Unsafety::Unsafe => "unsafe",
1650 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1651 pub enum ImplPolarity {
1652 /// `impl Trait for Type`
1654 /// `impl !Trait for Type`
1658 impl fmt::Debug for ImplPolarity {
1659 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1661 ImplPolarity::Positive => "positive".fmt(f),
1662 ImplPolarity::Negative => "negative".fmt(f),
1668 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1669 pub enum FunctionRetTy {
1670 /// Functions with return type `!`that always
1671 /// raise an error or exit (i.e. never return to the caller)
1673 /// Return type is not specified.
1675 /// Functions default to `()` and
1676 /// closures default to inference. Span points to where return
1677 /// type would be inserted.
1683 impl FunctionRetTy {
1684 pub fn span(&self) -> Span {
1686 FunctionRetTy::None(span) => span,
1687 FunctionRetTy::Default(span) => span,
1688 FunctionRetTy::Ty(ref ty) => ty.span,
1693 /// Represents the kind of 'self' associated with a method
1694 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1700 /// `&'lt self`, `&'lt mut self`
1701 Region(Option<Lifetime>, Mutability, Ident),
1703 Explicit(P<Ty>, Ident),
1706 pub type ExplicitSelf = Spanned<SelfKind>;
1708 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1710 /// A span from the first token past `{` to the last token until `}`.
1711 /// For `mod foo;`, the inner span ranges from the first token
1712 /// to the last token in the external file.
1714 pub items: Vec<P<Item>>,
1717 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1718 pub struct ForeignMod {
1720 pub items: Vec<P<ForeignItem>>,
1723 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1724 pub struct EnumDef {
1725 pub variants: Vec<P<Variant>>,
1728 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1729 pub struct Variant_ {
1731 pub attrs: Vec<Attribute>,
1732 pub data: VariantData,
1733 /// Explicit discriminant, eg `Foo = 1`
1734 pub disr_expr: Option<P<Expr>>,
1737 pub type Variant = Spanned<Variant_>;
1739 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1740 pub enum PathListItem_ {
1743 /// renamed in list, eg `use foo::{bar as baz};`
1744 rename: Option<Ident>,
1748 /// renamed in list, eg `use foo::{self as baz};`
1749 rename: Option<Ident>,
1754 impl PathListItem_ {
1755 pub fn id(&self) -> NodeId {
1757 PathListIdent { id, .. } | PathListMod { id, .. } => id
1761 pub fn name(&self) -> Option<Ident> {
1763 PathListIdent { name, .. } => Some(name),
1764 PathListMod { .. } => None,
1768 pub fn rename(&self) -> Option<Ident> {
1770 PathListIdent { rename, .. } | PathListMod { rename, .. } => rename
1775 pub type PathListItem = Spanned<PathListItem_>;
1777 pub type ViewPath = Spanned<ViewPath_>;
1779 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1780 pub enum ViewPath_ {
1782 /// `foo::bar::baz as quux`
1786 /// `foo::bar::baz` (with `as baz` implicitly on the right)
1787 ViewPathSimple(Ident, Path),
1792 /// `foo::bar::{a,b,c}`
1793 ViewPathList(Path, Vec<PathListItem>)
1796 /// Meta-data associated with an item
1797 pub type Attribute = Spanned<Attribute_>;
1799 /// Distinguishes between Attributes that decorate items and Attributes that
1800 /// are contained as statements within items. These two cases need to be
1801 /// distinguished for pretty-printing.
1802 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1803 pub enum AttrStyle {
1808 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1809 pub struct AttrId(pub usize);
1811 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
1812 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1813 pub struct Attribute_ {
1815 pub style: AttrStyle,
1816 pub value: P<MetaItem>,
1817 pub is_sugared_doc: bool,
1820 /// TraitRef's appear in impls.
1822 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1823 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1824 /// If this impl is an ItemKind::Impl, the impl_id is redundant (it could be the
1825 /// same as the impl's node id).
1826 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1827 pub struct TraitRef {
1832 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1833 pub struct PolyTraitRef {
1834 /// The `'a` in `<'a> Foo<&'a T>`
1835 pub bound_lifetimes: Vec<LifetimeDef>,
1837 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1838 pub trait_ref: TraitRef,
1843 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1844 pub enum Visibility {
1850 pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1852 Visibility::Inherited => parent_visibility,
1853 Visibility::Public => *self
1858 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1859 pub struct StructField_ {
1860 pub kind: StructFieldKind,
1863 pub attrs: Vec<Attribute>,
1867 pub fn ident(&self) -> Option<Ident> {
1869 NamedField(ref ident, _) => Some(ident.clone()),
1870 UnnamedField(_) => None
1875 pub type StructField = Spanned<StructField_>;
1877 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1878 pub enum StructFieldKind {
1879 NamedField(Ident, Visibility),
1880 /// Element of a tuple-like struct
1881 UnnamedField(Visibility),
1884 impl StructFieldKind {
1885 pub fn is_unnamed(&self) -> bool {
1887 UnnamedField(..) => true,
1888 NamedField(..) => false,
1892 pub fn visibility(&self) -> Visibility {
1894 NamedField(_, vis) | UnnamedField(vis) => vis
1899 /// Fields and Ids of enum variants and structs
1901 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1902 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1903 /// One shared Id can be successfully used for these two purposes.
1904 /// Id of the whole enum lives in `Item`.
1906 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
1907 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
1908 /// the variant itself" from enum variants.
1909 /// Id of the whole struct lives in `Item`.
1910 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1911 pub enum VariantData {
1912 Struct(Vec<StructField>, NodeId),
1913 Tuple(Vec<StructField>, NodeId),
1918 pub fn fields(&self) -> &[StructField] {
1920 VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
1924 pub fn id(&self) -> NodeId {
1926 VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id
1929 pub fn is_struct(&self) -> bool {
1930 if let VariantData::Struct(..) = *self { true } else { false }
1932 pub fn is_tuple(&self) -> bool {
1933 if let VariantData::Tuple(..) = *self { true } else { false }
1935 pub fn is_unit(&self) -> bool {
1936 if let VariantData::Unit(..) = *self { true } else { false }
1941 FIXME (#3300): Should allow items to be anonymous. Right now
1942 we just use dummy names for anon items.
1946 /// The name might be a dummy name in case of anonymous items
1947 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1950 pub attrs: Vec<Attribute>,
1953 pub vis: Visibility,
1958 pub fn attrs(&self) -> &[Attribute] {
1963 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1965 /// An`extern crate` item, with optional original crate name,
1967 /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
1968 ExternCrate(Option<Name>),
1969 /// A `use` or `pub use` item
1973 Static(P<Ty>, Mutability, P<Expr>),
1975 Const(P<Ty>, P<Expr>),
1976 /// A function declaration
1977 Fn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
1980 /// An external module
1981 ForeignMod(ForeignMod),
1982 /// A type alias, e.g. `type Foo = Bar<u8>`
1983 Ty(P<Ty>, Generics),
1984 /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
1985 Enum(EnumDef, Generics),
1986 /// A struct definition, e.g. `struct Foo<A> {x: A}`
1987 Struct(VariantData, Generics),
1988 /// Represents a Trait Declaration
1994 // Default trait implementations
1996 // `impl Trait for .. {}`
1997 DefaultImpl(Unsafety, TraitRef),
1998 /// An implementation, eg `impl<A> Trait for Foo { .. }`
2002 Option<TraitRef>, // (optional) trait this impl implements
2005 /// A macro invocation (which includes macro definition)
2010 pub fn descriptive_variant(&self) -> &str {
2012 ItemKind::ExternCrate(..) => "extern crate",
2013 ItemKind::Use(..) => "use",
2014 ItemKind::Static(..) => "static item",
2015 ItemKind::Const(..) => "constant item",
2016 ItemKind::Fn(..) => "function",
2017 ItemKind::Mod(..) => "module",
2018 ItemKind::ForeignMod(..) => "foreign module",
2019 ItemKind::Ty(..) => "type alias",
2020 ItemKind::Enum(..) => "enum",
2021 ItemKind::Struct(..) => "struct",
2022 ItemKind::Trait(..) => "trait",
2024 ItemKind::Impl(..) |
2025 ItemKind::DefaultImpl(..) => "item"
2030 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2031 pub struct ForeignItem {
2033 pub attrs: Vec<Attribute>,
2034 pub node: ForeignItemKind,
2037 pub vis: Visibility,
2040 /// An item within an `extern` block
2041 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2042 pub enum ForeignItemKind {
2043 /// A foreign function
2044 Fn(P<FnDecl>, Generics),
2045 /// A foreign static item (`static ext: u8`), with optional mutability
2046 /// (the boolean is true when mutable)
2047 Static(P<Ty>, bool),
2050 impl ForeignItemKind {
2051 pub fn descriptive_variant(&self) -> &str {
2053 ForeignItemKind::Fn(..) => "foreign function",
2054 ForeignItemKind::Static(..) => "foreign static item"
2059 /// A macro definition, in this crate or imported from another.
2061 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
2062 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2063 pub struct MacroDef {
2065 pub attrs: Vec<Attribute>,
2068 pub imported_from: Option<Ident>,
2070 pub use_locally: bool,
2071 pub allow_internal_unstable: bool,
2072 pub body: Vec<TokenTree>,
2080 // are ASTs encodable?
2082 fn check_asts_encodable() {
2083 fn assert_encodable<T: serialize::Encodable>() {}
2084 assert_encodable::<Crate>();