]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/ty/mod.rs
split ty.rs into smaller parts
[rust.git] / src / librustc / middle / ty / mod.rs
1 // Copyright 2012-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 pub use self::ImplOrTraitItemId::*;
12 pub use self::ClosureKind::*;
13 pub use self::Variance::*;
14 pub use self::AutoAdjustment::*;
15 pub use self::Representability::*;
16 pub use self::AutoRef::*;
17 pub use self::DtorKind::*;
18 pub use self::ExplicitSelfCategory::*;
19 pub use self::ImplOrTraitItemContainer::*;
20 pub use self::BorrowKind::*;
21 pub use self::ImplOrTraitItem::*;
22 pub use self::IntVarValue::*;
23 pub use self::CopyImplementationError::*;
24 pub use self::LvaluePreference::*;
25
26 use back::svh::Svh;
27 use front::map as ast_map;
28 use front::map::LinkedPath;
29 use metadata::csearch;
30 use middle;
31 use middle::const_eval::{self, ConstVal, ErrKind};
32 use middle::const_eval::EvalHint::UncheckedExprHint;
33 use middle::def::{self, ExportMap};
34 use middle::def_id::{DefId, LOCAL_CRATE};
35 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
36 use middle::infer;
37 use middle::pat_util;
38 use middle::subst::{self, ParamSpace, Subst, Substs, VecPerParamSpace};
39 use middle::traits;
40 use middle::ty;
41 use middle::ty::fold::TypeFolder;
42 use middle::ty::walk::TypeWalker;
43 use util::common::memoized;
44 use util::nodemap::{NodeMap, NodeSet, DefIdMap};
45 use util::nodemap::FnvHashMap;
46 use util::num::ToPrimitive;
47
48 use std::borrow::{Borrow, Cow};
49 use std::cell::{Cell, RefCell};
50 use std::cmp;
51 use std::hash::{Hash, SipHasher, Hasher};
52 use std::iter;
53 use std::rc::Rc;
54 use std::slice;
55 use std::vec::IntoIter;
56 use std::collections::{HashMap, HashSet};
57 use syntax::ast::{self, CrateNum, Name, NodeId};
58 use syntax::codemap::Span;
59 use syntax::parse::token::{InternedString, special_idents};
60
61 use rustc_front::hir;
62 use rustc_front::hir::{ItemImpl, ItemTrait};
63 use rustc_front::hir::{MutImmutable, MutMutable, Visibility};
64 use rustc_front::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
65
66 pub use self::sty::{Binder, DebruijnIndex};
67 pub use self::sty::{BuiltinBound, BuiltinBounds, ExistentialBounds};
68 pub use self::sty::{BareFnTy, FnSig, PolyFnSig, FnOutput, PolyFnOutput};
69 pub use self::sty::{ClosureTy, InferTy, ParamTy, ProjectionTy, TraitTy};
70 pub use self::sty::{ClosureSubsts, TypeAndMut};
71 pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef};
72 pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
73 pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
74 pub use self::sty::BoundRegion::*;
75 pub use self::sty::FnOutput::*;
76 pub use self::sty::InferTy::*;
77 pub use self::sty::Region::*;
78 pub use self::sty::TypeVariants::*;
79
80 pub use self::sty::BuiltinBound::Send as BoundSend;
81 pub use self::sty::BuiltinBound::Sized as BoundSized;
82 pub use self::sty::BuiltinBound::Copy as BoundCopy;
83 pub use self::sty::BuiltinBound::Sync as BoundSync;
84
85 pub use self::contents::TypeContents;
86 pub use self::context::{ctxt, tls};
87 pub use self::context::{CtxtArenas, Lift, Tables};
88
89 pub mod cast;
90 pub mod error;
91 pub mod fast_reject;
92 pub mod fold;
93 pub mod _match;
94 pub mod outlives;
95 pub mod relate;
96 pub mod walk;
97 pub mod wf;
98
99 mod contents;
100 mod context;
101 mod flags;
102 mod ivar;
103 mod structural_impls;
104 mod sty;
105
106 pub type Disr = u64;
107
108 pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
109
110 // Data types
111
112 /// The complete set of all analyses described in this module. This is
113 /// produced by the driver and fed to trans and later passes.
114 pub struct CrateAnalysis {
115     pub export_map: ExportMap,
116     pub exported_items: middle::privacy::ExportedItems,
117     pub public_items: middle::privacy::PublicItems,
118     pub reachable: NodeSet,
119     pub name: String,
120     pub glob_map: Option<GlobMap>,
121 }
122
123
124 #[derive(Copy, Clone)]
125 pub enum DtorKind {
126     NoDtor,
127     TraitDtor(bool)
128 }
129
130 impl DtorKind {
131     pub fn is_present(&self) -> bool {
132         match *self {
133             TraitDtor(..) => true,
134             _ => false
135         }
136     }
137
138     pub fn has_drop_flag(&self) -> bool {
139         match self {
140             &NoDtor => false,
141             &TraitDtor(flag) => flag
142         }
143     }
144 }
145
146 pub trait IntTypeExt {
147     fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx>;
148     fn i64_to_disr(&self, val: i64) -> Option<Disr>;
149     fn u64_to_disr(&self, val: u64) -> Option<Disr>;
150     fn disr_incr(&self, val: Disr) -> Option<Disr>;
151     fn disr_string(&self, val: Disr) -> String;
152     fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr;
153 }
154
155 impl IntTypeExt for attr::IntType {
156     fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> {
157         match *self {
158             SignedInt(hir::TyI8)      => cx.types.i8,
159             SignedInt(hir::TyI16)     => cx.types.i16,
160             SignedInt(hir::TyI32)     => cx.types.i32,
161             SignedInt(hir::TyI64)     => cx.types.i64,
162             SignedInt(hir::TyIs)   => cx.types.isize,
163             UnsignedInt(hir::TyU8)    => cx.types.u8,
164             UnsignedInt(hir::TyU16)   => cx.types.u16,
165             UnsignedInt(hir::TyU32)   => cx.types.u32,
166             UnsignedInt(hir::TyU64)   => cx.types.u64,
167             UnsignedInt(hir::TyUs) => cx.types.usize,
168         }
169     }
170
171     fn i64_to_disr(&self, val: i64) -> Option<Disr> {
172         match *self {
173             SignedInt(hir::TyI8)    => val.to_i8()  .map(|v| v as Disr),
174             SignedInt(hir::TyI16)   => val.to_i16() .map(|v| v as Disr),
175             SignedInt(hir::TyI32)   => val.to_i32() .map(|v| v as Disr),
176             SignedInt(hir::TyI64)   => val.to_i64() .map(|v| v as Disr),
177             UnsignedInt(hir::TyU8)  => val.to_u8()  .map(|v| v as Disr),
178             UnsignedInt(hir::TyU16) => val.to_u16() .map(|v| v as Disr),
179             UnsignedInt(hir::TyU32) => val.to_u32() .map(|v| v as Disr),
180             UnsignedInt(hir::TyU64) => val.to_u64() .map(|v| v as Disr),
181
182             UnsignedInt(hir::TyUs) |
183             SignedInt(hir::TyIs) => unreachable!(),
184         }
185     }
186
187     fn u64_to_disr(&self, val: u64) -> Option<Disr> {
188         match *self {
189             SignedInt(hir::TyI8)    => val.to_i8()  .map(|v| v as Disr),
190             SignedInt(hir::TyI16)   => val.to_i16() .map(|v| v as Disr),
191             SignedInt(hir::TyI32)   => val.to_i32() .map(|v| v as Disr),
192             SignedInt(hir::TyI64)   => val.to_i64() .map(|v| v as Disr),
193             UnsignedInt(hir::TyU8)  => val.to_u8()  .map(|v| v as Disr),
194             UnsignedInt(hir::TyU16) => val.to_u16() .map(|v| v as Disr),
195             UnsignedInt(hir::TyU32) => val.to_u32() .map(|v| v as Disr),
196             UnsignedInt(hir::TyU64) => val.to_u64() .map(|v| v as Disr),
197
198             UnsignedInt(hir::TyUs) |
199             SignedInt(hir::TyIs) => unreachable!(),
200         }
201     }
202
203     fn disr_incr(&self, val: Disr) -> Option<Disr> {
204         macro_rules! add1 {
205             ($e:expr) => { $e.and_then(|v|v.checked_add(1)).map(|v| v as Disr) }
206         }
207         match *self {
208             // SignedInt repr means we *want* to reinterpret the bits
209             // treating the highest bit of Disr as a sign-bit, so
210             // cast to i64 before range-checking.
211             SignedInt(hir::TyI8)    => add1!((val as i64).to_i8()),
212             SignedInt(hir::TyI16)   => add1!((val as i64).to_i16()),
213             SignedInt(hir::TyI32)   => add1!((val as i64).to_i32()),
214             SignedInt(hir::TyI64)   => add1!(Some(val as i64)),
215
216             UnsignedInt(hir::TyU8)  => add1!(val.to_u8()),
217             UnsignedInt(hir::TyU16) => add1!(val.to_u16()),
218             UnsignedInt(hir::TyU32) => add1!(val.to_u32()),
219             UnsignedInt(hir::TyU64) => add1!(Some(val)),
220
221             UnsignedInt(hir::TyUs) |
222             SignedInt(hir::TyIs) => unreachable!(),
223         }
224     }
225
226     // This returns a String because (1.) it is only used for
227     // rendering an error message and (2.) a string can represent the
228     // full range from `i64::MIN` through `u64::MAX`.
229     fn disr_string(&self, val: Disr) -> String {
230         match *self {
231             SignedInt(hir::TyI8)    => format!("{}", val as i8 ),
232             SignedInt(hir::TyI16)   => format!("{}", val as i16),
233             SignedInt(hir::TyI32)   => format!("{}", val as i32),
234             SignedInt(hir::TyI64)   => format!("{}", val as i64),
235             UnsignedInt(hir::TyU8)  => format!("{}", val as u8 ),
236             UnsignedInt(hir::TyU16) => format!("{}", val as u16),
237             UnsignedInt(hir::TyU32) => format!("{}", val as u32),
238             UnsignedInt(hir::TyU64) => format!("{}", val as u64),
239
240             UnsignedInt(hir::TyUs) |
241             SignedInt(hir::TyIs) => unreachable!(),
242         }
243     }
244
245     fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr {
246         macro_rules! add1 {
247             ($e:expr) => { ($e).wrapping_add(1) as Disr }
248         }
249         let val = val.unwrap_or(ty::INITIAL_DISCRIMINANT_VALUE);
250         match *self {
251             SignedInt(hir::TyI8)    => add1!(val as i8 ),
252             SignedInt(hir::TyI16)   => add1!(val as i16),
253             SignedInt(hir::TyI32)   => add1!(val as i32),
254             SignedInt(hir::TyI64)   => add1!(val as i64),
255             UnsignedInt(hir::TyU8)  => add1!(val as u8 ),
256             UnsignedInt(hir::TyU16) => add1!(val as u16),
257             UnsignedInt(hir::TyU32) => add1!(val as u32),
258             UnsignedInt(hir::TyU64) => add1!(val as u64),
259
260             UnsignedInt(hir::TyUs) |
261             SignedInt(hir::TyIs) => unreachable!(),
262         }
263     }
264 }
265
266 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
267 pub enum ImplOrTraitItemContainer {
268     TraitContainer(DefId),
269     ImplContainer(DefId),
270 }
271
272 impl ImplOrTraitItemContainer {
273     pub fn id(&self) -> DefId {
274         match *self {
275             TraitContainer(id) => id,
276             ImplContainer(id) => id,
277         }
278     }
279 }
280
281 #[derive(Clone)]
282 pub enum ImplOrTraitItem<'tcx> {
283     ConstTraitItem(Rc<AssociatedConst<'tcx>>),
284     MethodTraitItem(Rc<Method<'tcx>>),
285     TypeTraitItem(Rc<AssociatedType<'tcx>>),
286 }
287
288 impl<'tcx> ImplOrTraitItem<'tcx> {
289     fn id(&self) -> ImplOrTraitItemId {
290         match *self {
291             ConstTraitItem(ref associated_const) => {
292                 ConstTraitItemId(associated_const.def_id)
293             }
294             MethodTraitItem(ref method) => MethodTraitItemId(method.def_id),
295             TypeTraitItem(ref associated_type) => {
296                 TypeTraitItemId(associated_type.def_id)
297             }
298         }
299     }
300
301     pub fn def_id(&self) -> DefId {
302         match *self {
303             ConstTraitItem(ref associated_const) => associated_const.def_id,
304             MethodTraitItem(ref method) => method.def_id,
305             TypeTraitItem(ref associated_type) => associated_type.def_id,
306         }
307     }
308
309     pub fn name(&self) -> Name {
310         match *self {
311             ConstTraitItem(ref associated_const) => associated_const.name,
312             MethodTraitItem(ref method) => method.name,
313             TypeTraitItem(ref associated_type) => associated_type.name,
314         }
315     }
316
317     pub fn vis(&self) -> hir::Visibility {
318         match *self {
319             ConstTraitItem(ref associated_const) => associated_const.vis,
320             MethodTraitItem(ref method) => method.vis,
321             TypeTraitItem(ref associated_type) => associated_type.vis,
322         }
323     }
324
325     pub fn container(&self) -> ImplOrTraitItemContainer {
326         match *self {
327             ConstTraitItem(ref associated_const) => associated_const.container,
328             MethodTraitItem(ref method) => method.container,
329             TypeTraitItem(ref associated_type) => associated_type.container,
330         }
331     }
332
333     pub fn as_opt_method(&self) -> Option<Rc<Method<'tcx>>> {
334         match *self {
335             MethodTraitItem(ref m) => Some((*m).clone()),
336             _ => None,
337         }
338     }
339 }
340
341 #[derive(Clone, Copy, Debug)]
342 pub enum ImplOrTraitItemId {
343     ConstTraitItemId(DefId),
344     MethodTraitItemId(DefId),
345     TypeTraitItemId(DefId),
346 }
347
348 impl ImplOrTraitItemId {
349     pub fn def_id(&self) -> DefId {
350         match *self {
351             ConstTraitItemId(def_id) => def_id,
352             MethodTraitItemId(def_id) => def_id,
353             TypeTraitItemId(def_id) => def_id,
354         }
355     }
356 }
357
358 #[derive(Clone, Debug)]
359 pub struct Method<'tcx> {
360     pub name: Name,
361     pub generics: Generics<'tcx>,
362     pub predicates: GenericPredicates<'tcx>,
363     pub fty: BareFnTy<'tcx>,
364     pub explicit_self: ExplicitSelfCategory,
365     pub vis: hir::Visibility,
366     pub def_id: DefId,
367     pub container: ImplOrTraitItemContainer,
368
369     // If this method is provided, we need to know where it came from
370     pub provided_source: Option<DefId>
371 }
372
373 impl<'tcx> Method<'tcx> {
374     pub fn new(name: Name,
375                generics: ty::Generics<'tcx>,
376                predicates: GenericPredicates<'tcx>,
377                fty: BareFnTy<'tcx>,
378                explicit_self: ExplicitSelfCategory,
379                vis: hir::Visibility,
380                def_id: DefId,
381                container: ImplOrTraitItemContainer,
382                provided_source: Option<DefId>)
383                -> Method<'tcx> {
384        Method {
385             name: name,
386             generics: generics,
387             predicates: predicates,
388             fty: fty,
389             explicit_self: explicit_self,
390             vis: vis,
391             def_id: def_id,
392             container: container,
393             provided_source: provided_source
394         }
395     }
396
397     pub fn container_id(&self) -> DefId {
398         match self.container {
399             TraitContainer(id) => id,
400             ImplContainer(id) => id,
401         }
402     }
403 }
404
405 #[derive(Clone, Copy, Debug)]
406 pub struct AssociatedConst<'tcx> {
407     pub name: Name,
408     pub ty: Ty<'tcx>,
409     pub vis: hir::Visibility,
410     pub def_id: DefId,
411     pub container: ImplOrTraitItemContainer,
412     pub default: Option<DefId>,
413 }
414
415 #[derive(Clone, Copy, Debug)]
416 pub struct AssociatedType<'tcx> {
417     pub name: Name,
418     pub ty: Option<Ty<'tcx>>,
419     pub vis: hir::Visibility,
420     pub def_id: DefId,
421     pub container: ImplOrTraitItemContainer,
422 }
423
424 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
425 pub struct ItemVariances {
426     pub types: VecPerParamSpace<Variance>,
427     pub regions: VecPerParamSpace<Variance>,
428 }
429
430 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
431 pub enum Variance {
432     Covariant,      // T<A> <: T<B> iff A <: B -- e.g., function return type
433     Invariant,      // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
434     Contravariant,  // T<A> <: T<B> iff B <: A -- e.g., function param type
435     Bivariant,      // T<A> <: T<B>            -- e.g., unused type parameter
436 }
437
438 #[derive(Copy, Clone)]
439 pub enum AutoAdjustment<'tcx> {
440     AdjustReifyFnPointer,   // go from a fn-item type to a fn-pointer type
441     AdjustUnsafeFnPointer,  // go from a safe fn pointer to an unsafe fn pointer
442     AdjustDerefRef(AutoDerefRef<'tcx>),
443 }
444
445 /// Represents coercing a pointer to a different kind of pointer - where 'kind'
446 /// here means either or both of raw vs borrowed vs unique and fat vs thin.
447 ///
448 /// We transform pointers by following the following steps in order:
449 /// 1. Deref the pointer `self.autoderefs` times (may be 0).
450 /// 2. If `autoref` is `Some(_)`, then take the address and produce either a
451 ///    `&` or `*` pointer.
452 /// 3. If `unsize` is `Some(_)`, then apply the unsize transformation,
453 ///    which will do things like convert thin pointers to fat
454 ///    pointers, or convert structs containing thin pointers to
455 ///    structs containing fat pointers, or convert between fat
456 ///    pointers.  We don't store the details of how the transform is
457 ///    done (in fact, we don't know that, because it might depend on
458 ///    the precise type parameters). We just store the target
459 ///    type. Trans figures out what has to be done at monomorphization
460 ///    time based on the precise source/target type at hand.
461 ///
462 /// To make that more concrete, here are some common scenarios:
463 ///
464 /// 1. The simplest cases are where the pointer is not adjusted fat vs thin.
465 /// Here the pointer will be dereferenced N times (where a dereference can
466 /// happen to to raw or borrowed pointers or any smart pointer which implements
467 /// Deref, including Box<_>). The number of dereferences is given by
468 /// `autoderefs`.  It can then be auto-referenced zero or one times, indicated
469 /// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
470 /// None.
471 ///
472 /// 2. A thin-to-fat coercon involves unsizing the underlying data. We start
473 /// with a thin pointer, deref a number of times, unsize the underlying data,
474 /// then autoref. The 'unsize' phase may change a fixed length array to a
475 /// dynamically sized one, a concrete object to a trait object, or statically
476 /// sized struct to a dyncamically sized one. E.g., &[i32; 4] -> &[i32] is
477 /// represented by:
478 ///
479 /// ```
480 /// AutoDerefRef {
481 ///     autoderefs: 1,          // &[i32; 4] -> [i32; 4]
482 ///     autoref: Some(AutoPtr), // [i32] -> &[i32]
483 ///     unsize: Some([i32]),    // [i32; 4] -> [i32]
484 /// }
485 /// ```
486 ///
487 /// Note that for a struct, the 'deep' unsizing of the struct is not recorded.
488 /// E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
489 /// The autoderef and -ref are the same as in the above example, but the type
490 /// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
491 /// the underlying conversions from `[i32; 4]` to `[i32]`.
492 ///
493 /// 3. Coercing a `Box<T>` to `Box<Trait>` is an interesting special case.  In
494 /// that case, we have the pointer we need coming in, so there are no
495 /// autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
496 /// At some point, of course, `Box` should move out of the compiler, in which
497 /// case this is analogous to transformating a struct. E.g., Box<[i32; 4]> ->
498 /// Box<[i32]> is represented by:
499 ///
500 /// ```
501 /// AutoDerefRef {
502 ///     autoderefs: 0,
503 ///     autoref: None,
504 ///     unsize: Some(Box<[i32]>),
505 /// }
506 /// ```
507 #[derive(Copy, Clone)]
508 pub struct AutoDerefRef<'tcx> {
509     /// Step 1. Apply a number of dereferences, producing an lvalue.
510     pub autoderefs: usize,
511
512     /// Step 2. Optionally produce a pointer/reference from the value.
513     pub autoref: Option<AutoRef<'tcx>>,
514
515     /// Step 3. Unsize a pointer/reference value, e.g. `&[T; n]` to
516     /// `&[T]`. The stored type is the target pointer type. Note that
517     /// the source could be a thin or fat pointer.
518     pub unsize: Option<Ty<'tcx>>,
519 }
520
521 #[derive(Copy, Clone, PartialEq, Debug)]
522 pub enum AutoRef<'tcx> {
523     /// Convert from T to &T.
524     AutoPtr(&'tcx Region, hir::Mutability),
525
526     /// Convert from T to *T.
527     /// Value to thin pointer.
528     AutoUnsafe(hir::Mutability),
529 }
530
531 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
532 pub enum CustomCoerceUnsized {
533     /// Records the index of the field being coerced.
534     Struct(usize)
535 }
536
537 #[derive(Clone, Copy, Debug)]
538 pub struct MethodCallee<'tcx> {
539     /// Impl method ID, for inherent methods, or trait method ID, otherwise.
540     pub def_id: DefId,
541     pub ty: Ty<'tcx>,
542     pub substs: &'tcx subst::Substs<'tcx>
543 }
544
545 /// With method calls, we store some extra information in
546 /// side tables (i.e method_map). We use
547 /// MethodCall as a key to index into these tables instead of
548 /// just directly using the expression's NodeId. The reason
549 /// for this being that we may apply adjustments (coercions)
550 /// with the resulting expression also needing to use the
551 /// side tables. The problem with this is that we don't
552 /// assign a separate NodeId to this new expression
553 /// and so it would clash with the base expression if both
554 /// needed to add to the side tables. Thus to disambiguate
555 /// we also keep track of whether there's an adjustment in
556 /// our key.
557 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
558 pub struct MethodCall {
559     pub expr_id: NodeId,
560     pub autoderef: u32
561 }
562
563 impl MethodCall {
564     pub fn expr(id: NodeId) -> MethodCall {
565         MethodCall {
566             expr_id: id,
567             autoderef: 0
568         }
569     }
570
571     pub fn autoderef(expr_id: NodeId, autoderef: u32) -> MethodCall {
572         MethodCall {
573             expr_id: expr_id,
574             autoderef: 1 + autoderef
575         }
576     }
577 }
578
579 // maps from an expression id that corresponds to a method call to the details
580 // of the method to be invoked
581 pub type MethodMap<'tcx> = FnvHashMap<MethodCall, MethodCallee<'tcx>>;
582
583 // Contains information needed to resolve types and (in the future) look up
584 // the types of AST nodes.
585 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
586 pub struct CReaderCacheKey {
587     pub cnum: CrateNum,
588     pub pos: usize,
589     pub len: usize
590 }
591
592 /// A restriction that certain types must be the same size. The use of
593 /// `transmute` gives rise to these restrictions. These generally
594 /// cannot be checked until trans; therefore, each call to `transmute`
595 /// will push one or more such restriction into the
596 /// `transmute_restrictions` vector during `intrinsicck`. They are
597 /// then checked during `trans` by the fn `check_intrinsics`.
598 #[derive(Copy, Clone)]
599 pub struct TransmuteRestriction<'tcx> {
600     /// The span whence the restriction comes.
601     pub span: Span,
602
603     /// The type being transmuted from.
604     pub original_from: Ty<'tcx>,
605
606     /// The type being transmuted to.
607     pub original_to: Ty<'tcx>,
608
609     /// The type being transmuted from, with all type parameters
610     /// substituted for an arbitrary representative. Not to be shown
611     /// to the end user.
612     pub substituted_from: Ty<'tcx>,
613
614     /// The type being transmuted to, with all type parameters
615     /// substituted for an arbitrary representative. Not to be shown
616     /// to the end user.
617     pub substituted_to: Ty<'tcx>,
618
619     /// NodeId of the transmute intrinsic.
620     pub id: NodeId,
621 }
622
623 /// Describes the fragment-state associated with a NodeId.
624 ///
625 /// Currently only unfragmented paths have entries in the table,
626 /// but longer-term this enum is expected to expand to also
627 /// include data for fragmented paths.
628 #[derive(Copy, Clone, Debug)]
629 pub enum FragmentInfo {
630     Moved { var: NodeId, move_expr: NodeId },
631     Assigned { var: NodeId, assign_expr: NodeId, assignee_id: NodeId },
632 }
633
634 // Flags that we track on types. These flags are propagated upwards
635 // through the type during type construction, so that we can quickly
636 // check whether the type has various kinds of types in it without
637 // recursing over the type itself.
638 bitflags! {
639     flags TypeFlags: u32 {
640         const HAS_PARAMS         = 1 << 0,
641         const HAS_SELF           = 1 << 1,
642         const HAS_TY_INFER       = 1 << 2,
643         const HAS_RE_INFER       = 1 << 3,
644         const HAS_RE_EARLY_BOUND = 1 << 4,
645         const HAS_FREE_REGIONS   = 1 << 5,
646         const HAS_TY_ERR         = 1 << 6,
647         const HAS_PROJECTION     = 1 << 7,
648         const HAS_TY_CLOSURE     = 1 << 8,
649
650         // true if there are "names" of types and regions and so forth
651         // that are local to a particular fn
652         const HAS_LOCAL_NAMES   = 1 << 9,
653
654         const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
655                                    TypeFlags::HAS_SELF.bits |
656                                    TypeFlags::HAS_RE_EARLY_BOUND.bits,
657
658         // Flags representing the nominal content of a type,
659         // computed by FlagsComputation. If you add a new nominal
660         // flag, it should be added here too.
661         const NOMINAL_FLAGS     = TypeFlags::HAS_PARAMS.bits |
662                                   TypeFlags::HAS_SELF.bits |
663                                   TypeFlags::HAS_TY_INFER.bits |
664                                   TypeFlags::HAS_RE_INFER.bits |
665                                   TypeFlags::HAS_RE_EARLY_BOUND.bits |
666                                   TypeFlags::HAS_FREE_REGIONS.bits |
667                                   TypeFlags::HAS_TY_ERR.bits |
668                                   TypeFlags::HAS_PROJECTION.bits |
669                                   TypeFlags::HAS_TY_CLOSURE.bits |
670                                   TypeFlags::HAS_LOCAL_NAMES.bits,
671
672         // Caches for type_is_sized, type_moves_by_default
673         const SIZEDNESS_CACHED  = 1 << 16,
674         const IS_SIZED          = 1 << 17,
675         const MOVENESS_CACHED   = 1 << 18,
676         const MOVES_BY_DEFAULT  = 1 << 19,
677     }
678 }
679
680 pub struct TyS<'tcx> {
681     pub sty: TypeVariants<'tcx>,
682     pub flags: Cell<TypeFlags>,
683
684     // the maximal depth of any bound regions appearing in this type.
685     region_depth: u32,
686 }
687
688 impl<'tcx> PartialEq for TyS<'tcx> {
689     #[inline]
690     fn eq(&self, other: &TyS<'tcx>) -> bool {
691         // (self as *const _) == (other as *const _)
692         (self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
693     }
694 }
695 impl<'tcx> Eq for TyS<'tcx> {}
696
697 impl<'tcx> Hash for TyS<'tcx> {
698     fn hash<H: Hasher>(&self, s: &mut H) {
699         (self as *const TyS).hash(s)
700     }
701 }
702
703 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
704
705 /// Upvars do not get their own node-id. Instead, we use the pair of
706 /// the original var id (that is, the root variable that is referenced
707 /// by the upvar) and the id of the closure expression.
708 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
709 pub struct UpvarId {
710     pub var_id: NodeId,
711     pub closure_expr_id: NodeId,
712 }
713
714 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
715 pub enum BorrowKind {
716     /// Data must be immutable and is aliasable.
717     ImmBorrow,
718
719     /// Data must be immutable but not aliasable.  This kind of borrow
720     /// cannot currently be expressed by the user and is used only in
721     /// implicit closure bindings. It is needed when you the closure
722     /// is borrowing or mutating a mutable referent, e.g.:
723     ///
724     ///    let x: &mut isize = ...;
725     ///    let y = || *x += 5;
726     ///
727     /// If we were to try to translate this closure into a more explicit
728     /// form, we'd encounter an error with the code as written:
729     ///
730     ///    struct Env { x: & &mut isize }
731     ///    let x: &mut isize = ...;
732     ///    let y = (&mut Env { &x }, fn_ptr);  // Closure is pair of env and fn
733     ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
734     ///
735     /// This is then illegal because you cannot mutate a `&mut` found
736     /// in an aliasable location. To solve, you'd have to translate with
737     /// an `&mut` borrow:
738     ///
739     ///    struct Env { x: & &mut isize }
740     ///    let x: &mut isize = ...;
741     ///    let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
742     ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
743     ///
744     /// Now the assignment to `**env.x` is legal, but creating a
745     /// mutable pointer to `x` is not because `x` is not mutable. We
746     /// could fix this by declaring `x` as `let mut x`. This is ok in
747     /// user code, if awkward, but extra weird for closures, since the
748     /// borrow is hidden.
749     ///
750     /// So we introduce a "unique imm" borrow -- the referent is
751     /// immutable, but not aliasable. This solves the problem. For
752     /// simplicity, we don't give users the way to express this
753     /// borrow, it's just used when translating closures.
754     UniqueImmBorrow,
755
756     /// Data is mutable and not aliasable.
757     MutBorrow
758 }
759
760 /// Information describing the capture of an upvar. This is computed
761 /// during `typeck`, specifically by `regionck`.
762 #[derive(PartialEq, Clone, Debug, Copy)]
763 pub enum UpvarCapture {
764     /// Upvar is captured by value. This is always true when the
765     /// closure is labeled `move`, but can also be true in other cases
766     /// depending on inference.
767     ByValue,
768
769     /// Upvar is captured by reference.
770     ByRef(UpvarBorrow),
771 }
772
773 #[derive(PartialEq, Clone, Copy)]
774 pub struct UpvarBorrow {
775     /// The kind of borrow: by-ref upvars have access to shared
776     /// immutable borrows, which are not part of the normal language
777     /// syntax.
778     pub kind: BorrowKind,
779
780     /// Region of the resulting reference.
781     pub region: ty::Region,
782 }
783
784 pub type UpvarCaptureMap = FnvHashMap<UpvarId, UpvarCapture>;
785
786 #[derive(Copy, Clone)]
787 pub struct ClosureUpvar<'tcx> {
788     pub def: def::Def,
789     pub span: Span,
790     pub ty: Ty<'tcx>,
791 }
792
793 #[derive(Clone, Copy, PartialEq)]
794 pub enum IntVarValue {
795     IntType(hir::IntTy),
796     UintType(hir::UintTy),
797 }
798
799 /// Default region to use for the bound of objects that are
800 /// supplied as the value for this type parameter. This is derived
801 /// from `T:'a` annotations appearing in the type definition.  If
802 /// this is `None`, then the default is inherited from the
803 /// surrounding context. See RFC #599 for details.
804 #[derive(Copy, Clone)]
805 pub enum ObjectLifetimeDefault {
806     /// Require an explicit annotation. Occurs when multiple
807     /// `T:'a` constraints are found.
808     Ambiguous,
809
810     /// Use the base default, typically 'static, but in a fn body it is a fresh variable
811     BaseDefault,
812
813     /// Use the given region as the default.
814     Specific(Region),
815 }
816
817 #[derive(Clone)]
818 pub struct TypeParameterDef<'tcx> {
819     pub name: Name,
820     pub def_id: DefId,
821     pub space: subst::ParamSpace,
822     pub index: u32,
823     pub default_def_id: DefId, // for use in error reporing about defaults
824     pub default: Option<Ty<'tcx>>,
825     pub object_lifetime_default: ObjectLifetimeDefault,
826 }
827
828 #[derive(Clone)]
829 pub struct RegionParameterDef {
830     pub name: Name,
831     pub def_id: DefId,
832     pub space: subst::ParamSpace,
833     pub index: u32,
834     pub bounds: Vec<ty::Region>,
835 }
836
837 impl RegionParameterDef {
838     pub fn to_early_bound_region(&self) -> ty::Region {
839         ty::ReEarlyBound(ty::EarlyBoundRegion {
840             param_id: self.def_id.node,
841             space: self.space,
842             index: self.index,
843             name: self.name,
844         })
845     }
846     pub fn to_bound_region(&self) -> ty::BoundRegion {
847         ty::BoundRegion::BrNamed(self.def_id, self.name)
848     }
849 }
850
851 /// Information about the formal type/lifetime parameters associated
852 /// with an item or method. Analogous to hir::Generics.
853 #[derive(Clone, Debug)]
854 pub struct Generics<'tcx> {
855     pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
856     pub regions: VecPerParamSpace<RegionParameterDef>,
857 }
858
859 impl<'tcx> Generics<'tcx> {
860     pub fn empty() -> Generics<'tcx> {
861         Generics {
862             types: VecPerParamSpace::empty(),
863             regions: VecPerParamSpace::empty(),
864         }
865     }
866
867     pub fn is_empty(&self) -> bool {
868         self.types.is_empty() && self.regions.is_empty()
869     }
870
871     pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
872         !self.types.is_empty_in(space)
873     }
874
875     pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
876         !self.regions.is_empty_in(space)
877     }
878 }
879
880 /// Bounds on generics.
881 #[derive(Clone)]
882 pub struct GenericPredicates<'tcx> {
883     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
884 }
885
886 impl<'tcx> GenericPredicates<'tcx> {
887     pub fn empty() -> GenericPredicates<'tcx> {
888         GenericPredicates {
889             predicates: VecPerParamSpace::empty(),
890         }
891     }
892
893     pub fn instantiate(&self, tcx: &ctxt<'tcx>, substs: &Substs<'tcx>)
894                        -> InstantiatedPredicates<'tcx> {
895         InstantiatedPredicates {
896             predicates: self.predicates.subst(tcx, substs),
897         }
898     }
899
900     pub fn instantiate_supertrait(&self,
901                                   tcx: &ctxt<'tcx>,
902                                   poly_trait_ref: &ty::PolyTraitRef<'tcx>)
903                                   -> InstantiatedPredicates<'tcx>
904     {
905         InstantiatedPredicates {
906             predicates: self.predicates.map(|pred| pred.subst_supertrait(tcx, poly_trait_ref))
907         }
908     }
909 }
910
911 #[derive(Clone, PartialEq, Eq, Hash)]
912 pub enum Predicate<'tcx> {
913     /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
914     /// the `Self` type of the trait reference and `A`, `B`, and `C`
915     /// would be the parameters in the `TypeSpace`.
916     Trait(PolyTraitPredicate<'tcx>),
917
918     /// where `T1 == T2`.
919     Equate(PolyEquatePredicate<'tcx>),
920
921     /// where 'a : 'b
922     RegionOutlives(PolyRegionOutlivesPredicate),
923
924     /// where T : 'a
925     TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
926
927     /// where <T as TraitRef>::Name == X, approximately.
928     /// See `ProjectionPredicate` struct for details.
929     Projection(PolyProjectionPredicate<'tcx>),
930
931     /// no syntax: T WF
932     WellFormed(Ty<'tcx>),
933
934     /// trait must be object-safe
935     ObjectSafe(DefId),
936 }
937
938 impl<'tcx> Predicate<'tcx> {
939     /// Performs a substitution suitable for going from a
940     /// poly-trait-ref to supertraits that must hold if that
941     /// poly-trait-ref holds. This is slightly different from a normal
942     /// substitution in terms of what happens with bound regions.  See
943     /// lengthy comment below for details.
944     pub fn subst_supertrait(&self,
945                             tcx: &ctxt<'tcx>,
946                             trait_ref: &ty::PolyTraitRef<'tcx>)
947                             -> ty::Predicate<'tcx>
948     {
949         // The interaction between HRTB and supertraits is not entirely
950         // obvious. Let me walk you (and myself) through an example.
951         //
952         // Let's start with an easy case. Consider two traits:
953         //
954         //     trait Foo<'a> : Bar<'a,'a> { }
955         //     trait Bar<'b,'c> { }
956         //
957         // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
958         // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
959         // knew that `Foo<'x>` (for any 'x) then we also know that
960         // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
961         // normal substitution.
962         //
963         // In terms of why this is sound, the idea is that whenever there
964         // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
965         // holds.  So if there is an impl of `T:Foo<'a>` that applies to
966         // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
967         // `'a`.
968         //
969         // Another example to be careful of is this:
970         //
971         //     trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
972         //     trait Bar1<'b,'c> { }
973         //
974         // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
975         // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
976         // reason is similar to the previous example: any impl of
977         // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`.  So
978         // basically we would want to collapse the bound lifetimes from
979         // the input (`trait_ref`) and the supertraits.
980         //
981         // To achieve this in practice is fairly straightforward. Let's
982         // consider the more complicated scenario:
983         //
984         // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
985         //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
986         //   where both `'x` and `'b` would have a DB index of 1.
987         //   The substitution from the input trait-ref is therefore going to be
988         //   `'a => 'x` (where `'x` has a DB index of 1).
989         // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
990         //   early-bound parameter and `'b' is a late-bound parameter with a
991         //   DB index of 1.
992         // - If we replace `'a` with `'x` from the input, it too will have
993         //   a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
994         //   just as we wanted.
995         //
996         // There is only one catch. If we just apply the substitution `'a
997         // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
998         // adjust the DB index because we substituting into a binder (it
999         // tries to be so smart...) resulting in `for<'x> for<'b>
1000         // Bar1<'x,'b>` (we have no syntax for this, so use your
1001         // imagination). Basically the 'x will have DB index of 2 and 'b
1002         // will have DB index of 1. Not quite what we want. So we apply
1003         // the substitution to the *contents* of the trait reference,
1004         // rather than the trait reference itself (put another way, the
1005         // substitution code expects equal binding levels in the values
1006         // from the substitution and the value being substituted into, and
1007         // this trick achieves that).
1008
1009         let substs = &trait_ref.0.substs;
1010         match *self {
1011             Predicate::Trait(ty::Binder(ref data)) =>
1012                 Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
1013             Predicate::Equate(ty::Binder(ref data)) =>
1014                 Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
1015             Predicate::RegionOutlives(ty::Binder(ref data)) =>
1016                 Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))),
1017             Predicate::TypeOutlives(ty::Binder(ref data)) =>
1018                 Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))),
1019             Predicate::Projection(ty::Binder(ref data)) =>
1020                 Predicate::Projection(ty::Binder(data.subst(tcx, substs))),
1021             Predicate::WellFormed(data) =>
1022                 Predicate::WellFormed(data.subst(tcx, substs)),
1023             Predicate::ObjectSafe(trait_def_id) =>
1024                 Predicate::ObjectSafe(trait_def_id),
1025         }
1026     }
1027 }
1028
1029 #[derive(Clone, PartialEq, Eq, Hash)]
1030 pub struct TraitPredicate<'tcx> {
1031     pub trait_ref: TraitRef<'tcx>
1032 }
1033 pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
1034
1035 impl<'tcx> TraitPredicate<'tcx> {
1036     pub fn def_id(&self) -> DefId {
1037         self.trait_ref.def_id
1038     }
1039
1040     pub fn input_types(&self) -> &[Ty<'tcx>] {
1041         self.trait_ref.substs.types.as_slice()
1042     }
1043
1044     pub fn self_ty(&self) -> Ty<'tcx> {
1045         self.trait_ref.self_ty()
1046     }
1047 }
1048
1049 impl<'tcx> PolyTraitPredicate<'tcx> {
1050     pub fn def_id(&self) -> DefId {
1051         self.0.def_id()
1052     }
1053 }
1054
1055 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1056 pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
1057 pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
1058
1059 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1060 pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
1061 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
1062 pub type PolyRegionOutlivesPredicate = PolyOutlivesPredicate<ty::Region, ty::Region>;
1063 pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region>;
1064
1065 /// This kind of predicate has no *direct* correspondent in the
1066 /// syntax, but it roughly corresponds to the syntactic forms:
1067 ///
1068 /// 1. `T : TraitRef<..., Item=Type>`
1069 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
1070 ///
1071 /// In particular, form #1 is "desugared" to the combination of a
1072 /// normal trait predicate (`T : TraitRef<...>`) and one of these
1073 /// predicates. Form #2 is a broader form in that it also permits
1074 /// equality between arbitrary types. Processing an instance of Form
1075 /// #2 eventually yields one of these `ProjectionPredicate`
1076 /// instances to normalize the LHS.
1077 #[derive(Clone, PartialEq, Eq, Hash)]
1078 pub struct ProjectionPredicate<'tcx> {
1079     pub projection_ty: ProjectionTy<'tcx>,
1080     pub ty: Ty<'tcx>,
1081 }
1082
1083 pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
1084
1085 impl<'tcx> PolyProjectionPredicate<'tcx> {
1086     pub fn item_name(&self) -> Name {
1087         self.0.projection_ty.item_name // safe to skip the binder to access a name
1088     }
1089
1090     pub fn sort_key(&self) -> (DefId, Name) {
1091         self.0.projection_ty.sort_key()
1092     }
1093 }
1094
1095 pub trait ToPolyTraitRef<'tcx> {
1096     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
1097 }
1098
1099 impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
1100     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1101         assert!(!self.has_escaping_regions());
1102         ty::Binder(self.clone())
1103     }
1104 }
1105
1106 impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
1107     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1108         self.map_bound_ref(|trait_pred| trait_pred.trait_ref.clone())
1109     }
1110 }
1111
1112 impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
1113     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1114         // Note: unlike with TraitRef::to_poly_trait_ref(),
1115         // self.0.trait_ref is permitted to have escaping regions.
1116         // This is because here `self` has a `Binder` and so does our
1117         // return value, so we are preserving the number of binding
1118         // levels.
1119         ty::Binder(self.0.projection_ty.trait_ref.clone())
1120     }
1121 }
1122
1123 pub trait ToPredicate<'tcx> {
1124     fn to_predicate(&self) -> Predicate<'tcx>;
1125 }
1126
1127 impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
1128     fn to_predicate(&self) -> Predicate<'tcx> {
1129         // we're about to add a binder, so let's check that we don't
1130         // accidentally capture anything, or else that might be some
1131         // weird debruijn accounting.
1132         assert!(!self.has_escaping_regions());
1133
1134         ty::Predicate::Trait(ty::Binder(ty::TraitPredicate {
1135             trait_ref: self.clone()
1136         }))
1137     }
1138 }
1139
1140 impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
1141     fn to_predicate(&self) -> Predicate<'tcx> {
1142         ty::Predicate::Trait(self.to_poly_trait_predicate())
1143     }
1144 }
1145
1146 impl<'tcx> ToPredicate<'tcx> for PolyEquatePredicate<'tcx> {
1147     fn to_predicate(&self) -> Predicate<'tcx> {
1148         Predicate::Equate(self.clone())
1149     }
1150 }
1151
1152 impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate {
1153     fn to_predicate(&self) -> Predicate<'tcx> {
1154         Predicate::RegionOutlives(self.clone())
1155     }
1156 }
1157
1158 impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
1159     fn to_predicate(&self) -> Predicate<'tcx> {
1160         Predicate::TypeOutlives(self.clone())
1161     }
1162 }
1163
1164 impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
1165     fn to_predicate(&self) -> Predicate<'tcx> {
1166         Predicate::Projection(self.clone())
1167     }
1168 }
1169
1170 impl<'tcx> Predicate<'tcx> {
1171     /// Iterates over the types in this predicate. Note that in all
1172     /// cases this is skipping over a binder, so late-bound regions
1173     /// with depth 0 are bound by the predicate.
1174     pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
1175         let vec: Vec<_> = match *self {
1176             ty::Predicate::Trait(ref data) => {
1177                 data.0.trait_ref.substs.types.as_slice().to_vec()
1178             }
1179             ty::Predicate::Equate(ty::Binder(ref data)) => {
1180                 vec![data.0, data.1]
1181             }
1182             ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
1183                 vec![data.0]
1184             }
1185             ty::Predicate::RegionOutlives(..) => {
1186                 vec![]
1187             }
1188             ty::Predicate::Projection(ref data) => {
1189                 let trait_inputs = data.0.projection_ty.trait_ref.substs.types.as_slice();
1190                 trait_inputs.iter()
1191                             .cloned()
1192                             .chain(Some(data.0.ty))
1193                             .collect()
1194             }
1195             ty::Predicate::WellFormed(data) => {
1196                 vec![data]
1197             }
1198             ty::Predicate::ObjectSafe(_trait_def_id) => {
1199                 vec![]
1200             }
1201         };
1202
1203         // The only reason to collect into a vector here is that I was
1204         // too lazy to make the full (somewhat complicated) iterator
1205         // type that would be needed here. But I wanted this fn to
1206         // return an iterator conceptually, rather than a `Vec`, so as
1207         // to be closer to `Ty::walk`.
1208         vec.into_iter()
1209     }
1210
1211     pub fn has_escaping_regions(&self) -> bool {
1212         match *self {
1213             Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(),
1214             Predicate::Equate(ref p) => p.has_escaping_regions(),
1215             Predicate::RegionOutlives(ref p) => p.has_escaping_regions(),
1216             Predicate::TypeOutlives(ref p) => p.has_escaping_regions(),
1217             Predicate::Projection(ref p) => p.has_escaping_regions(),
1218             Predicate::WellFormed(p) => p.has_escaping_regions(),
1219             Predicate::ObjectSafe(_trait_def_id) => false,
1220         }
1221     }
1222
1223     pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
1224         match *self {
1225             Predicate::Trait(ref t) => {
1226                 Some(t.to_poly_trait_ref())
1227             }
1228             Predicate::Projection(..) |
1229             Predicate::Equate(..) |
1230             Predicate::RegionOutlives(..) |
1231             Predicate::WellFormed(..) |
1232             Predicate::ObjectSafe(..) |
1233             Predicate::TypeOutlives(..) => {
1234                 None
1235             }
1236         }
1237     }
1238 }
1239
1240 /// Represents the bounds declared on a particular set of type
1241 /// parameters.  Should eventually be generalized into a flag list of
1242 /// where clauses.  You can obtain a `InstantiatedPredicates` list from a
1243 /// `GenericPredicates` by using the `instantiate` method. Note that this method
1244 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
1245 /// the `GenericPredicates` are expressed in terms of the bound type
1246 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
1247 /// represented a set of bounds for some particular instantiation,
1248 /// meaning that the generic parameters have been substituted with
1249 /// their values.
1250 ///
1251 /// Example:
1252 ///
1253 ///     struct Foo<T,U:Bar<T>> { ... }
1254 ///
1255 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
1256 /// `[[], [U:Bar<T>]]`.  Now if there were some particular reference
1257 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
1258 /// [usize:Bar<isize>]]`.
1259 #[derive(Clone)]
1260 pub struct InstantiatedPredicates<'tcx> {
1261     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
1262 }
1263
1264 impl<'tcx> InstantiatedPredicates<'tcx> {
1265     pub fn empty() -> InstantiatedPredicates<'tcx> {
1266         InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
1267     }
1268
1269     pub fn has_escaping_regions(&self) -> bool {
1270         self.predicates.any(|p| p.has_escaping_regions())
1271     }
1272
1273     pub fn is_empty(&self) -> bool {
1274         self.predicates.is_empty()
1275     }
1276 }
1277
1278 impl<'tcx> TraitRef<'tcx> {
1279     pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
1280         TraitRef { def_id: def_id, substs: substs }
1281     }
1282
1283     pub fn self_ty(&self) -> Ty<'tcx> {
1284         self.substs.self_ty().unwrap()
1285     }
1286
1287     pub fn input_types(&self) -> &[Ty<'tcx>] {
1288         // Select only the "input types" from a trait-reference. For
1289         // now this is all the types that appear in the
1290         // trait-reference, but it should eventually exclude
1291         // associated types.
1292         self.substs.types.as_slice()
1293     }
1294 }
1295
1296 /// When type checking, we use the `ParameterEnvironment` to track
1297 /// details about the type/lifetime parameters that are in scope.
1298 /// It primarily stores the bounds information.
1299 ///
1300 /// Note: This information might seem to be redundant with the data in
1301 /// `tcx.ty_param_defs`, but it is not. That table contains the
1302 /// parameter definitions from an "outside" perspective, but this
1303 /// struct will contain the bounds for a parameter as seen from inside
1304 /// the function body. Currently the only real distinction is that
1305 /// bound lifetime parameters are replaced with free ones, but in the
1306 /// future I hope to refine the representation of types so as to make
1307 /// more distinctions clearer.
1308 #[derive(Clone)]
1309 pub struct ParameterEnvironment<'a, 'tcx:'a> {
1310     pub tcx: &'a ctxt<'tcx>,
1311
1312     /// See `construct_free_substs` for details.
1313     pub free_substs: Substs<'tcx>,
1314
1315     /// Each type parameter has an implicit region bound that
1316     /// indicates it must outlive at least the function body (the user
1317     /// may specify stronger requirements). This field indicates the
1318     /// region of the callee.
1319     pub implicit_region_bound: ty::Region,
1320
1321     /// Obligations that the caller must satisfy. This is basically
1322     /// the set of bounds on the in-scope type parameters, translated
1323     /// into Obligations, and elaborated and normalized.
1324     pub caller_bounds: Vec<ty::Predicate<'tcx>>,
1325
1326     /// Caches the results of trait selection. This cache is used
1327     /// for things that have to do with the parameters in scope.
1328     pub selection_cache: traits::SelectionCache<'tcx>,
1329
1330     /// Scope that is attached to free regions for this scope. This
1331     /// is usually the id of the fn body, but for more abstract scopes
1332     /// like structs we often use the node-id of the struct.
1333     ///
1334     /// FIXME(#3696). It would be nice to refactor so that free
1335     /// regions don't have this implicit scope and instead introduce
1336     /// relationships in the environment.
1337     pub free_id: ast::NodeId,
1338 }
1339
1340 impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
1341     pub fn with_caller_bounds(&self,
1342                               caller_bounds: Vec<ty::Predicate<'tcx>>)
1343                               -> ParameterEnvironment<'a,'tcx>
1344     {
1345         ParameterEnvironment {
1346             tcx: self.tcx,
1347             free_substs: self.free_substs.clone(),
1348             implicit_region_bound: self.implicit_region_bound,
1349             caller_bounds: caller_bounds,
1350             selection_cache: traits::SelectionCache::new(),
1351             free_id: self.free_id,
1352         }
1353     }
1354
1355     pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
1356         match cx.map.find(id) {
1357             Some(ast_map::NodeImplItem(ref impl_item)) => {
1358                 match impl_item.node {
1359                     hir::TypeImplItem(_) => {
1360                         // associated types don't have their own entry (for some reason),
1361                         // so for now just grab environment for the impl
1362                         let impl_id = cx.map.get_parent(id);
1363                         let impl_def_id = DefId::local(impl_id);
1364                         let scheme = cx.lookup_item_type(impl_def_id);
1365                         let predicates = cx.lookup_predicates(impl_def_id);
1366                         cx.construct_parameter_environment(impl_item.span,
1367                                                            &scheme.generics,
1368                                                            &predicates,
1369                                                            id)
1370                     }
1371                     hir::ConstImplItem(_, _) => {
1372                         let def_id = DefId::local(id);
1373                         let scheme = cx.lookup_item_type(def_id);
1374                         let predicates = cx.lookup_predicates(def_id);
1375                         cx.construct_parameter_environment(impl_item.span,
1376                                                            &scheme.generics,
1377                                                            &predicates,
1378                                                            id)
1379                     }
1380                     hir::MethodImplItem(_, ref body) => {
1381                         let method_def_id = DefId::local(id);
1382                         match cx.impl_or_trait_item(method_def_id) {
1383                             MethodTraitItem(ref method_ty) => {
1384                                 let method_generics = &method_ty.generics;
1385                                 let method_bounds = &method_ty.predicates;
1386                                 cx.construct_parameter_environment(
1387                                     impl_item.span,
1388                                     method_generics,
1389                                     method_bounds,
1390                                     body.id)
1391                             }
1392                             _ => {
1393                                 cx.sess
1394                                   .bug("ParameterEnvironment::for_item(): \
1395                                         got non-method item from impl method?!")
1396                             }
1397                         }
1398                     }
1399                 }
1400             }
1401             Some(ast_map::NodeTraitItem(trait_item)) => {
1402                 match trait_item.node {
1403                     hir::TypeTraitItem(..) => {
1404                         // associated types don't have their own entry (for some reason),
1405                         // so for now just grab environment for the trait
1406                         let trait_id = cx.map.get_parent(id);
1407                         let trait_def_id = DefId::local(trait_id);
1408                         let trait_def = cx.lookup_trait_def(trait_def_id);
1409                         let predicates = cx.lookup_predicates(trait_def_id);
1410                         cx.construct_parameter_environment(trait_item.span,
1411                                                            &trait_def.generics,
1412                                                            &predicates,
1413                                                            id)
1414                     }
1415                     hir::ConstTraitItem(..) => {
1416                         let def_id = DefId::local(id);
1417                         let scheme = cx.lookup_item_type(def_id);
1418                         let predicates = cx.lookup_predicates(def_id);
1419                         cx.construct_parameter_environment(trait_item.span,
1420                                                            &scheme.generics,
1421                                                            &predicates,
1422                                                            id)
1423                     }
1424                     hir::MethodTraitItem(_, ref body) => {
1425                         // for the body-id, use the id of the body
1426                         // block, unless this is a trait method with
1427                         // no default, then fallback to the method id.
1428                         let body_id = body.as_ref().map(|b| b.id).unwrap_or(id);
1429                         let method_def_id = DefId::local(id);
1430
1431                         match cx.impl_or_trait_item(method_def_id) {
1432                             MethodTraitItem(ref method_ty) => {
1433                                 let method_generics = &method_ty.generics;
1434                                 let method_bounds = &method_ty.predicates;
1435                                 cx.construct_parameter_environment(
1436                                     trait_item.span,
1437                                     method_generics,
1438                                     method_bounds,
1439                                     body_id)
1440                             }
1441                             _ => {
1442                                 cx.sess
1443                                   .bug("ParameterEnvironment::for_item(): \
1444                                         got non-method item from provided \
1445                                         method?!")
1446                             }
1447                         }
1448                     }
1449                 }
1450             }
1451             Some(ast_map::NodeItem(item)) => {
1452                 match item.node {
1453                     hir::ItemFn(_, _, _, _, _, ref body) => {
1454                         // We assume this is a function.
1455                         let fn_def_id = DefId::local(id);
1456                         let fn_scheme = cx.lookup_item_type(fn_def_id);
1457                         let fn_predicates = cx.lookup_predicates(fn_def_id);
1458
1459                         cx.construct_parameter_environment(item.span,
1460                                                            &fn_scheme.generics,
1461                                                            &fn_predicates,
1462                                                            body.id)
1463                     }
1464                     hir::ItemEnum(..) |
1465                     hir::ItemStruct(..) |
1466                     hir::ItemImpl(..) |
1467                     hir::ItemConst(..) |
1468                     hir::ItemStatic(..) => {
1469                         let def_id = DefId::local(id);
1470                         let scheme = cx.lookup_item_type(def_id);
1471                         let predicates = cx.lookup_predicates(def_id);
1472                         cx.construct_parameter_environment(item.span,
1473                                                            &scheme.generics,
1474                                                            &predicates,
1475                                                            id)
1476                     }
1477                     hir::ItemTrait(..) => {
1478                         let def_id = DefId::local(id);
1479                         let trait_def = cx.lookup_trait_def(def_id);
1480                         let predicates = cx.lookup_predicates(def_id);
1481                         cx.construct_parameter_environment(item.span,
1482                                                            &trait_def.generics,
1483                                                            &predicates,
1484                                                            id)
1485                     }
1486                     _ => {
1487                         cx.sess.span_bug(item.span,
1488                                          "ParameterEnvironment::from_item():
1489                                           can't create a parameter \
1490                                           environment for this kind of item")
1491                     }
1492                 }
1493             }
1494             Some(ast_map::NodeExpr(..)) => {
1495                 // This is a convenience to allow closures to work.
1496                 ParameterEnvironment::for_item(cx, cx.map.get_parent(id))
1497             }
1498             _ => {
1499                 cx.sess.bug(&format!("ParameterEnvironment::from_item(): \
1500                                      `{}` is not an item",
1501                                     cx.map.node_to_string(id)))
1502             }
1503         }
1504     }
1505
1506     pub fn can_type_implement_copy(&self, self_type: Ty<'tcx>, span: Span)
1507                                    -> Result<(),CopyImplementationError> {
1508         let tcx = self.tcx;
1509
1510         // FIXME: (@jroesch) float this code up
1511         let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(self.clone()), false);
1512
1513         let adt = match self_type.sty {
1514             ty::TyStruct(struct_def, substs) => {
1515                 for field in struct_def.all_fields() {
1516                     let field_ty = field.ty(tcx, substs);
1517                     if infcx.type_moves_by_default(field_ty, span) {
1518                         return Err(FieldDoesNotImplementCopy(field.name))
1519                     }
1520                 }
1521                 struct_def
1522             }
1523             ty::TyEnum(enum_def, substs) => {
1524                 for variant in &enum_def.variants {
1525                     for field in &variant.fields {
1526                         let field_ty = field.ty(tcx, substs);
1527                         if infcx.type_moves_by_default(field_ty, span) {
1528                             return Err(VariantDoesNotImplementCopy(variant.name))
1529                         }
1530                     }
1531                 }
1532                 enum_def
1533             }
1534             _ => return Err(TypeIsStructural),
1535         };
1536
1537         if adt.has_dtor() {
1538             return Err(TypeHasDestructor)
1539         }
1540
1541         Ok(())
1542     }
1543 }
1544
1545 #[derive(Copy, Clone)]
1546 pub enum CopyImplementationError {
1547     FieldDoesNotImplementCopy(Name),
1548     VariantDoesNotImplementCopy(Name),
1549     TypeIsStructural,
1550     TypeHasDestructor,
1551 }
1552
1553 /// A "type scheme", in ML terminology, is a type combined with some
1554 /// set of generic types that the type is, well, generic over. In Rust
1555 /// terms, it is the "type" of a fn item or struct -- this type will
1556 /// include various generic parameters that must be substituted when
1557 /// the item/struct is referenced. That is called converting the type
1558 /// scheme to a monotype.
1559 ///
1560 /// - `generics`: the set of type parameters and their bounds
1561 /// - `ty`: the base types, which may reference the parameters defined
1562 ///   in `generics`
1563 ///
1564 /// Note that TypeSchemes are also sometimes called "polytypes" (and
1565 /// in fact this struct used to carry that name, so you may find some
1566 /// stray references in a comment or something). We try to reserve the
1567 /// "poly" prefix to refer to higher-ranked things, as in
1568 /// `PolyTraitRef`.
1569 ///
1570 /// Note that each item also comes with predicates, see
1571 /// `lookup_predicates`.
1572 #[derive(Clone, Debug)]
1573 pub struct TypeScheme<'tcx> {
1574     pub generics: Generics<'tcx>,
1575     pub ty: Ty<'tcx>,
1576 }
1577
1578 bitflags! {
1579     flags TraitFlags: u32 {
1580         const NO_TRAIT_FLAGS        = 0,
1581         const HAS_DEFAULT_IMPL      = 1 << 0,
1582         const IS_OBJECT_SAFE        = 1 << 1,
1583         const OBJECT_SAFETY_VALID   = 1 << 2,
1584         const IMPLS_VALID           = 1 << 3,
1585     }
1586 }
1587
1588 /// As `TypeScheme` but for a trait ref.
1589 pub struct TraitDef<'tcx> {
1590     pub unsafety: hir::Unsafety,
1591
1592     /// If `true`, then this trait had the `#[rustc_paren_sugar]`
1593     /// attribute, indicating that it should be used with `Foo()`
1594     /// sugar. This is a temporary thing -- eventually any trait wil
1595     /// be usable with the sugar (or without it).
1596     pub paren_sugar: bool,
1597
1598     /// Generic type definitions. Note that `Self` is listed in here
1599     /// as having a single bound, the trait itself (e.g., in the trait
1600     /// `Eq`, there is a single bound `Self : Eq`). This is so that
1601     /// default methods get to assume that the `Self` parameters
1602     /// implements the trait.
1603     pub generics: Generics<'tcx>,
1604
1605     pub trait_ref: TraitRef<'tcx>,
1606
1607     /// A list of the associated types defined in this trait. Useful
1608     /// for resolving `X::Foo` type markers.
1609     pub associated_type_names: Vec<Name>,
1610
1611     // Impls of this trait. To allow for quicker lookup, the impls are indexed
1612     // by a simplified version of their Self type: impls with a simplifiable
1613     // Self are stored in nonblanket_impls keyed by it, while all other impls
1614     // are stored in blanket_impls.
1615
1616     /// Impls of the trait.
1617     pub nonblanket_impls: RefCell<
1618         FnvHashMap<fast_reject::SimplifiedType, Vec<DefId>>
1619     >,
1620
1621     /// Blanket impls associated with the trait.
1622     pub blanket_impls: RefCell<Vec<DefId>>,
1623
1624     /// Various flags
1625     pub flags: Cell<TraitFlags>
1626 }
1627
1628 impl<'tcx> TraitDef<'tcx> {
1629     // returns None if not yet calculated
1630     pub fn object_safety(&self) -> Option<bool> {
1631         if self.flags.get().intersects(TraitFlags::OBJECT_SAFETY_VALID) {
1632             Some(self.flags.get().intersects(TraitFlags::IS_OBJECT_SAFE))
1633         } else {
1634             None
1635         }
1636     }
1637
1638     pub fn set_object_safety(&self, is_safe: bool) {
1639         assert!(self.object_safety().map(|cs| cs == is_safe).unwrap_or(true));
1640         self.flags.set(
1641             self.flags.get() | if is_safe {
1642                 TraitFlags::OBJECT_SAFETY_VALID | TraitFlags::IS_OBJECT_SAFE
1643             } else {
1644                 TraitFlags::OBJECT_SAFETY_VALID
1645             }
1646         );
1647     }
1648
1649     /// Records a trait-to-implementation mapping.
1650     pub fn record_impl(&self,
1651                        tcx: &ctxt<'tcx>,
1652                        impl_def_id: DefId,
1653                        impl_trait_ref: TraitRef<'tcx>) {
1654         debug!("TraitDef::record_impl for {:?}, from {:?}",
1655                self, impl_trait_ref);
1656
1657         // We don't want to borrow_mut after we already populated all impls,
1658         // so check if an impl is present with an immutable borrow first.
1659         if let Some(sty) = fast_reject::simplify_type(tcx,
1660                                                       impl_trait_ref.self_ty(), false) {
1661             if let Some(is) = self.nonblanket_impls.borrow().get(&sty) {
1662                 if is.contains(&impl_def_id) {
1663                     return // duplicate - skip
1664                 }
1665             }
1666
1667             self.nonblanket_impls.borrow_mut().entry(sty).or_insert(vec![]).push(impl_def_id)
1668         } else {
1669             if self.blanket_impls.borrow().contains(&impl_def_id) {
1670                 return // duplicate - skip
1671             }
1672             self.blanket_impls.borrow_mut().push(impl_def_id)
1673         }
1674     }
1675
1676
1677     pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: &ctxt<'tcx>, mut f: F)  {
1678         tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
1679
1680         for &impl_def_id in self.blanket_impls.borrow().iter() {
1681             f(impl_def_id);
1682         }
1683
1684         for v in self.nonblanket_impls.borrow().values() {
1685             for &impl_def_id in v {
1686                 f(impl_def_id);
1687             }
1688         }
1689     }
1690
1691     /// Iterate over every impl that could possibly match the
1692     /// self-type `self_ty`.
1693     pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
1694                                                    tcx: &ctxt<'tcx>,
1695                                                    self_ty: Ty<'tcx>,
1696                                                    mut f: F)
1697     {
1698         tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
1699
1700         for &impl_def_id in self.blanket_impls.borrow().iter() {
1701             f(impl_def_id);
1702         }
1703
1704         // simplify_type(.., false) basically replaces type parameters and
1705         // projections with infer-variables. This is, of course, done on
1706         // the impl trait-ref when it is instantiated, but not on the
1707         // predicate trait-ref which is passed here.
1708         //
1709         // for example, if we match `S: Copy` against an impl like
1710         // `impl<T:Copy> Copy for Option<T>`, we replace the type variable
1711         // in `Option<T>` with an infer variable, to `Option<_>` (this
1712         // doesn't actually change fast_reject output), but we don't
1713         // replace `S` with anything - this impl of course can't be
1714         // selected, and as there are hundreds of similar impls,
1715         // considering them would significantly harm performance.
1716         if let Some(simp) = fast_reject::simplify_type(tcx, self_ty, true) {
1717             if let Some(impls) = self.nonblanket_impls.borrow().get(&simp) {
1718                 for &impl_def_id in impls {
1719                     f(impl_def_id);
1720                 }
1721             }
1722         } else {
1723             for v in self.nonblanket_impls.borrow().values() {
1724                 for &impl_def_id in v {
1725                     f(impl_def_id);
1726                 }
1727             }
1728         }
1729     }
1730
1731 }
1732
1733 bitflags! {
1734     flags AdtFlags: u32 {
1735         const NO_ADT_FLAGS        = 0,
1736         const IS_ENUM             = 1 << 0,
1737         const IS_DTORCK           = 1 << 1, // is this a dtorck type?
1738         const IS_DTORCK_VALID     = 1 << 2,
1739         const IS_PHANTOM_DATA     = 1 << 3,
1740         const IS_SIMD             = 1 << 4,
1741         const IS_FUNDAMENTAL      = 1 << 5,
1742         const IS_NO_DROP_FLAG     = 1 << 6,
1743     }
1744 }
1745
1746 pub type AdtDef<'tcx> = &'tcx AdtDefData<'tcx, 'static>;
1747 pub type VariantDef<'tcx> = &'tcx VariantDefData<'tcx, 'static>;
1748 pub type FieldDef<'tcx> = &'tcx FieldDefData<'tcx, 'static>;
1749
1750 // See comment on AdtDefData for explanation
1751 pub type AdtDefMaster<'tcx> = &'tcx AdtDefData<'tcx, 'tcx>;
1752 pub type VariantDefMaster<'tcx> = &'tcx VariantDefData<'tcx, 'tcx>;
1753 pub type FieldDefMaster<'tcx> = &'tcx FieldDefData<'tcx, 'tcx>;
1754
1755 pub struct VariantDefData<'tcx, 'container: 'tcx> {
1756     pub did: DefId,
1757     pub name: Name, // struct's name if this is a struct
1758     pub disr_val: Disr,
1759     pub fields: Vec<FieldDefData<'tcx, 'container>>
1760 }
1761
1762 pub struct FieldDefData<'tcx, 'container: 'tcx> {
1763     /// The field's DefId. NOTE: the fields of tuple-like enum variants
1764     /// are not real items, and don't have entries in tcache etc.
1765     pub did: DefId,
1766     /// special_idents::unnamed_field.name
1767     /// if this is a tuple-like field
1768     pub name: Name,
1769     pub vis: hir::Visibility,
1770     /// TyIVar is used here to allow for variance (see the doc at
1771     /// AdtDefData).
1772     ty: ivar::TyIVar<'tcx, 'container>
1773 }
1774
1775 /// The definition of an abstract data type - a struct or enum.
1776 ///
1777 /// These are all interned (by intern_adt_def) into the adt_defs
1778 /// table.
1779 ///
1780 /// Because of the possibility of nested tcx-s, this type
1781 /// needs 2 lifetimes: the traditional variant lifetime ('tcx)
1782 /// bounding the lifetime of the inner types is of course necessary.
1783 /// However, it is not sufficient - types from a child tcx must
1784 /// not be leaked into the master tcx by being stored in an AdtDefData.
1785 ///
1786 /// The 'container lifetime ensures that by outliving the container
1787 /// tcx and preventing shorter-lived types from being inserted. When
1788 /// write access is not needed, the 'container lifetime can be
1789 /// erased to 'static, which can be done by the AdtDef wrapper.
1790 pub struct AdtDefData<'tcx, 'container: 'tcx> {
1791     pub did: DefId,
1792     pub variants: Vec<VariantDefData<'tcx, 'container>>,
1793     destructor: Cell<Option<DefId>>,
1794     flags: Cell<AdtFlags>,
1795 }
1796
1797 impl<'tcx, 'container> PartialEq for AdtDefData<'tcx, 'container> {
1798     // AdtDefData are always interned and this is part of TyS equality
1799     #[inline]
1800     fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ }
1801 }
1802
1803 impl<'tcx, 'container> Eq for AdtDefData<'tcx, 'container> {}
1804
1805 impl<'tcx, 'container> Hash for AdtDefData<'tcx, 'container> {
1806     #[inline]
1807     fn hash<H: Hasher>(&self, s: &mut H) {
1808         (self as *const AdtDefData).hash(s)
1809     }
1810 }
1811
1812
1813 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1814 pub enum AdtKind { Struct, Enum }
1815
1816 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1817 pub enum VariantKind { Dict, Tuple, Unit }
1818
1819 impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
1820     fn new(tcx: &ctxt<'tcx>,
1821            did: DefId,
1822            kind: AdtKind,
1823            variants: Vec<VariantDefData<'tcx, 'container>>) -> Self {
1824         let mut flags = AdtFlags::NO_ADT_FLAGS;
1825         let attrs = tcx.get_attrs(did);
1826         if attr::contains_name(&attrs, "fundamental") {
1827             flags = flags | AdtFlags::IS_FUNDAMENTAL;
1828         }
1829         if attr::contains_name(&attrs, "unsafe_no_drop_flag") {
1830             flags = flags | AdtFlags::IS_NO_DROP_FLAG;
1831         }
1832         if tcx.lookup_simd(did) {
1833             flags = flags | AdtFlags::IS_SIMD;
1834         }
1835         if Some(did) == tcx.lang_items.phantom_data() {
1836             flags = flags | AdtFlags::IS_PHANTOM_DATA;
1837         }
1838         if let AdtKind::Enum = kind {
1839             flags = flags | AdtFlags::IS_ENUM;
1840         }
1841         AdtDefData {
1842             did: did,
1843             variants: variants,
1844             flags: Cell::new(flags),
1845             destructor: Cell::new(None)
1846         }
1847     }
1848
1849     fn calculate_dtorck(&'tcx self, tcx: &ctxt<'tcx>) {
1850         if tcx.is_adt_dtorck(self) {
1851             self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK);
1852         }
1853         self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK_VALID)
1854     }
1855
1856     /// Returns the kind of the ADT - Struct or Enum.
1857     #[inline]
1858     pub fn adt_kind(&self) -> AdtKind {
1859         if self.flags.get().intersects(AdtFlags::IS_ENUM) {
1860             AdtKind::Enum
1861         } else {
1862             AdtKind::Struct
1863         }
1864     }
1865
1866     /// Returns whether this is a dtorck type. If this returns
1867     /// true, this type being safe for destruction requires it to be
1868     /// alive; Otherwise, only the contents are required to be.
1869     #[inline]
1870     pub fn is_dtorck(&'tcx self, tcx: &ctxt<'tcx>) -> bool {
1871         if !self.flags.get().intersects(AdtFlags::IS_DTORCK_VALID) {
1872             self.calculate_dtorck(tcx)
1873         }
1874         self.flags.get().intersects(AdtFlags::IS_DTORCK)
1875     }
1876
1877     /// Returns whether this type is #[fundamental] for the purposes
1878     /// of coherence checking.
1879     #[inline]
1880     pub fn is_fundamental(&self) -> bool {
1881         self.flags.get().intersects(AdtFlags::IS_FUNDAMENTAL)
1882     }
1883
1884     #[inline]
1885     pub fn is_simd(&self) -> bool {
1886         self.flags.get().intersects(AdtFlags::IS_SIMD)
1887     }
1888
1889     /// Returns true if this is PhantomData<T>.
1890     #[inline]
1891     pub fn is_phantom_data(&self) -> bool {
1892         self.flags.get().intersects(AdtFlags::IS_PHANTOM_DATA)
1893     }
1894
1895     /// Returns whether this type has a destructor.
1896     pub fn has_dtor(&self) -> bool {
1897         match self.dtor_kind() {
1898             NoDtor => false,
1899             TraitDtor(..) => true
1900         }
1901     }
1902
1903     /// Asserts this is a struct and returns the struct's unique
1904     /// variant.
1905     pub fn struct_variant(&self) -> &VariantDefData<'tcx, 'container> {
1906         assert!(self.adt_kind() == AdtKind::Struct);
1907         &self.variants[0]
1908     }
1909
1910     #[inline]
1911     pub fn type_scheme(&self, tcx: &ctxt<'tcx>) -> TypeScheme<'tcx> {
1912         tcx.lookup_item_type(self.did)
1913     }
1914
1915     #[inline]
1916     pub fn predicates(&self, tcx: &ctxt<'tcx>) -> GenericPredicates<'tcx> {
1917         tcx.lookup_predicates(self.did)
1918     }
1919
1920     /// Returns an iterator over all fields contained
1921     /// by this ADT.
1922     #[inline]
1923     pub fn all_fields(&self) ->
1924             iter::FlatMap<
1925                 slice::Iter<VariantDefData<'tcx, 'container>>,
1926                 slice::Iter<FieldDefData<'tcx, 'container>>,
1927                 for<'s> fn(&'s VariantDefData<'tcx, 'container>)
1928                     -> slice::Iter<'s, FieldDefData<'tcx, 'container>>
1929             > {
1930         self.variants.iter().flat_map(VariantDefData::fields_iter)
1931     }
1932
1933     #[inline]
1934     pub fn is_empty(&self) -> bool {
1935         self.variants.is_empty()
1936     }
1937
1938     #[inline]
1939     pub fn is_univariant(&self) -> bool {
1940         self.variants.len() == 1
1941     }
1942
1943     pub fn is_payloadfree(&self) -> bool {
1944         !self.variants.is_empty() &&
1945             self.variants.iter().all(|v| v.fields.is_empty())
1946     }
1947
1948     pub fn variant_with_id(&self, vid: DefId) -> &VariantDefData<'tcx, 'container> {
1949         self.variants
1950             .iter()
1951             .find(|v| v.did == vid)
1952             .expect("variant_with_id: unknown variant")
1953     }
1954
1955     pub fn variant_index_with_id(&self, vid: DefId) -> usize {
1956         self.variants
1957             .iter()
1958             .position(|v| v.did == vid)
1959             .expect("variant_index_with_id: unknown variant")
1960     }
1961
1962     pub fn variant_of_def(&self, def: def::Def) -> &VariantDefData<'tcx, 'container> {
1963         match def {
1964             def::DefVariant(_, vid, _) => self.variant_with_id(vid),
1965             def::DefStruct(..) | def::DefTy(..) => self.struct_variant(),
1966             _ => panic!("unexpected def {:?} in variant_of_def", def)
1967         }
1968     }
1969
1970     pub fn destructor(&self) -> Option<DefId> {
1971         self.destructor.get()
1972     }
1973
1974     pub fn set_destructor(&self, dtor: DefId) {
1975         assert!(self.destructor.get().is_none());
1976         self.destructor.set(Some(dtor));
1977     }
1978
1979     pub fn dtor_kind(&self) -> DtorKind {
1980         match self.destructor.get() {
1981             Some(_) => {
1982                 TraitDtor(!self.flags.get().intersects(AdtFlags::IS_NO_DROP_FLAG))
1983             }
1984             None => NoDtor,
1985         }
1986     }
1987 }
1988
1989 impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
1990     #[inline]
1991     fn fields_iter(&self) -> slice::Iter<FieldDefData<'tcx, 'container>> {
1992         self.fields.iter()
1993     }
1994
1995     pub fn kind(&self) -> VariantKind {
1996         match self.fields.get(0) {
1997             None => VariantKind::Unit,
1998             Some(&FieldDefData { name, .. }) if name == special_idents::unnamed_field.name => {
1999                 VariantKind::Tuple
2000             }
2001             Some(_) => VariantKind::Dict
2002         }
2003     }
2004
2005     pub fn is_tuple_struct(&self) -> bool {
2006         self.kind() == VariantKind::Tuple
2007     }
2008
2009     #[inline]
2010     pub fn find_field_named(&self,
2011                             name: ast::Name)
2012                             -> Option<&FieldDefData<'tcx, 'container>> {
2013         self.fields.iter().find(|f| f.name == name)
2014     }
2015
2016     #[inline]
2017     pub fn field_named(&self, name: ast::Name) -> &FieldDefData<'tcx, 'container> {
2018         self.find_field_named(name).unwrap()
2019     }
2020 }
2021
2022 impl<'tcx, 'container> FieldDefData<'tcx, 'container> {
2023     pub fn new(did: DefId,
2024                name: Name,
2025                vis: hir::Visibility) -> Self {
2026         FieldDefData {
2027             did: did,
2028             name: name,
2029             vis: vis,
2030             ty: ivar::TyIVar::new()
2031         }
2032     }
2033
2034     pub fn ty(&self, tcx: &ctxt<'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
2035         self.unsubst_ty().subst(tcx, subst)
2036     }
2037
2038     pub fn unsubst_ty(&self) -> Ty<'tcx> {
2039         self.ty.unwrap()
2040     }
2041
2042     pub fn fulfill_ty(&self, ty: Ty<'container>) {
2043         self.ty.fulfill(ty);
2044     }
2045 }
2046
2047 /// Records the substitutions used to translate the polytype for an
2048 /// item into the monotype of an item reference.
2049 #[derive(Clone)]
2050 pub struct ItemSubsts<'tcx> {
2051     pub substs: Substs<'tcx>,
2052 }
2053
2054 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
2055 pub enum ClosureKind {
2056     // Warning: Ordering is significant here! The ordering is chosen
2057     // because the trait Fn is a subtrait of FnMut and so in turn, and
2058     // hence we order it so that Fn < FnMut < FnOnce.
2059     FnClosureKind,
2060     FnMutClosureKind,
2061     FnOnceClosureKind,
2062 }
2063
2064 impl ClosureKind {
2065     pub fn trait_did(&self, cx: &ctxt) -> DefId {
2066         let result = match *self {
2067             FnClosureKind => cx.lang_items.require(FnTraitLangItem),
2068             FnMutClosureKind => {
2069                 cx.lang_items.require(FnMutTraitLangItem)
2070             }
2071             FnOnceClosureKind => {
2072                 cx.lang_items.require(FnOnceTraitLangItem)
2073             }
2074         };
2075         match result {
2076             Ok(trait_did) => trait_did,
2077             Err(err) => cx.sess.fatal(&err[..]),
2078         }
2079     }
2080
2081     /// True if this a type that impls this closure kind
2082     /// must also implement `other`.
2083     pub fn extends(self, other: ty::ClosureKind) -> bool {
2084         match (self, other) {
2085             (FnClosureKind, FnClosureKind) => true,
2086             (FnClosureKind, FnMutClosureKind) => true,
2087             (FnClosureKind, FnOnceClosureKind) => true,
2088             (FnMutClosureKind, FnMutClosureKind) => true,
2089             (FnMutClosureKind, FnOnceClosureKind) => true,
2090             (FnOnceClosureKind, FnOnceClosureKind) => true,
2091             _ => false,
2092         }
2093     }
2094 }
2095
2096 impl<'tcx> ctxt<'tcx> {
2097     pub fn pat_contains_ref_binding(&self, pat: &hir::Pat) -> Option<hir::Mutability> {
2098         pat_util::pat_contains_ref_binding(&self.def_map, pat)
2099     }
2100
2101     pub fn arm_contains_ref_binding(&self, arm: &hir::Arm) -> Option<hir::Mutability> {
2102         pat_util::arm_contains_ref_binding(&self.def_map, arm)
2103     }
2104 }
2105
2106 impl<'tcx> TyS<'tcx> {
2107     /// Iterator that walks `self` and any types reachable from
2108     /// `self`, in depth-first order. Note that just walks the types
2109     /// that appear in `self`, it does not descend into the fields of
2110     /// structs or variants. For example:
2111     ///
2112     /// ```notrust
2113     /// isize => { isize }
2114     /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
2115     /// [isize] => { [isize], isize }
2116     /// ```
2117     pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
2118         TypeWalker::new(self)
2119     }
2120
2121     /// Iterator that walks the immediate children of `self`.  Hence
2122     /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
2123     /// (but not `i32`, like `walk`).
2124     pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
2125         walk::walk_shallow(self)
2126     }
2127
2128     pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
2129         match self.sty {
2130             ty::TyParam(ref d) => Some(d.clone()),
2131             _ => None,
2132         }
2133     }
2134
2135     pub fn is_param(&self, space: ParamSpace, index: u32) -> bool {
2136         match self.sty {
2137             ty::TyParam(ref data) => data.space == space && data.idx == index,
2138             _ => false,
2139         }
2140     }
2141
2142     /// Returns the regions directly referenced from this type (but
2143     /// not types reachable from this type via `walk_tys`). This
2144     /// ignores late-bound regions binders.
2145     pub fn regions(&self) -> Vec<ty::Region> {
2146         match self.sty {
2147             TyRef(region, _) => {
2148                 vec![*region]
2149             }
2150             TyTrait(ref obj) => {
2151                 let mut v = vec![obj.bounds.region_bound];
2152                 v.push_all(obj.principal.skip_binder().substs.regions().as_slice());
2153                 v
2154             }
2155             TyEnum(_, substs) |
2156             TyStruct(_, substs) => {
2157                 substs.regions().as_slice().to_vec()
2158             }
2159             TyClosure(_, ref substs) => {
2160                 substs.func_substs.regions().as_slice().to_vec()
2161             }
2162             TyProjection(ref data) => {
2163                 data.trait_ref.substs.regions().as_slice().to_vec()
2164             }
2165             TyBareFn(..) |
2166             TyBool |
2167             TyChar |
2168             TyInt(_) |
2169             TyUint(_) |
2170             TyFloat(_) |
2171             TyBox(_) |
2172             TyStr |
2173             TyArray(_, _) |
2174             TySlice(_) |
2175             TyRawPtr(_) |
2176             TyTuple(_) |
2177             TyParam(_) |
2178             TyInfer(_) |
2179             TyError => {
2180                 vec![]
2181             }
2182         }
2183     }
2184
2185     /// Walks `ty` and any types appearing within `ty`, invoking the
2186     /// callback `f` on each type. If the callback returns false, then the
2187     /// children of the current type are ignored.
2188     ///
2189     /// Note: prefer `ty.walk()` where possible.
2190     pub fn maybe_walk<F>(&'tcx self, mut f: F)
2191         where F : FnMut(Ty<'tcx>) -> bool
2192     {
2193         let mut walker = self.walk();
2194         while let Some(ty) = walker.next() {
2195             if !f(ty) {
2196                 walker.skip_current_subtree();
2197             }
2198         }
2199     }
2200 }
2201
2202 impl ParamTy {
2203     pub fn new(space: subst::ParamSpace,
2204                index: u32,
2205                name: Name)
2206                -> ParamTy {
2207         ParamTy { space: space, idx: index, name: name }
2208     }
2209
2210     pub fn for_self() -> ParamTy {
2211         ParamTy::new(subst::SelfSpace, 0, special_idents::type_self.name)
2212     }
2213
2214     pub fn for_def(def: &TypeParameterDef) -> ParamTy {
2215         ParamTy::new(def.space, def.index, def.name)
2216     }
2217
2218     pub fn to_ty<'tcx>(self, tcx: &ctxt<'tcx>) -> Ty<'tcx> {
2219         tcx.mk_param(self.space, self.idx, self.name)
2220     }
2221
2222     pub fn is_self(&self) -> bool {
2223         self.space == subst::SelfSpace && self.idx == 0
2224     }
2225 }
2226
2227 impl<'tcx> ItemSubsts<'tcx> {
2228     pub fn empty() -> ItemSubsts<'tcx> {
2229         ItemSubsts { substs: Substs::empty() }
2230     }
2231
2232     pub fn is_noop(&self) -> bool {
2233         self.substs.is_noop()
2234     }
2235 }
2236
2237 impl<'tcx> TyS<'tcx> {
2238     fn impls_bound<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
2239                        bound: ty::BuiltinBound,
2240                        span: Span)
2241                        -> bool
2242     {
2243         let tcx = param_env.tcx;
2244         let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()), false);
2245
2246         let is_impld = traits::type_known_to_meet_builtin_bound(&infcx,
2247                                                                 self, bound, span);
2248
2249         debug!("Ty::impls_bound({:?}, {:?}) = {:?}",
2250                self, bound, is_impld);
2251
2252         is_impld
2253     }
2254
2255     // FIXME (@jroesch): I made this public to use it, not sure if should be private
2256     pub fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
2257                            span: Span) -> bool {
2258         if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) {
2259             return self.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
2260         }
2261
2262         assert!(!self.needs_infer());
2263
2264         // Fast-path for primitive types
2265         let result = match self.sty {
2266             TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
2267             TyRawPtr(..) | TyBareFn(..) | TyRef(_, TypeAndMut {
2268                 mutbl: hir::MutImmutable, ..
2269             }) => Some(false),
2270
2271             TyStr | TyBox(..) | TyRef(_, TypeAndMut {
2272                 mutbl: hir::MutMutable, ..
2273             }) => Some(true),
2274
2275             TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) |
2276             TyClosure(..) | TyEnum(..) | TyStruct(..) |
2277             TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
2278         }.unwrap_or_else(|| !self.impls_bound(param_env, ty::BoundCopy, span));
2279
2280         if !self.has_param_types() && !self.has_self_ty() {
2281             self.flags.set(self.flags.get() | if result {
2282                 TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT
2283             } else {
2284                 TypeFlags::MOVENESS_CACHED
2285             });
2286         }
2287
2288         result
2289     }
2290
2291     #[inline]
2292     pub fn is_sized<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
2293                         span: Span) -> bool
2294     {
2295         if self.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) {
2296             return self.flags.get().intersects(TypeFlags::IS_SIZED);
2297         }
2298
2299         self.is_sized_uncached(param_env, span)
2300     }
2301
2302     fn is_sized_uncached<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
2303                              span: Span) -> bool {
2304         assert!(!self.needs_infer());
2305
2306         // Fast-path for primitive types
2307         let result = match self.sty {
2308             TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
2309             TyBox(..) | TyRawPtr(..) | TyRef(..) | TyBareFn(..) |
2310             TyArray(..) | TyTuple(..) | TyClosure(..) => Some(true),
2311
2312             TyStr | TyTrait(..) | TySlice(_) => Some(false),
2313
2314             TyEnum(..) | TyStruct(..) | TyProjection(..) | TyParam(..) |
2315             TyInfer(..) | TyError => None
2316         }.unwrap_or_else(|| self.impls_bound(param_env, ty::BoundSized, span));
2317
2318         if !self.has_param_types() && !self.has_self_ty() {
2319             self.flags.set(self.flags.get() | if result {
2320                 TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED
2321             } else {
2322                 TypeFlags::SIZEDNESS_CACHED
2323             });
2324         }
2325
2326         result
2327     }
2328 }
2329
2330 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2331 pub enum LvaluePreference {
2332     PreferMutLvalue,
2333     NoPreference
2334 }
2335
2336 impl LvaluePreference {
2337     pub fn from_mutbl(m: hir::Mutability) -> Self {
2338         match m {
2339             hir::MutMutable => PreferMutLvalue,
2340             hir::MutImmutable => NoPreference,
2341         }
2342     }
2343 }
2344
2345 /// Describes whether a type is representable. For types that are not
2346 /// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
2347 /// distinguish between types that are recursive with themselves and types that
2348 /// contain a different recursive type. These cases can therefore be treated
2349 /// differently when reporting errors.
2350 ///
2351 /// The ordering of the cases is significant. They are sorted so that cmp::max
2352 /// will keep the "more erroneous" of two values.
2353 #[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
2354 pub enum Representability {
2355     Representable,
2356     ContainsRecursive,
2357     SelfRecursive,
2358 }
2359
2360 impl<'tcx> TyS<'tcx> {
2361     /// Check whether a type is representable. This means it cannot contain unboxed
2362     /// structural recursion. This check is needed for structs and enums.
2363     pub fn is_representable(&'tcx self, cx: &ctxt<'tcx>, sp: Span) -> Representability {
2364
2365         // Iterate until something non-representable is found
2366         fn find_nonrepresentable<'tcx, It: Iterator<Item=Ty<'tcx>>>(cx: &ctxt<'tcx>, sp: Span,
2367                                                                     seen: &mut Vec<Ty<'tcx>>,
2368                                                                     iter: It)
2369                                                                     -> Representability {
2370             iter.fold(Representable,
2371                       |r, ty| cmp::max(r, is_type_structurally_recursive(cx, sp, seen, ty)))
2372         }
2373
2374         fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
2375                                            seen: &mut Vec<Ty<'tcx>>, ty: Ty<'tcx>)
2376                                            -> Representability {
2377             match ty.sty {
2378                 TyTuple(ref ts) => {
2379                     find_nonrepresentable(cx, sp, seen, ts.iter().cloned())
2380                 }
2381                 // Fixed-length vectors.
2382                 // FIXME(#11924) Behavior undecided for zero-length vectors.
2383                 TyArray(ty, _) => {
2384                     is_type_structurally_recursive(cx, sp, seen, ty)
2385                 }
2386                 TyStruct(def, substs) | TyEnum(def, substs) => {
2387                     find_nonrepresentable(cx,
2388                                           sp,
2389                                           seen,
2390                                           def.all_fields().map(|f| f.ty(cx, substs)))
2391                 }
2392                 TyClosure(..) => {
2393                     // this check is run on type definitions, so we don't expect
2394                     // to see closure types
2395                     cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
2396                 }
2397                 _ => Representable,
2398             }
2399         }
2400
2401         fn same_struct_or_enum<'tcx>(ty: Ty<'tcx>, def: AdtDef<'tcx>) -> bool {
2402             match ty.sty {
2403                 TyStruct(ty_def, _) | TyEnum(ty_def, _) => {
2404                      ty_def == def
2405                 }
2406                 _ => false
2407             }
2408         }
2409
2410         fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
2411             match (&a.sty, &b.sty) {
2412                 (&TyStruct(did_a, ref substs_a), &TyStruct(did_b, ref substs_b)) |
2413                 (&TyEnum(did_a, ref substs_a), &TyEnum(did_b, ref substs_b)) => {
2414                     if did_a != did_b {
2415                         return false;
2416                     }
2417
2418                     let types_a = substs_a.types.get_slice(subst::TypeSpace);
2419                     let types_b = substs_b.types.get_slice(subst::TypeSpace);
2420
2421                     let mut pairs = types_a.iter().zip(types_b);
2422
2423                     pairs.all(|(&a, &b)| same_type(a, b))
2424                 }
2425                 _ => {
2426                     a == b
2427                 }
2428             }
2429         }
2430
2431         // Does the type `ty` directly (without indirection through a pointer)
2432         // contain any types on stack `seen`?
2433         fn is_type_structurally_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
2434                                                 seen: &mut Vec<Ty<'tcx>>,
2435                                                 ty: Ty<'tcx>) -> Representability {
2436             debug!("is_type_structurally_recursive: {:?}", ty);
2437
2438             match ty.sty {
2439                 TyStruct(def, _) | TyEnum(def, _) => {
2440                     {
2441                         // Iterate through stack of previously seen types.
2442                         let mut iter = seen.iter();
2443
2444                         // The first item in `seen` is the type we are actually curious about.
2445                         // We want to return SelfRecursive if this type contains itself.
2446                         // It is important that we DON'T take generic parameters into account
2447                         // for this check, so that Bar<T> in this example counts as SelfRecursive:
2448                         //
2449                         // struct Foo;
2450                         // struct Bar<T> { x: Bar<Foo> }
2451
2452                         match iter.next() {
2453                             Some(&seen_type) => {
2454                                 if same_struct_or_enum(seen_type, def) {
2455                                     debug!("SelfRecursive: {:?} contains {:?}",
2456                                            seen_type,
2457                                            ty);
2458                                     return SelfRecursive;
2459                                 }
2460                             }
2461                             None => {}
2462                         }
2463
2464                         // We also need to know whether the first item contains other types
2465                         // that are structurally recursive. If we don't catch this case, we
2466                         // will recurse infinitely for some inputs.
2467                         //
2468                         // It is important that we DO take generic parameters into account
2469                         // here, so that code like this is considered SelfRecursive, not
2470                         // ContainsRecursive:
2471                         //
2472                         // struct Foo { Option<Option<Foo>> }
2473
2474                         for &seen_type in iter {
2475                             if same_type(ty, seen_type) {
2476                                 debug!("ContainsRecursive: {:?} contains {:?}",
2477                                        seen_type,
2478                                        ty);
2479                                 return ContainsRecursive;
2480                             }
2481                         }
2482                     }
2483
2484                     // For structs and enums, track all previously seen types by pushing them
2485                     // onto the 'seen' stack.
2486                     seen.push(ty);
2487                     let out = are_inner_types_recursive(cx, sp, seen, ty);
2488                     seen.pop();
2489                     out
2490                 }
2491                 _ => {
2492                     // No need to push in other cases.
2493                     are_inner_types_recursive(cx, sp, seen, ty)
2494                 }
2495             }
2496         }
2497
2498         debug!("is_type_representable: {:?}", self);
2499
2500         // To avoid a stack overflow when checking an enum variant or struct that
2501         // contains a different, structurally recursive type, maintain a stack
2502         // of seen types and check recursion for each of them (issues #3008, #3779).
2503         let mut seen: Vec<Ty> = Vec::new();
2504         let r = is_type_structurally_recursive(cx, sp, &mut seen, self);
2505         debug!("is_type_representable: {:?} is {:?}", self, r);
2506         r
2507     }
2508
2509     /// See `expr_ty_adjusted`
2510     pub fn adjust<F>(&'tcx self, cx: &ctxt<'tcx>,
2511                      span: Span,
2512                      expr_id: NodeId,
2513                      adjustment: Option<&AutoAdjustment<'tcx>>,
2514                      mut method_type: F)
2515                      -> Ty<'tcx> where
2516         F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
2517     {
2518         if let TyError = self.sty {
2519             return self;
2520         }
2521
2522         return match adjustment {
2523             Some(adjustment) => {
2524                 match *adjustment {
2525                    AdjustReifyFnPointer => {
2526                         match self.sty {
2527                             ty::TyBareFn(Some(_), b) => {
2528                                 cx.mk_fn(None, b)
2529                             }
2530                             _ => {
2531                                 cx.sess.bug(
2532                                     &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
2533                                               {:?}", self));
2534                             }
2535                         }
2536                     }
2537
2538                    AdjustUnsafeFnPointer => {
2539                         match self.sty {
2540                             ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b),
2541                             ref b => {
2542                                 cx.sess.bug(
2543                                     &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
2544                                              {:?}",
2545                                             b));
2546                             }
2547                         }
2548                    }
2549
2550                     AdjustDerefRef(ref adj) => {
2551                         let mut adjusted_ty = self;
2552
2553                         if !adjusted_ty.references_error() {
2554                             for i in 0..adj.autoderefs {
2555                                 adjusted_ty =
2556                                     adjusted_ty.adjust_for_autoderef(cx,
2557                                                                      expr_id,
2558                                                                      span,
2559                                                                      i as u32,
2560                                                                      &mut method_type);
2561                             }
2562                         }
2563
2564                         if let Some(target) = adj.unsize {
2565                             target
2566                         } else {
2567                             adjusted_ty.adjust_for_autoref(cx, adj.autoref)
2568                         }
2569                     }
2570                 }
2571             }
2572             None => self
2573         };
2574     }
2575
2576     pub fn adjust_for_autoderef<F>(&'tcx self,
2577                                    cx: &ctxt<'tcx>,
2578                                    expr_id: ast::NodeId,
2579                                    expr_span: Span,
2580                                    autoderef: u32, // how many autoderefs so far?
2581                                    mut method_type: F)
2582                                    -> Ty<'tcx> where
2583         F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
2584     {
2585         let method_call = MethodCall::autoderef(expr_id, autoderef);
2586         let mut adjusted_ty = self;
2587         if let Some(method_ty) = method_type(method_call) {
2588             // Method calls always have all late-bound regions
2589             // fully instantiated.
2590             let fn_ret = cx.no_late_bound_regions(&method_ty.fn_ret()).unwrap();
2591             adjusted_ty = fn_ret.unwrap();
2592         }
2593         match adjusted_ty.builtin_deref(true, NoPreference) {
2594             Some(mt) => mt.ty,
2595             None => {
2596                 cx.sess.span_bug(
2597                     expr_span,
2598                     &format!("the {}th autoderef failed: {}",
2599                              autoderef,
2600                              adjusted_ty)
2601                         );
2602             }
2603         }
2604     }
2605
2606     pub fn adjust_for_autoref(&'tcx self, cx: &ctxt<'tcx>,
2607                               autoref: Option<AutoRef<'tcx>>)
2608                               -> Ty<'tcx> {
2609         match autoref {
2610             None => self,
2611             Some(AutoPtr(r, m)) => {
2612                 cx.mk_ref(r, TypeAndMut { ty: self, mutbl: m })
2613             }
2614             Some(AutoUnsafe(m)) => {
2615                 cx.mk_ptr(TypeAndMut { ty: self, mutbl: m })
2616             }
2617         }
2618     }
2619
2620 }
2621
2622 /// Helper for looking things up in the various maps that are populated during
2623 /// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc).  All of
2624 /// these share the pattern that if the id is local, it should have been loaded
2625 /// into the map by the `typeck::collect` phase.  If the def-id is external,
2626 /// then we have to go consult the crate loading code (and cache the result for
2627 /// the future).
2628 fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
2629                                           def_id: DefId,
2630                                           map: &RefCell<DefIdMap<V>>,
2631                                           load_external: F) -> V where
2632     V: Clone,
2633     F: FnOnce() -> V,
2634 {
2635     match map.borrow().get(&def_id).cloned() {
2636         Some(v) => { return v; }
2637         None => { }
2638     }
2639
2640     if def_id.is_local() {
2641         panic!("No def'n found for {:?} in tcx.{}", def_id, descr);
2642     }
2643     let v = load_external();
2644     map.borrow_mut().insert(def_id, v.clone());
2645     v
2646 }
2647
2648 impl BorrowKind {
2649     pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
2650         match m {
2651             hir::MutMutable => MutBorrow,
2652             hir::MutImmutable => ImmBorrow,
2653         }
2654     }
2655
2656     /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
2657     /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
2658     /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
2659     /// question.
2660     pub fn to_mutbl_lossy(self) -> hir::Mutability {
2661         match self {
2662             MutBorrow => hir::MutMutable,
2663             ImmBorrow => hir::MutImmutable,
2664
2665             // We have no type corresponding to a unique imm borrow, so
2666             // use `&mut`. It gives all the capabilities of an `&uniq`
2667             // and hence is a safe "over approximation".
2668             UniqueImmBorrow => hir::MutMutable,
2669         }
2670     }
2671
2672     pub fn to_user_str(&self) -> &'static str {
2673         match *self {
2674             MutBorrow => "mutable",
2675             ImmBorrow => "immutable",
2676             UniqueImmBorrow => "uniquely immutable",
2677         }
2678     }
2679 }
2680
2681 impl<'tcx> ctxt<'tcx> {
2682     /// Returns the type of element at index `i` in tuple or tuple-like type `t`.
2683     /// For an enum `t`, `variant` is None only if `t` is a univariant enum.
2684     pub fn positional_element_ty(&self,
2685                                  ty: Ty<'tcx>,
2686                                  i: usize,
2687                                  variant: Option<DefId>) -> Option<Ty<'tcx>> {
2688         match (&ty.sty, variant) {
2689             (&TyStruct(def, substs), None) => {
2690                 def.struct_variant().fields.get(i).map(|f| f.ty(self, substs))
2691             }
2692             (&TyEnum(def, substs), Some(vid)) => {
2693                 def.variant_with_id(vid).fields.get(i).map(|f| f.ty(self, substs))
2694             }
2695             (&TyEnum(def, substs), None) => {
2696                 assert!(def.is_univariant());
2697                 def.variants[0].fields.get(i).map(|f| f.ty(self, substs))
2698             }
2699             (&TyTuple(ref v), None) => v.get(i).cloned(),
2700             _ => None
2701         }
2702     }
2703
2704     /// Returns the type of element at field `n` in struct or struct-like type `t`.
2705     /// For an enum `t`, `variant` must be some def id.
2706     pub fn named_element_ty(&self,
2707                             ty: Ty<'tcx>,
2708                             n: Name,
2709                             variant: Option<DefId>) -> Option<Ty<'tcx>> {
2710         match (&ty.sty, variant) {
2711             (&TyStruct(def, substs), None) => {
2712                 def.struct_variant().find_field_named(n).map(|f| f.ty(self, substs))
2713             }
2714             (&TyEnum(def, substs), Some(vid)) => {
2715                 def.variant_with_id(vid).find_field_named(n).map(|f| f.ty(self, substs))
2716             }
2717             _ => return None
2718         }
2719     }
2720
2721     pub fn node_id_to_type(&self, id: NodeId) -> Ty<'tcx> {
2722         match self.node_id_to_type_opt(id) {
2723            Some(ty) => ty,
2724            None => self.sess.bug(
2725                &format!("node_id_to_type: no type for node `{}`",
2726                         self.map.node_to_string(id)))
2727         }
2728     }
2729
2730     pub fn node_id_to_type_opt(&self, id: NodeId) -> Option<Ty<'tcx>> {
2731         self.tables.borrow().node_types.get(&id).cloned()
2732     }
2733
2734     pub fn node_id_item_substs(&self, id: NodeId) -> ItemSubsts<'tcx> {
2735         match self.tables.borrow().item_substs.get(&id) {
2736             None => ItemSubsts::empty(),
2737             Some(ts) => ts.clone(),
2738         }
2739     }
2740
2741     // Returns the type of a pattern as a monotype. Like @expr_ty, this function
2742     // doesn't provide type parameter substitutions.
2743     pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
2744         self.node_id_to_type(pat.id)
2745     }
2746     pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
2747         self.node_id_to_type_opt(pat.id)
2748     }
2749
2750     // Returns the type of an expression as a monotype.
2751     //
2752     // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression.  That is, in
2753     // some cases, we insert `AutoAdjustment` annotations such as auto-deref or
2754     // auto-ref.  The type returned by this function does not consider such
2755     // adjustments.  See `expr_ty_adjusted()` instead.
2756     //
2757     // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
2758     // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
2759     // instead of "fn(ty) -> T with T = isize".
2760     pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
2761         self.node_id_to_type(expr.id)
2762     }
2763
2764     pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
2765         self.node_id_to_type_opt(expr.id)
2766     }
2767
2768     /// Returns the type of `expr`, considering any `AutoAdjustment`
2769     /// entry recorded for that expression.
2770     ///
2771     /// It would almost certainly be better to store the adjusted ty in with
2772     /// the `AutoAdjustment`, but I opted not to do this because it would
2773     /// require serializing and deserializing the type and, although that's not
2774     /// hard to do, I just hate that code so much I didn't want to touch it
2775     /// unless it was to fix it properly, which seemed a distraction from the
2776     /// thread at hand! -nmatsakis
2777     pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> Ty<'tcx> {
2778         self.expr_ty(expr)
2779             .adjust(self, expr.span, expr.id,
2780                     self.tables.borrow().adjustments.get(&expr.id),
2781                     |method_call| {
2782             self.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
2783         })
2784     }
2785
2786     pub fn expr_span(&self, id: NodeId) -> Span {
2787         match self.map.find(id) {
2788             Some(ast_map::NodeExpr(e)) => {
2789                 e.span
2790             }
2791             Some(f) => {
2792                 self.sess.bug(&format!("Node id {} is not an expr: {:?}",
2793                                        id, f));
2794             }
2795             None => {
2796                 self.sess.bug(&format!("Node id {} is not present \
2797                                         in the node map", id));
2798             }
2799         }
2800     }
2801
2802     pub fn local_var_name_str(&self, id: NodeId) -> InternedString {
2803         match self.map.find(id) {
2804             Some(ast_map::NodeLocal(pat)) => {
2805                 match pat.node {
2806                     hir::PatIdent(_, ref path1, _) => path1.node.name.as_str(),
2807                     _ => {
2808                         self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, pat));
2809                     },
2810                 }
2811             },
2812             r => self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, r)),
2813         }
2814     }
2815
2816     pub fn resolve_expr(&self, expr: &hir::Expr) -> def::Def {
2817         match self.def_map.borrow().get(&expr.id) {
2818             Some(def) => def.full_def(),
2819             None => {
2820                 self.sess.span_bug(expr.span, &format!(
2821                     "no def-map entry for expr {}", expr.id));
2822             }
2823         }
2824     }
2825
2826     pub fn expr_is_lval(&self, expr: &hir::Expr) -> bool {
2827          match expr.node {
2828             hir::ExprPath(..) => {
2829                 // We can't use resolve_expr here, as this needs to run on broken
2830                 // programs. We don't need to through - associated items are all
2831                 // rvalues.
2832                 match self.def_map.borrow().get(&expr.id) {
2833                     Some(&def::PathResolution {
2834                         base_def: def::DefStatic(..), ..
2835                     }) | Some(&def::PathResolution {
2836                         base_def: def::DefUpvar(..), ..
2837                     }) | Some(&def::PathResolution {
2838                         base_def: def::DefLocal(..), ..
2839                     }) => {
2840                         true
2841                     }
2842
2843                     Some(..) => false,
2844
2845                     None => self.sess.span_bug(expr.span, &format!(
2846                         "no def for path {}", expr.id))
2847                 }
2848             }
2849
2850             hir::ExprUnary(hir::UnDeref, _) |
2851             hir::ExprField(..) |
2852             hir::ExprTupField(..) |
2853             hir::ExprIndex(..) => {
2854                 true
2855             }
2856
2857             hir::ExprCall(..) |
2858             hir::ExprMethodCall(..) |
2859             hir::ExprStruct(..) |
2860             hir::ExprRange(..) |
2861             hir::ExprTup(..) |
2862             hir::ExprIf(..) |
2863             hir::ExprMatch(..) |
2864             hir::ExprClosure(..) |
2865             hir::ExprBlock(..) |
2866             hir::ExprRepeat(..) |
2867             hir::ExprVec(..) |
2868             hir::ExprBreak(..) |
2869             hir::ExprAgain(..) |
2870             hir::ExprRet(..) |
2871             hir::ExprWhile(..) |
2872             hir::ExprLoop(..) |
2873             hir::ExprAssign(..) |
2874             hir::ExprInlineAsm(..) |
2875             hir::ExprAssignOp(..) |
2876             hir::ExprLit(_) |
2877             hir::ExprUnary(..) |
2878             hir::ExprBox(..) |
2879             hir::ExprAddrOf(..) |
2880             hir::ExprBinary(..) |
2881             hir::ExprCast(..) => {
2882                 false
2883             }
2884
2885             hir::ExprParen(ref e) => self.expr_is_lval(e),
2886         }
2887     }
2888
2889     pub fn provided_source(&self, id: DefId) -> Option<DefId> {
2890         self.provided_method_sources.borrow().get(&id).cloned()
2891     }
2892
2893     pub fn provided_trait_methods(&self, id: DefId) -> Vec<Rc<Method<'tcx>>> {
2894         if id.is_local() {
2895             if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id.node).node {
2896                 ms.iter().filter_map(|ti| {
2897                     if let hir::MethodTraitItem(_, Some(_)) = ti.node {
2898                         match self.impl_or_trait_item(DefId::local(ti.id)) {
2899                             MethodTraitItem(m) => Some(m),
2900                             _ => {
2901                                 self.sess.bug("provided_trait_methods(): \
2902                                                non-method item found from \
2903                                                looking up provided method?!")
2904                             }
2905                         }
2906                     } else {
2907                         None
2908                     }
2909                 }).collect()
2910             } else {
2911                 self.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
2912             }
2913         } else {
2914             csearch::get_provided_trait_methods(self, id)
2915         }
2916     }
2917
2918     pub fn associated_consts(&self, id: DefId) -> Vec<Rc<AssociatedConst<'tcx>>> {
2919         if id.is_local() {
2920             match self.map.expect_item(id.node).node {
2921                 ItemTrait(_, _, _, ref tis) => {
2922                     tis.iter().filter_map(|ti| {
2923                         if let hir::ConstTraitItem(_, _) = ti.node {
2924                             match self.impl_or_trait_item(DefId::local(ti.id)) {
2925                                 ConstTraitItem(ac) => Some(ac),
2926                                 _ => {
2927                                     self.sess.bug("associated_consts(): \
2928                                                    non-const item found from \
2929                                                    looking up a constant?!")
2930                                 }
2931                             }
2932                         } else {
2933                             None
2934                         }
2935                     }).collect()
2936                 }
2937                 ItemImpl(_, _, _, _, _, ref iis) => {
2938                     iis.iter().filter_map(|ii| {
2939                         if let hir::ConstImplItem(_, _) = ii.node {
2940                             match self.impl_or_trait_item(DefId::local(ii.id)) {
2941                                 ConstTraitItem(ac) => Some(ac),
2942                                 _ => {
2943                                     self.sess.bug("associated_consts(): \
2944                                                    non-const item found from \
2945                                                    looking up a constant?!")
2946                                 }
2947                             }
2948                         } else {
2949                             None
2950                         }
2951                     }).collect()
2952                 }
2953                 _ => {
2954                     self.sess.bug(&format!("associated_consts: `{:?}` is not a trait \
2955                                             or impl", id))
2956                 }
2957             }
2958         } else {
2959             csearch::get_associated_consts(self, id)
2960         }
2961     }
2962
2963     pub fn trait_items(&self, trait_did: DefId) -> Rc<Vec<ImplOrTraitItem<'tcx>>> {
2964         let mut trait_items = self.trait_items_cache.borrow_mut();
2965         match trait_items.get(&trait_did).cloned() {
2966             Some(trait_items) => trait_items,
2967             None => {
2968                 let def_ids = self.trait_item_def_ids(trait_did);
2969                 let items: Rc<Vec<ImplOrTraitItem>> =
2970                     Rc::new(def_ids.iter()
2971                                    .map(|d| self.impl_or_trait_item(d.def_id()))
2972                                    .collect());
2973                 trait_items.insert(trait_did, items.clone());
2974                 items
2975             }
2976         }
2977     }
2978
2979     pub fn trait_impl_polarity(&self, id: DefId) -> Option<hir::ImplPolarity> {
2980         if id.is_local() {
2981             match self.map.find(id.node) {
2982                 Some(ast_map::NodeItem(item)) => {
2983                     match item.node {
2984                         hir::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
2985                         _ => None
2986                     }
2987                 }
2988                 _ => None
2989             }
2990         } else {
2991             csearch::get_impl_polarity(self, id)
2992         }
2993     }
2994
2995     pub fn custom_coerce_unsized_kind(&self, did: DefId) -> CustomCoerceUnsized {
2996         memoized(&self.custom_coerce_unsized_kinds, did, |did: DefId| {
2997             let (kind, src) = if did.krate != LOCAL_CRATE {
2998                 (csearch::get_custom_coerce_unsized_kind(self, did), "external")
2999             } else {
3000                 (None, "local")
3001             };
3002
3003             match kind {
3004                 Some(kind) => kind,
3005                 None => {
3006                     self.sess.bug(&format!("custom_coerce_unsized_kind: \
3007                                             {} impl `{}` is missing its kind",
3008                                            src, self.item_path_str(did)));
3009                 }
3010             }
3011         })
3012     }
3013
3014     pub fn impl_or_trait_item(&self, id: DefId) -> ImplOrTraitItem<'tcx> {
3015         lookup_locally_or_in_crate_store(
3016             "impl_or_trait_items", id, &self.impl_or_trait_items,
3017             || csearch::get_impl_or_trait_item(self, id))
3018     }
3019
3020     pub fn trait_item_def_ids(&self, id: DefId) -> Rc<Vec<ImplOrTraitItemId>> {
3021         lookup_locally_or_in_crate_store(
3022             "trait_item_def_ids", id, &self.trait_item_def_ids,
3023             || Rc::new(csearch::get_trait_item_def_ids(&self.sess.cstore, id)))
3024     }
3025
3026     /// Returns the trait-ref corresponding to a given impl, or None if it is
3027     /// an inherent impl.
3028     pub fn impl_trait_ref(&self, id: DefId) -> Option<TraitRef<'tcx>> {
3029         lookup_locally_or_in_crate_store(
3030             "impl_trait_refs", id, &self.impl_trait_refs,
3031             || csearch::get_impl_trait(self, id))
3032     }
3033
3034     /// Returns whether this DefId refers to an impl
3035     pub fn is_impl(&self, id: DefId) -> bool {
3036         if id.is_local() {
3037             if let Some(ast_map::NodeItem(
3038                 &hir::Item { node: hir::ItemImpl(..), .. })) = self.map.find(id.node) {
3039                 true
3040             } else {
3041                 false
3042             }
3043         } else {
3044             csearch::is_impl(&self.sess.cstore, id)
3045         }
3046     }
3047
3048     pub fn trait_ref_to_def_id(&self, tr: &hir::TraitRef) -> DefId {
3049         self.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
3050     }
3051
3052     pub fn item_path_str(&self, id: DefId) -> String {
3053         self.with_path(id, |path| ast_map::path_to_string(path))
3054     }
3055
3056     pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
3057         F: FnOnce(ast_map::PathElems) -> T,
3058     {
3059         if id.is_local() {
3060             self.map.with_path(id.node, f)
3061         } else {
3062             f(csearch::get_item_path(self, id).iter().cloned().chain(LinkedPath::empty()))
3063         }
3064     }
3065
3066     pub fn item_name(&self, id: DefId) -> ast::Name {
3067         if id.is_local() {
3068             self.map.get_path_elem(id.node).name()
3069         } else {
3070             csearch::get_item_name(self, id)
3071         }
3072     }
3073
3074     /// Returns `(normalized_type, ty)`, where `normalized_type` is the
3075     /// IntType representation of one of {i64,i32,i16,i8,u64,u32,u16,u8},
3076     /// and `ty` is the original type (i.e. may include `isize` or
3077     /// `usize`).
3078     pub fn enum_repr_type(&self, opt_hint: Option<&attr::ReprAttr>)
3079                           -> (attr::IntType, Ty<'tcx>) {
3080         let repr_type = match opt_hint {
3081             // Feed in the given type
3082             Some(&attr::ReprInt(_, int_t)) => int_t,
3083             // ... but provide sensible default if none provided
3084             //
3085             // NB. Historically `fn enum_variants` generate i64 here, while
3086             // rustc_typeck::check would generate isize.
3087             _ => SignedInt(hir::TyIs),
3088         };
3089
3090         let repr_type_ty = repr_type.to_ty(self);
3091         let repr_type = match repr_type {
3092             SignedInt(hir::TyIs) =>
3093                 SignedInt(self.sess.target.int_type),
3094             UnsignedInt(hir::TyUs) =>
3095                 UnsignedInt(self.sess.target.uint_type),
3096             other => other
3097         };
3098
3099         (repr_type, repr_type_ty)
3100     }
3101
3102
3103     // Register a given item type
3104     pub fn register_item_type(&self, did: DefId, ty: TypeScheme<'tcx>) {
3105         self.tcache.borrow_mut().insert(did, ty);
3106     }
3107
3108     // If the given item is in an external crate, looks up its type and adds it to
3109     // the type cache. Returns the type parameters and type.
3110     pub fn lookup_item_type(&self, did: DefId) -> TypeScheme<'tcx> {
3111         lookup_locally_or_in_crate_store(
3112             "tcache", did, &self.tcache,
3113             || csearch::get_type(self, did))
3114     }
3115
3116     /// Given the did of a trait, returns its canonical trait ref.
3117     pub fn lookup_trait_def(&self, did: DefId) -> &'tcx TraitDef<'tcx> {
3118         lookup_locally_or_in_crate_store(
3119             "trait_defs", did, &self.trait_defs,
3120             || self.alloc_trait_def(csearch::get_trait_def(self, did))
3121         )
3122     }
3123
3124     /// Given the did of an ADT, return a master reference to its
3125     /// definition. Unless you are planning on fulfilling the ADT's fields,
3126     /// use lookup_adt_def instead.
3127     pub fn lookup_adt_def_master(&self, did: DefId) -> AdtDefMaster<'tcx> {
3128         lookup_locally_or_in_crate_store(
3129             "adt_defs", did, &self.adt_defs,
3130             || csearch::get_adt_def(self, did)
3131         )
3132     }
3133
3134     /// Given the did of an ADT, return a reference to its definition.
3135     pub fn lookup_adt_def(&self, did: DefId) -> AdtDef<'tcx> {
3136         // when reverse-variance goes away, a transmute::<AdtDefMaster,AdtDef>
3137         // woud be needed here.
3138         self.lookup_adt_def_master(did)
3139     }
3140
3141     /// Return the list of all interned ADT definitions
3142     pub fn adt_defs(&self) -> Vec<AdtDef<'tcx>> {
3143         self.adt_defs.borrow().values().cloned().collect()
3144     }
3145
3146     /// Given the did of an item, returns its full set of predicates.
3147     pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
3148         lookup_locally_or_in_crate_store(
3149             "predicates", did, &self.predicates,
3150             || csearch::get_predicates(self, did))
3151     }
3152
3153     /// Given the did of a trait, returns its superpredicates.
3154     pub fn lookup_super_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
3155         lookup_locally_or_in_crate_store(
3156             "super_predicates", did, &self.super_predicates,
3157             || csearch::get_super_predicates(self, did))
3158     }
3159
3160     /// Get the attributes of a definition.
3161     pub fn get_attrs(&self, did: DefId) -> Cow<'tcx, [hir::Attribute]> {
3162         if did.is_local() {
3163             Cow::Borrowed(self.map.attrs(did.node))
3164         } else {
3165             Cow::Owned(csearch::get_item_attrs(&self.sess.cstore, did))
3166         }
3167     }
3168
3169     /// Determine whether an item is annotated with an attribute
3170     pub fn has_attr(&self, did: DefId, attr: &str) -> bool {
3171         self.get_attrs(did).iter().any(|item| item.check_name(attr))
3172     }
3173
3174     /// Determine whether an item is annotated with `#[repr(packed)]`
3175     pub fn lookup_packed(&self, did: DefId) -> bool {
3176         self.lookup_repr_hints(did).contains(&attr::ReprPacked)
3177     }
3178
3179     /// Determine whether an item is annotated with `#[simd]`
3180     pub fn lookup_simd(&self, did: DefId) -> bool {
3181         self.has_attr(did, "simd")
3182             || self.lookup_repr_hints(did).contains(&attr::ReprSimd)
3183     }
3184
3185     /// Obtain the representation annotation for a struct definition.
3186     pub fn lookup_repr_hints(&self, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
3187         memoized(&self.repr_hint_cache, did, |did: DefId| {
3188             Rc::new(if did.is_local() {
3189                 self.get_attrs(did).iter().flat_map(|meta| {
3190                     attr::find_repr_attrs(self.sess.diagnostic(), meta).into_iter()
3191                 }).collect()
3192             } else {
3193                 csearch::get_repr_attrs(&self.sess.cstore, did)
3194             })
3195         })
3196     }
3197
3198
3199     /// Returns the deeply last field of nested structures, or the same type,
3200     /// if not a structure at all. Corresponds to the only possible unsized
3201     /// field, and its type can be used to determine unsizing strategy.
3202     pub fn struct_tail(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
3203         while let TyStruct(def, substs) = ty.sty {
3204             match def.struct_variant().fields.last() {
3205                 Some(f) => ty = f.ty(self, substs),
3206                 None => break
3207             }
3208         }
3209         ty
3210     }
3211
3212     /// Same as applying struct_tail on `source` and `target`, but only
3213     /// keeps going as long as the two types are instances of the same
3214     /// structure definitions.
3215     /// For `(Foo<Foo<T>>, Foo<Trait>)`, the result will be `(Foo<T>, Trait)`,
3216     /// whereas struct_tail produces `T`, and `Trait`, respectively.
3217     pub fn struct_lockstep_tails(&self,
3218                                  source: Ty<'tcx>,
3219                                  target: Ty<'tcx>)
3220                                  -> (Ty<'tcx>, Ty<'tcx>) {
3221         let (mut a, mut b) = (source, target);
3222         while let (&TyStruct(a_def, a_substs), &TyStruct(b_def, b_substs)) = (&a.sty, &b.sty) {
3223             if a_def != b_def {
3224                 break;
3225             }
3226             if let Some(f) = a_def.struct_variant().fields.last() {
3227                 a = f.ty(self, a_substs);
3228                 b = f.ty(self, b_substs);
3229             } else {
3230                 break;
3231             }
3232         }
3233         (a, b)
3234     }
3235
3236     // Returns the repeat count for a repeating vector expression.
3237     pub fn eval_repeat_count(&self, count_expr: &hir::Expr) -> usize {
3238         let hint = UncheckedExprHint(self.types.usize);
3239         match const_eval::eval_const_expr_partial(self, count_expr, hint) {
3240             Ok(val) => {
3241                 let found = match val {
3242                     ConstVal::Uint(count) => return count as usize,
3243                     ConstVal::Int(count) if count >= 0 => return count as usize,
3244                     const_val => const_val.description(),
3245                 };
3246                 span_err!(self.sess, count_expr.span, E0306,
3247                     "expected positive integer for repeat count, found {}",
3248                     found);
3249             }
3250             Err(err) => {
3251                 let err_msg = match count_expr.node {
3252                     hir::ExprPath(None, hir::Path {
3253                         global: false,
3254                         ref segments,
3255                         ..
3256                     }) if segments.len() == 1 =>
3257                         format!("found variable"),
3258                     _ => match err.kind {
3259                         ErrKind::MiscCatchAll => format!("but found {}", err.description()),
3260                         _ => format!("but {}", err.description())
3261                     }
3262                 };
3263                 span_err!(self.sess, count_expr.span, E0307,
3264                     "expected constant integer for repeat count, {}", err_msg);
3265             }
3266         }
3267         0
3268     }
3269
3270     // Iterate over a type parameter's bounded traits and any supertraits
3271     // of those traits, ignoring kinds.
3272     // Here, the supertraits are the transitive closure of the supertrait
3273     // relation on the supertraits from each bounded trait's constraint
3274     // list.
3275     pub fn each_bound_trait_and_supertraits<F>(&self,
3276                                                bounds: &[PolyTraitRef<'tcx>],
3277                                                mut f: F)
3278                                                -> bool where
3279         F: FnMut(PolyTraitRef<'tcx>) -> bool,
3280     {
3281         for bound_trait_ref in traits::transitive_bounds(self, bounds) {
3282             if !f(bound_trait_ref) {
3283                 return false;
3284             }
3285         }
3286         return true;
3287     }
3288
3289     /// Given a set of predicates that apply to an object type, returns
3290     /// the region bounds that the (erased) `Self` type must
3291     /// outlive. Precisely *because* the `Self` type is erased, the
3292     /// parameter `erased_self_ty` must be supplied to indicate what type
3293     /// has been used to represent `Self` in the predicates
3294     /// themselves. This should really be a unique type; `FreshTy(0)` is a
3295     /// popular choice.
3296     ///
3297     /// NB: in some cases, particularly around higher-ranked bounds,
3298     /// this function returns a kind of conservative approximation.
3299     /// That is, all regions returned by this function are definitely
3300     /// required, but there may be other region bounds that are not
3301     /// returned, as well as requirements like `for<'a> T: 'a`.
3302     ///
3303     /// Requires that trait definitions have been processed so that we can
3304     /// elaborate predicates and walk supertraits.
3305     pub fn required_region_bounds(&self,
3306                                   erased_self_ty: Ty<'tcx>,
3307                                   predicates: Vec<ty::Predicate<'tcx>>)
3308                                   -> Vec<ty::Region>    {
3309         debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
3310                erased_self_ty,
3311                predicates);
3312
3313         assert!(!erased_self_ty.has_escaping_regions());
3314
3315         traits::elaborate_predicates(self, predicates)
3316             .filter_map(|predicate| {
3317                 match predicate {
3318                     ty::Predicate::Projection(..) |
3319                     ty::Predicate::Trait(..) |
3320                     ty::Predicate::Equate(..) |
3321                     ty::Predicate::WellFormed(..) |
3322                     ty::Predicate::ObjectSafe(..) |
3323                     ty::Predicate::RegionOutlives(..) => {
3324                         None
3325                     }
3326                     ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t, r))) => {
3327                         // Search for a bound of the form `erased_self_ty
3328                         // : 'a`, but be wary of something like `for<'a>
3329                         // erased_self_ty : 'a` (we interpret a
3330                         // higher-ranked bound like that as 'static,
3331                         // though at present the code in `fulfill.rs`
3332                         // considers such bounds to be unsatisfiable, so
3333                         // it's kind of a moot point since you could never
3334                         // construct such an object, but this seems
3335                         // correct even if that code changes).
3336                         if t == erased_self_ty && !r.has_escaping_regions() {
3337                             Some(r)
3338                         } else {
3339                             None
3340                         }
3341                     }
3342                 }
3343             })
3344             .collect()
3345     }
3346
3347     pub fn item_variances(&self, item_id: DefId) -> Rc<ItemVariances> {
3348         lookup_locally_or_in_crate_store(
3349             "item_variance_map", item_id, &self.item_variance_map,
3350             || Rc::new(csearch::get_item_variances(&self.sess.cstore, item_id)))
3351     }
3352
3353     pub fn trait_has_default_impl(&self, trait_def_id: DefId) -> bool {
3354         self.populate_implementations_for_trait_if_necessary(trait_def_id);
3355
3356         let def = self.lookup_trait_def(trait_def_id);
3357         def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
3358     }
3359
3360     /// Records a trait-to-implementation mapping.
3361     pub fn record_trait_has_default_impl(&self, trait_def_id: DefId) {
3362         let def = self.lookup_trait_def(trait_def_id);
3363         def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
3364     }
3365
3366     /// Load primitive inherent implementations if necessary
3367     pub fn populate_implementations_for_primitive_if_necessary(&self,
3368                                                                primitive_def_id: DefId) {
3369         if primitive_def_id.is_local() {
3370             return
3371         }
3372
3373         if self.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
3374             return
3375         }
3376
3377         debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
3378                primitive_def_id);
3379
3380         let impl_items = csearch::get_impl_items(&self.sess.cstore, primitive_def_id);
3381
3382         // Store the implementation info.
3383         self.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
3384         self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
3385     }
3386
3387     /// Populates the type context with all the inherent implementations for
3388     /// the given type if necessary.
3389     pub fn populate_inherent_implementations_for_type_if_necessary(&self,
3390                                                                    type_id: DefId) {
3391         if type_id.is_local() {
3392             return
3393         }
3394
3395         if self.populated_external_types.borrow().contains(&type_id) {
3396             return
3397         }
3398
3399         debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
3400                type_id);
3401
3402         let mut inherent_impls = Vec::new();
3403         csearch::each_inherent_implementation_for_type(&self.sess.cstore, type_id, |impl_def_id| {
3404             // Record the implementation.
3405             inherent_impls.push(impl_def_id);
3406
3407             // Store the implementation info.
3408             let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
3409             self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
3410         });
3411
3412         self.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls));
3413         self.populated_external_types.borrow_mut().insert(type_id);
3414     }
3415
3416     /// Populates the type context with all the implementations for the given
3417     /// trait if necessary.
3418     pub fn populate_implementations_for_trait_if_necessary(&self, trait_id: DefId) {
3419         if trait_id.is_local() {
3420             return
3421         }
3422
3423         let def = self.lookup_trait_def(trait_id);
3424         if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
3425             return;
3426         }
3427
3428         debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
3429
3430         if csearch::is_defaulted_trait(&self.sess.cstore, trait_id) {
3431             self.record_trait_has_default_impl(trait_id);
3432         }
3433
3434         csearch::each_implementation_for_trait(&self.sess.cstore, trait_id, |impl_def_id| {
3435             let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
3436             let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
3437             // Record the trait->implementation mapping.
3438             def.record_impl(self, impl_def_id, trait_ref);
3439
3440             // For any methods that use a default implementation, add them to
3441             // the map. This is a bit unfortunate.
3442             for impl_item_def_id in &impl_items {
3443                 let method_def_id = impl_item_def_id.def_id();
3444                 match self.impl_or_trait_item(method_def_id) {
3445                     MethodTraitItem(method) => {
3446                         if let Some(source) = method.provided_source {
3447                             self.provided_method_sources
3448                                 .borrow_mut()
3449                                 .insert(method_def_id, source);
3450                         }
3451                     }
3452                     _ => {}
3453                 }
3454             }
3455
3456             // Store the implementation info.
3457             self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
3458         });
3459
3460         def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
3461     }
3462
3463     /// Given the def_id of an impl, return the def_id of the trait it implements.
3464     /// If it implements no trait, return `None`.
3465     pub fn trait_id_of_impl(&self, def_id: DefId) -> Option<DefId> {
3466         self.impl_trait_ref(def_id).map(|tr| tr.def_id)
3467     }
3468
3469     /// If the given def ID describes a method belonging to an impl, return the
3470     /// ID of the impl that the method belongs to. Otherwise, return `None`.
3471     pub fn impl_of_method(&self, def_id: DefId) -> Option<DefId> {
3472         if def_id.krate != LOCAL_CRATE {
3473             return match csearch::get_impl_or_trait_item(self,
3474                                                          def_id).container() {
3475                 TraitContainer(_) => None,
3476                 ImplContainer(def_id) => Some(def_id),
3477             };
3478         }
3479         match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
3480             Some(trait_item) => {
3481                 match trait_item.container() {
3482                     TraitContainer(_) => None,
3483                     ImplContainer(def_id) => Some(def_id),
3484                 }
3485             }
3486             None => None
3487         }
3488     }
3489
3490     /// If the given def ID describes an item belonging to a trait (either a
3491     /// default method or an implementation of a trait method), return the ID of
3492     /// the trait that the method belongs to. Otherwise, return `None`.
3493     pub fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
3494         if def_id.krate != LOCAL_CRATE {
3495             return csearch::get_trait_of_item(&self.sess.cstore, def_id, self);
3496         }
3497         match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
3498             Some(impl_or_trait_item) => {
3499                 match impl_or_trait_item.container() {
3500                     TraitContainer(def_id) => Some(def_id),
3501                     ImplContainer(def_id) => self.trait_id_of_impl(def_id),
3502                 }
3503             }
3504             None => None
3505         }
3506     }
3507
3508     /// If the given def ID describes an item belonging to a trait, (either a
3509     /// default method or an implementation of a trait method), return the ID of
3510     /// the method inside trait definition (this means that if the given def ID
3511     /// is already that of the original trait method, then the return value is
3512     /// the same).
3513     /// Otherwise, return `None`.
3514     pub fn trait_item_of_item(&self, def_id: DefId) -> Option<ImplOrTraitItemId> {
3515         let impl_item = match self.impl_or_trait_items.borrow().get(&def_id) {
3516             Some(m) => m.clone(),
3517             None => return None,
3518         };
3519         let name = impl_item.name();
3520         match self.trait_of_item(def_id) {
3521             Some(trait_did) => {
3522                 self.trait_items(trait_did).iter()
3523                     .find(|item| item.name() == name)
3524                     .map(|item| item.id())
3525             }
3526             None => None
3527         }
3528     }
3529
3530     /// Creates a hash of the type `Ty` which will be the same no matter what crate
3531     /// context it's calculated within. This is used by the `type_id` intrinsic.
3532     pub fn hash_crate_independent(&self, ty: Ty<'tcx>, svh: &Svh) -> u64 {
3533         let mut state = SipHasher::new();
3534         helper(self, ty, svh, &mut state);
3535         return state.finish();
3536
3537         fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh,
3538                         state: &mut SipHasher) {
3539             macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } }
3540             macro_rules! hash { ($e:expr) => { $e.hash(state) }  }
3541
3542             let region = |state: &mut SipHasher, r: Region| {
3543                 match r {
3544                     ReStatic => {}
3545                     ReLateBound(db, BrAnon(i)) => {
3546                         db.hash(state);
3547                         i.hash(state);
3548                     }
3549                     ReEmpty |
3550                     ReEarlyBound(..) |
3551                     ReLateBound(..) |
3552                     ReFree(..) |
3553                     ReScope(..) |
3554                     ReVar(..) |
3555                     ReSkolemized(..) => {
3556                         tcx.sess.bug("unexpected region found when hashing a type")
3557                     }
3558                 }
3559             };
3560             let did = |state: &mut SipHasher, did: DefId| {
3561                 let h = if did.is_local() {
3562                     svh.clone()
3563                 } else {
3564                     tcx.sess.cstore.get_crate_hash(did.krate)
3565                 };
3566                 h.as_str().hash(state);
3567                 did.node.hash(state);
3568             };
3569             let mt = |state: &mut SipHasher, mt: TypeAndMut| {
3570                 mt.mutbl.hash(state);
3571             };
3572             let fn_sig = |state: &mut SipHasher, sig: &Binder<FnSig<'tcx>>| {
3573                 let sig = tcx.anonymize_late_bound_regions(sig).0;
3574                 for a in &sig.inputs { helper(tcx, *a, svh, state); }
3575                 if let ty::FnConverging(output) = sig.output {
3576                     helper(tcx, output, svh, state);
3577                 }
3578             };
3579             ty.maybe_walk(|ty| {
3580                 match ty.sty {
3581                     TyBool => byte!(2),
3582                     TyChar => byte!(3),
3583                     TyInt(i) => {
3584                         byte!(4);
3585                         hash!(i);
3586                     }
3587                     TyUint(u) => {
3588                         byte!(5);
3589                         hash!(u);
3590                     }
3591                     TyFloat(f) => {
3592                         byte!(6);
3593                         hash!(f);
3594                     }
3595                     TyStr => {
3596                         byte!(7);
3597                     }
3598                     TyEnum(d, _) => {
3599                         byte!(8);
3600                         did(state, d.did);
3601                     }
3602                     TyBox(_) => {
3603                         byte!(9);
3604                     }
3605                     TyArray(_, n) => {
3606                         byte!(10);
3607                         n.hash(state);
3608                     }
3609                     TySlice(_) => {
3610                         byte!(11);
3611                     }
3612                     TyRawPtr(m) => {
3613                         byte!(12);
3614                         mt(state, m);
3615                     }
3616                     TyRef(r, m) => {
3617                         byte!(13);
3618                         region(state, *r);
3619                         mt(state, m);
3620                     }
3621                     TyBareFn(opt_def_id, ref b) => {
3622                         byte!(14);
3623                         hash!(opt_def_id);
3624                         hash!(b.unsafety);
3625                         hash!(b.abi);
3626                         fn_sig(state, &b.sig);
3627                         return false;
3628                     }
3629                     TyTrait(ref data) => {
3630                         byte!(17);
3631                         did(state, data.principal_def_id());
3632                         hash!(data.bounds);
3633
3634                         let principal = tcx.anonymize_late_bound_regions(&data.principal).0;
3635                         for subty in &principal.substs.types {
3636                             helper(tcx, subty, svh, state);
3637                         }
3638
3639                         return false;
3640                     }
3641                     TyStruct(d, _) => {
3642                         byte!(18);
3643                         did(state, d.did);
3644                     }
3645                     TyTuple(ref inner) => {
3646                         byte!(19);
3647                         hash!(inner.len());
3648                     }
3649                     TyParam(p) => {
3650                         byte!(20);
3651                         hash!(p.space);
3652                         hash!(p.idx);
3653                         hash!(p.name.as_str());
3654                     }
3655                     TyInfer(_) => unreachable!(),
3656                     TyError => byte!(21),
3657                     TyClosure(d, _) => {
3658                         byte!(22);
3659                         did(state, d);
3660                     }
3661                     TyProjection(ref data) => {
3662                         byte!(23);
3663                         did(state, data.trait_ref.def_id);
3664                         hash!(data.item_name.as_str());
3665                     }
3666                 }
3667                 true
3668             });
3669         }
3670     }
3671
3672     /// Construct a parameter environment suitable for static contexts or other contexts where there
3673     /// are no free type/lifetime parameters in scope.
3674     pub fn empty_parameter_environment<'a>(&'a self)
3675                                            -> ParameterEnvironment<'a,'tcx> {
3676         ty::ParameterEnvironment { tcx: self,
3677                                    free_substs: Substs::empty(),
3678                                    caller_bounds: Vec::new(),
3679                                    implicit_region_bound: ty::ReEmpty,
3680                                    selection_cache: traits::SelectionCache::new(),
3681
3682                                    // for an empty parameter
3683                                    // environment, there ARE no free
3684                                    // regions, so it shouldn't matter
3685                                    // what we use for the free id
3686                                    free_id: ast::DUMMY_NODE_ID }
3687     }
3688
3689     /// Constructs and returns a substitution that can be applied to move from
3690     /// the "outer" view of a type or method to the "inner" view.
3691     /// In general, this means converting from bound parameters to
3692     /// free parameters. Since we currently represent bound/free type
3693     /// parameters in the same way, this only has an effect on regions.
3694     pub fn construct_free_substs(&self, generics: &Generics<'tcx>,
3695                                  free_id: NodeId) -> Substs<'tcx> {
3696         // map T => T
3697         let mut types = VecPerParamSpace::empty();
3698         for def in generics.types.as_slice() {
3699             debug!("construct_parameter_environment(): push_types_from_defs: def={:?}",
3700                     def);
3701             types.push(def.space, self.mk_param_from_def(def));
3702         }
3703
3704         let free_id_outlive = self.region_maps.item_extent(free_id);
3705
3706         // map bound 'a => free 'a
3707         let mut regions = VecPerParamSpace::empty();
3708         for def in generics.regions.as_slice() {
3709             let region =
3710                 ReFree(FreeRegion { scope: free_id_outlive,
3711                                     bound_region: BrNamed(def.def_id, def.name) });
3712             debug!("push_region_params {:?}", region);
3713             regions.push(def.space, region);
3714         }
3715
3716         Substs {
3717             types: types,
3718             regions: subst::NonerasedRegions(regions)
3719         }
3720     }
3721
3722     /// See `ParameterEnvironment` struct def'n for details
3723     pub fn construct_parameter_environment<'a>(&'a self,
3724                                                span: Span,
3725                                                generics: &ty::Generics<'tcx>,
3726                                                generic_predicates: &ty::GenericPredicates<'tcx>,
3727                                                free_id: NodeId)
3728                                                -> ParameterEnvironment<'a, 'tcx>
3729     {
3730         //
3731         // Construct the free substs.
3732         //
3733
3734         let free_substs = self.construct_free_substs(generics, free_id);
3735         let free_id_outlive = self.region_maps.item_extent(free_id);
3736
3737         //
3738         // Compute the bounds on Self and the type parameters.
3739         //
3740
3741         let bounds = generic_predicates.instantiate(self, &free_substs);
3742         let bounds = self.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds));
3743         let predicates = bounds.predicates.into_vec();
3744
3745         debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
3746                free_id,
3747                free_substs,
3748                predicates);
3749
3750         //
3751         // Finally, we have to normalize the bounds in the environment, in
3752         // case they contain any associated type projections. This process
3753         // can yield errors if the put in illegal associated types, like
3754         // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
3755         // report these errors right here; this doesn't actually feel
3756         // right to me, because constructing the environment feels like a
3757         // kind of a "idempotent" action, but I'm not sure where would be
3758         // a better place. In practice, we construct environments for
3759         // every fn once during type checking, and we'll abort if there
3760         // are any errors at that point, so after type checking you can be
3761         // sure that this will succeed without errors anyway.
3762         //
3763
3764         let unnormalized_env = ty::ParameterEnvironment {
3765             tcx: self,
3766             free_substs: free_substs,
3767             implicit_region_bound: ty::ReScope(free_id_outlive),
3768             caller_bounds: predicates,
3769             selection_cache: traits::SelectionCache::new(),
3770             free_id: free_id,
3771         };
3772
3773         let cause = traits::ObligationCause::misc(span, free_id);
3774         traits::normalize_param_env_or_error(unnormalized_env, cause)
3775     }
3776
3777     pub fn is_method_call(&self, expr_id: NodeId) -> bool {
3778         self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id))
3779     }
3780
3781     pub fn is_overloaded_autoderef(&self, expr_id: NodeId, autoderefs: u32) -> bool {
3782         self.tables.borrow().method_map.contains_key(&MethodCall::autoderef(expr_id,
3783                                                                             autoderefs))
3784     }
3785
3786     pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
3787         Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
3788     }
3789
3790
3791     /// Returns true if this ADT is a dtorck type, i.e. whether it being
3792     /// safe for destruction requires it to be alive
3793     fn is_adt_dtorck(&self, adt: AdtDef<'tcx>) -> bool {
3794         let dtor_method = match adt.destructor() {
3795             Some(dtor) => dtor,
3796             None => return false
3797         };
3798         let impl_did = self.impl_of_method(dtor_method).unwrap_or_else(|| {
3799             self.sess.bug(&format!("no Drop impl for the dtor of `{:?}`", adt))
3800         });
3801         let generics = adt.type_scheme(self).generics;
3802
3803         // In `impl<'a> Drop ...`, we automatically assume
3804         // `'a` is meaningful and thus represents a bound
3805         // through which we could reach borrowed data.
3806         //
3807         // FIXME (pnkfelix): In the future it would be good to
3808         // extend the language to allow the user to express,
3809         // in the impl signature, that a lifetime is not
3810         // actually used (something like `where 'a: ?Live`).
3811         if generics.has_region_params(subst::TypeSpace) {
3812             debug!("typ: {:?} has interesting dtor due to region params",
3813                    adt);
3814             return true;
3815         }
3816
3817         let mut seen_items = Vec::new();
3818         let mut items_to_inspect = vec![impl_did];
3819         while let Some(item_def_id) = items_to_inspect.pop() {
3820             if seen_items.contains(&item_def_id) {
3821                 continue;
3822             }
3823
3824             for pred in self.lookup_predicates(item_def_id).predicates {
3825                 let result = match pred {
3826                     ty::Predicate::Equate(..) |
3827                     ty::Predicate::RegionOutlives(..) |
3828                     ty::Predicate::TypeOutlives(..) |
3829                     ty::Predicate::WellFormed(..) |
3830                     ty::Predicate::ObjectSafe(..) |
3831                     ty::Predicate::Projection(..) => {
3832                         // For now, assume all these where-clauses
3833                         // may give drop implementation capabilty
3834                         // to access borrowed data.
3835                         true
3836                     }
3837
3838                     ty::Predicate::Trait(ty::Binder(ref t_pred)) => {
3839                         let def_id = t_pred.trait_ref.def_id;
3840                         if self.trait_items(def_id).len() != 0 {
3841                             // If trait has items, assume it adds
3842                             // capability to access borrowed data.
3843                             true
3844                         } else {
3845                             // Trait without items is itself
3846                             // uninteresting from POV of dropck.
3847                             //
3848                             // However, may have parent w/ items;
3849                             // so schedule checking of predicates,
3850                             items_to_inspect.push(def_id);
3851                             // and say "no capability found" for now.
3852                             false
3853                         }
3854                     }
3855                 };
3856
3857                 if result {
3858                     debug!("typ: {:?} has interesting dtor due to generic preds, e.g. {:?}",
3859                            adt, pred);
3860                     return true;
3861                 }
3862             }
3863
3864             seen_items.push(item_def_id);
3865         }
3866
3867         debug!("typ: {:?} is dtorck-safe", adt);
3868         false
3869     }
3870 }
3871
3872 /// The category of explicit self.
3873 #[derive(Clone, Copy, Eq, PartialEq, Debug)]
3874 pub enum ExplicitSelfCategory {
3875     StaticExplicitSelfCategory,
3876     ByValueExplicitSelfCategory,
3877     ByReferenceExplicitSelfCategory(Region, hir::Mutability),
3878     ByBoxExplicitSelfCategory,
3879 }
3880
3881 /// A free variable referred to in a function.
3882 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
3883 pub struct Freevar {
3884     /// The variable being accessed free.
3885     pub def: def::Def,
3886
3887     // First span where it is accessed (there can be multiple).
3888     pub span: Span
3889 }
3890
3891 pub type FreevarMap = NodeMap<Vec<Freevar>>;
3892
3893 pub type CaptureModeMap = NodeMap<hir::CaptureClause>;
3894
3895 // Trait method resolution
3896 pub type TraitMap = NodeMap<Vec<DefId>>;
3897
3898 // Map from the NodeId of a glob import to a list of items which are actually
3899 // imported.
3900 pub type GlobMap = HashMap<NodeId, HashSet<Name>>;
3901
3902 impl<'tcx> AutoAdjustment<'tcx> {
3903     pub fn is_identity(&self) -> bool {
3904         match *self {
3905             AdjustReifyFnPointer |
3906             AdjustUnsafeFnPointer => false,
3907             AdjustDerefRef(ref r) => r.is_identity(),
3908         }
3909     }
3910 }
3911
3912 impl<'tcx> AutoDerefRef<'tcx> {
3913     pub fn is_identity(&self) -> bool {
3914         self.autoderefs == 0 && self.unsize.is_none() && self.autoref.is_none()
3915     }
3916 }
3917
3918 impl<'tcx> ctxt<'tcx> {
3919     pub fn with_freevars<T, F>(&self, fid: NodeId, f: F) -> T where
3920         F: FnOnce(&[Freevar]) -> T,
3921     {
3922         match self.freevars.borrow().get(&fid) {
3923             None => f(&[]),
3924             Some(d) => f(&d[..])
3925         }
3926     }
3927
3928     pub fn make_substs_for_receiver_types(&self,
3929                                           trait_ref: &ty::TraitRef<'tcx>,
3930                                           method: &ty::Method<'tcx>)
3931                                           -> subst::Substs<'tcx>
3932     {
3933         /*!
3934          * Substitutes the values for the receiver's type parameters
3935          * that are found in method, leaving the method's type parameters
3936          * intact.
3937          */
3938
3939         let meth_tps: Vec<Ty> =
3940             method.generics.types.get_slice(subst::FnSpace)
3941                   .iter()
3942                   .map(|def| self.mk_param_from_def(def))
3943                   .collect();
3944         let meth_regions: Vec<ty::Region> =
3945             method.generics.regions.get_slice(subst::FnSpace)
3946                   .iter()
3947                   .map(|def| def.to_early_bound_region())
3948                   .collect();
3949         trait_ref.substs.clone().with_method(meth_tps, meth_regions)
3950     }
3951 }
3952
3953 /// An "escaping region" is a bound region whose binder is not part of `t`.
3954 ///
3955 /// So, for example, consider a type like the following, which has two binders:
3956 ///
3957 ///    for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
3958 ///    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
3959 ///                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~  inner scope
3960 ///
3961 /// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
3962 /// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
3963 /// fn type*, that type has an escaping region: `'a`.
3964 ///
3965 /// Note that what I'm calling an "escaping region" is often just called a "free region". However,
3966 /// we already use the term "free region". It refers to the regions that we use to represent bound
3967 /// regions on a fn definition while we are typechecking its body.
3968 ///
3969 /// To clarify, conceptually there is no particular difference between an "escaping" region and a
3970 /// "free" region. However, there is a big difference in practice. Basically, when "entering" a
3971 /// binding level, one is generally required to do some sort of processing to a bound region, such
3972 /// as replacing it with a fresh/skolemized region, or making an entry in the environment to
3973 /// represent the scope to which it is attached, etc. An escaping region represents a bound region
3974 /// for which this processing has not yet been done.
3975 pub trait RegionEscape {
3976     fn has_escaping_regions(&self) -> bool {
3977         self.has_regions_escaping_depth(0)
3978     }
3979
3980     fn has_regions_escaping_depth(&self, depth: u32) -> bool;
3981 }
3982
3983 pub trait HasTypeFlags {
3984     fn has_type_flags(&self, flags: TypeFlags) -> bool;
3985     fn has_projection_types(&self) -> bool {
3986         self.has_type_flags(TypeFlags::HAS_PROJECTION)
3987     }
3988     fn references_error(&self) -> bool {
3989         self.has_type_flags(TypeFlags::HAS_TY_ERR)
3990     }
3991     fn has_param_types(&self) -> bool {
3992         self.has_type_flags(TypeFlags::HAS_PARAMS)
3993     }
3994     fn has_self_ty(&self) -> bool {
3995         self.has_type_flags(TypeFlags::HAS_SELF)
3996     }
3997     fn has_infer_types(&self) -> bool {
3998         self.has_type_flags(TypeFlags::HAS_TY_INFER)
3999     }
4000     fn needs_infer(&self) -> bool {
4001         self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
4002     }
4003     fn needs_subst(&self) -> bool {
4004         self.has_type_flags(TypeFlags::NEEDS_SUBST)
4005     }
4006     fn has_closure_types(&self) -> bool {
4007         self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
4008     }
4009     fn has_erasable_regions(&self) -> bool {
4010         self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND |
4011                             TypeFlags::HAS_RE_INFER |
4012                             TypeFlags::HAS_FREE_REGIONS)
4013     }
4014     /// Indicates whether this value references only 'global'
4015     /// types/lifetimes that are the same regardless of what fn we are
4016     /// in. This is used for caching. Errs on the side of returning
4017     /// false.
4018     fn is_global(&self) -> bool {
4019         !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES)
4020     }
4021 }