]> git.lizzy.rs Git - rust.git/blob - src/librustc_front/hir.rs
4232254327cdec14221f85577018cc2c17603016
[rust.git] / src / librustc_front / hir.rs
1 // Copyright 2015 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 HIR.
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::FunctionRetTy::*;
21 pub use self::ForeignItem_::*;
22 pub use self::Item_::*;
23 pub use self::Mutability::*;
24 pub use self::Pat_::*;
25 pub use self::PathListItem_::*;
26 pub use self::PrimTy::*;
27 pub use self::Stmt_::*;
28 pub use self::StructFieldKind::*;
29 pub use self::TraitItem_::*;
30 pub use self::Ty_::*;
31 pub use self::TyParamBound::*;
32 pub use self::UnOp::*;
33 pub use self::UnsafeSource::*;
34 pub use self::ViewPath_::*;
35 pub use self::Visibility::*;
36 pub use self::PathParameters::*;
37
38 use intravisit::Visitor;
39 use rustc_data_structures::fnv::FnvHashMap;
40 use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId};
41 use syntax::abi::Abi;
42 use syntax::ast::{Name, Ident, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect};
43 use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, CrateConfig};
44 use syntax::owned_slice::OwnedSlice;
45 use syntax::parse::token::InternedString;
46 use syntax::ptr::P;
47
48 use print::pprust;
49 use util;
50
51 use std::fmt;
52 use serialize::{Encodable, Encoder, Decoder};
53
54 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
55 pub struct Lifetime {
56     pub id: NodeId,
57     pub span: Span,
58     pub name: Name,
59 }
60
61 impl fmt::Debug for Lifetime {
62     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63         write!(f,
64                "lifetime({}: {})",
65                self.id,
66                pprust::lifetime_to_string(self))
67     }
68 }
69
70 /// A lifetime definition, eg `'a: 'b+'c+'d`
71 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
72 pub struct LifetimeDef {
73     pub lifetime: Lifetime,
74     pub bounds: Vec<Lifetime>,
75 }
76
77 /// A "Path" is essentially Rust's notion of a name; for instance:
78 /// std::cmp::PartialEq  .  It's represented as a sequence of identifiers,
79 /// along with a bunch of supporting information.
80 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
81 pub struct Path {
82     pub span: Span,
83     /// A `::foo` path, is relative to the crate root rather than current
84     /// module (like paths in an import).
85     pub global: bool,
86     /// The segments in the path: the things separated by `::`.
87     pub segments: Vec<PathSegment>,
88 }
89
90 impl fmt::Debug for Path {
91     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92         write!(f, "path({})", pprust::path_to_string(self))
93     }
94 }
95
96 impl fmt::Display for Path {
97     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
98         write!(f, "{}", pprust::path_to_string(self))
99     }
100 }
101
102 /// A segment of a path: an identifier, an optional lifetime, and a set of
103 /// types.
104 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
105 pub struct PathSegment {
106     /// The identifier portion of this path segment.
107     pub identifier: Ident,
108
109     /// Type/lifetime parameters attached to this path. They come in
110     /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
111     /// this is more than just simple syntactic sugar; the use of
112     /// parens affects the region binding rules, so we preserve the
113     /// distinction.
114     pub parameters: PathParameters,
115 }
116
117 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
118 pub enum PathParameters {
119     /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
120     AngleBracketedParameters(AngleBracketedParameterData),
121     /// The `(A,B)` and `C` in `Foo(A,B) -> C`
122     ParenthesizedParameters(ParenthesizedParameterData),
123 }
124
125 impl PathParameters {
126     pub fn none() -> PathParameters {
127         AngleBracketedParameters(AngleBracketedParameterData {
128             lifetimes: Vec::new(),
129             types: OwnedSlice::empty(),
130             bindings: OwnedSlice::empty(),
131         })
132     }
133
134     pub fn is_empty(&self) -> bool {
135         match *self {
136             AngleBracketedParameters(ref data) => data.is_empty(),
137
138             // Even if the user supplied no types, something like
139             // `X()` is equivalent to `X<(),()>`.
140             ParenthesizedParameters(..) => false,
141         }
142     }
143
144     pub fn has_lifetimes(&self) -> bool {
145         match *self {
146             AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(),
147             ParenthesizedParameters(_) => false,
148         }
149     }
150
151     pub fn has_types(&self) -> bool {
152         match *self {
153             AngleBracketedParameters(ref data) => !data.types.is_empty(),
154             ParenthesizedParameters(..) => true,
155         }
156     }
157
158     /// Returns the types that the user wrote. Note that these do not necessarily map to the type
159     /// parameters in the parenthesized case.
160     pub fn types(&self) -> Vec<&P<Ty>> {
161         match *self {
162             AngleBracketedParameters(ref data) => {
163                 data.types.iter().collect()
164             }
165             ParenthesizedParameters(ref data) => {
166                 data.inputs
167                     .iter()
168                     .chain(data.output.iter())
169                     .collect()
170             }
171         }
172     }
173
174     pub fn lifetimes(&self) -> Vec<&Lifetime> {
175         match *self {
176             AngleBracketedParameters(ref data) => {
177                 data.lifetimes.iter().collect()
178             }
179             ParenthesizedParameters(_) => {
180                 Vec::new()
181             }
182         }
183     }
184
185     pub fn bindings(&self) -> Vec<&P<TypeBinding>> {
186         match *self {
187             AngleBracketedParameters(ref data) => {
188                 data.bindings.iter().collect()
189             }
190             ParenthesizedParameters(_) => {
191                 Vec::new()
192             }
193         }
194     }
195 }
196
197 /// A path like `Foo<'a, T>`
198 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
199 pub struct AngleBracketedParameterData {
200     /// The lifetime parameters for this path segment.
201     pub lifetimes: Vec<Lifetime>,
202     /// The type parameters for this path segment, if present.
203     pub types: OwnedSlice<P<Ty>>,
204     /// Bindings (equality constraints) on associated types, if present.
205     /// E.g., `Foo<A=Bar>`.
206     pub bindings: OwnedSlice<P<TypeBinding>>,
207 }
208
209 impl AngleBracketedParameterData {
210     fn is_empty(&self) -> bool {
211         self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
212     }
213 }
214
215 /// A path like `Foo(A,B) -> C`
216 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
217 pub struct ParenthesizedParameterData {
218     /// Overall span
219     pub span: Span,
220
221     /// `(A,B)`
222     pub inputs: Vec<P<Ty>>,
223
224     /// `C`
225     pub output: Option<P<Ty>>,
226 }
227
228 /// The AST represents all type param bounds as types.
229 /// typeck::collect::compute_bounds matches these against
230 /// the "special" built-in traits (see middle::lang_items) and
231 /// detects Copy, Send and Sync.
232 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
233 pub enum TyParamBound {
234     TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
235     RegionTyParamBound(Lifetime),
236 }
237
238 /// A modifier on a bound, currently this is only used for `?Sized`, where the
239 /// modifier is `Maybe`. Negative bounds should also be handled here.
240 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
241 pub enum TraitBoundModifier {
242     None,
243     Maybe,
244 }
245
246 pub type TyParamBounds = OwnedSlice<TyParamBound>;
247
248 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
249 pub struct TyParam {
250     pub name: Name,
251     pub id: NodeId,
252     pub bounds: TyParamBounds,
253     pub default: Option<P<Ty>>,
254     pub span: Span,
255 }
256
257 /// Represents lifetimes and type parameters attached to a declaration
258 /// of a function, enum, trait, etc.
259 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
260 pub struct Generics {
261     pub lifetimes: Vec<LifetimeDef>,
262     pub ty_params: OwnedSlice<TyParam>,
263     pub where_clause: WhereClause,
264 }
265
266 impl Generics {
267     pub fn is_lt_parameterized(&self) -> bool {
268         !self.lifetimes.is_empty()
269     }
270     pub fn is_type_parameterized(&self) -> bool {
271         !self.ty_params.is_empty()
272     }
273     pub fn is_parameterized(&self) -> bool {
274         self.is_lt_parameterized() || self.is_type_parameterized()
275     }
276 }
277
278 /// A `where` clause in a definition
279 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
280 pub struct WhereClause {
281     pub id: NodeId,
282     pub predicates: Vec<WherePredicate>,
283 }
284
285 /// A single predicate in a `where` clause
286 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
287 pub enum WherePredicate {
288     /// A type binding, eg `for<'c> Foo: Send+Clone+'c`
289     BoundPredicate(WhereBoundPredicate),
290     /// A lifetime predicate, e.g. `'a: 'b+'c`
291     RegionPredicate(WhereRegionPredicate),
292     /// An equality predicate (unsupported)
293     EqPredicate(WhereEqPredicate),
294 }
295
296 /// A type bound, eg `for<'c> Foo: Send+Clone+'c`
297 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
298 pub struct WhereBoundPredicate {
299     pub span: Span,
300     /// Any lifetimes from a `for` binding
301     pub bound_lifetimes: Vec<LifetimeDef>,
302     /// The type being bounded
303     pub bounded_ty: P<Ty>,
304     /// Trait and lifetime bounds (`Clone+Send+'static`)
305     pub bounds: OwnedSlice<TyParamBound>,
306 }
307
308 /// A lifetime predicate, e.g. `'a: 'b+'c`
309 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
310 pub struct WhereRegionPredicate {
311     pub span: Span,
312     pub lifetime: Lifetime,
313     pub bounds: Vec<Lifetime>,
314 }
315
316 /// An equality predicate (unsupported), e.g. `T=int`
317 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
318 pub struct WhereEqPredicate {
319     pub id: NodeId,
320     pub span: Span,
321     pub path: Path,
322     pub ty: P<Ty>,
323 }
324
325 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
326 pub struct Crate {
327     pub module: Mod,
328     pub attrs: Vec<Attribute>,
329     pub config: CrateConfig,
330     pub span: Span,
331     pub exported_macros: Vec<MacroDef>,
332     pub items: FnvHashMap<NodeId, Item>,
333 }
334
335 impl Crate {
336     pub fn item(&self, id: NodeId) -> &Item {
337         &self.items[&id]
338     }
339
340     /// Visits all items in the crate in some determinstic (but
341     /// unspecified) order. If you just need to process every item,
342     /// but don't care about nesting, this method is the best choice.
343     ///
344     /// If you do care about nesting -- usually because your algorithm
345     /// follows lexical scoping rules -- then you want a different
346     /// approach. You should override `visit_nested_item` in your
347     /// visitor and then call `intravisit::walk_crate` instead.
348     pub fn visit_all_items<'hir, V:Visitor<'hir>>(&'hir self, visitor: &mut V) {
349         // In principle, we could just iterate over the hashmap, but
350         // in practice that makes the order of error reporting vary
351         // with small changes in the input etc etc, which makes the
352         // test base hard to maintain. So instead we sort by node-id
353         // so as to get reproducible results.
354         let mut pairs: Vec<_> = self.items.iter().collect();
355         pairs.sort_by(|&(id1, _), &(id2, _)| id1.cmp(id2));
356
357         for (_, item) in pairs {
358             visitor.visit_item(item);
359         }
360     }
361 }
362
363 /// A macro definition, in this crate or imported from another.
364 ///
365 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
366 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
367 pub struct MacroDef {
368     pub name: Name,
369     pub attrs: Vec<Attribute>,
370     pub id: NodeId,
371     pub span: Span,
372     pub imported_from: Option<Name>,
373     pub export: bool,
374     pub use_locally: bool,
375     pub allow_internal_unstable: bool,
376     pub body: Vec<TokenTree>,
377 }
378
379 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
380 pub struct Block {
381     /// Statements in a block
382     pub stmts: Vec<P<Stmt>>,
383     /// An expression at the end of the block
384     /// without a semicolon, if any
385     pub expr: Option<P<Expr>>,
386     pub id: NodeId,
387     /// Distinguishes between `unsafe { ... }` and `{ ... }`
388     pub rules: BlockCheckMode,
389     pub span: Span,
390 }
391
392 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
393 pub struct Pat {
394     pub id: NodeId,
395     pub node: Pat_,
396     pub span: Span,
397 }
398
399 impl fmt::Debug for Pat {
400     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
401         write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self))
402     }
403 }
404
405 /// A single field in a struct pattern
406 ///
407 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
408 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
409 /// except is_shorthand is true
410 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
411 pub struct FieldPat {
412     /// The identifier for the field
413     pub name: Name,
414     /// The pattern the field is destructured to
415     pub pat: P<Pat>,
416     pub is_shorthand: bool,
417 }
418
419 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
420 pub enum BindingMode {
421     BindByRef(Mutability),
422     BindByValue(Mutability),
423 }
424
425 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
426 pub enum Pat_ {
427     /// Represents a wildcard pattern (`_`)
428     PatWild,
429
430     /// A PatIdent may either be a new bound variable,
431     /// or a nullary enum (in which case the third field
432     /// is None).
433     ///
434     /// In the nullary enum case, the parser can't determine
435     /// which it is. The resolver determines this, and
436     /// records this pattern's NodeId in an auxiliary
437     /// set (of "PatIdents that refer to nullary enums")
438     PatIdent(BindingMode, Spanned<Ident>, Option<P<Pat>>),
439
440     /// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
441     PatEnum(Path, Option<Vec<P<Pat>>>),
442
443     /// An associated const named using the qualified path `<T>::CONST` or
444     /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
445     /// referred to as simply `T::CONST`, in which case they will end up as
446     /// PatEnum, and the resolver will have to sort that out.
447     PatQPath(QSelf, Path),
448
449     /// Destructuring of a struct, e.g. `Foo {x, y, ..}`
450     /// The `bool` is `true` in the presence of a `..`
451     PatStruct(Path, Vec<Spanned<FieldPat>>, bool),
452     /// A tuple pattern `(a, b)`
453     PatTup(Vec<P<Pat>>),
454     /// A `box` pattern
455     PatBox(P<Pat>),
456     /// A reference pattern, e.g. `&mut (a, b)`
457     PatRegion(P<Pat>, Mutability),
458     /// A literal
459     PatLit(P<Expr>),
460     /// A range pattern, e.g. `1...2`
461     PatRange(P<Expr>, P<Expr>),
462     /// `[a, b, ..i, y, z]` is represented as:
463     ///     `PatVec(box [a, b], Some(i), box [y, z])`
464     PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
465 }
466
467 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
468 pub enum Mutability {
469     MutMutable,
470     MutImmutable,
471 }
472
473 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
474 pub enum BinOp_ {
475     /// The `+` operator (addition)
476     BiAdd,
477     /// The `-` operator (subtraction)
478     BiSub,
479     /// The `*` operator (multiplication)
480     BiMul,
481     /// The `/` operator (division)
482     BiDiv,
483     /// The `%` operator (modulus)
484     BiRem,
485     /// The `&&` operator (logical and)
486     BiAnd,
487     /// The `||` operator (logical or)
488     BiOr,
489     /// The `^` operator (bitwise xor)
490     BiBitXor,
491     /// The `&` operator (bitwise and)
492     BiBitAnd,
493     /// The `|` operator (bitwise or)
494     BiBitOr,
495     /// The `<<` operator (shift left)
496     BiShl,
497     /// The `>>` operator (shift right)
498     BiShr,
499     /// The `==` operator (equality)
500     BiEq,
501     /// The `<` operator (less than)
502     BiLt,
503     /// The `<=` operator (less than or equal to)
504     BiLe,
505     /// The `!=` operator (not equal to)
506     BiNe,
507     /// The `>=` operator (greater than or equal to)
508     BiGe,
509     /// The `>` operator (greater than)
510     BiGt,
511 }
512
513 pub type BinOp = Spanned<BinOp_>;
514
515 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
516 pub enum UnOp {
517     /// The `*` operator for dereferencing
518     UnDeref,
519     /// The `!` operator for logical inversion
520     UnNot,
521     /// The `-` operator for negation
522     UnNeg,
523 }
524
525 /// A statement
526 pub type Stmt = Spanned<Stmt_>;
527
528 impl fmt::Debug for Stmt_ {
529     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
530         // Sadness.
531         let spanned = codemap::dummy_spanned(self.clone());
532         write!(f,
533                "stmt({}: {})",
534                util::stmt_id(&spanned),
535                pprust::stmt_to_string(&spanned))
536     }
537 }
538
539 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
540 pub enum Stmt_ {
541     /// Could be an item or a local (let) binding:
542     StmtDecl(P<Decl>, NodeId),
543
544     /// Expr without trailing semi-colon (must have unit type):
545     StmtExpr(P<Expr>, NodeId),
546
547     /// Expr with trailing semi-colon (may have any type):
548     StmtSemi(P<Expr>, NodeId),
549 }
550
551 // FIXME (pending discussion of #1697, #2178...): local should really be
552 // a refinement on pat.
553 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
554 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
555 pub struct Local {
556     pub pat: P<Pat>,
557     pub ty: Option<P<Ty>>,
558     /// Initializer expression to set the value, if any
559     pub init: Option<P<Expr>>,
560     pub id: NodeId,
561     pub span: Span,
562 }
563
564 pub type Decl = Spanned<Decl_>;
565
566 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
567 pub enum Decl_ {
568     /// A local (let) binding:
569     DeclLocal(P<Local>),
570     /// An item binding:
571     DeclItem(ItemId),
572 }
573
574 /// represents one arm of a 'match'
575 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
576 pub struct Arm {
577     pub attrs: Vec<Attribute>,
578     pub pats: Vec<P<Pat>>,
579     pub guard: Option<P<Expr>>,
580     pub body: P<Expr>,
581 }
582
583 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
584 pub struct Field {
585     pub name: Spanned<Name>,
586     pub expr: P<Expr>,
587     pub span: Span,
588 }
589
590 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
591 pub enum BlockCheckMode {
592     DefaultBlock,
593     UnsafeBlock(UnsafeSource),
594     PushUnsafeBlock(UnsafeSource),
595     PopUnsafeBlock(UnsafeSource),
596     // Within this block (but outside a PopUnstableBlock), we suspend checking of stability.
597     PushUnstableBlock,
598     PopUnstableBlock,
599 }
600
601 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
602 pub enum UnsafeSource {
603     CompilerGenerated,
604     UserProvided,
605 }
606
607 /// An expression
608 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
609 pub struct Expr {
610     pub id: NodeId,
611     pub node: Expr_,
612     pub span: Span,
613 }
614
615 impl fmt::Debug for Expr {
616     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
617         write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self))
618     }
619 }
620
621 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
622 pub enum Expr_ {
623     /// A `box x` expression.
624     ExprBox(P<Expr>),
625     /// An array (`[a, b, c, d]`)
626     ExprVec(Vec<P<Expr>>),
627     /// A function call
628     ///
629     /// The first field resolves to the function itself,
630     /// and the second field is the list of arguments
631     ExprCall(P<Expr>, Vec<P<Expr>>),
632     /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
633     ///
634     /// The `Spanned<Name>` is the identifier for the method name.
635     /// The vector of `Ty`s are the ascripted type parameters for the method
636     /// (within the angle brackets).
637     ///
638     /// The first element of the vector of `Expr`s is the expression that evaluates
639     /// to the object on which the method is being called on (the receiver),
640     /// and the remaining elements are the rest of the arguments.
641     ///
642     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
643     /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
644     ExprMethodCall(Spanned<Name>, Vec<P<Ty>>, Vec<P<Expr>>),
645     /// A tuple (`(a, b, c ,d)`)
646     ExprTup(Vec<P<Expr>>),
647     /// A binary operation (For example: `a + b`, `a * b`)
648     ExprBinary(BinOp, P<Expr>, P<Expr>),
649     /// A unary operation (For example: `!x`, `*x`)
650     ExprUnary(UnOp, P<Expr>),
651     /// A literal (For example: `1u8`, `"foo"`)
652     ExprLit(P<Lit>),
653     /// A cast (`foo as f64`)
654     ExprCast(P<Expr>, P<Ty>),
655     /// An `if` block, with an optional else block
656     ///
657     /// `if expr { block } else { expr }`
658     ExprIf(P<Expr>, P<Block>, Option<P<Expr>>),
659     /// A while loop, with an optional label
660     ///
661     /// `'label: while expr { block }`
662     ExprWhile(P<Expr>, P<Block>, Option<Ident>),
663     /// Conditionless loop (can be exited with break, continue, or return)
664     ///
665     /// `'label: loop { block }`
666     ExprLoop(P<Block>, Option<Ident>),
667     /// A `match` block, with a source that indicates whether or not it is
668     /// the result of a desugaring, and if so, which kind.
669     ExprMatch(P<Expr>, Vec<Arm>, MatchSource),
670     /// A closure (for example, `move |a, b, c| {a + b + c}`)
671     ExprClosure(CaptureClause, P<FnDecl>, P<Block>),
672     /// A block (`{ ... }`)
673     ExprBlock(P<Block>),
674
675     /// An assignment (`a = foo()`)
676     ExprAssign(P<Expr>, P<Expr>),
677     /// An assignment with an operator
678     ///
679     /// For example, `a += 1`.
680     ExprAssignOp(BinOp, P<Expr>, P<Expr>),
681     /// Access of a named struct field (`obj.foo`)
682     ExprField(P<Expr>, Spanned<Name>),
683     /// Access of an unnamed field of a struct or tuple-struct
684     ///
685     /// For example, `foo.0`.
686     ExprTupField(P<Expr>, Spanned<usize>),
687     /// An indexing operation (`foo[2]`)
688     ExprIndex(P<Expr>, P<Expr>),
689     /// A range (`1..2`, `1..`, or `..2`)
690     ExprRange(Option<P<Expr>>, Option<P<Expr>>),
691
692     /// Variable reference, possibly containing `::` and/or type
693     /// parameters, e.g. foo::bar::<baz>.
694     ///
695     /// Optionally "qualified",
696     /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
697     ExprPath(Option<QSelf>, Path),
698
699     /// A referencing operation (`&a` or `&mut a`)
700     ExprAddrOf(Mutability, P<Expr>),
701     /// A `break`, with an optional label to break
702     ExprBreak(Option<Spanned<Ident>>),
703     /// A `continue`, with an optional label
704     ExprAgain(Option<Spanned<Ident>>),
705     /// A `return`, with an optional value to be returned
706     ExprRet(Option<P<Expr>>),
707
708     /// Output of the `asm!()` macro
709     ExprInlineAsm(InlineAsm),
710
711     /// A struct literal expression.
712     ///
713     /// For example, `Foo {x: 1, y: 2}`, or
714     /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
715     ExprStruct(Path, Vec<Field>, Option<P<Expr>>),
716
717     /// A vector literal constructed from one repeated element.
718     ///
719     /// For example, `[1u8; 5]`. The first expression is the element
720     /// to be repeated; the second is the number of times to repeat it.
721     ExprRepeat(P<Expr>, P<Expr>),
722 }
723
724 /// The explicit Self type in a "qualified path". The actual
725 /// path, including the trait and the associated item, is stored
726 /// separately. `position` represents the index of the associated
727 /// item qualified with this Self type.
728 ///
729 ///     <Vec<T> as a::b::Trait>::AssociatedItem
730 ///      ^~~~~     ~~~~~~~~~~~~~~^
731 ///      ty        position = 3
732 ///
733 ///     <Vec<T>>::AssociatedItem
734 ///      ^~~~~    ^
735 ///      ty       position = 0
736 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
737 pub struct QSelf {
738     pub ty: P<Ty>,
739     pub position: usize,
740 }
741
742 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
743 pub enum MatchSource {
744     Normal,
745     IfLetDesugar {
746         contains_else_clause: bool,
747     },
748     WhileLetDesugar,
749     ForLoopDesugar,
750 }
751
752 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
753 pub enum CaptureClause {
754     CaptureByValue,
755     CaptureByRef,
756 }
757
758 // NB: If you change this, you'll probably want to change the corresponding
759 // type structure in middle/ty.rs as well.
760 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
761 pub struct MutTy {
762     pub ty: P<Ty>,
763     pub mutbl: Mutability,
764 }
765
766 /// Represents a method's signature in a trait declaration,
767 /// or in an implementation.
768 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
769 pub struct MethodSig {
770     pub unsafety: Unsafety,
771     pub constness: Constness,
772     pub abi: Abi,
773     pub decl: P<FnDecl>,
774     pub generics: Generics,
775     pub explicit_self: ExplicitSelf,
776 }
777
778 /// Represents a method declaration in a trait declaration, possibly including
779 /// a default implementation A trait method is either required (meaning it
780 /// doesn't have an implementation, just a signature) or provided (meaning it
781 /// has a default implementation).
782 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
783 pub struct TraitItem {
784     pub id: NodeId,
785     pub name: Name,
786     pub attrs: Vec<Attribute>,
787     pub node: TraitItem_,
788     pub span: Span,
789 }
790
791 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
792 pub enum TraitItem_ {
793     ConstTraitItem(P<Ty>, Option<P<Expr>>),
794     MethodTraitItem(MethodSig, Option<P<Block>>),
795     TypeTraitItem(TyParamBounds, Option<P<Ty>>),
796 }
797
798 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
799 pub struct ImplItem {
800     pub id: NodeId,
801     pub name: Name,
802     pub vis: Visibility,
803     pub attrs: Vec<Attribute>,
804     pub node: ImplItemKind,
805     pub span: Span,
806 }
807
808 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
809 pub enum ImplItemKind {
810     Const(P<Ty>, P<Expr>),
811     Method(MethodSig, P<Block>),
812     Type(P<Ty>),
813 }
814
815 // Bind a type to an associated type: `A=Foo`.
816 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
817 pub struct TypeBinding {
818     pub id: NodeId,
819     pub name: Name,
820     pub ty: P<Ty>,
821     pub span: Span,
822 }
823
824
825 // NB PartialEq method appears below.
826 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
827 pub struct Ty {
828     pub id: NodeId,
829     pub node: Ty_,
830     pub span: Span,
831 }
832
833 impl fmt::Debug for Ty {
834     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
835         write!(f, "type({})", pprust::ty_to_string(self))
836     }
837 }
838
839 /// Not represented directly in the AST, referred to by name through a ty_path.
840 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
841 pub enum PrimTy {
842     TyInt(IntTy),
843     TyUint(UintTy),
844     TyFloat(FloatTy),
845     TyStr,
846     TyBool,
847     TyChar,
848 }
849
850 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
851 pub struct BareFnTy {
852     pub unsafety: Unsafety,
853     pub abi: Abi,
854     pub lifetimes: Vec<LifetimeDef>,
855     pub decl: P<FnDecl>,
856 }
857
858 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
859 /// The different kinds of types recognized by the compiler
860 pub enum Ty_ {
861     TyVec(P<Ty>),
862     /// A fixed length array (`[T; n]`)
863     TyFixedLengthVec(P<Ty>, P<Expr>),
864     /// A raw pointer (`*const T` or `*mut T`)
865     TyPtr(MutTy),
866     /// A reference (`&'a T` or `&'a mut T`)
867     TyRptr(Option<Lifetime>, MutTy),
868     /// A bare function (e.g. `fn(usize) -> bool`)
869     TyBareFn(P<BareFnTy>),
870     /// A tuple (`(A, B, C, D,...)`)
871     TyTup(Vec<P<Ty>>),
872     /// A path (`module::module::...::Type`), optionally
873     /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
874     ///
875     /// Type parameters are stored in the Path itself
876     TyPath(Option<QSelf>, Path),
877     /// Something like `A+B`. Note that `B` must always be a path.
878     TyObjectSum(P<Ty>, TyParamBounds),
879     /// A type like `for<'a> Foo<&'a Bar>`
880     TyPolyTraitRef(TyParamBounds),
881     /// Unused for now
882     TyTypeof(P<Expr>),
883     /// TyInfer means the type should be inferred instead of it having been
884     /// specified. This can appear anywhere in a type.
885     TyInfer,
886 }
887
888 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
889 pub struct InlineAsm {
890     pub asm: InternedString,
891     pub asm_str_style: StrStyle,
892     pub outputs: Vec<(InternedString, P<Expr>, bool)>,
893     pub inputs: Vec<(InternedString, P<Expr>)>,
894     pub clobbers: Vec<InternedString>,
895     pub volatile: bool,
896     pub alignstack: bool,
897     pub dialect: AsmDialect,
898     pub expn_id: ExpnId,
899 }
900
901 /// represents an argument in a function header
902 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
903 pub struct Arg {
904     pub ty: P<Ty>,
905     pub pat: P<Pat>,
906     pub id: NodeId,
907 }
908
909 impl Arg {
910     pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
911         let path = Spanned {
912             span: span,
913             node: self_ident,
914         };
915         Arg {
916             // HACK(eddyb) fake type for the self argument.
917             ty: P(Ty {
918                 id: DUMMY_NODE_ID,
919                 node: TyInfer,
920                 span: DUMMY_SP,
921             }),
922             pat: P(Pat {
923                 id: DUMMY_NODE_ID,
924                 node: PatIdent(BindByValue(mutability), path, None),
925                 span: span,
926             }),
927             id: DUMMY_NODE_ID,
928         }
929     }
930 }
931
932 /// Represents the header (not the body) of a function declaration
933 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
934 pub struct FnDecl {
935     pub inputs: Vec<Arg>,
936     pub output: FunctionRetTy,
937     pub variadic: bool,
938 }
939
940 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
941 pub enum Unsafety {
942     Unsafe,
943     Normal,
944 }
945
946 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
947 pub enum Constness {
948     Const,
949     NotConst,
950 }
951
952 impl fmt::Display for Unsafety {
953     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
954         fmt::Display::fmt(match *self {
955                               Unsafety::Normal => "normal",
956                               Unsafety::Unsafe => "unsafe",
957                           },
958                           f)
959     }
960 }
961
962 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
963 pub enum ImplPolarity {
964     /// `impl Trait for Type`
965     Positive,
966     /// `impl !Trait for Type`
967     Negative,
968 }
969
970 impl fmt::Debug for ImplPolarity {
971     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
972         match *self {
973             ImplPolarity::Positive => "positive".fmt(f),
974             ImplPolarity::Negative => "negative".fmt(f),
975         }
976     }
977 }
978
979
980 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
981 pub enum FunctionRetTy {
982     /// Functions with return type `!`that always
983     /// raise an error or exit (i.e. never return to the caller)
984     NoReturn(Span),
985     /// Return type is not specified.
986     ///
987     /// Functions default to `()` and
988     /// closures default to inference. Span points to where return
989     /// type would be inserted.
990     DefaultReturn(Span),
991     /// Everything else
992     Return(P<Ty>),
993 }
994
995 impl FunctionRetTy {
996     pub fn span(&self) -> Span {
997         match *self {
998             NoReturn(span) => span,
999             DefaultReturn(span) => span,
1000             Return(ref ty) => ty.span,
1001         }
1002     }
1003 }
1004
1005 /// Represents the kind of 'self' associated with a method
1006 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1007 pub enum ExplicitSelf_ {
1008     /// No self
1009     SelfStatic,
1010     /// `self`
1011     SelfValue(Name),
1012     /// `&'lt self`, `&'lt mut self`
1013     SelfRegion(Option<Lifetime>, Mutability, Name),
1014     /// `self: TYPE`
1015     SelfExplicit(P<Ty>, Name),
1016 }
1017
1018 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
1019
1020 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1021 pub struct Mod {
1022     /// A span from the first token past `{` to the last token until `}`.
1023     /// For `mod foo;`, the inner span ranges from the first token
1024     /// to the last token in the external file.
1025     pub inner: Span,
1026     pub item_ids: Vec<ItemId>,
1027 }
1028
1029 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1030 pub struct ForeignMod {
1031     pub abi: Abi,
1032     pub items: Vec<P<ForeignItem>>,
1033 }
1034
1035 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1036 pub struct EnumDef {
1037     pub variants: Vec<P<Variant>>,
1038 }
1039
1040 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1041 pub struct Variant_ {
1042     pub name: Name,
1043     pub attrs: Vec<Attribute>,
1044     pub data: VariantData,
1045     /// Explicit discriminant, eg `Foo = 1`
1046     pub disr_expr: Option<P<Expr>>,
1047 }
1048
1049 pub type Variant = Spanned<Variant_>;
1050
1051 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1052 pub enum PathListItem_ {
1053     PathListIdent {
1054         name: Name,
1055         /// renamed in list, eg `use foo::{bar as baz};`
1056         rename: Option<Name>,
1057         id: NodeId,
1058     },
1059     PathListMod {
1060         /// renamed in list, eg `use foo::{self as baz};`
1061         rename: Option<Name>,
1062         id: NodeId,
1063     },
1064 }
1065
1066 impl PathListItem_ {
1067     pub fn id(&self) -> NodeId {
1068         match *self {
1069             PathListIdent { id, .. } | PathListMod { id, .. } => id,
1070         }
1071     }
1072
1073     pub fn name(&self) -> Option<Name> {
1074         match *self {
1075             PathListIdent { name, .. } => Some(name),
1076             PathListMod { .. } => None,
1077         }
1078     }
1079
1080     pub fn rename(&self) -> Option<Name> {
1081         match *self {
1082             PathListIdent { rename, .. } | PathListMod { rename, .. } => rename,
1083         }
1084     }
1085 }
1086
1087 pub type PathListItem = Spanned<PathListItem_>;
1088
1089 pub type ViewPath = Spanned<ViewPath_>;
1090
1091 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1092 pub enum ViewPath_ {
1093     /// `foo::bar::baz as quux`
1094     ///
1095     /// or just
1096     ///
1097     /// `foo::bar::baz` (with `as baz` implicitly on the right)
1098     ViewPathSimple(Name, Path),
1099
1100     /// `foo::bar::*`
1101     ViewPathGlob(Path),
1102
1103     /// `foo::bar::{a,b,c}`
1104     ViewPathList(Path, Vec<PathListItem>),
1105 }
1106
1107 /// TraitRef's appear in impls.
1108 ///
1109 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1110 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1111 /// If this impl is an ItemImpl, the impl_id is redundant (it could be the
1112 /// same as the impl's node id).
1113 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1114 pub struct TraitRef {
1115     pub path: Path,
1116     pub ref_id: NodeId,
1117 }
1118
1119 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1120 pub struct PolyTraitRef {
1121     /// The `'a` in `<'a> Foo<&'a T>`
1122     pub bound_lifetimes: Vec<LifetimeDef>,
1123
1124     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1125     pub trait_ref: TraitRef,
1126
1127     pub span: Span,
1128 }
1129
1130 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1131 pub enum Visibility {
1132     Public,
1133     Inherited,
1134 }
1135
1136 impl Visibility {
1137     pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1138         match self {
1139             &Inherited => parent_visibility,
1140             &Public => *self,
1141         }
1142     }
1143 }
1144
1145 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1146 pub struct StructField_ {
1147     pub kind: StructFieldKind,
1148     pub id: NodeId,
1149     pub ty: P<Ty>,
1150     pub attrs: Vec<Attribute>,
1151 }
1152
1153 impl StructField_ {
1154     pub fn name(&self) -> Option<Name> {
1155         match self.kind {
1156             NamedField(name, _) => Some(name),
1157             UnnamedField(_) => None,
1158         }
1159     }
1160 }
1161
1162 pub type StructField = Spanned<StructField_>;
1163
1164 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1165 pub enum StructFieldKind {
1166     NamedField(Name, Visibility),
1167     /// Element of a tuple-like struct
1168     UnnamedField(Visibility),
1169 }
1170
1171 impl StructFieldKind {
1172     pub fn is_unnamed(&self) -> bool {
1173         match *self {
1174             UnnamedField(..) => true,
1175             NamedField(..) => false,
1176         }
1177     }
1178
1179     pub fn visibility(&self) -> Visibility {
1180         match *self {
1181             NamedField(_, vis) | UnnamedField(vis) => vis,
1182         }
1183     }
1184 }
1185
1186 /// Fields and Ids of enum variants and structs
1187 ///
1188 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1189 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1190 /// One shared Id can be successfully used for these two purposes.
1191 /// Id of the whole enum lives in `Item`.
1192 ///
1193 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
1194 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
1195 /// the variant itself" from enum variants.
1196 /// Id of the whole struct lives in `Item`.
1197 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1198 pub enum VariantData {
1199     Struct(Vec<StructField>, NodeId),
1200     Tuple(Vec<StructField>, NodeId),
1201     Unit(NodeId),
1202 }
1203
1204 impl VariantData {
1205     pub fn fields(&self) -> &[StructField] {
1206         match *self {
1207             VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
1208             _ => &[],
1209         }
1210     }
1211     pub fn id(&self) -> NodeId {
1212         match *self {
1213             VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
1214         }
1215     }
1216     pub fn is_struct(&self) -> bool {
1217         if let VariantData::Struct(..) = *self {
1218             true
1219         } else {
1220             false
1221         }
1222     }
1223     pub fn is_tuple(&self) -> bool {
1224         if let VariantData::Tuple(..) = *self {
1225             true
1226         } else {
1227             false
1228         }
1229     }
1230     pub fn is_unit(&self) -> bool {
1231         if let VariantData::Unit(..) = *self {
1232             true
1233         } else {
1234             false
1235         }
1236     }
1237 }
1238
1239 // The bodies for items are stored "out of line", in a separate
1240 // hashmap in the `Crate`. Here we just record the node-id of the item
1241 // so it can fetched later.
1242 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1243 pub struct ItemId {
1244     pub id: NodeId,
1245 }
1246
1247 //  FIXME (#3300): Should allow items to be anonymous. Right now
1248 //  we just use dummy names for anon items.
1249 /// An item
1250 ///
1251 /// The name might be a dummy name in case of anonymous items
1252 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1253 pub struct Item {
1254     pub name: Name,
1255     pub attrs: Vec<Attribute>,
1256     pub id: NodeId,
1257     pub node: Item_,
1258     pub vis: Visibility,
1259     pub span: Span,
1260 }
1261
1262 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1263 pub enum Item_ {
1264     /// An`extern crate` item, with optional original crate name,
1265     ///
1266     /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
1267     ItemExternCrate(Option<Name>),
1268     /// A `use` or `pub use` item
1269     ItemUse(P<ViewPath>),
1270
1271     /// A `static` item
1272     ItemStatic(P<Ty>, Mutability, P<Expr>),
1273     /// A `const` item
1274     ItemConst(P<Ty>, P<Expr>),
1275     /// A function declaration
1276     ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
1277     /// A module
1278     ItemMod(Mod),
1279     /// An external module
1280     ItemForeignMod(ForeignMod),
1281     /// A type alias, e.g. `type Foo = Bar<u8>`
1282     ItemTy(P<Ty>, Generics),
1283     /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
1284     ItemEnum(EnumDef, Generics),
1285     /// A struct definition, e.g. `struct Foo<A> {x: A}`
1286     ItemStruct(VariantData, Generics),
1287     /// Represents a Trait Declaration
1288     ItemTrait(Unsafety, Generics, TyParamBounds, Vec<P<TraitItem>>),
1289
1290     // Default trait implementations
1291     ///
1292     /// `impl Trait for .. {}`
1293     ItemDefaultImpl(Unsafety, TraitRef),
1294     /// An implementation, eg `impl<A> Trait for Foo { .. }`
1295     ItemImpl(Unsafety,
1296              ImplPolarity,
1297              Generics,
1298              Option<TraitRef>, // (optional) trait this impl implements
1299              P<Ty>, // self
1300              Vec<P<ImplItem>>),
1301 }
1302
1303 impl Item_ {
1304     pub fn descriptive_variant(&self) -> &str {
1305         match *self {
1306             ItemExternCrate(..) => "extern crate",
1307             ItemUse(..) => "use",
1308             ItemStatic(..) => "static item",
1309             ItemConst(..) => "constant item",
1310             ItemFn(..) => "function",
1311             ItemMod(..) => "module",
1312             ItemForeignMod(..) => "foreign module",
1313             ItemTy(..) => "type alias",
1314             ItemEnum(..) => "enum",
1315             ItemStruct(..) => "struct",
1316             ItemTrait(..) => "trait",
1317             ItemImpl(..) |
1318             ItemDefaultImpl(..) => "item",
1319         }
1320     }
1321 }
1322
1323 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1324 pub struct ForeignItem {
1325     pub name: Name,
1326     pub attrs: Vec<Attribute>,
1327     pub node: ForeignItem_,
1328     pub id: NodeId,
1329     pub span: Span,
1330     pub vis: Visibility,
1331 }
1332
1333 /// An item within an `extern` block
1334 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1335 pub enum ForeignItem_ {
1336     /// A foreign function
1337     ForeignItemFn(P<FnDecl>, Generics),
1338     /// A foreign static item (`static ext: u8`), with optional mutability
1339     /// (the boolean is true when mutable)
1340     ForeignItemStatic(P<Ty>, bool),
1341 }
1342
1343 impl ForeignItem_ {
1344     pub fn descriptive_variant(&self) -> &str {
1345         match *self {
1346             ForeignItemFn(..) => "foreign function",
1347             ForeignItemStatic(..) => "foreign static item",
1348         }
1349     }
1350 }