]> git.lizzy.rs Git - rust.git/blob - src/librustc/hir/mod.rs
1b14caad3c83c0a5b0db044a78d7bb9e76855746
[rust.git] / src / librustc / hir / mod.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::Expr_::*;
19 pub use self::FunctionRetTy::*;
20 pub use self::ForeignItem_::*;
21 pub use self::Item_::*;
22 pub use self::Mutability::*;
23 pub use self::PrimTy::*;
24 pub use self::Stmt_::*;
25 pub use self::Ty_::*;
26 pub use self::TyParamBound::*;
27 pub use self::UnOp::*;
28 pub use self::UnsafeSource::*;
29 pub use self::Visibility::{Public, Inherited};
30 pub use self::PathParameters::*;
31
32 use hir::def::Def;
33 use hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
34 use util::nodemap::{NodeMap, FxHashSet};
35
36 use syntax_pos::{Span, DUMMY_SP};
37 use syntax::codemap::{self, Spanned};
38 use syntax::abi::Abi;
39 use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
40 use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
41 use syntax::ext::hygiene::SyntaxContext;
42 use syntax::ptr::P;
43 use syntax::symbol::{Symbol, keywords};
44 use syntax::tokenstream::TokenStream;
45 use syntax::util::ThinVec;
46
47 use rustc_data_structures::indexed_vec;
48
49 use std::collections::BTreeMap;
50 use std::fmt;
51
52 /// HIR doesn't commit to a concrete storage type and have its own alias for a vector.
53 /// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar
54 /// behavior. Unlike AST, HIR is mostly a static structure, so we can use an owned slice instead
55 /// of `Vec` to avoid keeping extra capacity.
56 pub type HirVec<T> = P<[T]>;
57
58 macro_rules! hir_vec {
59     ($elem:expr; $n:expr) => (
60         $crate::hir::HirVec::from(vec![$elem; $n])
61     );
62     ($($x:expr),*) => (
63         $crate::hir::HirVec::from(vec![$($x),*])
64     );
65     ($($x:expr,)*) => (hir_vec![$($x),*])
66 }
67
68 pub mod check_attr;
69 pub mod def;
70 pub mod def_id;
71 pub mod intravisit;
72 pub mod itemlikevisit;
73 pub mod lowering;
74 pub mod map;
75 pub mod pat_util;
76 pub mod print;
77 pub mod svh;
78
79 /// A HirId uniquely identifies a node in the HIR of then current crate. It is
80 /// composed of the `owner`, which is the DefIndex of the directly enclosing
81 /// hir::Item, hir::TraitItem, or hir::ImplItem (i.e. the closest "item-like"),
82 /// and the `local_id` which is unique within the given owner.
83 ///
84 /// This two-level structure makes for more stable values: One can move an item
85 /// around within the source code, or add or remove stuff before it, without
86 /// the local_id part of the HirId changing, which is a very useful property
87 /// incremental compilation where we have to persist things through changes to
88 /// the code base.
89 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug,
90          RustcEncodable, RustcDecodable)]
91 pub struct HirId {
92     pub owner: DefIndex,
93     pub local_id: ItemLocalId,
94 }
95
96 /// An `ItemLocalId` uniquely identifies something within a given "item-like",
97 /// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
98 /// guarantee that the numerical value of a given `ItemLocalId` corresponds to
99 /// the node's position within the owning item in any way, but there is a
100 /// guarantee that the `LocalItemId`s within an owner occupy a dense range of
101 /// integers starting at zero, so a mapping that maps all or most nodes within
102 /// an "item-like" to something else can be implement by a `Vec` instead of a
103 /// tree or hash map.
104 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug,
105          RustcEncodable, RustcDecodable)]
106 pub struct ItemLocalId(pub u32);
107
108 impl ItemLocalId {
109     pub fn as_usize(&self) -> usize {
110         self.0 as usize
111     }
112 }
113
114 impl indexed_vec::Idx for ItemLocalId {
115     fn new(idx: usize) -> Self {
116         debug_assert!((idx as u32) as usize == idx);
117         ItemLocalId(idx as u32)
118     }
119
120     fn index(self) -> usize {
121         self.0 as usize
122     }
123 }
124
125 /// The `HirId` corresponding to CRATE_NODE_ID and CRATE_DEF_INDEX
126 pub const CRATE_HIR_ID: HirId = HirId {
127     owner: CRATE_DEF_INDEX,
128     local_id: ItemLocalId(0)
129 };
130
131 pub const DUMMY_HIR_ID: HirId = HirId {
132     owner: CRATE_DEF_INDEX,
133     local_id: ItemLocalId(!0)
134 };
135
136 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
137 pub struct Lifetime {
138     pub id: NodeId,
139     pub span: Span,
140
141     /// Either "'a", referring to a named lifetime definition,
142     /// or "" (aka keywords::Invalid), for elision placeholders.
143     ///
144     /// HIR lowering inserts these placeholders in type paths that
145     /// refer to type definitions needing lifetime parameters,
146     /// `&T` and `&mut T`, and trait objects without `... + 'a`.
147     pub name: Name,
148 }
149
150 impl fmt::Debug for Lifetime {
151     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
152         write!(f,
153                "lifetime({}: {})",
154                self.id,
155                print::to_string(print::NO_ANN, |s| s.print_lifetime(self)))
156     }
157 }
158
159 impl Lifetime {
160     pub fn is_elided(&self) -> bool {
161         self.name == keywords::Invalid.name()
162     }
163
164     pub fn is_static(&self) -> bool {
165         self.name == "'static"
166     }
167 }
168
169 /// A lifetime definition, eg `'a: 'b+'c+'d`
170 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
171 pub struct LifetimeDef {
172     pub lifetime: Lifetime,
173     pub bounds: HirVec<Lifetime>,
174     pub pure_wrt_drop: bool,
175 }
176
177 /// A "Path" is essentially Rust's notion of a name; for instance:
178 /// std::cmp::PartialEq  .  It's represented as a sequence of identifiers,
179 /// along with a bunch of supporting information.
180 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
181 pub struct Path {
182     pub span: Span,
183     /// The definition that the path resolved to.
184     pub def: Def,
185     /// The segments in the path: the things separated by `::`.
186     pub segments: HirVec<PathSegment>,
187 }
188
189 impl Path {
190     pub fn is_global(&self) -> bool {
191         !self.segments.is_empty() && self.segments[0].name == keywords::CrateRoot.name()
192     }
193 }
194
195 impl fmt::Debug for Path {
196     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
197         write!(f, "path({})",
198                print::to_string(print::NO_ANN, |s| s.print_path(self, false)))
199     }
200 }
201
202 /// A segment of a path: an identifier, an optional lifetime, and a set of
203 /// types.
204 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
205 pub struct PathSegment {
206     /// The identifier portion of this path segment.
207     pub name: Name,
208
209     /// Type/lifetime parameters attached to this path. They come in
210     /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
211     /// this is more than just simple syntactic sugar; the use of
212     /// parens affects the region binding rules, so we preserve the
213     /// distinction.
214     pub parameters: PathParameters,
215 }
216
217 impl PathSegment {
218     /// Convert an identifier to the corresponding segment.
219     pub fn from_name(name: Name) -> PathSegment {
220         PathSegment {
221             name,
222             parameters: PathParameters::none()
223         }
224     }
225 }
226
227 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
228 pub enum PathParameters {
229     /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
230     AngleBracketedParameters(AngleBracketedParameterData),
231     /// The `(A,B)` and `C` in `Foo(A,B) -> C`
232     ParenthesizedParameters(ParenthesizedParameterData),
233 }
234
235 impl PathParameters {
236     pub fn none() -> PathParameters {
237         AngleBracketedParameters(AngleBracketedParameterData {
238             lifetimes: HirVec::new(),
239             types: HirVec::new(),
240             infer_types: true,
241             bindings: HirVec::new(),
242         })
243     }
244
245     /// Returns the types that the user wrote. Note that these do not necessarily map to the type
246     /// parameters in the parenthesized case.
247     pub fn types(&self) -> HirVec<&P<Ty>> {
248         match *self {
249             AngleBracketedParameters(ref data) => {
250                 data.types.iter().collect()
251             }
252             ParenthesizedParameters(ref data) => {
253                 data.inputs
254                     .iter()
255                     .chain(data.output.iter())
256                     .collect()
257             }
258         }
259     }
260
261     pub fn lifetimes(&self) -> HirVec<&Lifetime> {
262         match *self {
263             AngleBracketedParameters(ref data) => {
264                 data.lifetimes.iter().collect()
265             }
266             ParenthesizedParameters(_) => {
267                 HirVec::new()
268             }
269         }
270     }
271
272     pub fn bindings(&self) -> HirVec<&TypeBinding> {
273         match *self {
274             AngleBracketedParameters(ref data) => {
275                 data.bindings.iter().collect()
276             }
277             ParenthesizedParameters(_) => {
278                 HirVec::new()
279             }
280         }
281     }
282 }
283
284 /// A path like `Foo<'a, T>`
285 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
286 pub struct AngleBracketedParameterData {
287     /// The lifetime parameters for this path segment.
288     pub lifetimes: HirVec<Lifetime>,
289     /// The type parameters for this path segment, if present.
290     pub types: HirVec<P<Ty>>,
291     /// Whether to infer remaining type parameters, if any.
292     /// This only applies to expression and pattern paths, and
293     /// out of those only the segments with no type parameters
294     /// to begin with, e.g. `Vec::new` is `<Vec<..>>::new::<..>`.
295     pub infer_types: bool,
296     /// Bindings (equality constraints) on associated types, if present.
297     /// E.g., `Foo<A=Bar>`.
298     pub bindings: HirVec<TypeBinding>,
299 }
300
301 /// A path like `Foo(A,B) -> C`
302 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
303 pub struct ParenthesizedParameterData {
304     /// Overall span
305     pub span: Span,
306
307     /// `(A,B)`
308     pub inputs: HirVec<P<Ty>>,
309
310     /// `C`
311     pub output: Option<P<Ty>>,
312 }
313
314 /// The AST represents all type param bounds as types.
315 /// typeck::collect::compute_bounds matches these against
316 /// the "special" built-in traits (see middle::lang_items) and
317 /// detects Copy, Send and Sync.
318 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
319 pub enum TyParamBound {
320     TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
321     RegionTyParamBound(Lifetime),
322 }
323
324 /// A modifier on a bound, currently this is only used for `?Sized`, where the
325 /// modifier is `Maybe`. Negative bounds should also be handled here.
326 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
327 pub enum TraitBoundModifier {
328     None,
329     Maybe,
330 }
331
332 pub type TyParamBounds = HirVec<TyParamBound>;
333
334 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
335 pub struct TyParam {
336     pub name: Name,
337     pub id: NodeId,
338     pub bounds: TyParamBounds,
339     pub default: Option<P<Ty>>,
340     pub span: Span,
341     pub pure_wrt_drop: bool,
342 }
343
344 /// Represents lifetimes and type parameters attached to a declaration
345 /// of a function, enum, trait, etc.
346 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
347 pub struct Generics {
348     pub lifetimes: HirVec<LifetimeDef>,
349     pub ty_params: HirVec<TyParam>,
350     pub where_clause: WhereClause,
351     pub span: Span,
352 }
353
354 impl Generics {
355     pub fn empty() -> Generics {
356         Generics {
357             lifetimes: HirVec::new(),
358             ty_params: HirVec::new(),
359             where_clause: WhereClause {
360                 id: DUMMY_NODE_ID,
361                 predicates: HirVec::new(),
362             },
363             span: DUMMY_SP,
364         }
365     }
366
367     pub fn is_lt_parameterized(&self) -> bool {
368         !self.lifetimes.is_empty()
369     }
370
371     pub fn is_type_parameterized(&self) -> bool {
372         !self.ty_params.is_empty()
373     }
374
375     pub fn is_parameterized(&self) -> bool {
376         self.is_lt_parameterized() || self.is_type_parameterized()
377     }
378 }
379
380 pub enum UnsafeGeneric {
381     Region(LifetimeDef, &'static str),
382     Type(TyParam, &'static str),
383 }
384
385 impl UnsafeGeneric {
386     pub fn attr_name(&self) -> &'static str {
387         match *self {
388             UnsafeGeneric::Region(_, s) => s,
389             UnsafeGeneric::Type(_, s) => s,
390         }
391     }
392 }
393
394 impl Generics {
395     pub fn carries_unsafe_attr(&self) -> Option<UnsafeGeneric> {
396         for r in &self.lifetimes {
397             if r.pure_wrt_drop {
398                 return Some(UnsafeGeneric::Region(r.clone(), "may_dangle"));
399             }
400         }
401         for t in &self.ty_params {
402             if t.pure_wrt_drop {
403                 return Some(UnsafeGeneric::Type(t.clone(), "may_dangle"));
404             }
405         }
406         return None;
407     }
408 }
409
410 /// A `where` clause in a definition
411 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
412 pub struct WhereClause {
413     pub id: NodeId,
414     pub predicates: HirVec<WherePredicate>,
415 }
416
417 /// A single predicate in a `where` clause
418 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
419 pub enum WherePredicate {
420     /// A type binding, eg `for<'c> Foo: Send+Clone+'c`
421     BoundPredicate(WhereBoundPredicate),
422     /// A lifetime predicate, e.g. `'a: 'b+'c`
423     RegionPredicate(WhereRegionPredicate),
424     /// An equality predicate (unsupported)
425     EqPredicate(WhereEqPredicate),
426 }
427
428 /// A type bound, eg `for<'c> Foo: Send+Clone+'c`
429 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
430 pub struct WhereBoundPredicate {
431     pub span: Span,
432     /// Any lifetimes from a `for` binding
433     pub bound_lifetimes: HirVec<LifetimeDef>,
434     /// The type being bounded
435     pub bounded_ty: P<Ty>,
436     /// Trait and lifetime bounds (`Clone+Send+'static`)
437     pub bounds: TyParamBounds,
438 }
439
440 /// A lifetime predicate, e.g. `'a: 'b+'c`
441 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
442 pub struct WhereRegionPredicate {
443     pub span: Span,
444     pub lifetime: Lifetime,
445     pub bounds: HirVec<Lifetime>,
446 }
447
448 /// An equality predicate (unsupported), e.g. `T=int`
449 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
450 pub struct WhereEqPredicate {
451     pub id: NodeId,
452     pub span: Span,
453     pub lhs_ty: P<Ty>,
454     pub rhs_ty: P<Ty>,
455 }
456
457 pub type CrateConfig = HirVec<P<MetaItem>>;
458
459 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
460 pub struct Crate {
461     pub module: Mod,
462     pub attrs: HirVec<Attribute>,
463     pub span: Span,
464     pub exported_macros: HirVec<MacroDef>,
465
466     // NB: We use a BTreeMap here so that `visit_all_items` iterates
467     // over the ids in increasing order. In principle it should not
468     // matter what order we visit things in, but in *practice* it
469     // does, because it can affect the order in which errors are
470     // detected, which in turn can make compile-fail tests yield
471     // slightly different results.
472     pub items: BTreeMap<NodeId, Item>,
473
474     pub trait_items: BTreeMap<TraitItemId, TraitItem>,
475     pub impl_items: BTreeMap<ImplItemId, ImplItem>,
476     pub bodies: BTreeMap<BodyId, Body>,
477     pub trait_impls: BTreeMap<DefId, Vec<NodeId>>,
478     pub trait_default_impl: BTreeMap<DefId, NodeId>,
479
480     /// A list of the body ids written out in the order in which they
481     /// appear in the crate. If you're going to process all the bodies
482     /// in the crate, you should iterate over this list rather than the keys
483     /// of bodies.
484     pub body_ids: Vec<BodyId>,
485 }
486
487 impl Crate {
488     pub fn item(&self, id: NodeId) -> &Item {
489         &self.items[&id]
490     }
491
492     pub fn trait_item(&self, id: TraitItemId) -> &TraitItem {
493         &self.trait_items[&id]
494     }
495
496     pub fn impl_item(&self, id: ImplItemId) -> &ImplItem {
497         &self.impl_items[&id]
498     }
499
500     /// Visits all items in the crate in some determinstic (but
501     /// unspecified) order. If you just need to process every item,
502     /// but don't care about nesting, this method is the best choice.
503     ///
504     /// If you do care about nesting -- usually because your algorithm
505     /// follows lexical scoping rules -- then you want a different
506     /// approach. You should override `visit_nested_item` in your
507     /// visitor and then call `intravisit::walk_crate` instead.
508     pub fn visit_all_item_likes<'hir, V>(&'hir self, visitor: &mut V)
509         where V: itemlikevisit::ItemLikeVisitor<'hir>
510     {
511         for (_, item) in &self.items {
512             visitor.visit_item(item);
513         }
514
515         for (_, trait_item) in &self.trait_items {
516             visitor.visit_trait_item(trait_item);
517         }
518
519         for (_, impl_item) in &self.impl_items {
520             visitor.visit_impl_item(impl_item);
521         }
522     }
523
524     pub fn body(&self, id: BodyId) -> &Body {
525         &self.bodies[&id]
526     }
527 }
528
529 /// A macro definition, in this crate or imported from another.
530 ///
531 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
532 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
533 pub struct MacroDef {
534     pub name: Name,
535     pub vis: Visibility,
536     pub attrs: HirVec<Attribute>,
537     pub id: NodeId,
538     pub span: Span,
539     pub body: TokenStream,
540     pub legacy: bool,
541 }
542
543 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
544 pub struct Block {
545     /// Statements in a block
546     pub stmts: HirVec<Stmt>,
547     /// An expression at the end of the block
548     /// without a semicolon, if any
549     pub expr: Option<P<Expr>>,
550     pub id: NodeId,
551     /// Distinguishes between `unsafe { ... }` and `{ ... }`
552     pub rules: BlockCheckMode,
553     pub span: Span,
554     /// If true, then there may exist `break 'a` values that aim to
555     /// break out of this block early. As of this writing, this is not
556     /// currently permitted in Rust itself, but it is generated as
557     /// part of `catch` statements.
558     pub targeted_by_break: bool,
559 }
560
561 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
562 pub struct Pat {
563     pub id: NodeId,
564     pub node: PatKind,
565     pub span: Span,
566 }
567
568 impl fmt::Debug for Pat {
569     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
570         write!(f, "pat({}: {})", self.id,
571                print::to_string(print::NO_ANN, |s| s.print_pat(self)))
572     }
573 }
574
575 impl Pat {
576     // FIXME(#19596) this is a workaround, but there should be a better way
577     fn walk_<G>(&self, it: &mut G) -> bool
578         where G: FnMut(&Pat) -> bool
579     {
580         if !it(self) {
581             return false;
582         }
583
584         match self.node {
585             PatKind::Binding(.., Some(ref p)) => p.walk_(it),
586             PatKind::Struct(_, ref fields, _) => {
587                 fields.iter().all(|field| field.node.pat.walk_(it))
588             }
589             PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => {
590                 s.iter().all(|p| p.walk_(it))
591             }
592             PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
593                 s.walk_(it)
594             }
595             PatKind::Slice(ref before, ref slice, ref after) => {
596                 before.iter().all(|p| p.walk_(it)) &&
597                 slice.iter().all(|p| p.walk_(it)) &&
598                 after.iter().all(|p| p.walk_(it))
599             }
600             PatKind::Wild |
601             PatKind::Lit(_) |
602             PatKind::Range(..) |
603             PatKind::Binding(..) |
604             PatKind::Path(_) => {
605                 true
606             }
607         }
608     }
609
610     pub fn walk<F>(&self, mut it: F) -> bool
611         where F: FnMut(&Pat) -> bool
612     {
613         self.walk_(&mut it)
614     }
615 }
616
617 /// A single field in a struct pattern
618 ///
619 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
620 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
621 /// except is_shorthand is true
622 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
623 pub struct FieldPat {
624     /// The identifier for the field
625     pub name: Name,
626     /// The pattern the field is destructured to
627     pub pat: P<Pat>,
628     pub is_shorthand: bool,
629 }
630
631 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
632 pub enum BindingMode {
633     BindByRef(Mutability),
634     BindByValue(Mutability),
635 }
636
637 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
638 pub enum RangeEnd {
639     Included,
640     Excluded,
641 }
642
643 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
644 pub enum PatKind {
645     /// Represents a wildcard pattern (`_`)
646     Wild,
647
648     /// A fresh binding `ref mut binding @ OPT_SUBPATTERN`.
649     /// The `DefId` is for the definition of the variable being bound.
650     Binding(BindingMode, DefId, Spanned<Name>, Option<P<Pat>>),
651
652     /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
653     /// The `bool` is `true` in the presence of a `..`.
654     Struct(QPath, HirVec<Spanned<FieldPat>>, bool),
655
656     /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
657     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
658     /// 0 <= position <= subpats.len()
659     TupleStruct(QPath, HirVec<P<Pat>>, Option<usize>),
660
661     /// A path pattern for an unit struct/variant or a (maybe-associated) constant.
662     Path(QPath),
663
664     /// A tuple pattern `(a, b)`.
665     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
666     /// 0 <= position <= subpats.len()
667     Tuple(HirVec<P<Pat>>, Option<usize>),
668     /// A `box` pattern
669     Box(P<Pat>),
670     /// A reference pattern, e.g. `&mut (a, b)`
671     Ref(P<Pat>, Mutability),
672     /// A literal
673     Lit(P<Expr>),
674     /// A range pattern, e.g. `1...2` or `1..2`
675     Range(P<Expr>, P<Expr>, RangeEnd),
676     /// `[a, b, ..i, y, z]` is represented as:
677     ///     `PatKind::Slice(box [a, b], Some(i), box [y, z])`
678     Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
679 }
680
681 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
682 pub enum Mutability {
683     MutMutable,
684     MutImmutable,
685 }
686
687 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
688 pub enum BinOp_ {
689     /// The `+` operator (addition)
690     BiAdd,
691     /// The `-` operator (subtraction)
692     BiSub,
693     /// The `*` operator (multiplication)
694     BiMul,
695     /// The `/` operator (division)
696     BiDiv,
697     /// The `%` operator (modulus)
698     BiRem,
699     /// The `&&` operator (logical and)
700     BiAnd,
701     /// The `||` operator (logical or)
702     BiOr,
703     /// The `^` operator (bitwise xor)
704     BiBitXor,
705     /// The `&` operator (bitwise and)
706     BiBitAnd,
707     /// The `|` operator (bitwise or)
708     BiBitOr,
709     /// The `<<` operator (shift left)
710     BiShl,
711     /// The `>>` operator (shift right)
712     BiShr,
713     /// The `==` operator (equality)
714     BiEq,
715     /// The `<` operator (less than)
716     BiLt,
717     /// The `<=` operator (less than or equal to)
718     BiLe,
719     /// The `!=` operator (not equal to)
720     BiNe,
721     /// The `>=` operator (greater than or equal to)
722     BiGe,
723     /// The `>` operator (greater than)
724     BiGt,
725 }
726
727 impl BinOp_ {
728     pub fn as_str(self) -> &'static str {
729         match self {
730             BiAdd => "+",
731             BiSub => "-",
732             BiMul => "*",
733             BiDiv => "/",
734             BiRem => "%",
735             BiAnd => "&&",
736             BiOr => "||",
737             BiBitXor => "^",
738             BiBitAnd => "&",
739             BiBitOr => "|",
740             BiShl => "<<",
741             BiShr => ">>",
742             BiEq => "==",
743             BiLt => "<",
744             BiLe => "<=",
745             BiNe => "!=",
746             BiGe => ">=",
747             BiGt => ">",
748         }
749     }
750
751     pub fn is_lazy(self) -> bool {
752         match self {
753             BiAnd | BiOr => true,
754             _ => false,
755         }
756     }
757
758     pub fn is_shift(self) -> bool {
759         match self {
760             BiShl | BiShr => true,
761             _ => false,
762         }
763     }
764
765     pub fn is_comparison(self) -> bool {
766         match self {
767             BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true,
768             BiAnd |
769             BiOr |
770             BiAdd |
771             BiSub |
772             BiMul |
773             BiDiv |
774             BiRem |
775             BiBitXor |
776             BiBitAnd |
777             BiBitOr |
778             BiShl |
779             BiShr => false,
780         }
781     }
782
783     /// Returns `true` if the binary operator takes its arguments by value
784     pub fn is_by_value(self) -> bool {
785         !self.is_comparison()
786     }
787 }
788
789 pub type BinOp = Spanned<BinOp_>;
790
791 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
792 pub enum UnOp {
793     /// The `*` operator for dereferencing
794     UnDeref,
795     /// The `!` operator for logical inversion
796     UnNot,
797     /// The `-` operator for negation
798     UnNeg,
799 }
800
801 impl UnOp {
802     pub fn as_str(self) -> &'static str {
803         match self {
804             UnDeref => "*",
805             UnNot => "!",
806             UnNeg => "-",
807         }
808     }
809
810     /// Returns `true` if the unary operator takes its argument by value
811     pub fn is_by_value(self) -> bool {
812         match self {
813             UnNeg | UnNot => true,
814             _ => false,
815         }
816     }
817 }
818
819 /// A statement
820 pub type Stmt = Spanned<Stmt_>;
821
822 impl fmt::Debug for Stmt_ {
823     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
824         // Sadness.
825         let spanned = codemap::dummy_spanned(self.clone());
826         write!(f,
827                "stmt({}: {})",
828                spanned.node.id(),
829                print::to_string(print::NO_ANN, |s| s.print_stmt(&spanned)))
830     }
831 }
832
833 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
834 pub enum Stmt_ {
835     /// Could be an item or a local (let) binding:
836     StmtDecl(P<Decl>, NodeId),
837
838     /// Expr without trailing semi-colon (must have unit type):
839     StmtExpr(P<Expr>, NodeId),
840
841     /// Expr with trailing semi-colon (may have any type):
842     StmtSemi(P<Expr>, NodeId),
843 }
844
845 impl Stmt_ {
846     pub fn attrs(&self) -> &[Attribute] {
847         match *self {
848             StmtDecl(ref d, _) => d.node.attrs(),
849             StmtExpr(ref e, _) |
850             StmtSemi(ref e, _) => &e.attrs,
851         }
852     }
853
854     pub fn id(&self) -> NodeId {
855         match *self {
856             StmtDecl(_, id) => id,
857             StmtExpr(_, id) => id,
858             StmtSemi(_, id) => id,
859         }
860     }
861 }
862
863 // FIXME (pending discussion of #1697, #2178...): local should really be
864 // a refinement on pat.
865 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
866 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
867 pub struct Local {
868     pub pat: P<Pat>,
869     pub ty: Option<P<Ty>>,
870     /// Initializer expression to set the value, if any
871     pub init: Option<P<Expr>>,
872     pub id: NodeId,
873     pub span: Span,
874     pub attrs: ThinVec<Attribute>,
875     pub source: LocalSource,
876 }
877
878 pub type Decl = Spanned<Decl_>;
879
880 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
881 pub enum Decl_ {
882     /// A local (let) binding:
883     DeclLocal(P<Local>),
884     /// An item binding:
885     DeclItem(ItemId),
886 }
887
888 impl Decl_ {
889     pub fn attrs(&self) -> &[Attribute] {
890         match *self {
891             DeclLocal(ref l) => &l.attrs,
892             DeclItem(_) => &[]
893         }
894     }
895 }
896
897 /// represents one arm of a 'match'
898 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
899 pub struct Arm {
900     pub attrs: HirVec<Attribute>,
901     pub pats: HirVec<P<Pat>>,
902     pub guard: Option<P<Expr>>,
903     pub body: P<Expr>,
904 }
905
906 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
907 pub struct Field {
908     pub name: Spanned<Name>,
909     pub expr: P<Expr>,
910     pub span: Span,
911     pub is_shorthand: bool,
912 }
913
914 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
915 pub enum BlockCheckMode {
916     DefaultBlock,
917     UnsafeBlock(UnsafeSource),
918     PushUnsafeBlock(UnsafeSource),
919     PopUnsafeBlock(UnsafeSource),
920 }
921
922 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
923 pub enum UnsafeSource {
924     CompilerGenerated,
925     UserProvided,
926 }
927
928 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
929 pub struct BodyId {
930     pub node_id: NodeId,
931 }
932
933 /// The body of a function or constant value.
934 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
935 pub struct Body {
936     pub arguments: HirVec<Arg>,
937     pub value: Expr
938 }
939
940 impl Body {
941     pub fn id(&self) -> BodyId {
942         BodyId {
943             node_id: self.value.id
944         }
945     }
946 }
947
948 /// An expression
949 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
950 pub struct Expr {
951     pub id: NodeId,
952     pub span: Span,
953     pub node: Expr_,
954     pub attrs: ThinVec<Attribute>,
955 }
956
957 impl fmt::Debug for Expr {
958     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
959         write!(f, "expr({}: {})", self.id,
960                print::to_string(print::NO_ANN, |s| s.print_expr(self)))
961     }
962 }
963
964 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
965 pub enum Expr_ {
966     /// A `box x` expression.
967     ExprBox(P<Expr>),
968     /// An array (`[a, b, c, d]`)
969     ExprArray(HirVec<Expr>),
970     /// A function call
971     ///
972     /// The first field resolves to the function itself (usually an `ExprPath`),
973     /// and the second field is the list of arguments
974     ExprCall(P<Expr>, HirVec<Expr>),
975     /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
976     ///
977     /// The `PathSegment`/`Span` represent the method name and its generic arguments
978     /// (within the angle brackets).
979     /// The first element of the vector of `Expr`s is the expression that evaluates
980     /// to the object on which the method is being called on (the receiver),
981     /// and the remaining elements are the rest of the arguments.
982     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
983     /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
984     ExprMethodCall(PathSegment, Span, HirVec<Expr>),
985     /// A tuple (`(a, b, c ,d)`)
986     ExprTup(HirVec<Expr>),
987     /// A binary operation (For example: `a + b`, `a * b`)
988     ExprBinary(BinOp, P<Expr>, P<Expr>),
989     /// A unary operation (For example: `!x`, `*x`)
990     ExprUnary(UnOp, P<Expr>),
991     /// A literal (For example: `1`, `"foo"`)
992     ExprLit(P<Lit>),
993     /// A cast (`foo as f64`)
994     ExprCast(P<Expr>, P<Ty>),
995     ExprType(P<Expr>, P<Ty>),
996     /// An `if` block, with an optional else block
997     ///
998     /// `if expr { expr } else { expr }`
999     ExprIf(P<Expr>, P<Expr>, Option<P<Expr>>),
1000     /// A while loop, with an optional label
1001     ///
1002     /// `'label: while expr { block }`
1003     ExprWhile(P<Expr>, P<Block>, Option<Spanned<Name>>),
1004     /// Conditionless loop (can be exited with break, continue, or return)
1005     ///
1006     /// `'label: loop { block }`
1007     ExprLoop(P<Block>, Option<Spanned<Name>>, LoopSource),
1008     /// A `match` block, with a source that indicates whether or not it is
1009     /// the result of a desugaring, and if so, which kind.
1010     ExprMatch(P<Expr>, HirVec<Arm>, MatchSource),
1011     /// A closure (for example, `move |a, b, c| {a + b + c}`).
1012     ///
1013     /// The final span is the span of the argument block `|...|`
1014     ExprClosure(CaptureClause, P<FnDecl>, BodyId, Span),
1015     /// A block (`{ ... }`)
1016     ExprBlock(P<Block>),
1017
1018     /// An assignment (`a = foo()`)
1019     ExprAssign(P<Expr>, P<Expr>),
1020     /// An assignment with an operator
1021     ///
1022     /// For example, `a += 1`.
1023     ExprAssignOp(BinOp, P<Expr>, P<Expr>),
1024     /// Access of a named struct field (`obj.foo`)
1025     ExprField(P<Expr>, Spanned<Name>),
1026     /// Access of an unnamed field of a struct or tuple-struct
1027     ///
1028     /// For example, `foo.0`.
1029     ExprTupField(P<Expr>, Spanned<usize>),
1030     /// An indexing operation (`foo[2]`)
1031     ExprIndex(P<Expr>, P<Expr>),
1032
1033     /// Path to a definition, possibly containing lifetime or type parameters.
1034     ExprPath(QPath),
1035
1036     /// A referencing operation (`&a` or `&mut a`)
1037     ExprAddrOf(Mutability, P<Expr>),
1038     /// A `break`, with an optional label to break
1039     ExprBreak(Destination, Option<P<Expr>>),
1040     /// A `continue`, with an optional label
1041     ExprAgain(Destination),
1042     /// A `return`, with an optional value to be returned
1043     ExprRet(Option<P<Expr>>),
1044
1045     /// Inline assembly (from `asm!`), with its outputs and inputs.
1046     ExprInlineAsm(P<InlineAsm>, HirVec<Expr>, HirVec<Expr>),
1047
1048     /// A struct or struct-like variant literal expression.
1049     ///
1050     /// For example, `Foo {x: 1, y: 2}`, or
1051     /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
1052     ExprStruct(QPath, HirVec<Field>, Option<P<Expr>>),
1053
1054     /// An array literal constructed from one repeated element.
1055     ///
1056     /// For example, `[1; 5]`. The first expression is the element
1057     /// to be repeated; the second is the number of times to repeat it.
1058     ExprRepeat(P<Expr>, BodyId),
1059 }
1060
1061 /// Optionally `Self`-qualified value/type path or associated extension.
1062 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1063 pub enum QPath {
1064     /// Path to a definition, optionally "fully-qualified" with a `Self`
1065     /// type, if the path points to an associated item in a trait.
1066     ///
1067     /// E.g. an unqualified path like `Clone::clone` has `None` for `Self`,
1068     /// while `<Vec<T> as Clone>::clone` has `Some(Vec<T>)` for `Self`,
1069     /// even though they both have the same two-segment `Clone::clone` `Path`.
1070     Resolved(Option<P<Ty>>, P<Path>),
1071
1072     /// Type-related paths, e.g. `<T>::default` or `<T>::Output`.
1073     /// Will be resolved by type-checking to an associated item.
1074     ///
1075     /// UFCS source paths can desugar into this, with `Vec::new` turning into
1076     /// `<Vec>::new`, and `T::X::Y::method` into `<<<T>::X>::Y>::method`,
1077     /// the `X` and `Y` nodes each being a `TyPath(QPath::TypeRelative(..))`.
1078     TypeRelative(P<Ty>, P<PathSegment>)
1079 }
1080
1081 /// Hints at the original code for a let statement
1082 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1083 pub enum LocalSource {
1084     /// A `match _ { .. }`
1085     Normal,
1086     /// A desugared `for _ in _ { .. }` loop
1087     ForLoopDesugar,
1088 }
1089
1090 /// Hints at the original code for a `match _ { .. }`
1091 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1092 pub enum MatchSource {
1093     /// A `match _ { .. }`
1094     Normal,
1095     /// An `if let _ = _ { .. }` (optionally with `else { .. }`)
1096     IfLetDesugar {
1097         contains_else_clause: bool,
1098     },
1099     /// A `while let _ = _ { .. }` (which was desugared to a
1100     /// `loop { match _ { .. } }`)
1101     WhileLetDesugar,
1102     /// A desugared `for _ in _ { .. }` loop
1103     ForLoopDesugar,
1104     /// A desugared `?` operator
1105     TryDesugar,
1106 }
1107
1108 /// The loop type that yielded an ExprLoop
1109 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1110 pub enum LoopSource {
1111     /// A `loop { .. }` loop
1112     Loop,
1113     /// A `while let _ = _ { .. }` loop
1114     WhileLet,
1115     /// A `for _ in _ { .. }` loop
1116     ForLoop,
1117 }
1118
1119 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1120 pub enum LoopIdError {
1121     OutsideLoopScope,
1122     UnlabeledCfInWhileCondition,
1123     UnresolvedLabel,
1124 }
1125
1126 impl fmt::Display for LoopIdError {
1127     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1128         fmt::Display::fmt(match *self {
1129             LoopIdError::OutsideLoopScope => "not inside loop scope",
1130             LoopIdError::UnlabeledCfInWhileCondition =>
1131                 "unlabeled control flow (break or continue) in while condition",
1132             LoopIdError::UnresolvedLabel => "label not found",
1133         }, f)
1134     }
1135 }
1136
1137 // FIXME(cramertj) this should use `Result` once master compiles w/ a vesion of Rust where
1138 // `Result` implements `Encodable`/`Decodable`
1139 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1140 pub enum LoopIdResult {
1141     Ok(NodeId),
1142     Err(LoopIdError),
1143 }
1144 impl Into<Result<NodeId, LoopIdError>> for LoopIdResult {
1145     fn into(self) -> Result<NodeId, LoopIdError> {
1146         match self {
1147             LoopIdResult::Ok(ok) => Ok(ok),
1148             LoopIdResult::Err(err) => Err(err),
1149         }
1150     }
1151 }
1152 impl From<Result<NodeId, LoopIdError>> for LoopIdResult {
1153     fn from(res: Result<NodeId, LoopIdError>) -> Self {
1154         match res {
1155             Ok(ok) => LoopIdResult::Ok(ok),
1156             Err(err) => LoopIdResult::Err(err),
1157         }
1158     }
1159 }
1160
1161 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1162 pub enum ScopeTarget {
1163     Block(NodeId),
1164     Loop(LoopIdResult),
1165 }
1166
1167 impl ScopeTarget {
1168     pub fn opt_id(self) -> Option<NodeId> {
1169         match self {
1170             ScopeTarget::Block(node_id) |
1171             ScopeTarget::Loop(LoopIdResult::Ok(node_id)) => Some(node_id),
1172             ScopeTarget::Loop(LoopIdResult::Err(_)) => None,
1173         }
1174     }
1175 }
1176
1177 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1178 pub struct Destination {
1179     // This is `Some(_)` iff there is an explicit user-specified `label
1180     pub ident: Option<Spanned<Ident>>,
1181
1182     // These errors are caught and then reported during the diagnostics pass in
1183     // librustc_passes/loops.rs
1184     pub target_id: ScopeTarget,
1185 }
1186
1187 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1188 pub enum CaptureClause {
1189     CaptureByValue,
1190     CaptureByRef,
1191 }
1192
1193 // NB: If you change this, you'll probably want to change the corresponding
1194 // type structure in middle/ty.rs as well.
1195 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1196 pub struct MutTy {
1197     pub ty: P<Ty>,
1198     pub mutbl: Mutability,
1199 }
1200
1201 /// Represents a method's signature in a trait declaration or implementation.
1202 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1203 pub struct MethodSig {
1204     pub unsafety: Unsafety,
1205     pub constness: Constness,
1206     pub abi: Abi,
1207     pub decl: P<FnDecl>,
1208     pub generics: Generics,
1209 }
1210
1211 // The bodies for items are stored "out of line", in a separate
1212 // hashmap in the `Crate`. Here we just record the node-id of the item
1213 // so it can fetched later.
1214 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1215 pub struct TraitItemId {
1216     pub node_id: NodeId,
1217 }
1218
1219 /// Represents an item declaration within a trait declaration,
1220 /// possibly including a default implementation. A trait item is
1221 /// either required (meaning it doesn't have an implementation, just a
1222 /// signature) or provided (meaning it has a default implementation).
1223 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1224 pub struct TraitItem {
1225     pub id: NodeId,
1226     pub name: Name,
1227     pub attrs: HirVec<Attribute>,
1228     pub node: TraitItemKind,
1229     pub span: Span,
1230 }
1231
1232 /// A trait method's body (or just argument names).
1233 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1234 pub enum TraitMethod {
1235     /// No default body in the trait, just a signature.
1236     Required(HirVec<Spanned<Name>>),
1237
1238     /// Both signature and body are provided in the trait.
1239     Provided(BodyId),
1240 }
1241
1242 /// Represents a trait method or associated constant or type
1243 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1244 pub enum TraitItemKind {
1245     /// An associated constant with an optional value (otherwise `impl`s
1246     /// must contain a value)
1247     Const(P<Ty>, Option<BodyId>),
1248     /// A method with an optional body
1249     Method(MethodSig, TraitMethod),
1250     /// An associated type with (possibly empty) bounds and optional concrete
1251     /// type
1252     Type(TyParamBounds, Option<P<Ty>>),
1253 }
1254
1255 // The bodies for items are stored "out of line", in a separate
1256 // hashmap in the `Crate`. Here we just record the node-id of the item
1257 // so it can fetched later.
1258 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1259 pub struct ImplItemId {
1260     pub node_id: NodeId,
1261 }
1262
1263 /// Represents anything within an `impl` block
1264 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1265 pub struct ImplItem {
1266     pub id: NodeId,
1267     pub name: Name,
1268     pub vis: Visibility,
1269     pub defaultness: Defaultness,
1270     pub attrs: HirVec<Attribute>,
1271     pub node: ImplItemKind,
1272     pub span: Span,
1273 }
1274
1275 /// Represents different contents within `impl`s
1276 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1277 pub enum ImplItemKind {
1278     /// An associated constant of the given type, set to the constant result
1279     /// of the expression
1280     Const(P<Ty>, BodyId),
1281     /// A method implementation with the given signature and body
1282     Method(MethodSig, BodyId),
1283     /// An associated type
1284     Type(P<Ty>),
1285 }
1286
1287 // Bind a type to an associated type: `A=Foo`.
1288 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1289 pub struct TypeBinding {
1290     pub id: NodeId,
1291     pub name: Name,
1292     pub ty: P<Ty>,
1293     pub span: Span,
1294 }
1295
1296
1297 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1298 pub struct Ty {
1299     pub id: NodeId,
1300     pub node: Ty_,
1301     pub span: Span,
1302 }
1303
1304 impl fmt::Debug for Ty {
1305     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1306         write!(f, "type({})",
1307                print::to_string(print::NO_ANN, |s| s.print_type(self)))
1308     }
1309 }
1310
1311 /// Not represented directly in the AST, referred to by name through a ty_path.
1312 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1313 pub enum PrimTy {
1314     TyInt(IntTy),
1315     TyUint(UintTy),
1316     TyFloat(FloatTy),
1317     TyStr,
1318     TyBool,
1319     TyChar,
1320 }
1321
1322 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1323 pub struct BareFnTy {
1324     pub unsafety: Unsafety,
1325     pub abi: Abi,
1326     pub lifetimes: HirVec<LifetimeDef>,
1327     pub decl: P<FnDecl>,
1328 }
1329
1330 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1331 /// The different kinds of types recognized by the compiler
1332 pub enum Ty_ {
1333     /// A variable length slice (`[T]`)
1334     TySlice(P<Ty>),
1335     /// A fixed length array (`[T; n]`)
1336     TyArray(P<Ty>, BodyId),
1337     /// A raw pointer (`*const T` or `*mut T`)
1338     TyPtr(MutTy),
1339     /// A reference (`&'a T` or `&'a mut T`)
1340     TyRptr(Lifetime, MutTy),
1341     /// A bare function (e.g. `fn(usize) -> bool`)
1342     TyBareFn(P<BareFnTy>),
1343     /// The never type (`!`)
1344     TyNever,
1345     /// A tuple (`(A, B, C, D,...)`)
1346     TyTup(HirVec<P<Ty>>),
1347     /// A path to a type definition (`module::module::...::Type`), or an
1348     /// associated type, e.g. `<Vec<T> as Trait>::Type` or `<T>::Target`.
1349     ///
1350     /// Type parameters may be stored in each `PathSegment`.
1351     TyPath(QPath),
1352     /// A trait object type `Bound1 + Bound2 + Bound3`
1353     /// where `Bound` is a trait or a lifetime.
1354     TyTraitObject(HirVec<PolyTraitRef>, Lifetime),
1355     /// An `impl Bound1 + Bound2 + Bound3` type
1356     /// where `Bound` is a trait or a lifetime.
1357     TyImplTrait(TyParamBounds),
1358     /// Unused for now
1359     TyTypeof(BodyId),
1360     /// TyInfer means the type should be inferred instead of it having been
1361     /// specified. This can appear anywhere in a type.
1362     TyInfer,
1363     /// Placeholder for a type that has failed to be defined.
1364     TyErr,
1365 }
1366
1367 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1368 pub struct InlineAsmOutput {
1369     pub constraint: Symbol,
1370     pub is_rw: bool,
1371     pub is_indirect: bool,
1372 }
1373
1374 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1375 pub struct InlineAsm {
1376     pub asm: Symbol,
1377     pub asm_str_style: StrStyle,
1378     pub outputs: HirVec<InlineAsmOutput>,
1379     pub inputs: HirVec<Symbol>,
1380     pub clobbers: HirVec<Symbol>,
1381     pub volatile: bool,
1382     pub alignstack: bool,
1383     pub dialect: AsmDialect,
1384     pub ctxt: SyntaxContext,
1385 }
1386
1387 /// represents an argument in a function header
1388 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1389 pub struct Arg {
1390     pub pat: P<Pat>,
1391     pub id: NodeId,
1392 }
1393
1394 /// Represents the header (not the body) of a function declaration
1395 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1396 pub struct FnDecl {
1397     pub inputs: HirVec<P<Ty>>,
1398     pub output: FunctionRetTy,
1399     pub variadic: bool,
1400     /// True if this function has an `self`, `&self` or `&mut self` receiver
1401     /// (but not a `self: Xxx` one).
1402     pub has_implicit_self: bool,
1403 }
1404
1405 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1406 pub enum Unsafety {
1407     Unsafe,
1408     Normal,
1409 }
1410
1411 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1412 pub enum Constness {
1413     Const,
1414     NotConst,
1415 }
1416
1417 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1418 pub enum Defaultness {
1419     Default { has_value: bool },
1420     Final,
1421 }
1422
1423 impl Defaultness {
1424     pub fn has_value(&self) -> bool {
1425         match *self {
1426             Defaultness::Default { has_value, .. } => has_value,
1427             Defaultness::Final => true,
1428         }
1429     }
1430
1431     pub fn is_final(&self) -> bool {
1432         *self == Defaultness::Final
1433     }
1434
1435     pub fn is_default(&self) -> bool {
1436         match *self {
1437             Defaultness::Default { .. } => true,
1438             _ => false,
1439         }
1440     }
1441 }
1442
1443 impl fmt::Display for Unsafety {
1444     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1445         fmt::Display::fmt(match *self {
1446                               Unsafety::Normal => "normal",
1447                               Unsafety::Unsafe => "unsafe",
1448                           },
1449                           f)
1450     }
1451 }
1452
1453 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1454 pub enum ImplPolarity {
1455     /// `impl Trait for Type`
1456     Positive,
1457     /// `impl !Trait for Type`
1458     Negative,
1459 }
1460
1461 impl fmt::Debug for ImplPolarity {
1462     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1463         match *self {
1464             ImplPolarity::Positive => "positive".fmt(f),
1465             ImplPolarity::Negative => "negative".fmt(f),
1466         }
1467     }
1468 }
1469
1470
1471 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1472 pub enum FunctionRetTy {
1473     /// Return type is not specified.
1474     ///
1475     /// Functions default to `()` and
1476     /// closures default to inference. Span points to where return
1477     /// type would be inserted.
1478     DefaultReturn(Span),
1479     /// Everything else
1480     Return(P<Ty>),
1481 }
1482
1483 impl FunctionRetTy {
1484     pub fn span(&self) -> Span {
1485         match *self {
1486             DefaultReturn(span) => span,
1487             Return(ref ty) => ty.span,
1488         }
1489     }
1490 }
1491
1492 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1493 pub struct Mod {
1494     /// A span from the first token past `{` to the last token until `}`.
1495     /// For `mod foo;`, the inner span ranges from the first token
1496     /// to the last token in the external file.
1497     pub inner: Span,
1498     pub item_ids: HirVec<ItemId>,
1499 }
1500
1501 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1502 pub struct ForeignMod {
1503     pub abi: Abi,
1504     pub items: HirVec<ForeignItem>,
1505 }
1506
1507 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1508 pub struct GlobalAsm {
1509     pub asm: Symbol,
1510     pub ctxt: SyntaxContext,
1511 }
1512
1513 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1514 pub struct EnumDef {
1515     pub variants: HirVec<Variant>,
1516 }
1517
1518 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1519 pub struct Variant_ {
1520     pub name: Name,
1521     pub attrs: HirVec<Attribute>,
1522     pub data: VariantData,
1523     /// Explicit discriminant, eg `Foo = 1`
1524     pub disr_expr: Option<BodyId>,
1525 }
1526
1527 pub type Variant = Spanned<Variant_>;
1528
1529 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1530 pub enum UseKind {
1531     /// One import, e.g. `use foo::bar` or `use foo::bar as baz`.
1532     /// Also produced for each element of a list `use`, e.g.
1533     // `use foo::{a, b}` lowers to `use foo::a; use foo::b;`.
1534     Single,
1535
1536     /// Glob import, e.g. `use foo::*`.
1537     Glob,
1538
1539     /// Degenerate list import, e.g. `use foo::{a, b}` produces
1540     /// an additional `use foo::{}` for performing checks such as
1541     /// unstable feature gating. May be removed in the future.
1542     ListStem,
1543 }
1544
1545 /// TraitRef's appear in impls.
1546 ///
1547 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1548 /// that the ref_id is for. Note that ref_id's value is not the NodeId of the
1549 /// trait being referred to but just a unique NodeId that serves as a key
1550 /// within the DefMap.
1551 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1552 pub struct TraitRef {
1553     pub path: Path,
1554     pub ref_id: NodeId,
1555 }
1556
1557 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1558 pub struct PolyTraitRef {
1559     /// The `'a` in `<'a> Foo<&'a T>`
1560     pub bound_lifetimes: HirVec<LifetimeDef>,
1561
1562     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1563     pub trait_ref: TraitRef,
1564
1565     pub span: Span,
1566 }
1567
1568 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1569 pub enum Visibility {
1570     Public,
1571     Crate,
1572     Restricted { path: P<Path>, id: NodeId },
1573     Inherited,
1574 }
1575
1576 impl Visibility {
1577     pub fn is_pub_restricted(&self) -> bool {
1578         use self::Visibility::*;
1579         match self {
1580             &Public |
1581             &Inherited => false,
1582             &Crate |
1583             &Restricted { .. } => true,
1584         }
1585     }
1586 }
1587
1588 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1589 pub struct StructField {
1590     pub span: Span,
1591     pub name: Name,
1592     pub vis: Visibility,
1593     pub id: NodeId,
1594     pub ty: P<Ty>,
1595     pub attrs: HirVec<Attribute>,
1596 }
1597
1598 impl StructField {
1599     // Still necessary in couple of places
1600     pub fn is_positional(&self) -> bool {
1601         let first = self.name.as_str().as_bytes()[0];
1602         first >= b'0' && first <= b'9'
1603     }
1604 }
1605
1606 /// Fields and Ids of enum variants and structs
1607 ///
1608 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1609 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1610 /// One shared Id can be successfully used for these two purposes.
1611 /// Id of the whole enum lives in `Item`.
1612 ///
1613 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
1614 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
1615 /// the variant itself" from enum variants.
1616 /// Id of the whole struct lives in `Item`.
1617 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1618 pub enum VariantData {
1619     Struct(HirVec<StructField>, NodeId),
1620     Tuple(HirVec<StructField>, NodeId),
1621     Unit(NodeId),
1622 }
1623
1624 impl VariantData {
1625     pub fn fields(&self) -> &[StructField] {
1626         match *self {
1627             VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
1628             _ => &[],
1629         }
1630     }
1631     pub fn id(&self) -> NodeId {
1632         match *self {
1633             VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
1634         }
1635     }
1636     pub fn is_struct(&self) -> bool {
1637         if let VariantData::Struct(..) = *self {
1638             true
1639         } else {
1640             false
1641         }
1642     }
1643     pub fn is_tuple(&self) -> bool {
1644         if let VariantData::Tuple(..) = *self {
1645             true
1646         } else {
1647             false
1648         }
1649     }
1650     pub fn is_unit(&self) -> bool {
1651         if let VariantData::Unit(..) = *self {
1652             true
1653         } else {
1654             false
1655         }
1656     }
1657 }
1658
1659 // The bodies for items are stored "out of line", in a separate
1660 // hashmap in the `Crate`. Here we just record the node-id of the item
1661 // so it can fetched later.
1662 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1663 pub struct ItemId {
1664     pub id: NodeId,
1665 }
1666
1667 /// An item
1668 ///
1669 /// The name might be a dummy name in case of anonymous items
1670 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1671 pub struct Item {
1672     pub name: Name,
1673     pub attrs: HirVec<Attribute>,
1674     pub id: NodeId,
1675     pub node: Item_,
1676     pub vis: Visibility,
1677     pub span: Span,
1678 }
1679
1680 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1681 pub enum Item_ {
1682     /// An `extern crate` item, with optional original crate name,
1683     ///
1684     /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
1685     ItemExternCrate(Option<Name>),
1686
1687     /// `use foo::bar::*;` or `use foo::bar::baz as quux;`
1688     ///
1689     /// or just
1690     ///
1691     /// `use foo::bar::baz;` (with `as baz` implicitly on the right)
1692     ItemUse(P<Path>, UseKind),
1693
1694     /// A `static` item
1695     ItemStatic(P<Ty>, Mutability, BodyId),
1696     /// A `const` item
1697     ItemConst(P<Ty>, BodyId),
1698     /// A function declaration
1699     ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, BodyId),
1700     /// A module
1701     ItemMod(Mod),
1702     /// An external module
1703     ItemForeignMod(ForeignMod),
1704     /// Module-level inline assembly (from global_asm!)
1705     ItemGlobalAsm(P<GlobalAsm>),
1706     /// A type alias, e.g. `type Foo = Bar<u8>`
1707     ItemTy(P<Ty>, Generics),
1708     /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
1709     ItemEnum(EnumDef, Generics),
1710     /// A struct definition, e.g. `struct Foo<A> {x: A}`
1711     ItemStruct(VariantData, Generics),
1712     /// A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
1713     ItemUnion(VariantData, Generics),
1714     /// Represents a Trait Declaration
1715     ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
1716
1717     // Default trait implementations
1718     ///
1719     /// `impl Trait for .. {}`
1720     ItemDefaultImpl(Unsafety, TraitRef),
1721     /// An implementation, eg `impl<A> Trait for Foo { .. }`
1722     ItemImpl(Unsafety,
1723              ImplPolarity,
1724              Defaultness,
1725              Generics,
1726              Option<TraitRef>, // (optional) trait this impl implements
1727              P<Ty>, // self
1728              HirVec<ImplItemRef>),
1729 }
1730
1731 impl Item_ {
1732     pub fn descriptive_variant(&self) -> &str {
1733         match *self {
1734             ItemExternCrate(..) => "extern crate",
1735             ItemUse(..) => "use",
1736             ItemStatic(..) => "static item",
1737             ItemConst(..) => "constant item",
1738             ItemFn(..) => "function",
1739             ItemMod(..) => "module",
1740             ItemForeignMod(..) => "foreign module",
1741             ItemGlobalAsm(..) => "global asm",
1742             ItemTy(..) => "type alias",
1743             ItemEnum(..) => "enum",
1744             ItemStruct(..) => "struct",
1745             ItemUnion(..) => "union",
1746             ItemTrait(..) => "trait",
1747             ItemImpl(..) |
1748             ItemDefaultImpl(..) => "item",
1749         }
1750     }
1751 }
1752
1753 /// A reference from an trait to one of its associated items. This
1754 /// contains the item's id, naturally, but also the item's name and
1755 /// some other high-level details (like whether it is an associated
1756 /// type or method, and whether it is public). This allows other
1757 /// passes to find the impl they want without loading the id (which
1758 /// means fewer edges in the incremental compilation graph).
1759 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1760 pub struct TraitItemRef {
1761     pub id: TraitItemId,
1762     pub name: Name,
1763     pub kind: AssociatedItemKind,
1764     pub span: Span,
1765     pub defaultness: Defaultness,
1766 }
1767
1768 /// A reference from an impl to one of its associated items. This
1769 /// contains the item's id, naturally, but also the item's name and
1770 /// some other high-level details (like whether it is an associated
1771 /// type or method, and whether it is public). This allows other
1772 /// passes to find the impl they want without loading the id (which
1773 /// means fewer edges in the incremental compilation graph).
1774 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1775 pub struct ImplItemRef {
1776     pub id: ImplItemId,
1777     pub name: Name,
1778     pub kind: AssociatedItemKind,
1779     pub span: Span,
1780     pub vis: Visibility,
1781     pub defaultness: Defaultness,
1782 }
1783
1784 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1785 pub enum AssociatedItemKind {
1786     Const,
1787     Method { has_self: bool },
1788     Type,
1789 }
1790
1791 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1792 pub struct ForeignItem {
1793     pub name: Name,
1794     pub attrs: HirVec<Attribute>,
1795     pub node: ForeignItem_,
1796     pub id: NodeId,
1797     pub span: Span,
1798     pub vis: Visibility,
1799 }
1800
1801 /// An item within an `extern` block
1802 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1803 pub enum ForeignItem_ {
1804     /// A foreign function
1805     ForeignItemFn(P<FnDecl>, HirVec<Spanned<Name>>, Generics),
1806     /// A foreign static item (`static ext: u8`), with optional mutability
1807     /// (the boolean is true when mutable)
1808     ForeignItemStatic(P<Ty>, bool),
1809 }
1810
1811 impl ForeignItem_ {
1812     pub fn descriptive_variant(&self) -> &str {
1813         match *self {
1814             ForeignItemFn(..) => "foreign function",
1815             ForeignItemStatic(..) => "foreign static item",
1816         }
1817     }
1818 }
1819
1820 /// A free variable referred to in a function.
1821 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
1822 pub struct Freevar {
1823     /// The variable being accessed free.
1824     pub def: Def,
1825
1826     // First span where it is accessed (there can be multiple).
1827     pub span: Span
1828 }
1829
1830 pub type FreevarMap = NodeMap<Vec<Freevar>>;
1831
1832 pub type CaptureModeMap = NodeMap<CaptureClause>;
1833
1834 #[derive(Clone, Debug)]
1835 pub struct TraitCandidate {
1836     pub def_id: DefId,
1837     pub import_id: Option<NodeId>,
1838 }
1839
1840 // Trait method resolution
1841 pub type TraitMap = NodeMap<Vec<TraitCandidate>>;
1842
1843 // Map from the NodeId of a glob import to a list of items which are actually
1844 // imported.
1845 pub type GlobMap = NodeMap<FxHashSet<Name>>;