]> git.lizzy.rs Git - rust.git/blob - src/librustc/hir/mod.rs
Auto merge of #41282 - arielb1:missing-impl-item, r=petrochenkov
[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 == keywords::StaticLifetime.name()
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 attrs: HirVec<Attribute>,
536     pub id: NodeId,
537     pub span: Span,
538     pub body: TokenStream,
539 }
540
541 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
542 pub struct Block {
543     /// Statements in a block
544     pub stmts: HirVec<Stmt>,
545     /// An expression at the end of the block
546     /// without a semicolon, if any
547     pub expr: Option<P<Expr>>,
548     pub id: NodeId,
549     /// Distinguishes between `unsafe { ... }` and `{ ... }`
550     pub rules: BlockCheckMode,
551     pub span: Span,
552     /// If true, then there may exist `break 'a` values that aim to
553     /// break out of this block early. As of this writing, this is not
554     /// currently permitted in Rust itself, but it is generated as
555     /// part of `catch` statements.
556     pub targeted_by_break: bool,
557 }
558
559 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
560 pub struct Pat {
561     pub id: NodeId,
562     pub node: PatKind,
563     pub span: Span,
564 }
565
566 impl fmt::Debug for Pat {
567     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
568         write!(f, "pat({}: {})", self.id,
569                print::to_string(print::NO_ANN, |s| s.print_pat(self)))
570     }
571 }
572
573 impl Pat {
574     // FIXME(#19596) this is a workaround, but there should be a better way
575     fn walk_<G>(&self, it: &mut G) -> bool
576         where G: FnMut(&Pat) -> bool
577     {
578         if !it(self) {
579             return false;
580         }
581
582         match self.node {
583             PatKind::Binding(.., Some(ref p)) => p.walk_(it),
584             PatKind::Struct(_, ref fields, _) => {
585                 fields.iter().all(|field| field.node.pat.walk_(it))
586             }
587             PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => {
588                 s.iter().all(|p| p.walk_(it))
589             }
590             PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
591                 s.walk_(it)
592             }
593             PatKind::Slice(ref before, ref slice, ref after) => {
594                 before.iter().all(|p| p.walk_(it)) &&
595                 slice.iter().all(|p| p.walk_(it)) &&
596                 after.iter().all(|p| p.walk_(it))
597             }
598             PatKind::Wild |
599             PatKind::Lit(_) |
600             PatKind::Range(..) |
601             PatKind::Binding(..) |
602             PatKind::Path(_) => {
603                 true
604             }
605         }
606     }
607
608     pub fn walk<F>(&self, mut it: F) -> bool
609         where F: FnMut(&Pat) -> bool
610     {
611         self.walk_(&mut it)
612     }
613 }
614
615 /// A single field in a struct pattern
616 ///
617 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
618 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
619 /// except is_shorthand is true
620 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
621 pub struct FieldPat {
622     /// The identifier for the field
623     pub name: Name,
624     /// The pattern the field is destructured to
625     pub pat: P<Pat>,
626     pub is_shorthand: bool,
627 }
628
629 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
630 pub enum BindingMode {
631     BindByRef(Mutability),
632     BindByValue(Mutability),
633 }
634
635 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
636 pub enum RangeEnd {
637     Included,
638     Excluded,
639 }
640
641 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
642 pub enum PatKind {
643     /// Represents a wildcard pattern (`_`)
644     Wild,
645
646     /// A fresh binding `ref mut binding @ OPT_SUBPATTERN`.
647     /// The `DefId` is for the definition of the variable being bound.
648     Binding(BindingMode, DefId, Spanned<Name>, Option<P<Pat>>),
649
650     /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
651     /// The `bool` is `true` in the presence of a `..`.
652     Struct(QPath, HirVec<Spanned<FieldPat>>, bool),
653
654     /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
655     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
656     /// 0 <= position <= subpats.len()
657     TupleStruct(QPath, HirVec<P<Pat>>, Option<usize>),
658
659     /// A path pattern for an unit struct/variant or a (maybe-associated) constant.
660     Path(QPath),
661
662     /// A tuple pattern `(a, b)`.
663     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
664     /// 0 <= position <= subpats.len()
665     Tuple(HirVec<P<Pat>>, Option<usize>),
666     /// A `box` pattern
667     Box(P<Pat>),
668     /// A reference pattern, e.g. `&mut (a, b)`
669     Ref(P<Pat>, Mutability),
670     /// A literal
671     Lit(P<Expr>),
672     /// A range pattern, e.g. `1...2` or `1..2`
673     Range(P<Expr>, P<Expr>, RangeEnd),
674     /// `[a, b, ..i, y, z]` is represented as:
675     ///     `PatKind::Slice(box [a, b], Some(i), box [y, z])`
676     Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
677 }
678
679 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
680 pub enum Mutability {
681     MutMutable,
682     MutImmutable,
683 }
684
685 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
686 pub enum BinOp_ {
687     /// The `+` operator (addition)
688     BiAdd,
689     /// The `-` operator (subtraction)
690     BiSub,
691     /// The `*` operator (multiplication)
692     BiMul,
693     /// The `/` operator (division)
694     BiDiv,
695     /// The `%` operator (modulus)
696     BiRem,
697     /// The `&&` operator (logical and)
698     BiAnd,
699     /// The `||` operator (logical or)
700     BiOr,
701     /// The `^` operator (bitwise xor)
702     BiBitXor,
703     /// The `&` operator (bitwise and)
704     BiBitAnd,
705     /// The `|` operator (bitwise or)
706     BiBitOr,
707     /// The `<<` operator (shift left)
708     BiShl,
709     /// The `>>` operator (shift right)
710     BiShr,
711     /// The `==` operator (equality)
712     BiEq,
713     /// The `<` operator (less than)
714     BiLt,
715     /// The `<=` operator (less than or equal to)
716     BiLe,
717     /// The `!=` operator (not equal to)
718     BiNe,
719     /// The `>=` operator (greater than or equal to)
720     BiGe,
721     /// The `>` operator (greater than)
722     BiGt,
723 }
724
725 impl BinOp_ {
726     pub fn as_str(self) -> &'static str {
727         match self {
728             BiAdd => "+",
729             BiSub => "-",
730             BiMul => "*",
731             BiDiv => "/",
732             BiRem => "%",
733             BiAnd => "&&",
734             BiOr => "||",
735             BiBitXor => "^",
736             BiBitAnd => "&",
737             BiBitOr => "|",
738             BiShl => "<<",
739             BiShr => ">>",
740             BiEq => "==",
741             BiLt => "<",
742             BiLe => "<=",
743             BiNe => "!=",
744             BiGe => ">=",
745             BiGt => ">",
746         }
747     }
748
749     pub fn is_lazy(self) -> bool {
750         match self {
751             BiAnd | BiOr => true,
752             _ => false,
753         }
754     }
755
756     pub fn is_shift(self) -> bool {
757         match self {
758             BiShl | BiShr => true,
759             _ => false,
760         }
761     }
762
763     pub fn is_comparison(self) -> bool {
764         match self {
765             BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true,
766             BiAnd |
767             BiOr |
768             BiAdd |
769             BiSub |
770             BiMul |
771             BiDiv |
772             BiRem |
773             BiBitXor |
774             BiBitAnd |
775             BiBitOr |
776             BiShl |
777             BiShr => false,
778         }
779     }
780
781     /// Returns `true` if the binary operator takes its arguments by value
782     pub fn is_by_value(self) -> bool {
783         !self.is_comparison()
784     }
785 }
786
787 pub type BinOp = Spanned<BinOp_>;
788
789 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
790 pub enum UnOp {
791     /// The `*` operator for dereferencing
792     UnDeref,
793     /// The `!` operator for logical inversion
794     UnNot,
795     /// The `-` operator for negation
796     UnNeg,
797 }
798
799 impl UnOp {
800     pub fn as_str(self) -> &'static str {
801         match self {
802             UnDeref => "*",
803             UnNot => "!",
804             UnNeg => "-",
805         }
806     }
807
808     /// Returns `true` if the unary operator takes its argument by value
809     pub fn is_by_value(self) -> bool {
810         match self {
811             UnNeg | UnNot => true,
812             _ => false,
813         }
814     }
815 }
816
817 /// A statement
818 pub type Stmt = Spanned<Stmt_>;
819
820 impl fmt::Debug for Stmt_ {
821     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
822         // Sadness.
823         let spanned = codemap::dummy_spanned(self.clone());
824         write!(f,
825                "stmt({}: {})",
826                spanned.node.id(),
827                print::to_string(print::NO_ANN, |s| s.print_stmt(&spanned)))
828     }
829 }
830
831 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
832 pub enum Stmt_ {
833     /// Could be an item or a local (let) binding:
834     StmtDecl(P<Decl>, NodeId),
835
836     /// Expr without trailing semi-colon (must have unit type):
837     StmtExpr(P<Expr>, NodeId),
838
839     /// Expr with trailing semi-colon (may have any type):
840     StmtSemi(P<Expr>, NodeId),
841 }
842
843 impl Stmt_ {
844     pub fn attrs(&self) -> &[Attribute] {
845         match *self {
846             StmtDecl(ref d, _) => d.node.attrs(),
847             StmtExpr(ref e, _) |
848             StmtSemi(ref e, _) => &e.attrs,
849         }
850     }
851
852     pub fn id(&self) -> NodeId {
853         match *self {
854             StmtDecl(_, id) => id,
855             StmtExpr(_, id) => id,
856             StmtSemi(_, id) => id,
857         }
858     }
859 }
860
861 // FIXME (pending discussion of #1697, #2178...): local should really be
862 // a refinement on pat.
863 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
864 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
865 pub struct Local {
866     pub pat: P<Pat>,
867     pub ty: Option<P<Ty>>,
868     /// Initializer expression to set the value, if any
869     pub init: Option<P<Expr>>,
870     pub id: NodeId,
871     pub span: Span,
872     pub attrs: ThinVec<Attribute>,
873 }
874
875 pub type Decl = Spanned<Decl_>;
876
877 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
878 pub enum Decl_ {
879     /// A local (let) binding:
880     DeclLocal(P<Local>),
881     /// An item binding:
882     DeclItem(ItemId),
883 }
884
885 impl Decl_ {
886     pub fn attrs(&self) -> &[Attribute] {
887         match *self {
888             DeclLocal(ref l) => &l.attrs,
889             DeclItem(_) => &[]
890         }
891     }
892 }
893
894 /// represents one arm of a 'match'
895 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
896 pub struct Arm {
897     pub attrs: HirVec<Attribute>,
898     pub pats: HirVec<P<Pat>>,
899     pub guard: Option<P<Expr>>,
900     pub body: P<Expr>,
901 }
902
903 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
904 pub struct Field {
905     pub name: Spanned<Name>,
906     pub expr: P<Expr>,
907     pub span: Span,
908     pub is_shorthand: bool,
909 }
910
911 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
912 pub enum BlockCheckMode {
913     DefaultBlock,
914     UnsafeBlock(UnsafeSource),
915     PushUnsafeBlock(UnsafeSource),
916     PopUnsafeBlock(UnsafeSource),
917 }
918
919 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
920 pub enum UnsafeSource {
921     CompilerGenerated,
922     UserProvided,
923 }
924
925 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
926 pub struct BodyId {
927     pub node_id: NodeId,
928 }
929
930 /// The body of a function or constant value.
931 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
932 pub struct Body {
933     pub arguments: HirVec<Arg>,
934     pub value: Expr
935 }
936
937 impl Body {
938     pub fn id(&self) -> BodyId {
939         BodyId {
940             node_id: self.value.id
941         }
942     }
943 }
944
945 /// An expression
946 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
947 pub struct Expr {
948     pub id: NodeId,
949     pub span: Span,
950     pub node: Expr_,
951     pub attrs: ThinVec<Attribute>,
952 }
953
954 impl fmt::Debug for Expr {
955     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
956         write!(f, "expr({}: {})", self.id,
957                print::to_string(print::NO_ANN, |s| s.print_expr(self)))
958     }
959 }
960
961 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
962 pub enum Expr_ {
963     /// A `box x` expression.
964     ExprBox(P<Expr>),
965     /// An array (`[a, b, c, d]`)
966     ExprArray(HirVec<Expr>),
967     /// A function call
968     ///
969     /// The first field resolves to the function itself (usually an `ExprPath`),
970     /// and the second field is the list of arguments
971     ExprCall(P<Expr>, HirVec<Expr>),
972     /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
973     ///
974     /// The `Spanned<Name>` is the identifier for the method name.
975     /// The vector of `Ty`s are the ascripted type parameters for the method
976     /// (within the angle brackets).
977     ///
978     /// The first element of the vector of `Expr`s is the expression that
979     /// evaluates to the object on which the method is being called on (the
980     /// receiver), and the remaining elements are the rest of the arguments.
981     ///
982     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
983     /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
984     ExprMethodCall(Spanned<Name>, HirVec<P<Ty>>, 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 `match _ { .. }`
1082 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1083 pub enum MatchSource {
1084     /// A `match _ { .. }`
1085     Normal,
1086     /// An `if let _ = _ { .. }` (optionally with `else { .. }`)
1087     IfLetDesugar {
1088         contains_else_clause: bool,
1089     },
1090     /// A `while let _ = _ { .. }` (which was desugared to a
1091     /// `loop { match _ { .. } }`)
1092     WhileLetDesugar,
1093     /// A desugared `for _ in _ { .. }` loop
1094     ForLoopDesugar,
1095     /// A desugared `?` operator
1096     TryDesugar,
1097 }
1098
1099 /// The loop type that yielded an ExprLoop
1100 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1101 pub enum LoopSource {
1102     /// A `loop { .. }` loop
1103     Loop,
1104     /// A `while let _ = _ { .. }` loop
1105     WhileLet,
1106     /// A `for _ in _ { .. }` loop
1107     ForLoop,
1108 }
1109
1110 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1111 pub enum LoopIdError {
1112     OutsideLoopScope,
1113     UnlabeledCfInWhileCondition,
1114     UnresolvedLabel,
1115 }
1116
1117 impl fmt::Display for LoopIdError {
1118     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1119         fmt::Display::fmt(match *self {
1120             LoopIdError::OutsideLoopScope => "not inside loop scope",
1121             LoopIdError::UnlabeledCfInWhileCondition =>
1122                 "unlabeled control flow (break or continue) in while condition",
1123             LoopIdError::UnresolvedLabel => "label not found",
1124         }, f)
1125     }
1126 }
1127
1128 // FIXME(cramertj) this should use `Result` once master compiles w/ a vesion of Rust where
1129 // `Result` implements `Encodable`/`Decodable`
1130 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1131 pub enum LoopIdResult {
1132     Ok(NodeId),
1133     Err(LoopIdError),
1134 }
1135 impl Into<Result<NodeId, LoopIdError>> for LoopIdResult {
1136     fn into(self) -> Result<NodeId, LoopIdError> {
1137         match self {
1138             LoopIdResult::Ok(ok) => Ok(ok),
1139             LoopIdResult::Err(err) => Err(err),
1140         }
1141     }
1142 }
1143 impl From<Result<NodeId, LoopIdError>> for LoopIdResult {
1144     fn from(res: Result<NodeId, LoopIdError>) -> Self {
1145         match res {
1146             Ok(ok) => LoopIdResult::Ok(ok),
1147             Err(err) => LoopIdResult::Err(err),
1148         }
1149     }
1150 }
1151
1152 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1153 pub enum ScopeTarget {
1154     Block(NodeId),
1155     Loop(LoopIdResult),
1156 }
1157
1158 impl ScopeTarget {
1159     pub fn opt_id(self) -> Option<NodeId> {
1160         match self {
1161             ScopeTarget::Block(node_id) |
1162             ScopeTarget::Loop(LoopIdResult::Ok(node_id)) => Some(node_id),
1163             ScopeTarget::Loop(LoopIdResult::Err(_)) => None,
1164         }
1165     }
1166 }
1167
1168 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1169 pub struct Destination {
1170     // This is `Some(_)` iff there is an explicit user-specified `label
1171     pub ident: Option<Spanned<Ident>>,
1172
1173     // These errors are caught and then reported during the diagnostics pass in
1174     // librustc_passes/loops.rs
1175     pub target_id: ScopeTarget,
1176 }
1177
1178 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1179 pub enum CaptureClause {
1180     CaptureByValue,
1181     CaptureByRef,
1182 }
1183
1184 // NB: If you change this, you'll probably want to change the corresponding
1185 // type structure in middle/ty.rs as well.
1186 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1187 pub struct MutTy {
1188     pub ty: P<Ty>,
1189     pub mutbl: Mutability,
1190 }
1191
1192 /// Represents a method's signature in a trait declaration or implementation.
1193 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1194 pub struct MethodSig {
1195     pub unsafety: Unsafety,
1196     pub constness: Constness,
1197     pub abi: Abi,
1198     pub decl: P<FnDecl>,
1199     pub generics: Generics,
1200 }
1201
1202 // The bodies for items are stored "out of line", in a separate
1203 // hashmap in the `Crate`. Here we just record the node-id of the item
1204 // so it can fetched later.
1205 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1206 pub struct TraitItemId {
1207     pub node_id: NodeId,
1208 }
1209
1210 /// Represents an item declaration within a trait declaration,
1211 /// possibly including a default implementation. A trait item is
1212 /// either required (meaning it doesn't have an implementation, just a
1213 /// signature) or provided (meaning it has a default implementation).
1214 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1215 pub struct TraitItem {
1216     pub id: NodeId,
1217     pub name: Name,
1218     pub attrs: HirVec<Attribute>,
1219     pub node: TraitItemKind,
1220     pub span: Span,
1221 }
1222
1223 /// A trait method's body (or just argument names).
1224 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1225 pub enum TraitMethod {
1226     /// No default body in the trait, just a signature.
1227     Required(HirVec<Spanned<Name>>),
1228
1229     /// Both signature and body are provided in the trait.
1230     Provided(BodyId),
1231 }
1232
1233 /// Represents a trait method or associated constant or type
1234 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1235 pub enum TraitItemKind {
1236     /// An associated constant with an optional value (otherwise `impl`s
1237     /// must contain a value)
1238     Const(P<Ty>, Option<BodyId>),
1239     /// A method with an optional body
1240     Method(MethodSig, TraitMethod),
1241     /// An associated type with (possibly empty) bounds and optional concrete
1242     /// type
1243     Type(TyParamBounds, Option<P<Ty>>),
1244 }
1245
1246 // The bodies for items are stored "out of line", in a separate
1247 // hashmap in the `Crate`. Here we just record the node-id of the item
1248 // so it can fetched later.
1249 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1250 pub struct ImplItemId {
1251     pub node_id: NodeId,
1252 }
1253
1254 /// Represents anything within an `impl` block
1255 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1256 pub struct ImplItem {
1257     pub id: NodeId,
1258     pub name: Name,
1259     pub vis: Visibility,
1260     pub defaultness: Defaultness,
1261     pub attrs: HirVec<Attribute>,
1262     pub node: ImplItemKind,
1263     pub span: Span,
1264 }
1265
1266 /// Represents different contents within `impl`s
1267 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1268 pub enum ImplItemKind {
1269     /// An associated constant of the given type, set to the constant result
1270     /// of the expression
1271     Const(P<Ty>, BodyId),
1272     /// A method implementation with the given signature and body
1273     Method(MethodSig, BodyId),
1274     /// An associated type
1275     Type(P<Ty>),
1276 }
1277
1278 // Bind a type to an associated type: `A=Foo`.
1279 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1280 pub struct TypeBinding {
1281     pub id: NodeId,
1282     pub name: Name,
1283     pub ty: P<Ty>,
1284     pub span: Span,
1285 }
1286
1287
1288 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1289 pub struct Ty {
1290     pub id: NodeId,
1291     pub node: Ty_,
1292     pub span: Span,
1293 }
1294
1295 impl fmt::Debug for Ty {
1296     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1297         write!(f, "type({})",
1298                print::to_string(print::NO_ANN, |s| s.print_type(self)))
1299     }
1300 }
1301
1302 /// Not represented directly in the AST, referred to by name through a ty_path.
1303 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1304 pub enum PrimTy {
1305     TyInt(IntTy),
1306     TyUint(UintTy),
1307     TyFloat(FloatTy),
1308     TyStr,
1309     TyBool,
1310     TyChar,
1311 }
1312
1313 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1314 pub struct BareFnTy {
1315     pub unsafety: Unsafety,
1316     pub abi: Abi,
1317     pub lifetimes: HirVec<LifetimeDef>,
1318     pub decl: P<FnDecl>,
1319 }
1320
1321 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1322 /// The different kinds of types recognized by the compiler
1323 pub enum Ty_ {
1324     /// A variable length slice (`[T]`)
1325     TySlice(P<Ty>),
1326     /// A fixed length array (`[T; n]`)
1327     TyArray(P<Ty>, BodyId),
1328     /// A raw pointer (`*const T` or `*mut T`)
1329     TyPtr(MutTy),
1330     /// A reference (`&'a T` or `&'a mut T`)
1331     TyRptr(Lifetime, MutTy),
1332     /// A bare function (e.g. `fn(usize) -> bool`)
1333     TyBareFn(P<BareFnTy>),
1334     /// The never type (`!`)
1335     TyNever,
1336     /// A tuple (`(A, B, C, D,...)`)
1337     TyTup(HirVec<P<Ty>>),
1338     /// A path to a type definition (`module::module::...::Type`), or an
1339     /// associated type, e.g. `<Vec<T> as Trait>::Type` or `<T>::Target`.
1340     ///
1341     /// Type parameters may be stored in each `PathSegment`.
1342     TyPath(QPath),
1343     /// A trait object type `Bound1 + Bound2 + Bound3`
1344     /// where `Bound` is a trait or a lifetime.
1345     TyTraitObject(HirVec<PolyTraitRef>, Lifetime),
1346     /// An `impl Bound1 + Bound2 + Bound3` type
1347     /// where `Bound` is a trait or a lifetime.
1348     TyImplTrait(TyParamBounds),
1349     /// Unused for now
1350     TyTypeof(BodyId),
1351     /// TyInfer means the type should be inferred instead of it having been
1352     /// specified. This can appear anywhere in a type.
1353     TyInfer,
1354     /// Placeholder for a type that has failed to be defined.
1355     TyErr,
1356 }
1357
1358 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1359 pub struct InlineAsmOutput {
1360     pub constraint: Symbol,
1361     pub is_rw: bool,
1362     pub is_indirect: bool,
1363 }
1364
1365 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1366 pub struct InlineAsm {
1367     pub asm: Symbol,
1368     pub asm_str_style: StrStyle,
1369     pub outputs: HirVec<InlineAsmOutput>,
1370     pub inputs: HirVec<Symbol>,
1371     pub clobbers: HirVec<Symbol>,
1372     pub volatile: bool,
1373     pub alignstack: bool,
1374     pub dialect: AsmDialect,
1375     pub ctxt: SyntaxContext,
1376 }
1377
1378 /// represents an argument in a function header
1379 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1380 pub struct Arg {
1381     pub pat: P<Pat>,
1382     pub id: NodeId,
1383 }
1384
1385 /// Represents the header (not the body) of a function declaration
1386 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1387 pub struct FnDecl {
1388     pub inputs: HirVec<P<Ty>>,
1389     pub output: FunctionRetTy,
1390     pub variadic: bool,
1391     /// True if this function has an `self`, `&self` or `&mut self` receiver
1392     /// (but not a `self: Xxx` one).
1393     pub has_implicit_self: bool,
1394 }
1395
1396 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1397 pub enum Unsafety {
1398     Unsafe,
1399     Normal,
1400 }
1401
1402 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1403 pub enum Constness {
1404     Const,
1405     NotConst,
1406 }
1407
1408 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1409 pub enum Defaultness {
1410     Default { has_value: bool },
1411     Final,
1412 }
1413
1414 impl Defaultness {
1415     pub fn has_value(&self) -> bool {
1416         match *self {
1417             Defaultness::Default { has_value, .. } => has_value,
1418             Defaultness::Final => true,
1419         }
1420     }
1421
1422     pub fn is_final(&self) -> bool {
1423         *self == Defaultness::Final
1424     }
1425
1426     pub fn is_default(&self) -> bool {
1427         match *self {
1428             Defaultness::Default { .. } => true,
1429             _ => false,
1430         }
1431     }
1432 }
1433
1434 impl fmt::Display for Unsafety {
1435     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1436         fmt::Display::fmt(match *self {
1437                               Unsafety::Normal => "normal",
1438                               Unsafety::Unsafe => "unsafe",
1439                           },
1440                           f)
1441     }
1442 }
1443
1444 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1445 pub enum ImplPolarity {
1446     /// `impl Trait for Type`
1447     Positive,
1448     /// `impl !Trait for Type`
1449     Negative,
1450 }
1451
1452 impl fmt::Debug for ImplPolarity {
1453     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1454         match *self {
1455             ImplPolarity::Positive => "positive".fmt(f),
1456             ImplPolarity::Negative => "negative".fmt(f),
1457         }
1458     }
1459 }
1460
1461
1462 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1463 pub enum FunctionRetTy {
1464     /// Return type is not specified.
1465     ///
1466     /// Functions default to `()` and
1467     /// closures default to inference. Span points to where return
1468     /// type would be inserted.
1469     DefaultReturn(Span),
1470     /// Everything else
1471     Return(P<Ty>),
1472 }
1473
1474 impl FunctionRetTy {
1475     pub fn span(&self) -> Span {
1476         match *self {
1477             DefaultReturn(span) => span,
1478             Return(ref ty) => ty.span,
1479         }
1480     }
1481 }
1482
1483 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1484 pub struct Mod {
1485     /// A span from the first token past `{` to the last token until `}`.
1486     /// For `mod foo;`, the inner span ranges from the first token
1487     /// to the last token in the external file.
1488     pub inner: Span,
1489     pub item_ids: HirVec<ItemId>,
1490 }
1491
1492 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1493 pub struct ForeignMod {
1494     pub abi: Abi,
1495     pub items: HirVec<ForeignItem>,
1496 }
1497
1498 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1499 pub struct GlobalAsm {
1500     pub asm: Symbol,
1501     pub ctxt: SyntaxContext,
1502 }
1503
1504 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1505 pub struct EnumDef {
1506     pub variants: HirVec<Variant>,
1507 }
1508
1509 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1510 pub struct Variant_ {
1511     pub name: Name,
1512     pub attrs: HirVec<Attribute>,
1513     pub data: VariantData,
1514     /// Explicit discriminant, eg `Foo = 1`
1515     pub disr_expr: Option<BodyId>,
1516 }
1517
1518 pub type Variant = Spanned<Variant_>;
1519
1520 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1521 pub enum UseKind {
1522     /// One import, e.g. `use foo::bar` or `use foo::bar as baz`.
1523     /// Also produced for each element of a list `use`, e.g.
1524     // `use foo::{a, b}` lowers to `use foo::a; use foo::b;`.
1525     Single,
1526
1527     /// Glob import, e.g. `use foo::*`.
1528     Glob,
1529
1530     /// Degenerate list import, e.g. `use foo::{a, b}` produces
1531     /// an additional `use foo::{}` for performing checks such as
1532     /// unstable feature gating. May be removed in the future.
1533     ListStem,
1534 }
1535
1536 /// TraitRef's appear in impls.
1537 ///
1538 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1539 /// that the ref_id is for. Note that ref_id's value is not the NodeId of the
1540 /// trait being referred to but just a unique NodeId that serves as a key
1541 /// within the DefMap.
1542 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1543 pub struct TraitRef {
1544     pub path: Path,
1545     pub ref_id: NodeId,
1546 }
1547
1548 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1549 pub struct PolyTraitRef {
1550     /// The `'a` in `<'a> Foo<&'a T>`
1551     pub bound_lifetimes: HirVec<LifetimeDef>,
1552
1553     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1554     pub trait_ref: TraitRef,
1555
1556     pub span: Span,
1557 }
1558
1559 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1560 pub enum Visibility {
1561     Public,
1562     Crate,
1563     Restricted { path: P<Path>, id: NodeId },
1564     Inherited,
1565 }
1566
1567 impl Visibility {
1568     pub fn is_pub_restricted(&self) -> bool {
1569         use self::Visibility::*;
1570         match self {
1571             &Public |
1572             &Inherited => false,
1573             &Crate |
1574             &Restricted { .. } => true,
1575         }
1576     }
1577 }
1578
1579 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1580 pub struct StructField {
1581     pub span: Span,
1582     pub name: Name,
1583     pub vis: Visibility,
1584     pub id: NodeId,
1585     pub ty: P<Ty>,
1586     pub attrs: HirVec<Attribute>,
1587 }
1588
1589 impl StructField {
1590     // Still necessary in couple of places
1591     pub fn is_positional(&self) -> bool {
1592         let first = self.name.as_str().as_bytes()[0];
1593         first >= b'0' && first <= b'9'
1594     }
1595 }
1596
1597 /// Fields and Ids of enum variants and structs
1598 ///
1599 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1600 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1601 /// One shared Id can be successfully used for these two purposes.
1602 /// Id of the whole enum lives in `Item`.
1603 ///
1604 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
1605 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
1606 /// the variant itself" from enum variants.
1607 /// Id of the whole struct lives in `Item`.
1608 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1609 pub enum VariantData {
1610     Struct(HirVec<StructField>, NodeId),
1611     Tuple(HirVec<StructField>, NodeId),
1612     Unit(NodeId),
1613 }
1614
1615 impl VariantData {
1616     pub fn fields(&self) -> &[StructField] {
1617         match *self {
1618             VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
1619             _ => &[],
1620         }
1621     }
1622     pub fn id(&self) -> NodeId {
1623         match *self {
1624             VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
1625         }
1626     }
1627     pub fn is_struct(&self) -> bool {
1628         if let VariantData::Struct(..) = *self {
1629             true
1630         } else {
1631             false
1632         }
1633     }
1634     pub fn is_tuple(&self) -> bool {
1635         if let VariantData::Tuple(..) = *self {
1636             true
1637         } else {
1638             false
1639         }
1640     }
1641     pub fn is_unit(&self) -> bool {
1642         if let VariantData::Unit(..) = *self {
1643             true
1644         } else {
1645             false
1646         }
1647     }
1648 }
1649
1650 // The bodies for items are stored "out of line", in a separate
1651 // hashmap in the `Crate`. Here we just record the node-id of the item
1652 // so it can fetched later.
1653 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1654 pub struct ItemId {
1655     pub id: NodeId,
1656 }
1657
1658 /// An item
1659 ///
1660 /// The name might be a dummy name in case of anonymous items
1661 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1662 pub struct Item {
1663     pub name: Name,
1664     pub attrs: HirVec<Attribute>,
1665     pub id: NodeId,
1666     pub node: Item_,
1667     pub vis: Visibility,
1668     pub span: Span,
1669 }
1670
1671 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1672 pub enum Item_ {
1673     /// An`extern crate` item, with optional original crate name,
1674     ///
1675     /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
1676     ItemExternCrate(Option<Name>),
1677
1678     /// `use foo::bar::*;` or `use foo::bar::baz as quux;`
1679     ///
1680     /// or just
1681     ///
1682     /// `use foo::bar::baz;` (with `as baz` implicitly on the right)
1683     ItemUse(P<Path>, UseKind),
1684
1685     /// A `static` item
1686     ItemStatic(P<Ty>, Mutability, BodyId),
1687     /// A `const` item
1688     ItemConst(P<Ty>, BodyId),
1689     /// A function declaration
1690     ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, BodyId),
1691     /// A module
1692     ItemMod(Mod),
1693     /// An external module
1694     ItemForeignMod(ForeignMod),
1695     /// Module-level inline assembly (from global_asm!)
1696     ItemGlobalAsm(P<GlobalAsm>),
1697     /// A type alias, e.g. `type Foo = Bar<u8>`
1698     ItemTy(P<Ty>, Generics),
1699     /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
1700     ItemEnum(EnumDef, Generics),
1701     /// A struct definition, e.g. `struct Foo<A> {x: A}`
1702     ItemStruct(VariantData, Generics),
1703     /// A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
1704     ItemUnion(VariantData, Generics),
1705     /// Represents a Trait Declaration
1706     ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
1707
1708     // Default trait implementations
1709     ///
1710     /// `impl Trait for .. {}`
1711     ItemDefaultImpl(Unsafety, TraitRef),
1712     /// An implementation, eg `impl<A> Trait for Foo { .. }`
1713     ItemImpl(Unsafety,
1714              ImplPolarity,
1715              Generics,
1716              Option<TraitRef>, // (optional) trait this impl implements
1717              P<Ty>, // self
1718              HirVec<ImplItemRef>),
1719 }
1720
1721 impl Item_ {
1722     pub fn descriptive_variant(&self) -> &str {
1723         match *self {
1724             ItemExternCrate(..) => "extern crate",
1725             ItemUse(..) => "use",
1726             ItemStatic(..) => "static item",
1727             ItemConst(..) => "constant item",
1728             ItemFn(..) => "function",
1729             ItemMod(..) => "module",
1730             ItemForeignMod(..) => "foreign module",
1731             ItemGlobalAsm(..) => "global asm",
1732             ItemTy(..) => "type alias",
1733             ItemEnum(..) => "enum",
1734             ItemStruct(..) => "struct",
1735             ItemUnion(..) => "union",
1736             ItemTrait(..) => "trait",
1737             ItemImpl(..) |
1738             ItemDefaultImpl(..) => "item",
1739         }
1740     }
1741 }
1742
1743 /// A reference from an trait to one of its associated items. This
1744 /// contains the item's id, naturally, but also the item's name and
1745 /// some other high-level details (like whether it is an associated
1746 /// type or method, and whether it is public). This allows other
1747 /// passes to find the impl they want without loading the id (which
1748 /// means fewer edges in the incremental compilation graph).
1749 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1750 pub struct TraitItemRef {
1751     pub id: TraitItemId,
1752     pub name: Name,
1753     pub kind: AssociatedItemKind,
1754     pub span: Span,
1755     pub defaultness: Defaultness,
1756 }
1757
1758 /// A reference from an impl to one of its associated items. This
1759 /// contains the item's id, naturally, but also the item's name and
1760 /// some other high-level details (like whether it is an associated
1761 /// type or method, and whether it is public). This allows other
1762 /// passes to find the impl they want without loading the id (which
1763 /// means fewer edges in the incremental compilation graph).
1764 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1765 pub struct ImplItemRef {
1766     pub id: ImplItemId,
1767     pub name: Name,
1768     pub kind: AssociatedItemKind,
1769     pub span: Span,
1770     pub vis: Visibility,
1771     pub defaultness: Defaultness,
1772 }
1773
1774 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1775 pub enum AssociatedItemKind {
1776     Const,
1777     Method { has_self: bool },
1778     Type,
1779 }
1780
1781 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1782 pub struct ForeignItem {
1783     pub name: Name,
1784     pub attrs: HirVec<Attribute>,
1785     pub node: ForeignItem_,
1786     pub id: NodeId,
1787     pub span: Span,
1788     pub vis: Visibility,
1789 }
1790
1791 /// An item within an `extern` block
1792 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1793 pub enum ForeignItem_ {
1794     /// A foreign function
1795     ForeignItemFn(P<FnDecl>, HirVec<Spanned<Name>>, Generics),
1796     /// A foreign static item (`static ext: u8`), with optional mutability
1797     /// (the boolean is true when mutable)
1798     ForeignItemStatic(P<Ty>, bool),
1799 }
1800
1801 impl ForeignItem_ {
1802     pub fn descriptive_variant(&self) -> &str {
1803         match *self {
1804             ForeignItemFn(..) => "foreign function",
1805             ForeignItemStatic(..) => "foreign static item",
1806         }
1807     }
1808 }
1809
1810 /// A free variable referred to in a function.
1811 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
1812 pub struct Freevar {
1813     /// The variable being accessed free.
1814     pub def: Def,
1815
1816     // First span where it is accessed (there can be multiple).
1817     pub span: Span
1818 }
1819
1820 pub type FreevarMap = NodeMap<Vec<Freevar>>;
1821
1822 pub type CaptureModeMap = NodeMap<CaptureClause>;
1823
1824 #[derive(Clone, Debug)]
1825 pub struct TraitCandidate {
1826     pub def_id: DefId,
1827     pub import_id: Option<NodeId>,
1828 }
1829
1830 // Trait method resolution
1831 pub type TraitMap = NodeMap<Vec<TraitCandidate>>;
1832
1833 // Map from the NodeId of a glob import to a list of items which are actually
1834 // imported.
1835 pub type GlobMap = NodeMap<FxHashSet<Name>>;