]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ast.rs
[breaking-change] move ast_util functions to methods
[rust.git] / src / libsyntax / ast.rs
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.
4 //
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.
10
11 // The Rust abstract syntax tree.
12
13 pub use self::BindingMode::*;
14 pub use self::BinOp_::*;
15 pub use self::BlockCheckMode::*;
16 pub use self::CaptureClause::*;
17 pub use self::Decl_::*;
18 pub use self::ExplicitSelf_::*;
19 pub use self::Expr_::*;
20 pub use self::FloatTy::*;
21 pub use self::FunctionRetTy::*;
22 pub use self::ForeignItem_::*;
23 pub use self::IntTy::*;
24 pub use self::Item_::*;
25 pub use self::KleeneOp::*;
26 pub use self::Lit_::*;
27 pub use self::LitIntType::*;
28 pub use self::MacStmtStyle::*;
29 pub use self::MetaItem_::*;
30 pub use self::Mutability::*;
31 pub use self::Pat_::*;
32 pub use self::PathListItem_::*;
33 pub use self::PrimTy::*;
34 pub use self::Sign::*;
35 pub use self::Stmt_::*;
36 pub use self::StrStyle::*;
37 pub use self::StructFieldKind::*;
38 pub use self::TraitItem_::*;
39 pub use self::Ty_::*;
40 pub use self::TyParamBound::*;
41 pub use self::UintTy::*;
42 pub use self::UnOp::*;
43 pub use self::UnsafeSource::*;
44 pub use self::ViewPath_::*;
45 pub use self::Visibility::*;
46 pub use self::PathParameters::*;
47
48 use attr::ThinAttributes;
49 use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
50 use abi::Abi;
51 use ext::base;
52 use ext::tt::macro_parser;
53 use owned_slice::OwnedSlice;
54 use parse::token::{InternedString, str_to_ident};
55 use parse::token;
56 use parse::lexer;
57 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
58 use print::pprust;
59 use ptr::P;
60
61 use std::fmt;
62 use std::rc::Rc;
63 use std::borrow::Cow;
64 use std::hash::{Hash, Hasher};
65 use serialize::{Encodable, Decodable, Encoder, Decoder};
66
67 /// A name is a part of an identifier, representing a string or gensym. It's
68 /// the result of interning.
69 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
70 pub struct Name(pub u32);
71
72 /// A SyntaxContext represents a chain of macro-expandings
73 /// and renamings. Each macro expansion corresponds to
74 /// a fresh u32. This u32 is a reference to a table stored
75 // in thread-local storage.
76 // The special value EMPTY_CTXT is used to indicate an empty
77 // syntax context.
78 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
79 pub struct SyntaxContext(pub u32);
80
81 /// An identifier contains a Name (index into the interner
82 /// table) and a SyntaxContext to track renaming and
83 /// macro expansion per Flatt et al., "Macros That Work Together"
84 #[derive(Clone, Copy, Eq)]
85 pub struct Ident {
86     pub name: Name,
87     pub ctxt: SyntaxContext
88 }
89
90 impl Name {
91     pub fn as_str(self) -> token::InternedString {
92         token::InternedString::new_from_name(self)
93     }
94 }
95
96 impl fmt::Debug for Name {
97     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
98         write!(f, "{}({})", self, self.0)
99     }
100 }
101
102 impl fmt::Display for Name {
103     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104         fmt::Display::fmt(&self.as_str(), f)
105     }
106 }
107
108 impl Encodable for Name {
109     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
110         s.emit_str(&self.as_str())
111     }
112 }
113
114 impl Decodable for Name {
115     fn decode<D: Decoder>(d: &mut D) -> Result<Name, D::Error> {
116         Ok(token::intern(&try!(d.read_str())[..]))
117     }
118 }
119
120 pub const EMPTY_CTXT : SyntaxContext = SyntaxContext(0);
121
122 impl Ident {
123     pub fn new(name: Name, ctxt: SyntaxContext) -> Ident {
124         Ident {name: name, ctxt: ctxt}
125     }
126     pub fn with_empty_ctxt(name: Name) -> Ident {
127         Ident {name: name, ctxt: EMPTY_CTXT}
128     }
129 }
130
131 impl PartialEq for Ident {
132     fn eq(&self, other: &Ident) -> bool {
133         if self.ctxt != other.ctxt {
134             // There's no one true way to compare Idents. They can be compared
135             // non-hygienically `id1.name == id2.name`, hygienically
136             // `mtwt::resolve(id1) == mtwt::resolve(id2)`, or even member-wise
137             // `(id1.name, id1.ctxt) == (id2.name, id2.ctxt)` depending on the situation.
138             // Ideally, PartialEq should not be implemented for Ident at all, but that
139             // would be too impractical, because many larger structures (Token, in particular)
140             // including Idents as their parts derive PartialEq and use it for non-hygienic
141             // comparisons. That's why PartialEq is implemented and defaults to non-hygienic
142             // comparison. Hash is implemented too and is consistent with PartialEq, i.e. only
143             // the name of Ident is hashed. Still try to avoid comparing idents in your code
144             // (especially as keys in hash maps), use one of the three methods listed above
145             // explicitly.
146             //
147             // If you see this panic, then some idents from different contexts were compared
148             // non-hygienically. It's likely a bug. Use one of the three comparison methods
149             // listed above explicitly.
150
151             panic!("idents with different contexts are compared with operator `==`: \
152                 {:?}, {:?}.", self, other);
153         }
154
155         self.name == other.name
156     }
157 }
158
159 impl Hash for Ident {
160     fn hash<H: Hasher>(&self, state: &mut H) {
161         self.name.hash(state)
162     }
163 }
164
165 impl fmt::Debug for Ident {
166     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
167         write!(f, "{}#{}", self.name, self.ctxt.0)
168     }
169 }
170
171 impl fmt::Display for Ident {
172     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
173         fmt::Display::fmt(&self.name, f)
174     }
175 }
176
177 impl Encodable for Ident {
178     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
179         self.name.encode(s)
180     }
181 }
182
183 impl Decodable for Ident {
184     fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
185         Ok(Ident::with_empty_ctxt(try!(Name::decode(d))))
186     }
187 }
188
189 /// A mark represents a unique id associated with a macro expansion
190 pub type Mrk = u32;
191
192 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
193 pub struct Lifetime {
194     pub id: NodeId,
195     pub span: Span,
196     pub name: Name
197 }
198
199 impl fmt::Debug for Lifetime {
200     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
201         write!(f, "lifetime({}: {})", self.id, pprust::lifetime_to_string(self))
202     }
203 }
204
205 /// A lifetime definition, eg `'a: 'b+'c+'d`
206 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
207 pub struct LifetimeDef {
208     pub lifetime: Lifetime,
209     pub bounds: Vec<Lifetime>
210 }
211
212 /// A "Path" is essentially Rust's notion of a name; for instance:
213 /// std::cmp::PartialEq  .  It's represented as a sequence of identifiers,
214 /// along with a bunch of supporting information.
215 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
216 pub struct Path {
217     pub span: Span,
218     /// A `::foo` path, is relative to the crate root rather than current
219     /// module (like paths in an import).
220     pub global: bool,
221     /// The segments in the path: the things separated by `::`.
222     pub segments: Vec<PathSegment>,
223 }
224
225 impl fmt::Debug for Path {
226     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
227         write!(f, "path({})", pprust::path_to_string(self))
228     }
229 }
230
231 impl fmt::Display for Path {
232     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233         write!(f, "{}", pprust::path_to_string(self))
234     }
235 }
236
237 /// A segment of a path: an identifier, an optional lifetime, and a set of
238 /// types.
239 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
240 pub struct PathSegment {
241     /// The identifier portion of this path segment.
242     pub identifier: Ident,
243
244     /// Type/lifetime parameters attached to this path. They come in
245     /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
246     /// this is more than just simple syntactic sugar; the use of
247     /// parens affects the region binding rules, so we preserve the
248     /// distinction.
249     pub parameters: PathParameters,
250 }
251
252 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
253 pub enum PathParameters {
254     /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
255     AngleBracketedParameters(AngleBracketedParameterData),
256     /// The `(A,B)` and `C` in `Foo(A,B) -> C`
257     ParenthesizedParameters(ParenthesizedParameterData),
258 }
259
260 impl PathParameters {
261     pub fn none() -> PathParameters {
262         AngleBracketedParameters(AngleBracketedParameterData {
263             lifetimes: Vec::new(),
264             types: OwnedSlice::empty(),
265             bindings: OwnedSlice::empty(),
266         })
267     }
268
269     pub fn is_empty(&self) -> bool {
270         match *self {
271             AngleBracketedParameters(ref data) => data.is_empty(),
272
273             // Even if the user supplied no types, something like
274             // `X()` is equivalent to `X<(),()>`.
275             ParenthesizedParameters(..) => false,
276         }
277     }
278
279     pub fn has_lifetimes(&self) -> bool {
280         match *self {
281             AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(),
282             ParenthesizedParameters(_) => false,
283         }
284     }
285
286     pub fn has_types(&self) -> bool {
287         match *self {
288             AngleBracketedParameters(ref data) => !data.types.is_empty(),
289             ParenthesizedParameters(..) => true,
290         }
291     }
292
293     /// Returns the types that the user wrote. Note that these do not necessarily map to the type
294     /// parameters in the parenthesized case.
295     pub fn types(&self) -> Vec<&P<Ty>> {
296         match *self {
297             AngleBracketedParameters(ref data) => {
298                 data.types.iter().collect()
299             }
300             ParenthesizedParameters(ref data) => {
301                 data.inputs.iter()
302                     .chain(data.output.iter())
303                     .collect()
304             }
305         }
306     }
307
308     pub fn lifetimes(&self) -> Vec<&Lifetime> {
309         match *self {
310             AngleBracketedParameters(ref data) => {
311                 data.lifetimes.iter().collect()
312             }
313             ParenthesizedParameters(_) => {
314                 Vec::new()
315             }
316         }
317     }
318
319     pub fn bindings(&self) -> Vec<&P<TypeBinding>> {
320         match *self {
321             AngleBracketedParameters(ref data) => {
322                 data.bindings.iter().collect()
323             }
324             ParenthesizedParameters(_) => {
325                 Vec::new()
326             }
327         }
328     }
329 }
330
331 /// A path like `Foo<'a, T>`
332 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
333 pub struct AngleBracketedParameterData {
334     /// The lifetime parameters for this path segment.
335     pub lifetimes: Vec<Lifetime>,
336     /// The type parameters for this path segment, if present.
337     pub types: OwnedSlice<P<Ty>>,
338     /// Bindings (equality constraints) on associated types, if present.
339     /// E.g., `Foo<A=Bar>`.
340     pub bindings: OwnedSlice<P<TypeBinding>>,
341 }
342
343 impl AngleBracketedParameterData {
344     fn is_empty(&self) -> bool {
345         self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
346     }
347 }
348
349 /// A path like `Foo(A,B) -> C`
350 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
351 pub struct ParenthesizedParameterData {
352     /// Overall span
353     pub span: Span,
354
355     /// `(A,B)`
356     pub inputs: Vec<P<Ty>>,
357
358     /// `C`
359     pub output: Option<P<Ty>>,
360 }
361
362 pub type CrateNum = u32;
363
364 pub type NodeId = u32;
365
366 /// Node id used to represent the root of the crate.
367 pub const CRATE_NODE_ID: NodeId = 0;
368
369 /// When parsing and doing expansions, we initially give all AST nodes this AST
370 /// node value. Then later, in the renumber pass, we renumber them to have
371 /// small, positive ids.
372 pub const DUMMY_NODE_ID: NodeId = !0;
373
374 pub trait NodeIdAssigner {
375     fn next_node_id(&self) -> NodeId;
376     fn peek_node_id(&self) -> NodeId;
377 }
378
379 /// The AST represents all type param bounds as types.
380 /// typeck::collect::compute_bounds matches these against
381 /// the "special" built-in traits (see middle::lang_items) and
382 /// detects Copy, Send and Sync.
383 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
384 pub enum TyParamBound {
385     TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
386     RegionTyParamBound(Lifetime)
387 }
388
389 /// A modifier on a bound, currently this is only used for `?Sized`, where the
390 /// modifier is `Maybe`. Negative bounds should also be handled here.
391 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
392 pub enum TraitBoundModifier {
393     None,
394     Maybe,
395 }
396
397 pub type TyParamBounds = OwnedSlice<TyParamBound>;
398
399 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
400 pub struct TyParam {
401     pub ident: Ident,
402     pub id: NodeId,
403     pub bounds: TyParamBounds,
404     pub default: Option<P<Ty>>,
405     pub span: Span
406 }
407
408 /// Represents lifetimes and type parameters attached to a declaration
409 /// of a function, enum, trait, etc.
410 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
411 pub struct Generics {
412     pub lifetimes: Vec<LifetimeDef>,
413     pub ty_params: OwnedSlice<TyParam>,
414     pub where_clause: WhereClause,
415 }
416
417 impl Generics {
418     pub fn is_lt_parameterized(&self) -> bool {
419         !self.lifetimes.is_empty()
420     }
421     pub fn is_type_parameterized(&self) -> bool {
422         !self.ty_params.is_empty()
423     }
424     pub fn is_parameterized(&self) -> bool {
425         self.is_lt_parameterized() || self.is_type_parameterized()
426     }
427 }
428
429 impl Default for Generics {
430     fn default() ->  Generics {
431         Generics {
432             lifetimes: Vec::new(),
433             ty_params: OwnedSlice::empty(),
434             where_clause: WhereClause {
435                 id: DUMMY_NODE_ID,
436                 predicates: Vec::new(),
437             }
438         }
439     }
440 }
441
442 /// A `where` clause in a definition
443 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
444 pub struct WhereClause {
445     pub id: NodeId,
446     pub predicates: Vec<WherePredicate>,
447 }
448
449 /// A single predicate in a `where` clause
450 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
451 pub enum WherePredicate {
452     /// A type binding, eg `for<'c> Foo: Send+Clone+'c`
453     BoundPredicate(WhereBoundPredicate),
454     /// A lifetime predicate, e.g. `'a: 'b+'c`
455     RegionPredicate(WhereRegionPredicate),
456     /// An equality predicate (unsupported)
457     EqPredicate(WhereEqPredicate),
458 }
459
460 /// A type bound, eg `for<'c> Foo: Send+Clone+'c`
461 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
462 pub struct WhereBoundPredicate {
463     pub span: Span,
464     /// Any lifetimes from a `for` binding
465     pub bound_lifetimes: Vec<LifetimeDef>,
466     /// The type being bounded
467     pub bounded_ty: P<Ty>,
468     /// Trait and lifetime bounds (`Clone+Send+'static`)
469     pub bounds: OwnedSlice<TyParamBound>,
470 }
471
472 /// A lifetime predicate, e.g. `'a: 'b+'c`
473 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
474 pub struct WhereRegionPredicate {
475     pub span: Span,
476     pub lifetime: Lifetime,
477     pub bounds: Vec<Lifetime>,
478 }
479
480 /// An equality predicate (unsupported), e.g. `T=int`
481 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
482 pub struct WhereEqPredicate {
483     pub id: NodeId,
484     pub span: Span,
485     pub path: Path,
486     pub ty: P<Ty>,
487 }
488
489 /// The set of MetaItems that define the compilation environment of the crate,
490 /// used to drive conditional compilation
491 pub type CrateConfig = Vec<P<MetaItem>> ;
492
493 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
494 pub struct Crate {
495     pub module: Mod,
496     pub attrs: Vec<Attribute>,
497     pub config: CrateConfig,
498     pub span: Span,
499     pub exported_macros: Vec<MacroDef>,
500 }
501
502 pub type MetaItem = Spanned<MetaItem_>;
503
504 #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
505 pub enum MetaItem_ {
506     MetaWord(InternedString),
507     MetaList(InternedString, Vec<P<MetaItem>>),
508     MetaNameValue(InternedString, Lit),
509 }
510
511 // can't be derived because the MetaList requires an unordered comparison
512 impl PartialEq for MetaItem_ {
513     fn eq(&self, other: &MetaItem_) -> bool {
514         match *self {
515             MetaWord(ref ns) => match *other {
516                 MetaWord(ref no) => (*ns) == (*no),
517                 _ => false
518             },
519             MetaNameValue(ref ns, ref vs) => match *other {
520                 MetaNameValue(ref no, ref vo) => {
521                     (*ns) == (*no) && vs.node == vo.node
522                 }
523                 _ => false
524             },
525             MetaList(ref ns, ref miss) => match *other {
526                 MetaList(ref no, ref miso) => {
527                     ns == no &&
528                         miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node))
529                 }
530                 _ => false
531             }
532         }
533     }
534 }
535
536 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
537 pub struct Block {
538     /// Statements in a block
539     pub stmts: Vec<P<Stmt>>,
540     /// An expression at the end of the block
541     /// without a semicolon, if any
542     pub expr: Option<P<Expr>>,
543     pub id: NodeId,
544     /// Distinguishes between `unsafe { ... }` and `{ ... }`
545     pub rules: BlockCheckMode,
546     pub span: Span,
547 }
548
549 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
550 pub struct Pat {
551     pub id: NodeId,
552     pub node: Pat_,
553     pub span: Span,
554 }
555
556 impl fmt::Debug for Pat {
557     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
558         write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self))
559     }
560 }
561
562 /// A single field in a struct pattern
563 ///
564 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
565 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
566 /// except is_shorthand is true
567 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
568 pub struct FieldPat {
569     /// The identifier for the field
570     pub ident: Ident,
571     /// The pattern the field is destructured to
572     pub pat: P<Pat>,
573     pub is_shorthand: bool,
574 }
575
576 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
577 pub enum BindingMode {
578     BindByRef(Mutability),
579     BindByValue(Mutability),
580 }
581
582 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
583 pub enum Pat_ {
584     /// Represents a wildcard pattern (`_`)
585     PatWild,
586
587     /// A PatIdent may either be a new bound variable,
588     /// or a nullary enum (in which case the third field
589     /// is None).
590     ///
591     /// In the nullary enum case, the parser can't determine
592     /// which it is. The resolver determines this, and
593     /// records this pattern's NodeId in an auxiliary
594     /// set (of "PatIdents that refer to nullary enums")
595     PatIdent(BindingMode, SpannedIdent, Option<P<Pat>>),
596
597     /// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
598     PatEnum(Path, Option<Vec<P<Pat>>>),
599
600     /// An associated const named using the qualified path `<T>::CONST` or
601     /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
602     /// referred to as simply `T::CONST`, in which case they will end up as
603     /// PatEnum, and the resolver will have to sort that out.
604     PatQPath(QSelf, Path),
605
606     /// Destructuring of a struct, e.g. `Foo {x, y, ..}`
607     /// The `bool` is `true` in the presence of a `..`
608     PatStruct(Path, Vec<Spanned<FieldPat>>, bool),
609     /// A tuple pattern `(a, b)`
610     PatTup(Vec<P<Pat>>),
611     /// A `box` pattern
612     PatBox(P<Pat>),
613     /// A reference pattern, e.g. `&mut (a, b)`
614     PatRegion(P<Pat>, Mutability),
615     /// A literal
616     PatLit(P<Expr>),
617     /// A range pattern, e.g. `1...2`
618     PatRange(P<Expr>, P<Expr>),
619     /// `[a, b, ..i, y, z]` is represented as:
620     ///     `PatVec(box [a, b], Some(i), box [y, z])`
621     PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
622     /// A macro pattern; pre-expansion
623     PatMac(Mac),
624 }
625
626 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
627 pub enum Mutability {
628     MutMutable,
629     MutImmutable,
630 }
631
632 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
633 pub enum BinOp_ {
634     /// The `+` operator (addition)
635     BiAdd,
636     /// The `-` operator (subtraction)
637     BiSub,
638     /// The `*` operator (multiplication)
639     BiMul,
640     /// The `/` operator (division)
641     BiDiv,
642     /// The `%` operator (modulus)
643     BiRem,
644     /// The `&&` operator (logical and)
645     BiAnd,
646     /// The `||` operator (logical or)
647     BiOr,
648     /// The `^` operator (bitwise xor)
649     BiBitXor,
650     /// The `&` operator (bitwise and)
651     BiBitAnd,
652     /// The `|` operator (bitwise or)
653     BiBitOr,
654     /// The `<<` operator (shift left)
655     BiShl,
656     /// The `>>` operator (shift right)
657     BiShr,
658     /// The `==` operator (equality)
659     BiEq,
660     /// The `<` operator (less than)
661     BiLt,
662     /// The `<=` operator (less than or equal to)
663     BiLe,
664     /// The `!=` operator (not equal to)
665     BiNe,
666     /// The `>=` operator (greater than or equal to)
667     BiGe,
668     /// The `>` operator (greater than)
669     BiGt,
670 }
671
672 impl BinOp_ {
673     pub fn to_string(&self) -> &'static str {
674         match *self {
675             BiAdd => "+",
676             BiSub => "-",
677             BiMul => "*",
678             BiDiv => "/",
679             BiRem => "%",
680             BiAnd => "&&",
681             BiOr => "||",
682             BiBitXor => "^",
683             BiBitAnd => "&",
684             BiBitOr => "|",
685             BiShl => "<<",
686             BiShr => ">>",
687             BiEq => "==",
688             BiLt => "<",
689             BiLe => "<=",
690             BiNe => "!=",
691             BiGe => ">=",
692             BiGt => ">"
693         }
694     }
695     pub fn lazy(&self) -> bool {
696         match *self {
697             BiAnd | BiOr => true,
698             _ => false
699         }
700     }
701
702     pub fn is_shift(&self) -> bool {
703         match *self {
704             BiShl | BiShr => true,
705             _ => false
706         }
707     }
708     pub fn is_comparison(&self) -> bool {
709         match *self {
710             BiEq | BiLt | BiLe | BiNe | BiGt | BiGe =>
711             true,
712             BiAnd | BiOr | BiAdd | BiSub | BiMul | BiDiv | BiRem |
713             BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr =>
714             false,
715         }
716     }
717     /// Returns `true` if the binary operator takes its arguments by value
718     pub fn is_by_value(&self) -> bool {
719         !BinOp_::is_comparison(self)
720     }
721 }
722
723 pub type BinOp = Spanned<BinOp_>;
724
725 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
726 pub enum UnOp {
727     /// The `*` operator for dereferencing
728     UnDeref,
729     /// The `!` operator for logical inversion
730     UnNot,
731     /// The `-` operator for negation
732     UnNeg
733 }
734
735 impl UnOp {
736     /// Returns `true` if the unary operator takes its argument by value
737     pub fn is_by_value(u: UnOp) -> bool {
738         match u {
739             UnNeg | UnNot => true,
740             _ => false,
741         }
742     }
743
744     pub fn to_string(op: UnOp) -> &'static str {
745         match op {
746             UnDeref => "*",
747             UnNot => "!",
748             UnNeg => "-",
749         }
750     }
751 }
752
753 /// A statement
754 pub type Stmt = Spanned<Stmt_>;
755
756 impl fmt::Debug for Stmt {
757     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
758         write!(f, "stmt({}: {})",
759                self.node.id()
760                    .map_or(Cow::Borrowed("<macro>"),|id|Cow::Owned(id.to_string())),
761                pprust::stmt_to_string(self))
762     }
763 }
764
765
766 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
767 pub enum Stmt_ {
768     /// Could be an item or a local (let) binding:
769     StmtDecl(P<Decl>, NodeId),
770
771     /// Expr without trailing semi-colon (must have unit type):
772     StmtExpr(P<Expr>, NodeId),
773
774     /// Expr with trailing semi-colon (may have any type):
775     StmtSemi(P<Expr>, NodeId),
776
777     StmtMac(P<Mac>, MacStmtStyle, ThinAttributes),
778 }
779
780 impl Stmt_ {
781     pub fn id(&self) -> Option<NodeId> {
782         match *self {
783             StmtDecl(_, id) => Some(id),
784             StmtExpr(_, id) => Some(id),
785             StmtSemi(_, id) => Some(id),
786             StmtMac(..) => None,
787         }
788     }
789
790     pub fn attrs(&self) -> &[Attribute] {
791         match *self {
792             StmtDecl(ref d, _) => d.attrs(),
793             StmtExpr(ref e, _) |
794             StmtSemi(ref e, _) => e.attrs(),
795             StmtMac(_, _, Some(ref b)) => b,
796             StmtMac(_, _, None) => &[],
797         }
798     }
799 }
800
801 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
802 pub enum MacStmtStyle {
803     /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
804     /// `foo!(...);`, `foo![...];`
805     MacStmtWithSemicolon,
806     /// The macro statement had braces; e.g. foo! { ... }
807     MacStmtWithBraces,
808     /// The macro statement had parentheses or brackets and no semicolon; e.g.
809     /// `foo!(...)`. All of these will end up being converted into macro
810     /// expressions.
811     MacStmtWithoutBraces,
812 }
813
814 // FIXME (pending discussion of #1697, #2178...): local should really be
815 // a refinement on pat.
816 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
817 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
818 pub struct Local {
819     pub pat: P<Pat>,
820     pub ty: Option<P<Ty>>,
821     /// Initializer expression to set the value, if any
822     pub init: Option<P<Expr>>,
823     pub id: NodeId,
824     pub span: Span,
825     pub attrs: ThinAttributes,
826 }
827
828 impl Local {
829     pub fn attrs(&self) -> &[Attribute] {
830         match self.attrs {
831             Some(ref b) => b,
832             None => &[],
833         }
834     }
835 }
836
837 pub type Decl = Spanned<Decl_>;
838
839 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
840 pub enum Decl_ {
841     /// A local (let) binding:
842     DeclLocal(P<Local>),
843     /// An item binding:
844     DeclItem(P<Item>),
845 }
846
847 impl Decl {
848     pub fn attrs(&self) -> &[Attribute] {
849         match self.node {
850             DeclLocal(ref l) => l.attrs(),
851             DeclItem(ref i) => i.attrs(),
852         }
853     }
854 }
855
856 /// represents one arm of a 'match'
857 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
858 pub struct Arm {
859     pub attrs: Vec<Attribute>,
860     pub pats: Vec<P<Pat>>,
861     pub guard: Option<P<Expr>>,
862     pub body: P<Expr>,
863 }
864
865 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
866 pub struct Field {
867     pub ident: SpannedIdent,
868     pub expr: P<Expr>,
869     pub span: Span,
870 }
871
872 pub type SpannedIdent = Spanned<Ident>;
873
874 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
875 pub enum BlockCheckMode {
876     DefaultBlock,
877     UnsafeBlock(UnsafeSource),
878 }
879
880 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
881 pub enum UnsafeSource {
882     CompilerGenerated,
883     UserProvided,
884 }
885
886 /// An expression
887 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash,)]
888 pub struct Expr {
889     pub id: NodeId,
890     pub node: Expr_,
891     pub span: Span,
892     pub attrs: ThinAttributes
893 }
894
895 impl Expr {
896     pub fn attrs(&self) -> &[Attribute] {
897         match self.attrs {
898             Some(ref b) => b,
899             None => &[],
900         }
901     }
902 }
903
904 impl fmt::Debug for Expr {
905     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
906         write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self))
907     }
908 }
909
910 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
911 pub enum Expr_ {
912     /// A `box x` expression.
913     ExprBox(P<Expr>),
914     /// First expr is the place; second expr is the value.
915     ExprInPlace(P<Expr>, P<Expr>),
916     /// An array (`[a, b, c, d]`)
917     ExprVec(Vec<P<Expr>>),
918     /// A function call
919     ///
920     /// The first field resolves to the function itself,
921     /// and the second field is the list of arguments
922     ExprCall(P<Expr>, Vec<P<Expr>>),
923     /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
924     ///
925     /// The `SpannedIdent` is the identifier for the method name.
926     /// The vector of `Ty`s are the ascripted type parameters for the method
927     /// (within the angle brackets).
928     ///
929     /// The first element of the vector of `Expr`s is the expression that evaluates
930     /// to the object on which the method is being called on (the receiver),
931     /// and the remaining elements are the rest of the arguments.
932     ///
933     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
934     /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
935     ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<P<Expr>>),
936     /// A tuple (`(a, b, c ,d)`)
937     ExprTup(Vec<P<Expr>>),
938     /// A binary operation (For example: `a + b`, `a * b`)
939     ExprBinary(BinOp, P<Expr>, P<Expr>),
940     /// A unary operation (For example: `!x`, `*x`)
941     ExprUnary(UnOp, P<Expr>),
942     /// A literal (For example: `1u8`, `"foo"`)
943     ExprLit(P<Lit>),
944     /// A cast (`foo as f64`)
945     ExprCast(P<Expr>, P<Ty>),
946     /// An `if` block, with an optional else block
947     ///
948     /// `if expr { block } else { expr }`
949     ExprIf(P<Expr>, P<Block>, Option<P<Expr>>),
950     /// An `if let` expression with an optional else block
951     ///
952     /// `if let pat = expr { block } else { expr }`
953     ///
954     /// This is desugared to a `match` expression.
955     ExprIfLet(P<Pat>, P<Expr>, P<Block>, Option<P<Expr>>),
956     /// A while loop, with an optional label
957     ///
958     /// `'label: while expr { block }`
959     ExprWhile(P<Expr>, P<Block>, Option<Ident>),
960     /// A while-let loop, with an optional label
961     ///
962     /// `'label: while let pat = expr { block }`
963     ///
964     /// This is desugared to a combination of `loop` and `match` expressions.
965     ExprWhileLet(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
966     /// A for loop, with an optional label
967     ///
968     /// `'label: for pat in expr { block }`
969     ///
970     /// This is desugared to a combination of `loop` and `match` expressions.
971     ExprForLoop(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
972     /// Conditionless loop (can be exited with break, continue, or return)
973     ///
974     /// `'label: loop { block }`
975     ExprLoop(P<Block>, Option<Ident>),
976     /// A `match` block.
977     ExprMatch(P<Expr>, Vec<Arm>),
978     /// A closure (for example, `move |a, b, c| {a + b + c}`)
979     ExprClosure(CaptureClause, P<FnDecl>, P<Block>),
980     /// A block (`{ ... }`)
981     ExprBlock(P<Block>),
982
983     /// An assignment (`a = foo()`)
984     ExprAssign(P<Expr>, P<Expr>),
985     /// An assignment with an operator
986     ///
987     /// For example, `a += 1`.
988     ExprAssignOp(BinOp, P<Expr>, P<Expr>),
989     /// Access of a named struct field (`obj.foo`)
990     ExprField(P<Expr>, SpannedIdent),
991     /// Access of an unnamed field of a struct or tuple-struct
992     ///
993     /// For example, `foo.0`.
994     ExprTupField(P<Expr>, Spanned<usize>),
995     /// An indexing operation (`foo[2]`)
996     ExprIndex(P<Expr>, P<Expr>),
997     /// A range (`1..2`, `1..`, or `..2`)
998     ExprRange(Option<P<Expr>>, Option<P<Expr>>),
999
1000     /// Variable reference, possibly containing `::` and/or type
1001     /// parameters, e.g. foo::bar::<baz>.
1002     ///
1003     /// Optionally "qualified",
1004     /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
1005     ExprPath(Option<QSelf>, Path),
1006
1007     /// A referencing operation (`&a` or `&mut a`)
1008     ExprAddrOf(Mutability, P<Expr>),
1009     /// A `break`, with an optional label to break
1010     ExprBreak(Option<SpannedIdent>),
1011     /// A `continue`, with an optional label
1012     ExprAgain(Option<SpannedIdent>),
1013     /// A `return`, with an optional value to be returned
1014     ExprRet(Option<P<Expr>>),
1015
1016     /// Output of the `asm!()` macro
1017     ExprInlineAsm(InlineAsm),
1018
1019     /// A macro invocation; pre-expansion
1020     ExprMac(Mac),
1021
1022     /// A struct literal expression.
1023     ///
1024     /// For example, `Foo {x: 1, y: 2}`, or
1025     /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
1026     ExprStruct(Path, Vec<Field>, Option<P<Expr>>),
1027
1028     /// An array literal constructed from one repeated element.
1029     ///
1030     /// For example, `[1u8; 5]`. The first expression is the element
1031     /// to be repeated; the second is the number of times to repeat it.
1032     ExprRepeat(P<Expr>, P<Expr>),
1033
1034     /// No-op: used solely so we can pretty-print faithfully
1035     ExprParen(P<Expr>)
1036 }
1037
1038 /// The explicit Self type in a "qualified path". The actual
1039 /// path, including the trait and the associated item, is stored
1040 /// separately. `position` represents the index of the associated
1041 /// item qualified with this Self type.
1042 ///
1043 /// ```ignore
1044 /// <Vec<T> as a::b::Trait>::AssociatedItem
1045 ///  ^~~~~     ~~~~~~~~~~~~~~^
1046 ///  ty        position = 3
1047 ///
1048 /// <Vec<T>>::AssociatedItem
1049 ///  ^~~~~    ^
1050 ///  ty       position = 0
1051 /// ```
1052 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1053 pub struct QSelf {
1054     pub ty: P<Ty>,
1055     pub position: usize
1056 }
1057
1058 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1059 pub enum CaptureClause {
1060     CaptureByValue,
1061     CaptureByRef,
1062 }
1063
1064 /// A delimited sequence of token trees
1065 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1066 pub struct Delimited {
1067     /// The type of delimiter
1068     pub delim: token::DelimToken,
1069     /// The span covering the opening delimiter
1070     pub open_span: Span,
1071     /// The delimited sequence of token trees
1072     pub tts: Vec<TokenTree>,
1073     /// The span covering the closing delimiter
1074     pub close_span: Span,
1075 }
1076
1077 impl Delimited {
1078     /// Returns the opening delimiter as a token.
1079     pub fn open_token(&self) -> token::Token {
1080         token::OpenDelim(self.delim)
1081     }
1082
1083     /// Returns the closing delimiter as a token.
1084     pub fn close_token(&self) -> token::Token {
1085         token::CloseDelim(self.delim)
1086     }
1087
1088     /// Returns the opening delimiter as a token tree.
1089     pub fn open_tt(&self) -> TokenTree {
1090         TokenTree::Token(self.open_span, self.open_token())
1091     }
1092
1093     /// Returns the closing delimiter as a token tree.
1094     pub fn close_tt(&self) -> TokenTree {
1095         TokenTree::Token(self.close_span, self.close_token())
1096     }
1097 }
1098
1099 /// A sequence of token treesee
1100 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1101 pub struct SequenceRepetition {
1102     /// The sequence of token trees
1103     pub tts: Vec<TokenTree>,
1104     /// The optional separator
1105     pub separator: Option<token::Token>,
1106     /// Whether the sequence can be repeated zero (*), or one or more times (+)
1107     pub op: KleeneOp,
1108     /// The number of `MatchNt`s that appear in the sequence (and subsequences)
1109     pub num_captures: usize,
1110 }
1111
1112 /// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
1113 /// for token sequences.
1114 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1115 pub enum KleeneOp {
1116     ZeroOrMore,
1117     OneOrMore,
1118 }
1119
1120 /// When the main rust parser encounters a syntax-extension invocation, it
1121 /// parses the arguments to the invocation as a token-tree. This is a very
1122 /// loose structure, such that all sorts of different AST-fragments can
1123 /// be passed to syntax extensions using a uniform type.
1124 ///
1125 /// If the syntax extension is an MBE macro, it will attempt to match its
1126 /// LHS token tree against the provided token tree, and if it finds a
1127 /// match, will transcribe the RHS token tree, splicing in any captured
1128 /// macro_parser::matched_nonterminals into the `SubstNt`s it finds.
1129 ///
1130 /// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
1131 /// Nothing special happens to misnamed or misplaced `SubstNt`s.
1132 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1133 pub enum TokenTree {
1134     /// A single token
1135     Token(Span, token::Token),
1136     /// A delimited sequence of token trees
1137     Delimited(Span, Rc<Delimited>),
1138
1139     // This only makes sense in MBE macros.
1140
1141     /// A kleene-style repetition sequence with a span
1142     // FIXME(eddyb) #12938 Use DST.
1143     Sequence(Span, Rc<SequenceRepetition>),
1144 }
1145
1146 impl TokenTree {
1147     pub fn len(&self) -> usize {
1148         match *self {
1149             TokenTree::Token(_, token::DocComment(name)) => {
1150                 match doc_comment_style(&name.as_str()) {
1151                     AttrStyle::Outer => 2,
1152                     AttrStyle::Inner => 3
1153                 }
1154             }
1155             TokenTree::Token(_, token::SpecialVarNt(..)) => 2,
1156             TokenTree::Token(_, token::MatchNt(..)) => 3,
1157             TokenTree::Delimited(_, ref delimed) => {
1158                 delimed.tts.len() + 2
1159             }
1160             TokenTree::Sequence(_, ref seq) => {
1161                 seq.tts.len()
1162             }
1163             TokenTree::Token(..) => 0
1164         }
1165     }
1166
1167     pub fn get_tt(&self, index: usize) -> TokenTree {
1168         match (self, index) {
1169             (&TokenTree::Token(sp, token::DocComment(_)), 0) => {
1170                 TokenTree::Token(sp, token::Pound)
1171             }
1172             (&TokenTree::Token(sp, token::DocComment(name)), 1)
1173             if doc_comment_style(&name.as_str()) == AttrStyle::Inner => {
1174                 TokenTree::Token(sp, token::Not)
1175             }
1176             (&TokenTree::Token(sp, token::DocComment(name)), _) => {
1177                 let stripped = strip_doc_comment_decoration(&name.as_str());
1178                 TokenTree::Delimited(sp, Rc::new(Delimited {
1179                     delim: token::Bracket,
1180                     open_span: sp,
1181                     tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc"),
1182                                                                 token::Plain)),
1183                               TokenTree::Token(sp, token::Eq),
1184                               TokenTree::Token(sp, token::Literal(
1185                                   token::StrRaw(token::intern(&stripped), 0), None))],
1186                     close_span: sp,
1187                 }))
1188             }
1189             (&TokenTree::Delimited(_, ref delimed), _) => {
1190                 if index == 0 {
1191                     return delimed.open_tt();
1192                 }
1193                 if index == delimed.tts.len() + 1 {
1194                     return delimed.close_tt();
1195                 }
1196                 delimed.tts[index - 1].clone()
1197             }
1198             (&TokenTree::Token(sp, token::SpecialVarNt(var)), _) => {
1199                 let v = [TokenTree::Token(sp, token::Dollar),
1200                          TokenTree::Token(sp, token::Ident(token::str_to_ident(var.as_str()),
1201                                                   token::Plain))];
1202                 v[index].clone()
1203             }
1204             (&TokenTree::Token(sp, token::MatchNt(name, kind, name_st, kind_st)), _) => {
1205                 let v = [TokenTree::Token(sp, token::SubstNt(name, name_st)),
1206                          TokenTree::Token(sp, token::Colon),
1207                          TokenTree::Token(sp, token::Ident(kind, kind_st))];
1208                 v[index].clone()
1209             }
1210             (&TokenTree::Sequence(_, ref seq), _) => {
1211                 seq.tts[index].clone()
1212             }
1213             _ => panic!("Cannot expand a token tree")
1214         }
1215     }
1216
1217     /// Returns the `Span` corresponding to this token tree.
1218     pub fn get_span(&self) -> Span {
1219         match *self {
1220             TokenTree::Token(span, _)     => span,
1221             TokenTree::Delimited(span, _) => span,
1222             TokenTree::Sequence(span, _)  => span,
1223         }
1224     }
1225
1226     /// Use this token tree as a matcher to parse given tts.
1227     pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree])
1228                  -> macro_parser::NamedParseResult {
1229         // `None` is because we're not interpolating
1230         let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
1231                                                          None,
1232                                                          None,
1233                                                          tts.iter().cloned().collect(),
1234                                                          true);
1235         macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch)
1236     }
1237 }
1238
1239 pub type Mac = Spanned<Mac_>;
1240
1241 /// Represents a macro invocation. The Path indicates which macro
1242 /// is being invoked, and the vector of token-trees contains the source
1243 /// of the macro invocation.
1244 ///
1245 /// NB: the additional ident for a macro_rules-style macro is actually
1246 /// stored in the enclosing item. Oog.
1247 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1248 pub struct Mac_ {
1249     pub path: Path,
1250     pub tts: Vec<TokenTree>,
1251     pub ctxt: SyntaxContext,
1252 }
1253
1254 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1255 pub enum StrStyle {
1256     /// A regular string, like `"foo"`
1257     CookedStr,
1258     /// A raw string, like `r##"foo"##`
1259     ///
1260     /// The uint is the number of `#` symbols used
1261     RawStr(usize)
1262 }
1263
1264 /// A literal
1265 pub type Lit = Spanned<Lit_>;
1266
1267 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1268 pub enum Sign {
1269     Minus,
1270     Plus
1271 }
1272
1273 impl Sign {
1274     pub fn new<T: IntSign>(n: T) -> Sign {
1275         n.sign()
1276     }
1277 }
1278
1279 pub trait IntSign {
1280     fn sign(&self) -> Sign;
1281 }
1282 macro_rules! doit {
1283     ($($t:ident)*) => ($(impl IntSign for $t {
1284         #[allow(unused_comparisons)]
1285         fn sign(&self) -> Sign {
1286             if *self < 0 {Minus} else {Plus}
1287         }
1288     })*)
1289 }
1290 doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
1291
1292 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1293 pub enum LitIntType {
1294     SignedIntLit(IntTy, Sign),
1295     UnsignedIntLit(UintTy),
1296     UnsuffixedIntLit(Sign)
1297 }
1298
1299 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1300 pub enum Lit_ {
1301     /// A string literal (`"foo"`)
1302     LitStr(InternedString, StrStyle),
1303     /// A byte string (`b"foo"`)
1304     LitByteStr(Rc<Vec<u8>>),
1305     /// A byte char (`b'f'`)
1306     LitByte(u8),
1307     /// A character literal (`'a'`)
1308     LitChar(char),
1309     /// An integer literal (`1u8`)
1310     LitInt(u64, LitIntType),
1311     /// A float literal (`1f64` or `1E10f64`)
1312     LitFloat(InternedString, FloatTy),
1313     /// A float literal without a suffix (`1.0 or 1.0E10`)
1314     LitFloatUnsuffixed(InternedString),
1315     /// A boolean literal
1316     LitBool(bool),
1317 }
1318
1319 impl Lit_ {
1320     /// Returns true if this literal is a string and false otherwise.
1321     pub fn is_str(&self) -> bool {
1322         match *self {
1323             LitStr(..) => true,
1324             _ => false,
1325         }
1326     }
1327 }
1328
1329 // NB: If you change this, you'll probably want to change the corresponding
1330 // type structure in middle/ty.rs as well.
1331 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1332 pub struct MutTy {
1333     pub ty: P<Ty>,
1334     pub mutbl: Mutability,
1335 }
1336
1337 /// Represents a method's signature in a trait declaration,
1338 /// or in an implementation.
1339 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1340 pub struct MethodSig {
1341     pub unsafety: Unsafety,
1342     pub constness: Constness,
1343     pub abi: Abi,
1344     pub decl: P<FnDecl>,
1345     pub generics: Generics,
1346     pub explicit_self: ExplicitSelf,
1347 }
1348
1349 /// Represents a method declaration in a trait declaration, possibly including
1350 /// a default implementation A trait method is either required (meaning it
1351 /// doesn't have an implementation, just a signature) or provided (meaning it
1352 /// has a default implementation).
1353 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1354 pub struct TraitItem {
1355     pub id: NodeId,
1356     pub ident: Ident,
1357     pub attrs: Vec<Attribute>,
1358     pub node: TraitItem_,
1359     pub span: Span,
1360 }
1361
1362 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1363 pub enum TraitItem_ {
1364     ConstTraitItem(P<Ty>, Option<P<Expr>>),
1365     MethodTraitItem(MethodSig, Option<P<Block>>),
1366     TypeTraitItem(TyParamBounds, Option<P<Ty>>),
1367 }
1368
1369 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1370 pub struct ImplItem {
1371     pub id: NodeId,
1372     pub ident: Ident,
1373     pub vis: Visibility,
1374     pub attrs: Vec<Attribute>,
1375     pub node: ImplItemKind,
1376     pub span: Span,
1377 }
1378
1379 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1380 pub enum ImplItemKind {
1381     Const(P<Ty>, P<Expr>),
1382     Method(MethodSig, P<Block>),
1383     Type(P<Ty>),
1384     Macro(Mac),
1385 }
1386
1387 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1388 pub enum IntTy {
1389     TyIs,
1390     TyI8,
1391     TyI16,
1392     TyI32,
1393     TyI64,
1394 }
1395
1396 impl fmt::Debug for IntTy {
1397     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1398         fmt::Display::fmt(self, f)
1399     }
1400 }
1401
1402 impl fmt::Display for IntTy {
1403     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1404         write!(f, "{}", self.ty_to_string())
1405     }
1406 }
1407
1408 impl IntTy {
1409     pub fn ty_to_string(&self) -> &'static str {
1410         match *self {
1411             TyIs => "isize",
1412             TyI8 => "i8",
1413             TyI16 => "i16",
1414             TyI32 => "i32",
1415             TyI64 => "i64"
1416         }
1417     }
1418
1419     pub fn val_to_string(&self, val: i64) -> String {
1420         // cast to a u64 so we can correctly print INT64_MIN. All integral types
1421         // are parsed as u64, so we wouldn't want to print an extra negative
1422         // sign.
1423         format!("{}{}", val as u64, self.ty_to_string())
1424     }
1425
1426     pub fn ty_max(&self) -> u64 {
1427         match *self {
1428             TyI8 => 0x80,
1429             TyI16 => 0x8000,
1430             TyIs | TyI32 => 0x80000000, // actually ni about TyIs
1431             TyI64 => 0x8000000000000000
1432         }
1433     }
1434
1435     pub fn bit_width(&self) -> Option<usize> {
1436         Some(match *self {
1437             TyIs => return None,
1438             TyI8 => 8,
1439             TyI16 => 16,
1440             TyI32 => 32,
1441             TyI64 => 64,
1442         })
1443     }
1444 }
1445
1446 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1447 pub enum UintTy {
1448     TyUs,
1449     TyU8,
1450     TyU16,
1451     TyU32,
1452     TyU64,
1453 }
1454
1455 impl UintTy {
1456     pub fn ty_to_string(&self) -> &'static str {
1457         match *self {
1458             TyUs => "usize",
1459             TyU8 => "u8",
1460             TyU16 => "u16",
1461             TyU32 => "u32",
1462             TyU64 => "u64"
1463         }
1464     }
1465
1466     pub fn val_to_string(&self, val: u64) -> String {
1467         format!("{}{}", val, self.ty_to_string())
1468     }
1469
1470     pub fn ty_max(&self) -> u64 {
1471         match *self {
1472             TyU8 => 0xff,
1473             TyU16 => 0xffff,
1474             TyUs | TyU32 => 0xffffffff, // actually ni about TyUs
1475             TyU64 => 0xffffffffffffffff
1476         }
1477     }
1478
1479     pub fn bit_width(&self) -> Option<usize> {
1480         Some(match *self {
1481             TyUs => return None,
1482             TyU8 => 8,
1483             TyU16 => 16,
1484             TyU32 => 32,
1485             TyU64 => 64,
1486         })
1487     }
1488 }
1489
1490 impl fmt::Debug for UintTy {
1491     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1492         fmt::Display::fmt(self, f)
1493     }
1494 }
1495
1496 impl fmt::Display for UintTy {
1497     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1498         write!(f, "{}", self.ty_to_string())
1499     }
1500 }
1501
1502 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1503 pub enum FloatTy {
1504     TyF32,
1505     TyF64,
1506 }
1507
1508 impl fmt::Debug for FloatTy {
1509     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1510         fmt::Display::fmt(self, f)
1511     }
1512 }
1513
1514 impl fmt::Display for FloatTy {
1515     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1516         write!(f, "{}", self.ty_to_string())
1517     }
1518 }
1519
1520 impl FloatTy {
1521     pub fn ty_to_string(&self) -> &'static str {
1522         match *self {
1523             TyF32 => "f32",
1524             TyF64 => "f64",
1525         }
1526     }
1527
1528     pub fn bit_width(&self) -> usize {
1529         match *self {
1530             TyF32 => 32,
1531             TyF64 => 64,
1532         }
1533     }
1534 }
1535
1536 // Bind a type to an associated type: `A=Foo`.
1537 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1538 pub struct TypeBinding {
1539     pub id: NodeId,
1540     pub ident: Ident,
1541     pub ty: P<Ty>,
1542     pub span: Span,
1543 }
1544
1545 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1546 pub struct Ty {
1547     pub id: NodeId,
1548     pub node: Ty_,
1549     pub span: Span,
1550 }
1551
1552 impl fmt::Debug for Ty {
1553     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1554         write!(f, "type({})", pprust::ty_to_string(self))
1555     }
1556 }
1557
1558 /// Not represented directly in the AST, referred to by name through a ty_path.
1559 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1560 pub enum PrimTy {
1561     TyInt(IntTy),
1562     TyUint(UintTy),
1563     TyFloat(FloatTy),
1564     TyStr,
1565     TyBool,
1566     TyChar
1567 }
1568
1569 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1570 pub struct BareFnTy {
1571     pub unsafety: Unsafety,
1572     pub abi: Abi,
1573     pub lifetimes: Vec<LifetimeDef>,
1574     pub decl: P<FnDecl>
1575 }
1576
1577 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1578 /// The different kinds of types recognized by the compiler
1579 pub enum Ty_ {
1580     TyVec(P<Ty>),
1581     /// A fixed length array (`[T; n]`)
1582     TyFixedLengthVec(P<Ty>, P<Expr>),
1583     /// A raw pointer (`*const T` or `*mut T`)
1584     TyPtr(MutTy),
1585     /// A reference (`&'a T` or `&'a mut T`)
1586     TyRptr(Option<Lifetime>, MutTy),
1587     /// A bare function (e.g. `fn(usize) -> bool`)
1588     TyBareFn(P<BareFnTy>),
1589     /// A tuple (`(A, B, C, D,...)`)
1590     TyTup(Vec<P<Ty>> ),
1591     /// A path (`module::module::...::Type`), optionally
1592     /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
1593     ///
1594     /// Type parameters are stored in the Path itself
1595     TyPath(Option<QSelf>, Path),
1596     /// Something like `A+B`. Note that `B` must always be a path.
1597     TyObjectSum(P<Ty>, TyParamBounds),
1598     /// A type like `for<'a> Foo<&'a Bar>`
1599     TyPolyTraitRef(TyParamBounds),
1600     /// No-op; kept solely so that we can pretty-print faithfully
1601     TyParen(P<Ty>),
1602     /// Unused for now
1603     TyTypeof(P<Expr>),
1604     /// TyInfer means the type should be inferred instead of it having been
1605     /// specified. This can appear anywhere in a type.
1606     TyInfer,
1607     // A macro in the type position.
1608     TyMac(Mac)
1609 }
1610
1611 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1612 pub enum AsmDialect {
1613     Att,
1614     Intel,
1615 }
1616
1617 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1618 pub struct InlineAsmOutput {
1619     pub constraint: InternedString,
1620     pub expr: P<Expr>,
1621     pub is_rw: bool,
1622     pub is_indirect: bool,
1623 }
1624
1625 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1626 pub struct InlineAsm {
1627     pub asm: InternedString,
1628     pub asm_str_style: StrStyle,
1629     pub outputs: Vec<InlineAsmOutput>,
1630     pub inputs: Vec<(InternedString, P<Expr>)>,
1631     pub clobbers: Vec<InternedString>,
1632     pub volatile: bool,
1633     pub alignstack: bool,
1634     pub dialect: AsmDialect,
1635     pub expn_id: ExpnId,
1636 }
1637
1638 /// represents an argument in a function header
1639 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1640 pub struct Arg {
1641     pub ty: P<Ty>,
1642     pub pat: P<Pat>,
1643     pub id: NodeId,
1644 }
1645
1646 impl Arg {
1647     pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
1648         let path = Spanned{span:span,node:self_ident};
1649         Arg {
1650             // HACK(eddyb) fake type for the self argument.
1651             ty: P(Ty {
1652                 id: DUMMY_NODE_ID,
1653                 node: TyInfer,
1654                 span: DUMMY_SP,
1655             }),
1656             pat: P(Pat {
1657                 id: DUMMY_NODE_ID,
1658                 node: PatIdent(BindByValue(mutability), path, None),
1659                 span: span
1660             }),
1661             id: DUMMY_NODE_ID
1662         }
1663     }
1664 }
1665
1666 /// Represents the header (not the body) of a function declaration
1667 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1668 pub struct FnDecl {
1669     pub inputs: Vec<Arg>,
1670     pub output: FunctionRetTy,
1671     pub variadic: bool
1672 }
1673
1674 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1675 pub enum Unsafety {
1676     Unsafe,
1677     Normal,
1678 }
1679
1680 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1681 pub enum Constness {
1682     Const,
1683     NotConst,
1684 }
1685
1686 impl fmt::Display for Unsafety {
1687     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1688         fmt::Display::fmt(match *self {
1689             Unsafety::Normal => "normal",
1690             Unsafety::Unsafe => "unsafe",
1691         }, f)
1692     }
1693 }
1694
1695 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1696 pub enum ImplPolarity {
1697     /// `impl Trait for Type`
1698     Positive,
1699     /// `impl !Trait for Type`
1700     Negative,
1701 }
1702
1703 impl fmt::Debug for ImplPolarity {
1704     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1705         match *self {
1706             ImplPolarity::Positive => "positive".fmt(f),
1707             ImplPolarity::Negative => "negative".fmt(f),
1708         }
1709     }
1710 }
1711
1712
1713 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1714 pub enum FunctionRetTy {
1715     /// Functions with return type `!`that always
1716     /// raise an error or exit (i.e. never return to the caller)
1717     NoReturn(Span),
1718     /// Return type is not specified.
1719     ///
1720     /// Functions default to `()` and
1721     /// closures default to inference. Span points to where return
1722     /// type would be inserted.
1723     DefaultReturn(Span),
1724     /// Everything else
1725     Return(P<Ty>),
1726 }
1727
1728 impl FunctionRetTy {
1729     pub fn span(&self) -> Span {
1730         match *self {
1731             NoReturn(span) => span,
1732             DefaultReturn(span) => span,
1733             Return(ref ty) => ty.span
1734         }
1735     }
1736 }
1737
1738 /// Represents the kind of 'self' associated with a method
1739 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1740 pub enum ExplicitSelf_ {
1741     /// No self
1742     SelfStatic,
1743     /// `self`
1744     SelfValue(Ident),
1745     /// `&'lt self`, `&'lt mut self`
1746     SelfRegion(Option<Lifetime>, Mutability, Ident),
1747     /// `self: TYPE`
1748     SelfExplicit(P<Ty>, Ident),
1749 }
1750
1751 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
1752
1753 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1754 pub struct Mod {
1755     /// A span from the first token past `{` to the last token until `}`.
1756     /// For `mod foo;`, the inner span ranges from the first token
1757     /// to the last token in the external file.
1758     pub inner: Span,
1759     pub items: Vec<P<Item>>,
1760 }
1761
1762 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1763 pub struct ForeignMod {
1764     pub abi: Abi,
1765     pub items: Vec<P<ForeignItem>>,
1766 }
1767
1768 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1769 pub struct EnumDef {
1770     pub variants: Vec<P<Variant>>,
1771 }
1772
1773 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1774 pub struct Variant_ {
1775     pub name: Ident,
1776     pub attrs: Vec<Attribute>,
1777     pub data: VariantData,
1778     /// Explicit discriminant, eg `Foo = 1`
1779     pub disr_expr: Option<P<Expr>>,
1780 }
1781
1782 pub type Variant = Spanned<Variant_>;
1783
1784 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1785 pub enum PathListItem_ {
1786     PathListIdent {
1787         name: Ident,
1788         /// renamed in list, eg `use foo::{bar as baz};`
1789         rename: Option<Ident>,
1790         id: NodeId
1791     },
1792     PathListMod {
1793         /// renamed in list, eg `use foo::{self as baz};`
1794         rename: Option<Ident>,
1795         id: NodeId
1796     }
1797 }
1798
1799 impl PathListItem_ {
1800     pub fn id(&self) -> NodeId {
1801         match *self {
1802             PathListIdent { id, .. } | PathListMod { id, .. } => id
1803         }
1804     }
1805
1806     pub fn name(&self) -> Option<Ident> {
1807         match *self {
1808             PathListIdent { name, .. } => Some(name),
1809             PathListMod { .. } => None,
1810         }
1811     }
1812
1813     pub fn rename(&self) -> Option<Ident> {
1814         match *self {
1815             PathListIdent { rename, .. } | PathListMod { rename, .. } => rename
1816         }
1817     }
1818 }
1819
1820 pub type PathListItem = Spanned<PathListItem_>;
1821
1822 pub type ViewPath = Spanned<ViewPath_>;
1823
1824 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1825 pub enum ViewPath_ {
1826
1827     /// `foo::bar::baz as quux`
1828     ///
1829     /// or just
1830     ///
1831     /// `foo::bar::baz` (with `as baz` implicitly on the right)
1832     ViewPathSimple(Ident, Path),
1833
1834     /// `foo::bar::*`
1835     ViewPathGlob(Path),
1836
1837     /// `foo::bar::{a,b,c}`
1838     ViewPathList(Path, Vec<PathListItem>)
1839 }
1840
1841 /// Meta-data associated with an item
1842 pub type Attribute = Spanned<Attribute_>;
1843
1844 /// Distinguishes between Attributes that decorate items and Attributes that
1845 /// are contained as statements within items. These two cases need to be
1846 /// distinguished for pretty-printing.
1847 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1848 pub enum AttrStyle {
1849     Outer,
1850     Inner,
1851 }
1852
1853 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1854 pub struct AttrId(pub usize);
1855
1856 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
1857 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1858 pub struct Attribute_ {
1859     pub id: AttrId,
1860     pub style: AttrStyle,
1861     pub value: P<MetaItem>,
1862     pub is_sugared_doc: bool,
1863 }
1864
1865 /// TraitRef's appear in impls.
1866 ///
1867 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1868 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1869 /// If this impl is an ItemImpl, the impl_id is redundant (it could be the
1870 /// same as the impl's node id).
1871 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1872 pub struct TraitRef {
1873     pub path: Path,
1874     pub ref_id: NodeId,
1875 }
1876
1877 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1878 pub struct PolyTraitRef {
1879     /// The `'a` in `<'a> Foo<&'a T>`
1880     pub bound_lifetimes: Vec<LifetimeDef>,
1881
1882     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1883     pub trait_ref: TraitRef,
1884
1885     pub span: Span,
1886 }
1887
1888 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1889 pub enum Visibility {
1890     Public,
1891     Inherited,
1892 }
1893
1894 impl Visibility {
1895     pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1896         match *self {
1897             Inherited => parent_visibility,
1898             Public => *self
1899         }
1900     }
1901 }
1902
1903 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1904 pub struct StructField_ {
1905     pub kind: StructFieldKind,
1906     pub id: NodeId,
1907     pub ty: P<Ty>,
1908     pub attrs: Vec<Attribute>,
1909 }
1910
1911 impl StructField_ {
1912     pub fn ident(&self) -> Option<Ident> {
1913         match self.kind {
1914             NamedField(ref ident, _) => Some(ident.clone()),
1915             UnnamedField(_) => None
1916         }
1917     }
1918 }
1919
1920 pub type StructField = Spanned<StructField_>;
1921
1922 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1923 pub enum StructFieldKind {
1924     NamedField(Ident, Visibility),
1925     /// Element of a tuple-like struct
1926     UnnamedField(Visibility),
1927 }
1928
1929 impl StructFieldKind {
1930     pub fn is_unnamed(&self) -> bool {
1931         match *self {
1932             UnnamedField(..) => true,
1933             NamedField(..) => false,
1934         }
1935     }
1936
1937     pub fn visibility(&self) -> Visibility {
1938         match *self {
1939             NamedField(_, vis) | UnnamedField(vis) => vis
1940         }
1941     }
1942 }
1943
1944 /// Fields and Ids of enum variants and structs
1945 ///
1946 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1947 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1948 /// One shared Id can be successfully used for these two purposes.
1949 /// Id of the whole enum lives in `Item`.
1950 ///
1951 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
1952 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
1953 /// the variant itself" from enum variants.
1954 /// Id of the whole struct lives in `Item`.
1955 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1956 pub enum VariantData {
1957     Struct(Vec<StructField>, NodeId),
1958     Tuple(Vec<StructField>, NodeId),
1959     Unit(NodeId),
1960 }
1961
1962 impl VariantData {
1963     pub fn fields(&self) -> &[StructField] {
1964         match *self {
1965             VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
1966             _ => &[],
1967         }
1968     }
1969     pub fn id(&self) -> NodeId {
1970         match *self {
1971             VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id
1972         }
1973     }
1974     pub fn is_struct(&self) -> bool {
1975         if let VariantData::Struct(..) = *self { true } else { false }
1976     }
1977     pub fn is_tuple(&self) -> bool {
1978         if let VariantData::Tuple(..) = *self { true } else { false }
1979     }
1980     pub fn is_unit(&self) -> bool {
1981         if let VariantData::Unit(..) = *self { true } else { false }
1982     }
1983 }
1984
1985 /*
1986   FIXME (#3300): Should allow items to be anonymous. Right now
1987   we just use dummy names for anon items.
1988  */
1989 /// An item
1990 ///
1991 /// The name might be a dummy name in case of anonymous items
1992 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1993 pub struct Item {
1994     pub ident: Ident,
1995     pub attrs: Vec<Attribute>,
1996     pub id: NodeId,
1997     pub node: Item_,
1998     pub vis: Visibility,
1999     pub span: Span,
2000 }
2001
2002 impl Item {
2003     pub fn attrs(&self) -> &[Attribute] {
2004         &self.attrs
2005     }
2006 }
2007
2008 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2009 pub enum Item_ {
2010     /// An`extern crate` item, with optional original crate name,
2011     ///
2012     /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
2013     ItemExternCrate(Option<Name>),
2014     /// A `use` or `pub use` item
2015     ItemUse(P<ViewPath>),
2016
2017     /// A `static` item
2018     ItemStatic(P<Ty>, Mutability, P<Expr>),
2019     /// A `const` item
2020     ItemConst(P<Ty>, P<Expr>),
2021     /// A function declaration
2022     ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
2023     /// A module
2024     ItemMod(Mod),
2025     /// An external module
2026     ItemForeignMod(ForeignMod),
2027     /// A type alias, e.g. `type Foo = Bar<u8>`
2028     ItemTy(P<Ty>, Generics),
2029     /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
2030     ItemEnum(EnumDef, Generics),
2031     /// A struct definition, e.g. `struct Foo<A> {x: A}`
2032     ItemStruct(VariantData, Generics),
2033     /// Represents a Trait Declaration
2034     ItemTrait(Unsafety,
2035               Generics,
2036               TyParamBounds,
2037               Vec<P<TraitItem>>),
2038
2039     // Default trait implementations
2040     ///
2041     // `impl Trait for .. {}`
2042     ItemDefaultImpl(Unsafety, TraitRef),
2043     /// An implementation, eg `impl<A> Trait for Foo { .. }`
2044     ItemImpl(Unsafety,
2045              ImplPolarity,
2046              Generics,
2047              Option<TraitRef>, // (optional) trait this impl implements
2048              P<Ty>, // self
2049              Vec<P<ImplItem>>),
2050     /// A macro invocation (which includes macro definition)
2051     ItemMac(Mac),
2052 }
2053
2054 impl Item_ {
2055     pub fn descriptive_variant(&self) -> &str {
2056         match *self {
2057             ItemExternCrate(..) => "extern crate",
2058             ItemUse(..) => "use",
2059             ItemStatic(..) => "static item",
2060             ItemConst(..) => "constant item",
2061             ItemFn(..) => "function",
2062             ItemMod(..) => "module",
2063             ItemForeignMod(..) => "foreign module",
2064             ItemTy(..) => "type alias",
2065             ItemEnum(..) => "enum",
2066             ItemStruct(..) => "struct",
2067             ItemTrait(..) => "trait",
2068             ItemMac(..) |
2069             ItemImpl(..) |
2070             ItemDefaultImpl(..) => "item"
2071         }
2072     }
2073 }
2074
2075 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2076 pub struct ForeignItem {
2077     pub ident: Ident,
2078     pub attrs: Vec<Attribute>,
2079     pub node: ForeignItem_,
2080     pub id: NodeId,
2081     pub span: Span,
2082     pub vis: Visibility,
2083 }
2084
2085 /// An item within an `extern` block
2086 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2087 pub enum ForeignItem_ {
2088     /// A foreign function
2089     ForeignItemFn(P<FnDecl>, Generics),
2090     /// A foreign static item (`static ext: u8`), with optional mutability
2091     /// (the boolean is true when mutable)
2092     ForeignItemStatic(P<Ty>, bool),
2093 }
2094
2095 impl ForeignItem_ {
2096     pub fn descriptive_variant(&self) -> &str {
2097         match *self {
2098             ForeignItemFn(..) => "foreign function",
2099             ForeignItemStatic(..) => "foreign static item"
2100         }
2101     }
2102 }
2103
2104 /// A macro definition, in this crate or imported from another.
2105 ///
2106 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
2107 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2108 pub struct MacroDef {
2109     pub ident: Ident,
2110     pub attrs: Vec<Attribute>,
2111     pub id: NodeId,
2112     pub span: Span,
2113     pub imported_from: Option<Ident>,
2114     pub export: bool,
2115     pub use_locally: bool,
2116     pub allow_internal_unstable: bool,
2117     pub body: Vec<TokenTree>,
2118 }
2119
2120 #[cfg(test)]
2121 mod tests {
2122     use serialize;
2123     use super::*;
2124
2125     // are ASTs encodable?
2126     #[test]
2127     fn check_asts_encodable() {
2128         fn assert_encodable<T: serialize::Encodable>() {}
2129         assert_encodable::<Crate>();
2130     }
2131 }