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