]> git.lizzy.rs Git - rust.git/blob - src/librustc/hir/mod.rs
Auto merge of #42394 - ollie27:rustdoc_deref_box, r=QuietMisdreavus
[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: 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::<Bar, Baz>(a, b, c, d)`)
976     ///
977     /// The `Spanned<Name>` is the identifier for the method name.
978     /// The vector of `Ty`s are the ascripted type parameters for the method
979     /// (within the angle brackets).
980     ///
981     /// The first element of the vector of `Expr`s is the expression that
982     /// evaluates to the object on which the method is being called on (the
983     /// receiver), and the remaining elements are the rest of the arguments.
984     ///
985     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
986     /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
987     ExprMethodCall(Spanned<Name>, HirVec<P<Ty>>, HirVec<Expr>),
988     /// A tuple (`(a, b, c ,d)`)
989     ExprTup(HirVec<Expr>),
990     /// A binary operation (For example: `a + b`, `a * b`)
991     ExprBinary(BinOp, P<Expr>, P<Expr>),
992     /// A unary operation (For example: `!x`, `*x`)
993     ExprUnary(UnOp, P<Expr>),
994     /// A literal (For example: `1`, `"foo"`)
995     ExprLit(P<Lit>),
996     /// A cast (`foo as f64`)
997     ExprCast(P<Expr>, P<Ty>),
998     ExprType(P<Expr>, P<Ty>),
999     /// An `if` block, with an optional else block
1000     ///
1001     /// `if expr { expr } else { expr }`
1002     ExprIf(P<Expr>, P<Expr>, Option<P<Expr>>),
1003     /// A while loop, with an optional label
1004     ///
1005     /// `'label: while expr { block }`
1006     ExprWhile(P<Expr>, P<Block>, Option<Spanned<Name>>),
1007     /// Conditionless loop (can be exited with break, continue, or return)
1008     ///
1009     /// `'label: loop { block }`
1010     ExprLoop(P<Block>, Option<Spanned<Name>>, LoopSource),
1011     /// A `match` block, with a source that indicates whether or not it is
1012     /// the result of a desugaring, and if so, which kind.
1013     ExprMatch(P<Expr>, HirVec<Arm>, MatchSource),
1014     /// A closure (for example, `move |a, b, c| {a + b + c}`).
1015     ///
1016     /// The final span is the span of the argument block `|...|`
1017     ExprClosure(CaptureClause, P<FnDecl>, BodyId, Span),
1018     /// A block (`{ ... }`)
1019     ExprBlock(P<Block>),
1020
1021     /// An assignment (`a = foo()`)
1022     ExprAssign(P<Expr>, P<Expr>),
1023     /// An assignment with an operator
1024     ///
1025     /// For example, `a += 1`.
1026     ExprAssignOp(BinOp, P<Expr>, P<Expr>),
1027     /// Access of a named struct field (`obj.foo`)
1028     ExprField(P<Expr>, Spanned<Name>),
1029     /// Access of an unnamed field of a struct or tuple-struct
1030     ///
1031     /// For example, `foo.0`.
1032     ExprTupField(P<Expr>, Spanned<usize>),
1033     /// An indexing operation (`foo[2]`)
1034     ExprIndex(P<Expr>, P<Expr>),
1035
1036     /// Path to a definition, possibly containing lifetime or type parameters.
1037     ExprPath(QPath),
1038
1039     /// A referencing operation (`&a` or `&mut a`)
1040     ExprAddrOf(Mutability, P<Expr>),
1041     /// A `break`, with an optional label to break
1042     ExprBreak(Destination, Option<P<Expr>>),
1043     /// A `continue`, with an optional label
1044     ExprAgain(Destination),
1045     /// A `return`, with an optional value to be returned
1046     ExprRet(Option<P<Expr>>),
1047
1048     /// Inline assembly (from `asm!`), with its outputs and inputs.
1049     ExprInlineAsm(P<InlineAsm>, HirVec<Expr>, HirVec<Expr>),
1050
1051     /// A struct or struct-like variant literal expression.
1052     ///
1053     /// For example, `Foo {x: 1, y: 2}`, or
1054     /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
1055     ExprStruct(QPath, HirVec<Field>, Option<P<Expr>>),
1056
1057     /// An array literal constructed from one repeated element.
1058     ///
1059     /// For example, `[1; 5]`. The first expression is the element
1060     /// to be repeated; the second is the number of times to repeat it.
1061     ExprRepeat(P<Expr>, BodyId),
1062 }
1063
1064 /// Optionally `Self`-qualified value/type path or associated extension.
1065 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1066 pub enum QPath {
1067     /// Path to a definition, optionally "fully-qualified" with a `Self`
1068     /// type, if the path points to an associated item in a trait.
1069     ///
1070     /// E.g. an unqualified path like `Clone::clone` has `None` for `Self`,
1071     /// while `<Vec<T> as Clone>::clone` has `Some(Vec<T>)` for `Self`,
1072     /// even though they both have the same two-segment `Clone::clone` `Path`.
1073     Resolved(Option<P<Ty>>, P<Path>),
1074
1075     /// Type-related paths, e.g. `<T>::default` or `<T>::Output`.
1076     /// Will be resolved by type-checking to an associated item.
1077     ///
1078     /// UFCS source paths can desugar into this, with `Vec::new` turning into
1079     /// `<Vec>::new`, and `T::X::Y::method` into `<<<T>::X>::Y>::method`,
1080     /// the `X` and `Y` nodes each being a `TyPath(QPath::TypeRelative(..))`.
1081     TypeRelative(P<Ty>, P<PathSegment>)
1082 }
1083
1084 /// Hints at the original code for a let statement
1085 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1086 pub enum LocalSource {
1087     /// A `match _ { .. }`
1088     Normal,
1089     /// A desugared `for _ in _ { .. }` loop
1090     ForLoopDesugar,
1091 }
1092
1093 /// Hints at the original code for a `match _ { .. }`
1094 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1095 pub enum MatchSource {
1096     /// A `match _ { .. }`
1097     Normal,
1098     /// An `if let _ = _ { .. }` (optionally with `else { .. }`)
1099     IfLetDesugar {
1100         contains_else_clause: bool,
1101     },
1102     /// A `while let _ = _ { .. }` (which was desugared to a
1103     /// `loop { match _ { .. } }`)
1104     WhileLetDesugar,
1105     /// A desugared `for _ in _ { .. }` loop
1106     ForLoopDesugar,
1107     /// A desugared `?` operator
1108     TryDesugar,
1109 }
1110
1111 /// The loop type that yielded an ExprLoop
1112 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1113 pub enum LoopSource {
1114     /// A `loop { .. }` loop
1115     Loop,
1116     /// A `while let _ = _ { .. }` loop
1117     WhileLet,
1118     /// A `for _ in _ { .. }` loop
1119     ForLoop,
1120 }
1121
1122 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1123 pub enum LoopIdError {
1124     OutsideLoopScope,
1125     UnlabeledCfInWhileCondition,
1126     UnresolvedLabel,
1127 }
1128
1129 impl fmt::Display for LoopIdError {
1130     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1131         fmt::Display::fmt(match *self {
1132             LoopIdError::OutsideLoopScope => "not inside loop scope",
1133             LoopIdError::UnlabeledCfInWhileCondition =>
1134                 "unlabeled control flow (break or continue) in while condition",
1135             LoopIdError::UnresolvedLabel => "label not found",
1136         }, f)
1137     }
1138 }
1139
1140 // FIXME(cramertj) this should use `Result` once master compiles w/ a vesion of Rust where
1141 // `Result` implements `Encodable`/`Decodable`
1142 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1143 pub enum LoopIdResult {
1144     Ok(NodeId),
1145     Err(LoopIdError),
1146 }
1147 impl Into<Result<NodeId, LoopIdError>> for LoopIdResult {
1148     fn into(self) -> Result<NodeId, LoopIdError> {
1149         match self {
1150             LoopIdResult::Ok(ok) => Ok(ok),
1151             LoopIdResult::Err(err) => Err(err),
1152         }
1153     }
1154 }
1155 impl From<Result<NodeId, LoopIdError>> for LoopIdResult {
1156     fn from(res: Result<NodeId, LoopIdError>) -> Self {
1157         match res {
1158             Ok(ok) => LoopIdResult::Ok(ok),
1159             Err(err) => LoopIdResult::Err(err),
1160         }
1161     }
1162 }
1163
1164 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1165 pub enum ScopeTarget {
1166     Block(NodeId),
1167     Loop(LoopIdResult),
1168 }
1169
1170 impl ScopeTarget {
1171     pub fn opt_id(self) -> Option<NodeId> {
1172         match self {
1173             ScopeTarget::Block(node_id) |
1174             ScopeTarget::Loop(LoopIdResult::Ok(node_id)) => Some(node_id),
1175             ScopeTarget::Loop(LoopIdResult::Err(_)) => None,
1176         }
1177     }
1178 }
1179
1180 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1181 pub struct Destination {
1182     // This is `Some(_)` iff there is an explicit user-specified `label
1183     pub ident: Option<Spanned<Ident>>,
1184
1185     // These errors are caught and then reported during the diagnostics pass in
1186     // librustc_passes/loops.rs
1187     pub target_id: ScopeTarget,
1188 }
1189
1190 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1191 pub enum CaptureClause {
1192     CaptureByValue,
1193     CaptureByRef,
1194 }
1195
1196 // NB: If you change this, you'll probably want to change the corresponding
1197 // type structure in middle/ty.rs as well.
1198 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1199 pub struct MutTy {
1200     pub ty: P<Ty>,
1201     pub mutbl: Mutability,
1202 }
1203
1204 /// Represents a method's signature in a trait declaration or implementation.
1205 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1206 pub struct MethodSig {
1207     pub unsafety: Unsafety,
1208     pub constness: Constness,
1209     pub abi: Abi,
1210     pub decl: P<FnDecl>,
1211     pub generics: Generics,
1212 }
1213
1214 // The bodies for items are stored "out of line", in a separate
1215 // hashmap in the `Crate`. Here we just record the node-id of the item
1216 // so it can fetched later.
1217 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1218 pub struct TraitItemId {
1219     pub node_id: NodeId,
1220 }
1221
1222 /// Represents an item declaration within a trait declaration,
1223 /// possibly including a default implementation. A trait item is
1224 /// either required (meaning it doesn't have an implementation, just a
1225 /// signature) or provided (meaning it has a default implementation).
1226 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1227 pub struct TraitItem {
1228     pub id: NodeId,
1229     pub name: Name,
1230     pub attrs: HirVec<Attribute>,
1231     pub node: TraitItemKind,
1232     pub span: Span,
1233 }
1234
1235 /// A trait method's body (or just argument names).
1236 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1237 pub enum TraitMethod {
1238     /// No default body in the trait, just a signature.
1239     Required(HirVec<Spanned<Name>>),
1240
1241     /// Both signature and body are provided in the trait.
1242     Provided(BodyId),
1243 }
1244
1245 /// Represents a trait method or associated constant or type
1246 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1247 pub enum TraitItemKind {
1248     /// An associated constant with an optional value (otherwise `impl`s
1249     /// must contain a value)
1250     Const(P<Ty>, Option<BodyId>),
1251     /// A method with an optional body
1252     Method(MethodSig, TraitMethod),
1253     /// An associated type with (possibly empty) bounds and optional concrete
1254     /// type
1255     Type(TyParamBounds, Option<P<Ty>>),
1256 }
1257
1258 // The bodies for items are stored "out of line", in a separate
1259 // hashmap in the `Crate`. Here we just record the node-id of the item
1260 // so it can fetched later.
1261 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1262 pub struct ImplItemId {
1263     pub node_id: NodeId,
1264 }
1265
1266 /// Represents anything within an `impl` block
1267 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1268 pub struct ImplItem {
1269     pub id: NodeId,
1270     pub name: Name,
1271     pub vis: Visibility,
1272     pub defaultness: Defaultness,
1273     pub attrs: HirVec<Attribute>,
1274     pub node: ImplItemKind,
1275     pub span: Span,
1276 }
1277
1278 /// Represents different contents within `impl`s
1279 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1280 pub enum ImplItemKind {
1281     /// An associated constant of the given type, set to the constant result
1282     /// of the expression
1283     Const(P<Ty>, BodyId),
1284     /// A method implementation with the given signature and body
1285     Method(MethodSig, BodyId),
1286     /// An associated type
1287     Type(P<Ty>),
1288 }
1289
1290 // Bind a type to an associated type: `A=Foo`.
1291 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1292 pub struct TypeBinding {
1293     pub id: NodeId,
1294     pub name: Name,
1295     pub ty: P<Ty>,
1296     pub span: Span,
1297 }
1298
1299
1300 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1301 pub struct Ty {
1302     pub id: NodeId,
1303     pub node: Ty_,
1304     pub span: Span,
1305 }
1306
1307 impl fmt::Debug for Ty {
1308     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1309         write!(f, "type({})",
1310                print::to_string(print::NO_ANN, |s| s.print_type(self)))
1311     }
1312 }
1313
1314 /// Not represented directly in the AST, referred to by name through a ty_path.
1315 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1316 pub enum PrimTy {
1317     TyInt(IntTy),
1318     TyUint(UintTy),
1319     TyFloat(FloatTy),
1320     TyStr,
1321     TyBool,
1322     TyChar,
1323 }
1324
1325 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1326 pub struct BareFnTy {
1327     pub unsafety: Unsafety,
1328     pub abi: Abi,
1329     pub lifetimes: HirVec<LifetimeDef>,
1330     pub decl: P<FnDecl>,
1331 }
1332
1333 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1334 /// The different kinds of types recognized by the compiler
1335 pub enum Ty_ {
1336     /// A variable length slice (`[T]`)
1337     TySlice(P<Ty>),
1338     /// A fixed length array (`[T; n]`)
1339     TyArray(P<Ty>, BodyId),
1340     /// A raw pointer (`*const T` or `*mut T`)
1341     TyPtr(MutTy),
1342     /// A reference (`&'a T` or `&'a mut T`)
1343     TyRptr(Lifetime, MutTy),
1344     /// A bare function (e.g. `fn(usize) -> bool`)
1345     TyBareFn(P<BareFnTy>),
1346     /// The never type (`!`)
1347     TyNever,
1348     /// A tuple (`(A, B, C, D,...)`)
1349     TyTup(HirVec<P<Ty>>),
1350     /// A path to a type definition (`module::module::...::Type`), or an
1351     /// associated type, e.g. `<Vec<T> as Trait>::Type` or `<T>::Target`.
1352     ///
1353     /// Type parameters may be stored in each `PathSegment`.
1354     TyPath(QPath),
1355     /// A trait object type `Bound1 + Bound2 + Bound3`
1356     /// where `Bound` is a trait or a lifetime.
1357     TyTraitObject(HirVec<PolyTraitRef>, Lifetime),
1358     /// An `impl Bound1 + Bound2 + Bound3` type
1359     /// where `Bound` is a trait or a lifetime.
1360     TyImplTrait(TyParamBounds),
1361     /// Unused for now
1362     TyTypeof(BodyId),
1363     /// TyInfer means the type should be inferred instead of it having been
1364     /// specified. This can appear anywhere in a type.
1365     TyInfer,
1366     /// Placeholder for a type that has failed to be defined.
1367     TyErr,
1368 }
1369
1370 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1371 pub struct InlineAsmOutput {
1372     pub constraint: Symbol,
1373     pub is_rw: bool,
1374     pub is_indirect: bool,
1375 }
1376
1377 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1378 pub struct InlineAsm {
1379     pub asm: Symbol,
1380     pub asm_str_style: StrStyle,
1381     pub outputs: HirVec<InlineAsmOutput>,
1382     pub inputs: HirVec<Symbol>,
1383     pub clobbers: HirVec<Symbol>,
1384     pub volatile: bool,
1385     pub alignstack: bool,
1386     pub dialect: AsmDialect,
1387     pub ctxt: SyntaxContext,
1388 }
1389
1390 /// represents an argument in a function header
1391 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1392 pub struct Arg {
1393     pub pat: P<Pat>,
1394     pub id: NodeId,
1395 }
1396
1397 /// Represents the header (not the body) of a function declaration
1398 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1399 pub struct FnDecl {
1400     pub inputs: HirVec<P<Ty>>,
1401     pub output: FunctionRetTy,
1402     pub variadic: bool,
1403     /// True if this function has an `self`, `&self` or `&mut self` receiver
1404     /// (but not a `self: Xxx` one).
1405     pub has_implicit_self: bool,
1406 }
1407
1408 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1409 pub enum Unsafety {
1410     Unsafe,
1411     Normal,
1412 }
1413
1414 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1415 pub enum Constness {
1416     Const,
1417     NotConst,
1418 }
1419
1420 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1421 pub enum Defaultness {
1422     Default { has_value: bool },
1423     Final,
1424 }
1425
1426 impl Defaultness {
1427     pub fn has_value(&self) -> bool {
1428         match *self {
1429             Defaultness::Default { has_value, .. } => has_value,
1430             Defaultness::Final => true,
1431         }
1432     }
1433
1434     pub fn is_final(&self) -> bool {
1435         *self == Defaultness::Final
1436     }
1437
1438     pub fn is_default(&self) -> bool {
1439         match *self {
1440             Defaultness::Default { .. } => true,
1441             _ => false,
1442         }
1443     }
1444 }
1445
1446 impl fmt::Display for Unsafety {
1447     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1448         fmt::Display::fmt(match *self {
1449                               Unsafety::Normal => "normal",
1450                               Unsafety::Unsafe => "unsafe",
1451                           },
1452                           f)
1453     }
1454 }
1455
1456 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1457 pub enum ImplPolarity {
1458     /// `impl Trait for Type`
1459     Positive,
1460     /// `impl !Trait for Type`
1461     Negative,
1462 }
1463
1464 impl fmt::Debug for ImplPolarity {
1465     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1466         match *self {
1467             ImplPolarity::Positive => "positive".fmt(f),
1468             ImplPolarity::Negative => "negative".fmt(f),
1469         }
1470     }
1471 }
1472
1473
1474 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1475 pub enum FunctionRetTy {
1476     /// Return type is not specified.
1477     ///
1478     /// Functions default to `()` and
1479     /// closures default to inference. Span points to where return
1480     /// type would be inserted.
1481     DefaultReturn(Span),
1482     /// Everything else
1483     Return(P<Ty>),
1484 }
1485
1486 impl FunctionRetTy {
1487     pub fn span(&self) -> Span {
1488         match *self {
1489             DefaultReturn(span) => span,
1490             Return(ref ty) => ty.span,
1491         }
1492     }
1493 }
1494
1495 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1496 pub struct Mod {
1497     /// A span from the first token past `{` to the last token until `}`.
1498     /// For `mod foo;`, the inner span ranges from the first token
1499     /// to the last token in the external file.
1500     pub inner: Span,
1501     pub item_ids: HirVec<ItemId>,
1502 }
1503
1504 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1505 pub struct ForeignMod {
1506     pub abi: Abi,
1507     pub items: HirVec<ForeignItem>,
1508 }
1509
1510 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1511 pub struct GlobalAsm {
1512     pub asm: Symbol,
1513     pub ctxt: SyntaxContext,
1514 }
1515
1516 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1517 pub struct EnumDef {
1518     pub variants: HirVec<Variant>,
1519 }
1520
1521 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1522 pub struct Variant_ {
1523     pub name: Name,
1524     pub attrs: HirVec<Attribute>,
1525     pub data: VariantData,
1526     /// Explicit discriminant, eg `Foo = 1`
1527     pub disr_expr: Option<BodyId>,
1528 }
1529
1530 pub type Variant = Spanned<Variant_>;
1531
1532 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1533 pub enum UseKind {
1534     /// One import, e.g. `use foo::bar` or `use foo::bar as baz`.
1535     /// Also produced for each element of a list `use`, e.g.
1536     // `use foo::{a, b}` lowers to `use foo::a; use foo::b;`.
1537     Single,
1538
1539     /// Glob import, e.g. `use foo::*`.
1540     Glob,
1541
1542     /// Degenerate list import, e.g. `use foo::{a, b}` produces
1543     /// an additional `use foo::{}` for performing checks such as
1544     /// unstable feature gating. May be removed in the future.
1545     ListStem,
1546 }
1547
1548 /// TraitRef's appear in impls.
1549 ///
1550 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1551 /// that the ref_id is for. Note that ref_id's value is not the NodeId of the
1552 /// trait being referred to but just a unique NodeId that serves as a key
1553 /// within the DefMap.
1554 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1555 pub struct TraitRef {
1556     pub path: Path,
1557     pub ref_id: NodeId,
1558 }
1559
1560 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1561 pub struct PolyTraitRef {
1562     /// The `'a` in `<'a> Foo<&'a T>`
1563     pub bound_lifetimes: HirVec<LifetimeDef>,
1564
1565     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1566     pub trait_ref: TraitRef,
1567
1568     pub span: Span,
1569 }
1570
1571 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1572 pub enum Visibility {
1573     Public,
1574     Crate,
1575     Restricted { path: P<Path>, id: NodeId },
1576     Inherited,
1577 }
1578
1579 impl Visibility {
1580     pub fn is_pub_restricted(&self) -> bool {
1581         use self::Visibility::*;
1582         match self {
1583             &Public |
1584             &Inherited => false,
1585             &Crate |
1586             &Restricted { .. } => true,
1587         }
1588     }
1589 }
1590
1591 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1592 pub struct StructField {
1593     pub span: Span,
1594     pub name: Name,
1595     pub vis: Visibility,
1596     pub id: NodeId,
1597     pub ty: P<Ty>,
1598     pub attrs: HirVec<Attribute>,
1599 }
1600
1601 impl StructField {
1602     // Still necessary in couple of places
1603     pub fn is_positional(&self) -> bool {
1604         let first = self.name.as_str().as_bytes()[0];
1605         first >= b'0' && first <= b'9'
1606     }
1607 }
1608
1609 /// Fields and Ids of enum variants and structs
1610 ///
1611 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1612 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1613 /// One shared Id can be successfully used for these two purposes.
1614 /// Id of the whole enum lives in `Item`.
1615 ///
1616 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
1617 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
1618 /// the variant itself" from enum variants.
1619 /// Id of the whole struct lives in `Item`.
1620 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1621 pub enum VariantData {
1622     Struct(HirVec<StructField>, NodeId),
1623     Tuple(HirVec<StructField>, NodeId),
1624     Unit(NodeId),
1625 }
1626
1627 impl VariantData {
1628     pub fn fields(&self) -> &[StructField] {
1629         match *self {
1630             VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
1631             _ => &[],
1632         }
1633     }
1634     pub fn id(&self) -> NodeId {
1635         match *self {
1636             VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
1637         }
1638     }
1639     pub fn is_struct(&self) -> bool {
1640         if let VariantData::Struct(..) = *self {
1641             true
1642         } else {
1643             false
1644         }
1645     }
1646     pub fn is_tuple(&self) -> bool {
1647         if let VariantData::Tuple(..) = *self {
1648             true
1649         } else {
1650             false
1651         }
1652     }
1653     pub fn is_unit(&self) -> bool {
1654         if let VariantData::Unit(..) = *self {
1655             true
1656         } else {
1657             false
1658         }
1659     }
1660 }
1661
1662 // The bodies for items are stored "out of line", in a separate
1663 // hashmap in the `Crate`. Here we just record the node-id of the item
1664 // so it can fetched later.
1665 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1666 pub struct ItemId {
1667     pub id: NodeId,
1668 }
1669
1670 /// An item
1671 ///
1672 /// The name might be a dummy name in case of anonymous items
1673 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1674 pub struct Item {
1675     pub name: Name,
1676     pub attrs: HirVec<Attribute>,
1677     pub id: NodeId,
1678     pub node: Item_,
1679     pub vis: Visibility,
1680     pub span: Span,
1681 }
1682
1683 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1684 pub enum Item_ {
1685     /// An`extern crate` item, with optional original crate name,
1686     ///
1687     /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
1688     ItemExternCrate(Option<Name>),
1689
1690     /// `use foo::bar::*;` or `use foo::bar::baz as quux;`
1691     ///
1692     /// or just
1693     ///
1694     /// `use foo::bar::baz;` (with `as baz` implicitly on the right)
1695     ItemUse(P<Path>, UseKind),
1696
1697     /// A `static` item
1698     ItemStatic(P<Ty>, Mutability, BodyId),
1699     /// A `const` item
1700     ItemConst(P<Ty>, BodyId),
1701     /// A function declaration
1702     ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, BodyId),
1703     /// A module
1704     ItemMod(Mod),
1705     /// An external module
1706     ItemForeignMod(ForeignMod),
1707     /// Module-level inline assembly (from global_asm!)
1708     ItemGlobalAsm(P<GlobalAsm>),
1709     /// A type alias, e.g. `type Foo = Bar<u8>`
1710     ItemTy(P<Ty>, Generics),
1711     /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
1712     ItemEnum(EnumDef, Generics),
1713     /// A struct definition, e.g. `struct Foo<A> {x: A}`
1714     ItemStruct(VariantData, Generics),
1715     /// A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
1716     ItemUnion(VariantData, Generics),
1717     /// Represents a Trait Declaration
1718     ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
1719
1720     // Default trait implementations
1721     ///
1722     /// `impl Trait for .. {}`
1723     ItemDefaultImpl(Unsafety, TraitRef),
1724     /// An implementation, eg `impl<A> Trait for Foo { .. }`
1725     ItemImpl(Unsafety,
1726              ImplPolarity,
1727              Defaultness,
1728              Generics,
1729              Option<TraitRef>, // (optional) trait this impl implements
1730              P<Ty>, // self
1731              HirVec<ImplItemRef>),
1732 }
1733
1734 impl Item_ {
1735     pub fn descriptive_variant(&self) -> &str {
1736         match *self {
1737             ItemExternCrate(..) => "extern crate",
1738             ItemUse(..) => "use",
1739             ItemStatic(..) => "static item",
1740             ItemConst(..) => "constant item",
1741             ItemFn(..) => "function",
1742             ItemMod(..) => "module",
1743             ItemForeignMod(..) => "foreign module",
1744             ItemGlobalAsm(..) => "global asm",
1745             ItemTy(..) => "type alias",
1746             ItemEnum(..) => "enum",
1747             ItemStruct(..) => "struct",
1748             ItemUnion(..) => "union",
1749             ItemTrait(..) => "trait",
1750             ItemImpl(..) |
1751             ItemDefaultImpl(..) => "item",
1752         }
1753     }
1754 }
1755
1756 /// A reference from an trait to one of its associated items. This
1757 /// contains the item's id, naturally, but also the item's name and
1758 /// some other high-level details (like whether it is an associated
1759 /// type or method, and whether it is public). This allows other
1760 /// passes to find the impl they want without loading the id (which
1761 /// means fewer edges in the incremental compilation graph).
1762 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1763 pub struct TraitItemRef {
1764     pub id: TraitItemId,
1765     pub name: Name,
1766     pub kind: AssociatedItemKind,
1767     pub span: Span,
1768     pub defaultness: Defaultness,
1769 }
1770
1771 /// A reference from an impl to one of its associated items. This
1772 /// contains the item's id, naturally, but also the item's name and
1773 /// some other high-level details (like whether it is an associated
1774 /// type or method, and whether it is public). This allows other
1775 /// passes to find the impl they want without loading the id (which
1776 /// means fewer edges in the incremental compilation graph).
1777 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1778 pub struct ImplItemRef {
1779     pub id: ImplItemId,
1780     pub name: Name,
1781     pub kind: AssociatedItemKind,
1782     pub span: Span,
1783     pub vis: Visibility,
1784     pub defaultness: Defaultness,
1785 }
1786
1787 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1788 pub enum AssociatedItemKind {
1789     Const,
1790     Method { has_self: bool },
1791     Type,
1792 }
1793
1794 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1795 pub struct ForeignItem {
1796     pub name: Name,
1797     pub attrs: HirVec<Attribute>,
1798     pub node: ForeignItem_,
1799     pub id: NodeId,
1800     pub span: Span,
1801     pub vis: Visibility,
1802 }
1803
1804 /// An item within an `extern` block
1805 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1806 pub enum ForeignItem_ {
1807     /// A foreign function
1808     ForeignItemFn(P<FnDecl>, HirVec<Spanned<Name>>, Generics),
1809     /// A foreign static item (`static ext: u8`), with optional mutability
1810     /// (the boolean is true when mutable)
1811     ForeignItemStatic(P<Ty>, bool),
1812 }
1813
1814 impl ForeignItem_ {
1815     pub fn descriptive_variant(&self) -> &str {
1816         match *self {
1817             ForeignItemFn(..) => "foreign function",
1818             ForeignItemStatic(..) => "foreign static item",
1819         }
1820     }
1821 }
1822
1823 /// A free variable referred to in a function.
1824 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
1825 pub struct Freevar {
1826     /// The variable being accessed free.
1827     pub def: Def,
1828
1829     // First span where it is accessed (there can be multiple).
1830     pub span: Span
1831 }
1832
1833 pub type FreevarMap = NodeMap<Vec<Freevar>>;
1834
1835 pub type CaptureModeMap = NodeMap<CaptureClause>;
1836
1837 #[derive(Clone, Debug)]
1838 pub struct TraitCandidate {
1839     pub def_id: DefId,
1840     pub import_id: Option<NodeId>,
1841 }
1842
1843 // Trait method resolution
1844 pub type TraitMap = NodeMap<Vec<TraitCandidate>>;
1845
1846 // Map from the NodeId of a glob import to a list of items which are actually
1847 // imported.
1848 pub type GlobMap = NodeMap<FxHashSet<Name>>;