]> git.lizzy.rs Git - rust.git/blob - src/librustc_front/hir.rs
Auto merge of #32048 - bluss:overloaded-assign-op, r=eddyb
[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: `1u8`, `"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, `[1u8; 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 }
839
840 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
841 pub enum CaptureClause {
842     CaptureByValue,
843     CaptureByRef,
844 }
845
846 // NB: If you change this, you'll probably want to change the corresponding
847 // type structure in middle/ty.rs as well.
848 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
849 pub struct MutTy {
850     pub ty: P<Ty>,
851     pub mutbl: Mutability,
852 }
853
854 /// Represents a method's signature in a trait declaration,
855 /// or in an implementation.
856 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
857 pub struct MethodSig {
858     pub unsafety: Unsafety,
859     pub constness: Constness,
860     pub abi: Abi,
861     pub decl: P<FnDecl>,
862     pub generics: Generics,
863     pub explicit_self: ExplicitSelf,
864 }
865
866 /// Represents a method declaration in a trait declaration, possibly including
867 /// a default implementation A trait method is either required (meaning it
868 /// doesn't have an implementation, just a signature) or provided (meaning it
869 /// has a default implementation).
870 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
871 pub struct TraitItem {
872     pub id: NodeId,
873     pub name: Name,
874     pub attrs: HirVec<Attribute>,
875     pub node: TraitItem_,
876     pub span: Span,
877 }
878
879 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
880 pub enum TraitItem_ {
881     ConstTraitItem(P<Ty>, Option<P<Expr>>),
882     MethodTraitItem(MethodSig, Option<P<Block>>),
883     TypeTraitItem(TyParamBounds, Option<P<Ty>>),
884 }
885
886 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
887 pub struct ImplItem {
888     pub id: NodeId,
889     pub name: Name,
890     pub vis: Visibility,
891     pub attrs: HirVec<Attribute>,
892     pub node: ImplItemKind,
893     pub span: Span,
894 }
895
896 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
897 pub enum ImplItemKind {
898     Const(P<Ty>, P<Expr>),
899     Method(MethodSig, P<Block>),
900     Type(P<Ty>),
901 }
902
903 // Bind a type to an associated type: `A=Foo`.
904 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
905 pub struct TypeBinding {
906     pub id: NodeId,
907     pub name: Name,
908     pub ty: P<Ty>,
909     pub span: Span,
910 }
911
912
913 // NB PartialEq method appears below.
914 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
915 pub struct Ty {
916     pub id: NodeId,
917     pub node: Ty_,
918     pub span: Span,
919 }
920
921 impl fmt::Debug for Ty {
922     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
923         write!(f, "type({})", pprust::ty_to_string(self))
924     }
925 }
926
927 /// Not represented directly in the AST, referred to by name through a ty_path.
928 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
929 pub enum PrimTy {
930     TyInt(IntTy),
931     TyUint(UintTy),
932     TyFloat(FloatTy),
933     TyStr,
934     TyBool,
935     TyChar,
936 }
937
938 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
939 pub struct BareFnTy {
940     pub unsafety: Unsafety,
941     pub abi: Abi,
942     pub lifetimes: HirVec<LifetimeDef>,
943     pub decl: P<FnDecl>,
944 }
945
946 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
947 /// The different kinds of types recognized by the compiler
948 pub enum Ty_ {
949     TyVec(P<Ty>),
950     /// A fixed length array (`[T; n]`)
951     TyFixedLengthVec(P<Ty>, P<Expr>),
952     /// A raw pointer (`*const T` or `*mut T`)
953     TyPtr(MutTy),
954     /// A reference (`&'a T` or `&'a mut T`)
955     TyRptr(Option<Lifetime>, MutTy),
956     /// A bare function (e.g. `fn(usize) -> bool`)
957     TyBareFn(P<BareFnTy>),
958     /// A tuple (`(A, B, C, D,...)`)
959     TyTup(HirVec<P<Ty>>),
960     /// A path (`module::module::...::Type`), optionally
961     /// "qualified", e.g. `<HirVec<T> as SomeTrait>::SomeType`.
962     ///
963     /// Type parameters are stored in the Path itself
964     TyPath(Option<QSelf>, Path),
965     /// Something like `A+B`. Note that `B` must always be a path.
966     TyObjectSum(P<Ty>, TyParamBounds),
967     /// A type like `for<'a> Foo<&'a Bar>`
968     TyPolyTraitRef(TyParamBounds),
969     /// Unused for now
970     TyTypeof(P<Expr>),
971     /// TyInfer means the type should be inferred instead of it having been
972     /// specified. This can appear anywhere in a type.
973     TyInfer,
974 }
975
976 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
977 pub struct InlineAsmOutput {
978     pub constraint: InternedString,
979     pub expr: P<Expr>,
980     pub is_rw: bool,
981     pub is_indirect: bool,
982 }
983
984 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
985 pub struct InlineAsm {
986     pub asm: InternedString,
987     pub asm_str_style: StrStyle,
988     pub outputs: HirVec<InlineAsmOutput>,
989     pub inputs: HirVec<(InternedString, P<Expr>)>,
990     pub clobbers: HirVec<InternedString>,
991     pub volatile: bool,
992     pub alignstack: bool,
993     pub dialect: AsmDialect,
994     pub expn_id: ExpnId,
995 }
996
997 /// represents an argument in a function header
998 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
999 pub struct Arg {
1000     pub ty: P<Ty>,
1001     pub pat: P<Pat>,
1002     pub id: NodeId,
1003 }
1004
1005 impl Arg {
1006     pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
1007         let path = Spanned {
1008             span: span,
1009             node: self_ident,
1010         };
1011         Arg {
1012             // HACK(eddyb) fake type for the self argument.
1013             ty: P(Ty {
1014                 id: DUMMY_NODE_ID,
1015                 node: TyInfer,
1016                 span: DUMMY_SP,
1017             }),
1018             pat: P(Pat {
1019                 id: DUMMY_NODE_ID,
1020                 node: PatKind::Ident(BindByValue(mutability), path, None),
1021                 span: span,
1022             }),
1023             id: DUMMY_NODE_ID,
1024         }
1025     }
1026 }
1027
1028 /// Represents the header (not the body) of a function declaration
1029 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1030 pub struct FnDecl {
1031     pub inputs: HirVec<Arg>,
1032     pub output: FunctionRetTy,
1033     pub variadic: bool,
1034 }
1035
1036 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1037 pub enum Unsafety {
1038     Unsafe,
1039     Normal,
1040 }
1041
1042 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1043 pub enum Constness {
1044     Const,
1045     NotConst,
1046 }
1047
1048 impl fmt::Display for Unsafety {
1049     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1050         fmt::Display::fmt(match *self {
1051                               Unsafety::Normal => "normal",
1052                               Unsafety::Unsafe => "unsafe",
1053                           },
1054                           f)
1055     }
1056 }
1057
1058 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1059 pub enum ImplPolarity {
1060     /// `impl Trait for Type`
1061     Positive,
1062     /// `impl !Trait for Type`
1063     Negative,
1064 }
1065
1066 impl fmt::Debug for ImplPolarity {
1067     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1068         match *self {
1069             ImplPolarity::Positive => "positive".fmt(f),
1070             ImplPolarity::Negative => "negative".fmt(f),
1071         }
1072     }
1073 }
1074
1075
1076 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1077 pub enum FunctionRetTy {
1078     /// Functions with return type `!`that always
1079     /// raise an error or exit (i.e. never return to the caller)
1080     NoReturn(Span),
1081     /// Return type is not specified.
1082     ///
1083     /// Functions default to `()` and
1084     /// closures default to inference. Span points to where return
1085     /// type would be inserted.
1086     DefaultReturn(Span),
1087     /// Everything else
1088     Return(P<Ty>),
1089 }
1090
1091 impl FunctionRetTy {
1092     pub fn span(&self) -> Span {
1093         match *self {
1094             NoReturn(span) => span,
1095             DefaultReturn(span) => span,
1096             Return(ref ty) => ty.span,
1097         }
1098     }
1099 }
1100
1101 /// Represents the kind of 'self' associated with a method
1102 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1103 pub enum ExplicitSelf_ {
1104     /// No self
1105     SelfStatic,
1106     /// `self`
1107     SelfValue(Name),
1108     /// `&'lt self`, `&'lt mut self`
1109     SelfRegion(Option<Lifetime>, Mutability, Name),
1110     /// `self: TYPE`
1111     SelfExplicit(P<Ty>, Name),
1112 }
1113
1114 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
1115
1116 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1117 pub struct Mod {
1118     /// A span from the first token past `{` to the last token until `}`.
1119     /// For `mod foo;`, the inner span ranges from the first token
1120     /// to the last token in the external file.
1121     pub inner: Span,
1122     pub item_ids: HirVec<ItemId>,
1123 }
1124
1125 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1126 pub struct ForeignMod {
1127     pub abi: Abi,
1128     pub items: HirVec<ForeignItem>,
1129 }
1130
1131 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1132 pub struct EnumDef {
1133     pub variants: HirVec<Variant>,
1134 }
1135
1136 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1137 pub struct Variant_ {
1138     pub name: Name,
1139     pub attrs: HirVec<Attribute>,
1140     pub data: VariantData,
1141     /// Explicit discriminant, eg `Foo = 1`
1142     pub disr_expr: Option<P<Expr>>,
1143 }
1144
1145 pub type Variant = Spanned<Variant_>;
1146
1147 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1148 pub enum PathListItem_ {
1149     PathListIdent {
1150         name: Name,
1151         /// renamed in list, eg `use foo::{bar as baz};`
1152         rename: Option<Name>,
1153         id: NodeId,
1154     },
1155     PathListMod {
1156         /// renamed in list, eg `use foo::{self as baz};`
1157         rename: Option<Name>,
1158         id: NodeId,
1159     },
1160 }
1161
1162 impl PathListItem_ {
1163     pub fn id(&self) -> NodeId {
1164         match *self {
1165             PathListIdent { id, .. } | PathListMod { id, .. } => id,
1166         }
1167     }
1168
1169     pub fn name(&self) -> Option<Name> {
1170         match *self {
1171             PathListIdent { name, .. } => Some(name),
1172             PathListMod { .. } => None,
1173         }
1174     }
1175
1176     pub fn rename(&self) -> Option<Name> {
1177         match *self {
1178             PathListIdent { rename, .. } | PathListMod { rename, .. } => rename,
1179         }
1180     }
1181 }
1182
1183 pub type PathListItem = Spanned<PathListItem_>;
1184
1185 pub type ViewPath = Spanned<ViewPath_>;
1186
1187 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1188 pub enum ViewPath_ {
1189     /// `foo::bar::baz as quux`
1190     ///
1191     /// or just
1192     ///
1193     /// `foo::bar::baz` (with `as baz` implicitly on the right)
1194     ViewPathSimple(Name, Path),
1195
1196     /// `foo::bar::*`
1197     ViewPathGlob(Path),
1198
1199     /// `foo::bar::{a,b,c}`
1200     ViewPathList(Path, HirVec<PathListItem>),
1201 }
1202
1203 /// TraitRef's appear in impls.
1204 ///
1205 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1206 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1207 /// If this impl is an ItemImpl, the impl_id is redundant (it could be the
1208 /// same as the impl's node id).
1209 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1210 pub struct TraitRef {
1211     pub path: Path,
1212     pub ref_id: NodeId,
1213 }
1214
1215 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1216 pub struct PolyTraitRef {
1217     /// The `'a` in `<'a> Foo<&'a T>`
1218     pub bound_lifetimes: HirVec<LifetimeDef>,
1219
1220     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1221     pub trait_ref: TraitRef,
1222
1223     pub span: Span,
1224 }
1225
1226 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1227 pub enum Visibility {
1228     Public,
1229     Inherited,
1230 }
1231
1232 impl Visibility {
1233     pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
1234         match self {
1235             &Inherited => parent_visibility,
1236             &Public => *self,
1237         }
1238     }
1239 }
1240
1241 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1242 pub struct StructField {
1243     pub span: Span,
1244     pub name: Name,
1245     pub vis: Visibility,
1246     pub id: NodeId,
1247     pub ty: P<Ty>,
1248     pub attrs: HirVec<Attribute>,
1249 }
1250
1251 impl StructField {
1252     // Still necessary in couple of places
1253     pub fn is_positional(&self) -> bool {
1254         let first = self.name.as_str().as_bytes()[0];
1255         first >= b'0' && first <= b'9'
1256     }
1257 }
1258
1259 /// Fields and Ids of enum variants and structs
1260 ///
1261 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1262 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1263 /// One shared Id can be successfully used for these two purposes.
1264 /// Id of the whole enum lives in `Item`.
1265 ///
1266 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
1267 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
1268 /// the variant itself" from enum variants.
1269 /// Id of the whole struct lives in `Item`.
1270 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1271 pub enum VariantData {
1272     Struct(HirVec<StructField>, NodeId),
1273     Tuple(HirVec<StructField>, NodeId),
1274     Unit(NodeId),
1275 }
1276
1277 impl VariantData {
1278     pub fn fields(&self) -> &[StructField] {
1279         match *self {
1280             VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
1281             _ => &[],
1282         }
1283     }
1284     pub fn id(&self) -> NodeId {
1285         match *self {
1286             VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
1287         }
1288     }
1289     pub fn is_struct(&self) -> bool {
1290         if let VariantData::Struct(..) = *self {
1291             true
1292         } else {
1293             false
1294         }
1295     }
1296     pub fn is_tuple(&self) -> bool {
1297         if let VariantData::Tuple(..) = *self {
1298             true
1299         } else {
1300             false
1301         }
1302     }
1303     pub fn is_unit(&self) -> bool {
1304         if let VariantData::Unit(..) = *self {
1305             true
1306         } else {
1307             false
1308         }
1309     }
1310 }
1311
1312 // The bodies for items are stored "out of line", in a separate
1313 // hashmap in the `Crate`. Here we just record the node-id of the item
1314 // so it can fetched later.
1315 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1316 pub struct ItemId {
1317     pub id: NodeId,
1318 }
1319
1320 //  FIXME (#3300): Should allow items to be anonymous. Right now
1321 //  we just use dummy names for anon items.
1322 /// An item
1323 ///
1324 /// The name might be a dummy name in case of anonymous items
1325 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1326 pub struct Item {
1327     pub name: Name,
1328     pub attrs: HirVec<Attribute>,
1329     pub id: NodeId,
1330     pub node: Item_,
1331     pub vis: Visibility,
1332     pub span: Span,
1333 }
1334
1335 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1336 pub enum Item_ {
1337     /// An`extern crate` item, with optional original crate name,
1338     ///
1339     /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
1340     ItemExternCrate(Option<Name>),
1341     /// A `use` or `pub use` item
1342     ItemUse(P<ViewPath>),
1343
1344     /// A `static` item
1345     ItemStatic(P<Ty>, Mutability, P<Expr>),
1346     /// A `const` item
1347     ItemConst(P<Ty>, P<Expr>),
1348     /// A function declaration
1349     ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
1350     /// A module
1351     ItemMod(Mod),
1352     /// An external module
1353     ItemForeignMod(ForeignMod),
1354     /// A type alias, e.g. `type Foo = Bar<u8>`
1355     ItemTy(P<Ty>, Generics),
1356     /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
1357     ItemEnum(EnumDef, Generics),
1358     /// A struct definition, e.g. `struct Foo<A> {x: A}`
1359     ItemStruct(VariantData, Generics),
1360     /// Represents a Trait Declaration
1361     ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItem>),
1362
1363     // Default trait implementations
1364     ///
1365     /// `impl Trait for .. {}`
1366     ItemDefaultImpl(Unsafety, TraitRef),
1367     /// An implementation, eg `impl<A> Trait for Foo { .. }`
1368     ItemImpl(Unsafety,
1369              ImplPolarity,
1370              Generics,
1371              Option<TraitRef>, // (optional) trait this impl implements
1372              P<Ty>, // self
1373              HirVec<ImplItem>),
1374 }
1375
1376 impl Item_ {
1377     pub fn descriptive_variant(&self) -> &str {
1378         match *self {
1379             ItemExternCrate(..) => "extern crate",
1380             ItemUse(..) => "use",
1381             ItemStatic(..) => "static item",
1382             ItemConst(..) => "constant item",
1383             ItemFn(..) => "function",
1384             ItemMod(..) => "module",
1385             ItemForeignMod(..) => "foreign module",
1386             ItemTy(..) => "type alias",
1387             ItemEnum(..) => "enum",
1388             ItemStruct(..) => "struct",
1389             ItemTrait(..) => "trait",
1390             ItemImpl(..) |
1391             ItemDefaultImpl(..) => "item",
1392         }
1393     }
1394 }
1395
1396 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1397 pub struct ForeignItem {
1398     pub name: Name,
1399     pub attrs: HirVec<Attribute>,
1400     pub node: ForeignItem_,
1401     pub id: NodeId,
1402     pub span: Span,
1403     pub vis: Visibility,
1404 }
1405
1406 /// An item within an `extern` block
1407 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1408 pub enum ForeignItem_ {
1409     /// A foreign function
1410     ForeignItemFn(P<FnDecl>, Generics),
1411     /// A foreign static item (`static ext: u8`), with optional mutability
1412     /// (the boolean is true when mutable)
1413     ForeignItemStatic(P<Ty>, bool),
1414 }
1415
1416 impl ForeignItem_ {
1417     pub fn descriptive_variant(&self) -> &str {
1418         match *self {
1419             ForeignItemFn(..) => "foreign function",
1420             ForeignItemStatic(..) => "foreign static item",
1421         }
1422     }
1423 }