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