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