]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/ty/mod.rs
split ty::util and ty::adjustment
[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::DtorKind::*;
15 pub use self::ExplicitSelfCategory::*;
16 pub use self::ImplOrTraitItemContainer::*;
17 pub use self::BorrowKind::*;
18 pub use self::ImplOrTraitItem::*;
19 pub use self::IntVarValue::*;
20 pub use self::LvaluePreference::*;
21
22 use front::map as ast_map;
23 use front::map::LinkedPath;
24 use metadata::csearch;
25 use middle;
26 use middle::def::{self, ExportMap};
27 use middle::def_id::{DefId, LOCAL_CRATE};
28 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
29 use middle::subst::{self, ParamSpace, Subst, Substs, VecPerParamSpace};
30 use middle::traits;
31 use middle::ty;
32 use middle::ty::fold::TypeFolder;
33 use middle::ty::walk::TypeWalker;
34 use util::common::memoized;
35 use util::nodemap::{NodeMap, NodeSet, DefIdMap};
36 use util::nodemap::FnvHashMap;
37
38 use std::borrow::{Borrow, Cow};
39 use std::cell::{Cell, RefCell};
40 use std::hash::{Hash, Hasher};
41 use std::iter;
42 use std::rc::Rc;
43 use std::slice;
44 use std::vec::IntoIter;
45 use std::collections::{HashMap, HashSet};
46 use syntax::ast::{self, CrateNum, Name, NodeId};
47 use syntax::codemap::Span;
48 use syntax::parse::token::{InternedString, special_idents};
49
50 use rustc_front::hir;
51 use rustc_front::hir::{ItemImpl, ItemTrait};
52 use rustc_front::hir::{MutImmutable, MutMutable, Visibility};
53 use rustc_front::attr::{self, AttrMetaMethods};
54
55 pub use self::sty::{Binder, DebruijnIndex};
56 pub use self::sty::{BuiltinBound, BuiltinBounds, ExistentialBounds};
57 pub use self::sty::{BareFnTy, FnSig, PolyFnSig, FnOutput, PolyFnOutput};
58 pub use self::sty::{ClosureTy, InferTy, ParamTy, ProjectionTy, TraitTy};
59 pub use self::sty::{ClosureSubsts, TypeAndMut};
60 pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef};
61 pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
62 pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
63 pub use self::sty::BoundRegion::*;
64 pub use self::sty::FnOutput::*;
65 pub use self::sty::InferTy::*;
66 pub use self::sty::Region::*;
67 pub use self::sty::TypeVariants::*;
68
69 pub use self::sty::BuiltinBound::Send as BoundSend;
70 pub use self::sty::BuiltinBound::Sized as BoundSized;
71 pub use self::sty::BuiltinBound::Copy as BoundCopy;
72 pub use self::sty::BuiltinBound::Sync as BoundSync;
73
74 pub use self::contents::TypeContents;
75 pub use self::context::{ctxt, tls};
76 pub use self::context::{CtxtArenas, Lift, Tables};
77
78 pub mod adjustment;
79 pub mod cast;
80 pub mod error;
81 pub mod fast_reject;
82 pub mod fold;
83 pub mod _match;
84 pub mod outlives;
85 pub mod relate;
86 pub mod walk;
87 pub mod wf;
88 pub mod util;
89
90 mod contents;
91 mod context;
92 mod flags;
93 mod ivar;
94 mod structural_impls;
95 mod sty;
96
97 pub type Disr = u64;
98 pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
99
100 // Data types
101
102 /// The complete set of all analyses described in this module. This is
103 /// produced by the driver and fed to trans and later passes.
104 pub struct CrateAnalysis {
105     pub export_map: ExportMap,
106     pub exported_items: middle::privacy::ExportedItems,
107     pub public_items: middle::privacy::PublicItems,
108     pub reachable: NodeSet,
109     pub name: String,
110     pub glob_map: Option<GlobMap>,
111 }
112
113
114 #[derive(Copy, Clone)]
115 pub enum DtorKind {
116     NoDtor,
117     TraitDtor(bool)
118 }
119
120 impl DtorKind {
121     pub fn is_present(&self) -> bool {
122         match *self {
123             TraitDtor(..) => true,
124             _ => false
125         }
126     }
127
128     pub fn has_drop_flag(&self) -> bool {
129         match self {
130             &NoDtor => false,
131             &TraitDtor(flag) => flag
132         }
133     }
134 }
135
136 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
137 pub enum ImplOrTraitItemContainer {
138     TraitContainer(DefId),
139     ImplContainer(DefId),
140 }
141
142 impl ImplOrTraitItemContainer {
143     pub fn id(&self) -> DefId {
144         match *self {
145             TraitContainer(id) => id,
146             ImplContainer(id) => id,
147         }
148     }
149 }
150
151 #[derive(Clone)]
152 pub enum ImplOrTraitItem<'tcx> {
153     ConstTraitItem(Rc<AssociatedConst<'tcx>>),
154     MethodTraitItem(Rc<Method<'tcx>>),
155     TypeTraitItem(Rc<AssociatedType<'tcx>>),
156 }
157
158 impl<'tcx> ImplOrTraitItem<'tcx> {
159     fn id(&self) -> ImplOrTraitItemId {
160         match *self {
161             ConstTraitItem(ref associated_const) => {
162                 ConstTraitItemId(associated_const.def_id)
163             }
164             MethodTraitItem(ref method) => MethodTraitItemId(method.def_id),
165             TypeTraitItem(ref associated_type) => {
166                 TypeTraitItemId(associated_type.def_id)
167             }
168         }
169     }
170
171     pub fn def_id(&self) -> DefId {
172         match *self {
173             ConstTraitItem(ref associated_const) => associated_const.def_id,
174             MethodTraitItem(ref method) => method.def_id,
175             TypeTraitItem(ref associated_type) => associated_type.def_id,
176         }
177     }
178
179     pub fn name(&self) -> Name {
180         match *self {
181             ConstTraitItem(ref associated_const) => associated_const.name,
182             MethodTraitItem(ref method) => method.name,
183             TypeTraitItem(ref associated_type) => associated_type.name,
184         }
185     }
186
187     pub fn vis(&self) -> hir::Visibility {
188         match *self {
189             ConstTraitItem(ref associated_const) => associated_const.vis,
190             MethodTraitItem(ref method) => method.vis,
191             TypeTraitItem(ref associated_type) => associated_type.vis,
192         }
193     }
194
195     pub fn container(&self) -> ImplOrTraitItemContainer {
196         match *self {
197             ConstTraitItem(ref associated_const) => associated_const.container,
198             MethodTraitItem(ref method) => method.container,
199             TypeTraitItem(ref associated_type) => associated_type.container,
200         }
201     }
202
203     pub fn as_opt_method(&self) -> Option<Rc<Method<'tcx>>> {
204         match *self {
205             MethodTraitItem(ref m) => Some((*m).clone()),
206             _ => None,
207         }
208     }
209 }
210
211 #[derive(Clone, Copy, Debug)]
212 pub enum ImplOrTraitItemId {
213     ConstTraitItemId(DefId),
214     MethodTraitItemId(DefId),
215     TypeTraitItemId(DefId),
216 }
217
218 impl ImplOrTraitItemId {
219     pub fn def_id(&self) -> DefId {
220         match *self {
221             ConstTraitItemId(def_id) => def_id,
222             MethodTraitItemId(def_id) => def_id,
223             TypeTraitItemId(def_id) => def_id,
224         }
225     }
226 }
227
228 #[derive(Clone, Debug)]
229 pub struct Method<'tcx> {
230     pub name: Name,
231     pub generics: Generics<'tcx>,
232     pub predicates: GenericPredicates<'tcx>,
233     pub fty: BareFnTy<'tcx>,
234     pub explicit_self: ExplicitSelfCategory,
235     pub vis: hir::Visibility,
236     pub def_id: DefId,
237     pub container: ImplOrTraitItemContainer,
238
239     // If this method is provided, we need to know where it came from
240     pub provided_source: Option<DefId>
241 }
242
243 impl<'tcx> Method<'tcx> {
244     pub fn new(name: Name,
245                generics: ty::Generics<'tcx>,
246                predicates: GenericPredicates<'tcx>,
247                fty: BareFnTy<'tcx>,
248                explicit_self: ExplicitSelfCategory,
249                vis: hir::Visibility,
250                def_id: DefId,
251                container: ImplOrTraitItemContainer,
252                provided_source: Option<DefId>)
253                -> Method<'tcx> {
254        Method {
255             name: name,
256             generics: generics,
257             predicates: predicates,
258             fty: fty,
259             explicit_self: explicit_self,
260             vis: vis,
261             def_id: def_id,
262             container: container,
263             provided_source: provided_source
264         }
265     }
266
267     pub fn container_id(&self) -> DefId {
268         match self.container {
269             TraitContainer(id) => id,
270             ImplContainer(id) => id,
271         }
272     }
273 }
274
275 #[derive(Clone, Copy, Debug)]
276 pub struct AssociatedConst<'tcx> {
277     pub name: Name,
278     pub ty: Ty<'tcx>,
279     pub vis: hir::Visibility,
280     pub def_id: DefId,
281     pub container: ImplOrTraitItemContainer,
282     pub default: Option<DefId>,
283 }
284
285 #[derive(Clone, Copy, Debug)]
286 pub struct AssociatedType<'tcx> {
287     pub name: Name,
288     pub ty: Option<Ty<'tcx>>,
289     pub vis: hir::Visibility,
290     pub def_id: DefId,
291     pub container: ImplOrTraitItemContainer,
292 }
293
294 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
295 pub struct ItemVariances {
296     pub types: VecPerParamSpace<Variance>,
297     pub regions: VecPerParamSpace<Variance>,
298 }
299
300 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
301 pub enum Variance {
302     Covariant,      // T<A> <: T<B> iff A <: B -- e.g., function return type
303     Invariant,      // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
304     Contravariant,  // T<A> <: T<B> iff B <: A -- e.g., function param type
305     Bivariant,      // T<A> <: T<B>            -- e.g., unused type parameter
306 }
307
308 #[derive(Clone, Copy, Debug)]
309 pub struct MethodCallee<'tcx> {
310     /// Impl method ID, for inherent methods, or trait method ID, otherwise.
311     pub def_id: DefId,
312     pub ty: Ty<'tcx>,
313     pub substs: &'tcx subst::Substs<'tcx>
314 }
315
316 /// With method calls, we store some extra information in
317 /// side tables (i.e method_map). We use
318 /// MethodCall as a key to index into these tables instead of
319 /// just directly using the expression's NodeId. The reason
320 /// for this being that we may apply adjustments (coercions)
321 /// with the resulting expression also needing to use the
322 /// side tables. The problem with this is that we don't
323 /// assign a separate NodeId to this new expression
324 /// and so it would clash with the base expression if both
325 /// needed to add to the side tables. Thus to disambiguate
326 /// we also keep track of whether there's an adjustment in
327 /// our key.
328 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
329 pub struct MethodCall {
330     pub expr_id: NodeId,
331     pub autoderef: u32
332 }
333
334 impl MethodCall {
335     pub fn expr(id: NodeId) -> MethodCall {
336         MethodCall {
337             expr_id: id,
338             autoderef: 0
339         }
340     }
341
342     pub fn autoderef(expr_id: NodeId, autoderef: u32) -> MethodCall {
343         MethodCall {
344             expr_id: expr_id,
345             autoderef: 1 + autoderef
346         }
347     }
348 }
349
350 // maps from an expression id that corresponds to a method call to the details
351 // of the method to be invoked
352 pub type MethodMap<'tcx> = FnvHashMap<MethodCall, MethodCallee<'tcx>>;
353
354 // Contains information needed to resolve types and (in the future) look up
355 // the types of AST nodes.
356 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
357 pub struct CReaderCacheKey {
358     pub cnum: CrateNum,
359     pub pos: usize,
360     pub len: usize
361 }
362
363 /// A restriction that certain types must be the same size. The use of
364 /// `transmute` gives rise to these restrictions. These generally
365 /// cannot be checked until trans; therefore, each call to `transmute`
366 /// will push one or more such restriction into the
367 /// `transmute_restrictions` vector during `intrinsicck`. They are
368 /// then checked during `trans` by the fn `check_intrinsics`.
369 #[derive(Copy, Clone)]
370 pub struct TransmuteRestriction<'tcx> {
371     /// The span whence the restriction comes.
372     pub span: Span,
373
374     /// The type being transmuted from.
375     pub original_from: Ty<'tcx>,
376
377     /// The type being transmuted to.
378     pub original_to: Ty<'tcx>,
379
380     /// The type being transmuted from, with all type parameters
381     /// substituted for an arbitrary representative. Not to be shown
382     /// to the end user.
383     pub substituted_from: Ty<'tcx>,
384
385     /// The type being transmuted to, with all type parameters
386     /// substituted for an arbitrary representative. Not to be shown
387     /// to the end user.
388     pub substituted_to: Ty<'tcx>,
389
390     /// NodeId of the transmute intrinsic.
391     pub id: NodeId,
392 }
393
394 /// Describes the fragment-state associated with a NodeId.
395 ///
396 /// Currently only unfragmented paths have entries in the table,
397 /// but longer-term this enum is expected to expand to also
398 /// include data for fragmented paths.
399 #[derive(Copy, Clone, Debug)]
400 pub enum FragmentInfo {
401     Moved { var: NodeId, move_expr: NodeId },
402     Assigned { var: NodeId, assign_expr: NodeId, assignee_id: NodeId },
403 }
404
405 // Flags that we track on types. These flags are propagated upwards
406 // through the type during type construction, so that we can quickly
407 // check whether the type has various kinds of types in it without
408 // recursing over the type itself.
409 bitflags! {
410     flags TypeFlags: u32 {
411         const HAS_PARAMS         = 1 << 0,
412         const HAS_SELF           = 1 << 1,
413         const HAS_TY_INFER       = 1 << 2,
414         const HAS_RE_INFER       = 1 << 3,
415         const HAS_RE_EARLY_BOUND = 1 << 4,
416         const HAS_FREE_REGIONS   = 1 << 5,
417         const HAS_TY_ERR         = 1 << 6,
418         const HAS_PROJECTION     = 1 << 7,
419         const HAS_TY_CLOSURE     = 1 << 8,
420
421         // true if there are "names" of types and regions and so forth
422         // that are local to a particular fn
423         const HAS_LOCAL_NAMES   = 1 << 9,
424
425         const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
426                                    TypeFlags::HAS_SELF.bits |
427                                    TypeFlags::HAS_RE_EARLY_BOUND.bits,
428
429         // Flags representing the nominal content of a type,
430         // computed by FlagsComputation. If you add a new nominal
431         // flag, it should be added here too.
432         const NOMINAL_FLAGS     = TypeFlags::HAS_PARAMS.bits |
433                                   TypeFlags::HAS_SELF.bits |
434                                   TypeFlags::HAS_TY_INFER.bits |
435                                   TypeFlags::HAS_RE_INFER.bits |
436                                   TypeFlags::HAS_RE_EARLY_BOUND.bits |
437                                   TypeFlags::HAS_FREE_REGIONS.bits |
438                                   TypeFlags::HAS_TY_ERR.bits |
439                                   TypeFlags::HAS_PROJECTION.bits |
440                                   TypeFlags::HAS_TY_CLOSURE.bits |
441                                   TypeFlags::HAS_LOCAL_NAMES.bits,
442
443         // Caches for type_is_sized, type_moves_by_default
444         const SIZEDNESS_CACHED  = 1 << 16,
445         const IS_SIZED          = 1 << 17,
446         const MOVENESS_CACHED   = 1 << 18,
447         const MOVES_BY_DEFAULT  = 1 << 19,
448     }
449 }
450
451 pub struct TyS<'tcx> {
452     pub sty: TypeVariants<'tcx>,
453     pub flags: Cell<TypeFlags>,
454
455     // the maximal depth of any bound regions appearing in this type.
456     region_depth: u32,
457 }
458
459 impl<'tcx> PartialEq for TyS<'tcx> {
460     #[inline]
461     fn eq(&self, other: &TyS<'tcx>) -> bool {
462         // (self as *const _) == (other as *const _)
463         (self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
464     }
465 }
466 impl<'tcx> Eq for TyS<'tcx> {}
467
468 impl<'tcx> Hash for TyS<'tcx> {
469     fn hash<H: Hasher>(&self, s: &mut H) {
470         (self as *const TyS).hash(s)
471     }
472 }
473
474 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
475
476 /// Upvars do not get their own node-id. Instead, we use the pair of
477 /// the original var id (that is, the root variable that is referenced
478 /// by the upvar) and the id of the closure expression.
479 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
480 pub struct UpvarId {
481     pub var_id: NodeId,
482     pub closure_expr_id: NodeId,
483 }
484
485 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
486 pub enum BorrowKind {
487     /// Data must be immutable and is aliasable.
488     ImmBorrow,
489
490     /// Data must be immutable but not aliasable.  This kind of borrow
491     /// cannot currently be expressed by the user and is used only in
492     /// implicit closure bindings. It is needed when you the closure
493     /// is borrowing or mutating a mutable referent, e.g.:
494     ///
495     ///    let x: &mut isize = ...;
496     ///    let y = || *x += 5;
497     ///
498     /// If we were to try to translate this closure into a more explicit
499     /// form, we'd encounter an error with the code as written:
500     ///
501     ///    struct Env { x: & &mut isize }
502     ///    let x: &mut isize = ...;
503     ///    let y = (&mut Env { &x }, fn_ptr);  // Closure is pair of env and fn
504     ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
505     ///
506     /// This is then illegal because you cannot mutate a `&mut` found
507     /// in an aliasable location. To solve, you'd have to translate with
508     /// an `&mut` borrow:
509     ///
510     ///    struct Env { x: & &mut isize }
511     ///    let x: &mut isize = ...;
512     ///    let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
513     ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
514     ///
515     /// Now the assignment to `**env.x` is legal, but creating a
516     /// mutable pointer to `x` is not because `x` is not mutable. We
517     /// could fix this by declaring `x` as `let mut x`. This is ok in
518     /// user code, if awkward, but extra weird for closures, since the
519     /// borrow is hidden.
520     ///
521     /// So we introduce a "unique imm" borrow -- the referent is
522     /// immutable, but not aliasable. This solves the problem. For
523     /// simplicity, we don't give users the way to express this
524     /// borrow, it's just used when translating closures.
525     UniqueImmBorrow,
526
527     /// Data is mutable and not aliasable.
528     MutBorrow
529 }
530
531 /// Information describing the capture of an upvar. This is computed
532 /// during `typeck`, specifically by `regionck`.
533 #[derive(PartialEq, Clone, Debug, Copy)]
534 pub enum UpvarCapture {
535     /// Upvar is captured by value. This is always true when the
536     /// closure is labeled `move`, but can also be true in other cases
537     /// depending on inference.
538     ByValue,
539
540     /// Upvar is captured by reference.
541     ByRef(UpvarBorrow),
542 }
543
544 #[derive(PartialEq, Clone, Copy)]
545 pub struct UpvarBorrow {
546     /// The kind of borrow: by-ref upvars have access to shared
547     /// immutable borrows, which are not part of the normal language
548     /// syntax.
549     pub kind: BorrowKind,
550
551     /// Region of the resulting reference.
552     pub region: ty::Region,
553 }
554
555 pub type UpvarCaptureMap = FnvHashMap<UpvarId, UpvarCapture>;
556
557 #[derive(Copy, Clone)]
558 pub struct ClosureUpvar<'tcx> {
559     pub def: def::Def,
560     pub span: Span,
561     pub ty: Ty<'tcx>,
562 }
563
564 #[derive(Clone, Copy, PartialEq)]
565 pub enum IntVarValue {
566     IntType(hir::IntTy),
567     UintType(hir::UintTy),
568 }
569
570 /// Default region to use for the bound of objects that are
571 /// supplied as the value for this type parameter. This is derived
572 /// from `T:'a` annotations appearing in the type definition.  If
573 /// this is `None`, then the default is inherited from the
574 /// surrounding context. See RFC #599 for details.
575 #[derive(Copy, Clone)]
576 pub enum ObjectLifetimeDefault {
577     /// Require an explicit annotation. Occurs when multiple
578     /// `T:'a` constraints are found.
579     Ambiguous,
580
581     /// Use the base default, typically 'static, but in a fn body it is a fresh variable
582     BaseDefault,
583
584     /// Use the given region as the default.
585     Specific(Region),
586 }
587
588 #[derive(Clone)]
589 pub struct TypeParameterDef<'tcx> {
590     pub name: Name,
591     pub def_id: DefId,
592     pub space: subst::ParamSpace,
593     pub index: u32,
594     pub default_def_id: DefId, // for use in error reporing about defaults
595     pub default: Option<Ty<'tcx>>,
596     pub object_lifetime_default: ObjectLifetimeDefault,
597 }
598
599 #[derive(Clone)]
600 pub struct RegionParameterDef {
601     pub name: Name,
602     pub def_id: DefId,
603     pub space: subst::ParamSpace,
604     pub index: u32,
605     pub bounds: Vec<ty::Region>,
606 }
607
608 impl RegionParameterDef {
609     pub fn to_early_bound_region(&self) -> ty::Region {
610         ty::ReEarlyBound(ty::EarlyBoundRegion {
611             param_id: self.def_id.node,
612             space: self.space,
613             index: self.index,
614             name: self.name,
615         })
616     }
617     pub fn to_bound_region(&self) -> ty::BoundRegion {
618         ty::BoundRegion::BrNamed(self.def_id, self.name)
619     }
620 }
621
622 /// Information about the formal type/lifetime parameters associated
623 /// with an item or method. Analogous to hir::Generics.
624 #[derive(Clone, Debug)]
625 pub struct Generics<'tcx> {
626     pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
627     pub regions: VecPerParamSpace<RegionParameterDef>,
628 }
629
630 impl<'tcx> Generics<'tcx> {
631     pub fn empty() -> Generics<'tcx> {
632         Generics {
633             types: VecPerParamSpace::empty(),
634             regions: VecPerParamSpace::empty(),
635         }
636     }
637
638     pub fn is_empty(&self) -> bool {
639         self.types.is_empty() && self.regions.is_empty()
640     }
641
642     pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
643         !self.types.is_empty_in(space)
644     }
645
646     pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
647         !self.regions.is_empty_in(space)
648     }
649 }
650
651 /// Bounds on generics.
652 #[derive(Clone)]
653 pub struct GenericPredicates<'tcx> {
654     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
655 }
656
657 impl<'tcx> GenericPredicates<'tcx> {
658     pub fn empty() -> GenericPredicates<'tcx> {
659         GenericPredicates {
660             predicates: VecPerParamSpace::empty(),
661         }
662     }
663
664     pub fn instantiate(&self, tcx: &ctxt<'tcx>, substs: &Substs<'tcx>)
665                        -> InstantiatedPredicates<'tcx> {
666         InstantiatedPredicates {
667             predicates: self.predicates.subst(tcx, substs),
668         }
669     }
670
671     pub fn instantiate_supertrait(&self,
672                                   tcx: &ctxt<'tcx>,
673                                   poly_trait_ref: &ty::PolyTraitRef<'tcx>)
674                                   -> InstantiatedPredicates<'tcx>
675     {
676         InstantiatedPredicates {
677             predicates: self.predicates.map(|pred| pred.subst_supertrait(tcx, poly_trait_ref))
678         }
679     }
680 }
681
682 #[derive(Clone, PartialEq, Eq, Hash)]
683 pub enum Predicate<'tcx> {
684     /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
685     /// the `Self` type of the trait reference and `A`, `B`, and `C`
686     /// would be the parameters in the `TypeSpace`.
687     Trait(PolyTraitPredicate<'tcx>),
688
689     /// where `T1 == T2`.
690     Equate(PolyEquatePredicate<'tcx>),
691
692     /// where 'a : 'b
693     RegionOutlives(PolyRegionOutlivesPredicate),
694
695     /// where T : 'a
696     TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
697
698     /// where <T as TraitRef>::Name == X, approximately.
699     /// See `ProjectionPredicate` struct for details.
700     Projection(PolyProjectionPredicate<'tcx>),
701
702     /// no syntax: T WF
703     WellFormed(Ty<'tcx>),
704
705     /// trait must be object-safe
706     ObjectSafe(DefId),
707 }
708
709 impl<'tcx> Predicate<'tcx> {
710     /// Performs a substitution suitable for going from a
711     /// poly-trait-ref to supertraits that must hold if that
712     /// poly-trait-ref holds. This is slightly different from a normal
713     /// substitution in terms of what happens with bound regions.  See
714     /// lengthy comment below for details.
715     pub fn subst_supertrait(&self,
716                             tcx: &ctxt<'tcx>,
717                             trait_ref: &ty::PolyTraitRef<'tcx>)
718                             -> ty::Predicate<'tcx>
719     {
720         // The interaction between HRTB and supertraits is not entirely
721         // obvious. Let me walk you (and myself) through an example.
722         //
723         // Let's start with an easy case. Consider two traits:
724         //
725         //     trait Foo<'a> : Bar<'a,'a> { }
726         //     trait Bar<'b,'c> { }
727         //
728         // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
729         // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
730         // knew that `Foo<'x>` (for any 'x) then we also know that
731         // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
732         // normal substitution.
733         //
734         // In terms of why this is sound, the idea is that whenever there
735         // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
736         // holds.  So if there is an impl of `T:Foo<'a>` that applies to
737         // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
738         // `'a`.
739         //
740         // Another example to be careful of is this:
741         //
742         //     trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
743         //     trait Bar1<'b,'c> { }
744         //
745         // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
746         // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
747         // reason is similar to the previous example: any impl of
748         // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`.  So
749         // basically we would want to collapse the bound lifetimes from
750         // the input (`trait_ref`) and the supertraits.
751         //
752         // To achieve this in practice is fairly straightforward. Let's
753         // consider the more complicated scenario:
754         //
755         // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
756         //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
757         //   where both `'x` and `'b` would have a DB index of 1.
758         //   The substitution from the input trait-ref is therefore going to be
759         //   `'a => 'x` (where `'x` has a DB index of 1).
760         // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
761         //   early-bound parameter and `'b' is a late-bound parameter with a
762         //   DB index of 1.
763         // - If we replace `'a` with `'x` from the input, it too will have
764         //   a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
765         //   just as we wanted.
766         //
767         // There is only one catch. If we just apply the substitution `'a
768         // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
769         // adjust the DB index because we substituting into a binder (it
770         // tries to be so smart...) resulting in `for<'x> for<'b>
771         // Bar1<'x,'b>` (we have no syntax for this, so use your
772         // imagination). Basically the 'x will have DB index of 2 and 'b
773         // will have DB index of 1. Not quite what we want. So we apply
774         // the substitution to the *contents* of the trait reference,
775         // rather than the trait reference itself (put another way, the
776         // substitution code expects equal binding levels in the values
777         // from the substitution and the value being substituted into, and
778         // this trick achieves that).
779
780         let substs = &trait_ref.0.substs;
781         match *self {
782             Predicate::Trait(ty::Binder(ref data)) =>
783                 Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
784             Predicate::Equate(ty::Binder(ref data)) =>
785                 Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
786             Predicate::RegionOutlives(ty::Binder(ref data)) =>
787                 Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))),
788             Predicate::TypeOutlives(ty::Binder(ref data)) =>
789                 Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))),
790             Predicate::Projection(ty::Binder(ref data)) =>
791                 Predicate::Projection(ty::Binder(data.subst(tcx, substs))),
792             Predicate::WellFormed(data) =>
793                 Predicate::WellFormed(data.subst(tcx, substs)),
794             Predicate::ObjectSafe(trait_def_id) =>
795                 Predicate::ObjectSafe(trait_def_id),
796         }
797     }
798 }
799
800 #[derive(Clone, PartialEq, Eq, Hash)]
801 pub struct TraitPredicate<'tcx> {
802     pub trait_ref: TraitRef<'tcx>
803 }
804 pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
805
806 impl<'tcx> TraitPredicate<'tcx> {
807     pub fn def_id(&self) -> DefId {
808         self.trait_ref.def_id
809     }
810
811     pub fn input_types(&self) -> &[Ty<'tcx>] {
812         self.trait_ref.substs.types.as_slice()
813     }
814
815     pub fn self_ty(&self) -> Ty<'tcx> {
816         self.trait_ref.self_ty()
817     }
818 }
819
820 impl<'tcx> PolyTraitPredicate<'tcx> {
821     pub fn def_id(&self) -> DefId {
822         self.0.def_id()
823     }
824 }
825
826 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
827 pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
828 pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
829
830 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
831 pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
832 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
833 pub type PolyRegionOutlivesPredicate = PolyOutlivesPredicate<ty::Region, ty::Region>;
834 pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region>;
835
836 /// This kind of predicate has no *direct* correspondent in the
837 /// syntax, but it roughly corresponds to the syntactic forms:
838 ///
839 /// 1. `T : TraitRef<..., Item=Type>`
840 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
841 ///
842 /// In particular, form #1 is "desugared" to the combination of a
843 /// normal trait predicate (`T : TraitRef<...>`) and one of these
844 /// predicates. Form #2 is a broader form in that it also permits
845 /// equality between arbitrary types. Processing an instance of Form
846 /// #2 eventually yields one of these `ProjectionPredicate`
847 /// instances to normalize the LHS.
848 #[derive(Clone, PartialEq, Eq, Hash)]
849 pub struct ProjectionPredicate<'tcx> {
850     pub projection_ty: ProjectionTy<'tcx>,
851     pub ty: Ty<'tcx>,
852 }
853
854 pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
855
856 impl<'tcx> PolyProjectionPredicate<'tcx> {
857     pub fn item_name(&self) -> Name {
858         self.0.projection_ty.item_name // safe to skip the binder to access a name
859     }
860
861     pub fn sort_key(&self) -> (DefId, Name) {
862         self.0.projection_ty.sort_key()
863     }
864 }
865
866 pub trait ToPolyTraitRef<'tcx> {
867     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
868 }
869
870 impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
871     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
872         assert!(!self.has_escaping_regions());
873         ty::Binder(self.clone())
874     }
875 }
876
877 impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
878     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
879         self.map_bound_ref(|trait_pred| trait_pred.trait_ref.clone())
880     }
881 }
882
883 impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
884     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
885         // Note: unlike with TraitRef::to_poly_trait_ref(),
886         // self.0.trait_ref is permitted to have escaping regions.
887         // This is because here `self` has a `Binder` and so does our
888         // return value, so we are preserving the number of binding
889         // levels.
890         ty::Binder(self.0.projection_ty.trait_ref.clone())
891     }
892 }
893
894 pub trait ToPredicate<'tcx> {
895     fn to_predicate(&self) -> Predicate<'tcx>;
896 }
897
898 impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
899     fn to_predicate(&self) -> Predicate<'tcx> {
900         // we're about to add a binder, so let's check that we don't
901         // accidentally capture anything, or else that might be some
902         // weird debruijn accounting.
903         assert!(!self.has_escaping_regions());
904
905         ty::Predicate::Trait(ty::Binder(ty::TraitPredicate {
906             trait_ref: self.clone()
907         }))
908     }
909 }
910
911 impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
912     fn to_predicate(&self) -> Predicate<'tcx> {
913         ty::Predicate::Trait(self.to_poly_trait_predicate())
914     }
915 }
916
917 impl<'tcx> ToPredicate<'tcx> for PolyEquatePredicate<'tcx> {
918     fn to_predicate(&self) -> Predicate<'tcx> {
919         Predicate::Equate(self.clone())
920     }
921 }
922
923 impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate {
924     fn to_predicate(&self) -> Predicate<'tcx> {
925         Predicate::RegionOutlives(self.clone())
926     }
927 }
928
929 impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
930     fn to_predicate(&self) -> Predicate<'tcx> {
931         Predicate::TypeOutlives(self.clone())
932     }
933 }
934
935 impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
936     fn to_predicate(&self) -> Predicate<'tcx> {
937         Predicate::Projection(self.clone())
938     }
939 }
940
941 impl<'tcx> Predicate<'tcx> {
942     /// Iterates over the types in this predicate. Note that in all
943     /// cases this is skipping over a binder, so late-bound regions
944     /// with depth 0 are bound by the predicate.
945     pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
946         let vec: Vec<_> = match *self {
947             ty::Predicate::Trait(ref data) => {
948                 data.0.trait_ref.substs.types.as_slice().to_vec()
949             }
950             ty::Predicate::Equate(ty::Binder(ref data)) => {
951                 vec![data.0, data.1]
952             }
953             ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
954                 vec![data.0]
955             }
956             ty::Predicate::RegionOutlives(..) => {
957                 vec![]
958             }
959             ty::Predicate::Projection(ref data) => {
960                 let trait_inputs = data.0.projection_ty.trait_ref.substs.types.as_slice();
961                 trait_inputs.iter()
962                             .cloned()
963                             .chain(Some(data.0.ty))
964                             .collect()
965             }
966             ty::Predicate::WellFormed(data) => {
967                 vec![data]
968             }
969             ty::Predicate::ObjectSafe(_trait_def_id) => {
970                 vec![]
971             }
972         };
973
974         // The only reason to collect into a vector here is that I was
975         // too lazy to make the full (somewhat complicated) iterator
976         // type that would be needed here. But I wanted this fn to
977         // return an iterator conceptually, rather than a `Vec`, so as
978         // to be closer to `Ty::walk`.
979         vec.into_iter()
980     }
981
982     pub fn has_escaping_regions(&self) -> bool {
983         match *self {
984             Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(),
985             Predicate::Equate(ref p) => p.has_escaping_regions(),
986             Predicate::RegionOutlives(ref p) => p.has_escaping_regions(),
987             Predicate::TypeOutlives(ref p) => p.has_escaping_regions(),
988             Predicate::Projection(ref p) => p.has_escaping_regions(),
989             Predicate::WellFormed(p) => p.has_escaping_regions(),
990             Predicate::ObjectSafe(_trait_def_id) => false,
991         }
992     }
993
994     pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
995         match *self {
996             Predicate::Trait(ref t) => {
997                 Some(t.to_poly_trait_ref())
998             }
999             Predicate::Projection(..) |
1000             Predicate::Equate(..) |
1001             Predicate::RegionOutlives(..) |
1002             Predicate::WellFormed(..) |
1003             Predicate::ObjectSafe(..) |
1004             Predicate::TypeOutlives(..) => {
1005                 None
1006             }
1007         }
1008     }
1009 }
1010
1011 /// Represents the bounds declared on a particular set of type
1012 /// parameters.  Should eventually be generalized into a flag list of
1013 /// where clauses.  You can obtain a `InstantiatedPredicates` list from a
1014 /// `GenericPredicates` by using the `instantiate` method. Note that this method
1015 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
1016 /// the `GenericPredicates` are expressed in terms of the bound type
1017 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
1018 /// represented a set of bounds for some particular instantiation,
1019 /// meaning that the generic parameters have been substituted with
1020 /// their values.
1021 ///
1022 /// Example:
1023 ///
1024 ///     struct Foo<T,U:Bar<T>> { ... }
1025 ///
1026 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
1027 /// `[[], [U:Bar<T>]]`.  Now if there were some particular reference
1028 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
1029 /// [usize:Bar<isize>]]`.
1030 #[derive(Clone)]
1031 pub struct InstantiatedPredicates<'tcx> {
1032     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
1033 }
1034
1035 impl<'tcx> InstantiatedPredicates<'tcx> {
1036     pub fn empty() -> InstantiatedPredicates<'tcx> {
1037         InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
1038     }
1039
1040     pub fn has_escaping_regions(&self) -> bool {
1041         self.predicates.any(|p| p.has_escaping_regions())
1042     }
1043
1044     pub fn is_empty(&self) -> bool {
1045         self.predicates.is_empty()
1046     }
1047 }
1048
1049 impl<'tcx> TraitRef<'tcx> {
1050     pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
1051         TraitRef { def_id: def_id, substs: substs }
1052     }
1053
1054     pub fn self_ty(&self) -> Ty<'tcx> {
1055         self.substs.self_ty().unwrap()
1056     }
1057
1058     pub fn input_types(&self) -> &[Ty<'tcx>] {
1059         // Select only the "input types" from a trait-reference. For
1060         // now this is all the types that appear in the
1061         // trait-reference, but it should eventually exclude
1062         // associated types.
1063         self.substs.types.as_slice()
1064     }
1065 }
1066
1067 /// When type checking, we use the `ParameterEnvironment` to track
1068 /// details about the type/lifetime parameters that are in scope.
1069 /// It primarily stores the bounds information.
1070 ///
1071 /// Note: This information might seem to be redundant with the data in
1072 /// `tcx.ty_param_defs`, but it is not. That table contains the
1073 /// parameter definitions from an "outside" perspective, but this
1074 /// struct will contain the bounds for a parameter as seen from inside
1075 /// the function body. Currently the only real distinction is that
1076 /// bound lifetime parameters are replaced with free ones, but in the
1077 /// future I hope to refine the representation of types so as to make
1078 /// more distinctions clearer.
1079 #[derive(Clone)]
1080 pub struct ParameterEnvironment<'a, 'tcx:'a> {
1081     pub tcx: &'a ctxt<'tcx>,
1082
1083     /// See `construct_free_substs` for details.
1084     pub free_substs: Substs<'tcx>,
1085
1086     /// Each type parameter has an implicit region bound that
1087     /// indicates it must outlive at least the function body (the user
1088     /// may specify stronger requirements). This field indicates the
1089     /// region of the callee.
1090     pub implicit_region_bound: ty::Region,
1091
1092     /// Obligations that the caller must satisfy. This is basically
1093     /// the set of bounds on the in-scope type parameters, translated
1094     /// into Obligations, and elaborated and normalized.
1095     pub caller_bounds: Vec<ty::Predicate<'tcx>>,
1096
1097     /// Caches the results of trait selection. This cache is used
1098     /// for things that have to do with the parameters in scope.
1099     pub selection_cache: traits::SelectionCache<'tcx>,
1100
1101     /// Scope that is attached to free regions for this scope. This
1102     /// is usually the id of the fn body, but for more abstract scopes
1103     /// like structs we often use the node-id of the struct.
1104     ///
1105     /// FIXME(#3696). It would be nice to refactor so that free
1106     /// regions don't have this implicit scope and instead introduce
1107     /// relationships in the environment.
1108     pub free_id: ast::NodeId,
1109 }
1110
1111 impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
1112     pub fn with_caller_bounds(&self,
1113                               caller_bounds: Vec<ty::Predicate<'tcx>>)
1114                               -> ParameterEnvironment<'a,'tcx>
1115     {
1116         ParameterEnvironment {
1117             tcx: self.tcx,
1118             free_substs: self.free_substs.clone(),
1119             implicit_region_bound: self.implicit_region_bound,
1120             caller_bounds: caller_bounds,
1121             selection_cache: traits::SelectionCache::new(),
1122             free_id: self.free_id,
1123         }
1124     }
1125
1126     pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
1127         match cx.map.find(id) {
1128             Some(ast_map::NodeImplItem(ref impl_item)) => {
1129                 match impl_item.node {
1130                     hir::TypeImplItem(_) => {
1131                         // associated types don't have their own entry (for some reason),
1132                         // so for now just grab environment for the impl
1133                         let impl_id = cx.map.get_parent(id);
1134                         let impl_def_id = DefId::local(impl_id);
1135                         let scheme = cx.lookup_item_type(impl_def_id);
1136                         let predicates = cx.lookup_predicates(impl_def_id);
1137                         cx.construct_parameter_environment(impl_item.span,
1138                                                            &scheme.generics,
1139                                                            &predicates,
1140                                                            id)
1141                     }
1142                     hir::ConstImplItem(_, _) => {
1143                         let def_id = DefId::local(id);
1144                         let scheme = cx.lookup_item_type(def_id);
1145                         let predicates = cx.lookup_predicates(def_id);
1146                         cx.construct_parameter_environment(impl_item.span,
1147                                                            &scheme.generics,
1148                                                            &predicates,
1149                                                            id)
1150                     }
1151                     hir::MethodImplItem(_, ref body) => {
1152                         let method_def_id = DefId::local(id);
1153                         match cx.impl_or_trait_item(method_def_id) {
1154                             MethodTraitItem(ref method_ty) => {
1155                                 let method_generics = &method_ty.generics;
1156                                 let method_bounds = &method_ty.predicates;
1157                                 cx.construct_parameter_environment(
1158                                     impl_item.span,
1159                                     method_generics,
1160                                     method_bounds,
1161                                     body.id)
1162                             }
1163                             _ => {
1164                                 cx.sess
1165                                   .bug("ParameterEnvironment::for_item(): \
1166                                         got non-method item from impl method?!")
1167                             }
1168                         }
1169                     }
1170                 }
1171             }
1172             Some(ast_map::NodeTraitItem(trait_item)) => {
1173                 match trait_item.node {
1174                     hir::TypeTraitItem(..) => {
1175                         // associated types don't have their own entry (for some reason),
1176                         // so for now just grab environment for the trait
1177                         let trait_id = cx.map.get_parent(id);
1178                         let trait_def_id = DefId::local(trait_id);
1179                         let trait_def = cx.lookup_trait_def(trait_def_id);
1180                         let predicates = cx.lookup_predicates(trait_def_id);
1181                         cx.construct_parameter_environment(trait_item.span,
1182                                                            &trait_def.generics,
1183                                                            &predicates,
1184                                                            id)
1185                     }
1186                     hir::ConstTraitItem(..) => {
1187                         let def_id = DefId::local(id);
1188                         let scheme = cx.lookup_item_type(def_id);
1189                         let predicates = cx.lookup_predicates(def_id);
1190                         cx.construct_parameter_environment(trait_item.span,
1191                                                            &scheme.generics,
1192                                                            &predicates,
1193                                                            id)
1194                     }
1195                     hir::MethodTraitItem(_, ref body) => {
1196                         // for the body-id, use the id of the body
1197                         // block, unless this is a trait method with
1198                         // no default, then fallback to the method id.
1199                         let body_id = body.as_ref().map(|b| b.id).unwrap_or(id);
1200                         let method_def_id = DefId::local(id);
1201
1202                         match cx.impl_or_trait_item(method_def_id) {
1203                             MethodTraitItem(ref method_ty) => {
1204                                 let method_generics = &method_ty.generics;
1205                                 let method_bounds = &method_ty.predicates;
1206                                 cx.construct_parameter_environment(
1207                                     trait_item.span,
1208                                     method_generics,
1209                                     method_bounds,
1210                                     body_id)
1211                             }
1212                             _ => {
1213                                 cx.sess
1214                                   .bug("ParameterEnvironment::for_item(): \
1215                                         got non-method item from provided \
1216                                         method?!")
1217                             }
1218                         }
1219                     }
1220                 }
1221             }
1222             Some(ast_map::NodeItem(item)) => {
1223                 match item.node {
1224                     hir::ItemFn(_, _, _, _, _, ref body) => {
1225                         // We assume this is a function.
1226                         let fn_def_id = DefId::local(id);
1227                         let fn_scheme = cx.lookup_item_type(fn_def_id);
1228                         let fn_predicates = cx.lookup_predicates(fn_def_id);
1229
1230                         cx.construct_parameter_environment(item.span,
1231                                                            &fn_scheme.generics,
1232                                                            &fn_predicates,
1233                                                            body.id)
1234                     }
1235                     hir::ItemEnum(..) |
1236                     hir::ItemStruct(..) |
1237                     hir::ItemImpl(..) |
1238                     hir::ItemConst(..) |
1239                     hir::ItemStatic(..) => {
1240                         let def_id = DefId::local(id);
1241                         let scheme = cx.lookup_item_type(def_id);
1242                         let predicates = cx.lookup_predicates(def_id);
1243                         cx.construct_parameter_environment(item.span,
1244                                                            &scheme.generics,
1245                                                            &predicates,
1246                                                            id)
1247                     }
1248                     hir::ItemTrait(..) => {
1249                         let def_id = DefId::local(id);
1250                         let trait_def = cx.lookup_trait_def(def_id);
1251                         let predicates = cx.lookup_predicates(def_id);
1252                         cx.construct_parameter_environment(item.span,
1253                                                            &trait_def.generics,
1254                                                            &predicates,
1255                                                            id)
1256                     }
1257                     _ => {
1258                         cx.sess.span_bug(item.span,
1259                                          "ParameterEnvironment::from_item():
1260                                           can't create a parameter \
1261                                           environment for this kind of item")
1262                     }
1263                 }
1264             }
1265             Some(ast_map::NodeExpr(..)) => {
1266                 // This is a convenience to allow closures to work.
1267                 ParameterEnvironment::for_item(cx, cx.map.get_parent(id))
1268             }
1269             _ => {
1270                 cx.sess.bug(&format!("ParameterEnvironment::from_item(): \
1271                                      `{}` is not an item",
1272                                     cx.map.node_to_string(id)))
1273             }
1274         }
1275     }
1276 }
1277
1278 /// A "type scheme", in ML terminology, is a type combined with some
1279 /// set of generic types that the type is, well, generic over. In Rust
1280 /// terms, it is the "type" of a fn item or struct -- this type will
1281 /// include various generic parameters that must be substituted when
1282 /// the item/struct is referenced. That is called converting the type
1283 /// scheme to a monotype.
1284 ///
1285 /// - `generics`: the set of type parameters and their bounds
1286 /// - `ty`: the base types, which may reference the parameters defined
1287 ///   in `generics`
1288 ///
1289 /// Note that TypeSchemes are also sometimes called "polytypes" (and
1290 /// in fact this struct used to carry that name, so you may find some
1291 /// stray references in a comment or something). We try to reserve the
1292 /// "poly" prefix to refer to higher-ranked things, as in
1293 /// `PolyTraitRef`.
1294 ///
1295 /// Note that each item also comes with predicates, see
1296 /// `lookup_predicates`.
1297 #[derive(Clone, Debug)]
1298 pub struct TypeScheme<'tcx> {
1299     pub generics: Generics<'tcx>,
1300     pub ty: Ty<'tcx>,
1301 }
1302
1303 bitflags! {
1304     flags TraitFlags: u32 {
1305         const NO_TRAIT_FLAGS        = 0,
1306         const HAS_DEFAULT_IMPL      = 1 << 0,
1307         const IS_OBJECT_SAFE        = 1 << 1,
1308         const OBJECT_SAFETY_VALID   = 1 << 2,
1309         const IMPLS_VALID           = 1 << 3,
1310     }
1311 }
1312
1313 /// As `TypeScheme` but for a trait ref.
1314 pub struct TraitDef<'tcx> {
1315     pub unsafety: hir::Unsafety,
1316
1317     /// If `true`, then this trait had the `#[rustc_paren_sugar]`
1318     /// attribute, indicating that it should be used with `Foo()`
1319     /// sugar. This is a temporary thing -- eventually any trait wil
1320     /// be usable with the sugar (or without it).
1321     pub paren_sugar: bool,
1322
1323     /// Generic type definitions. Note that `Self` is listed in here
1324     /// as having a single bound, the trait itself (e.g., in the trait
1325     /// `Eq`, there is a single bound `Self : Eq`). This is so that
1326     /// default methods get to assume that the `Self` parameters
1327     /// implements the trait.
1328     pub generics: Generics<'tcx>,
1329
1330     pub trait_ref: TraitRef<'tcx>,
1331
1332     /// A list of the associated types defined in this trait. Useful
1333     /// for resolving `X::Foo` type markers.
1334     pub associated_type_names: Vec<Name>,
1335
1336     // Impls of this trait. To allow for quicker lookup, the impls are indexed
1337     // by a simplified version of their Self type: impls with a simplifiable
1338     // Self are stored in nonblanket_impls keyed by it, while all other impls
1339     // are stored in blanket_impls.
1340
1341     /// Impls of the trait.
1342     pub nonblanket_impls: RefCell<
1343         FnvHashMap<fast_reject::SimplifiedType, Vec<DefId>>
1344     >,
1345
1346     /// Blanket impls associated with the trait.
1347     pub blanket_impls: RefCell<Vec<DefId>>,
1348
1349     /// Various flags
1350     pub flags: Cell<TraitFlags>
1351 }
1352
1353 impl<'tcx> TraitDef<'tcx> {
1354     // returns None if not yet calculated
1355     pub fn object_safety(&self) -> Option<bool> {
1356         if self.flags.get().intersects(TraitFlags::OBJECT_SAFETY_VALID) {
1357             Some(self.flags.get().intersects(TraitFlags::IS_OBJECT_SAFE))
1358         } else {
1359             None
1360         }
1361     }
1362
1363     pub fn set_object_safety(&self, is_safe: bool) {
1364         assert!(self.object_safety().map(|cs| cs == is_safe).unwrap_or(true));
1365         self.flags.set(
1366             self.flags.get() | if is_safe {
1367                 TraitFlags::OBJECT_SAFETY_VALID | TraitFlags::IS_OBJECT_SAFE
1368             } else {
1369                 TraitFlags::OBJECT_SAFETY_VALID
1370             }
1371         );
1372     }
1373
1374     /// Records a trait-to-implementation mapping.
1375     pub fn record_impl(&self,
1376                        tcx: &ctxt<'tcx>,
1377                        impl_def_id: DefId,
1378                        impl_trait_ref: TraitRef<'tcx>) {
1379         debug!("TraitDef::record_impl for {:?}, from {:?}",
1380                self, impl_trait_ref);
1381
1382         // We don't want to borrow_mut after we already populated all impls,
1383         // so check if an impl is present with an immutable borrow first.
1384         if let Some(sty) = fast_reject::simplify_type(tcx,
1385                                                       impl_trait_ref.self_ty(), false) {
1386             if let Some(is) = self.nonblanket_impls.borrow().get(&sty) {
1387                 if is.contains(&impl_def_id) {
1388                     return // duplicate - skip
1389                 }
1390             }
1391
1392             self.nonblanket_impls.borrow_mut().entry(sty).or_insert(vec![]).push(impl_def_id)
1393         } else {
1394             if self.blanket_impls.borrow().contains(&impl_def_id) {
1395                 return // duplicate - skip
1396             }
1397             self.blanket_impls.borrow_mut().push(impl_def_id)
1398         }
1399     }
1400
1401
1402     pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: &ctxt<'tcx>, mut f: F)  {
1403         tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
1404
1405         for &impl_def_id in self.blanket_impls.borrow().iter() {
1406             f(impl_def_id);
1407         }
1408
1409         for v in self.nonblanket_impls.borrow().values() {
1410             for &impl_def_id in v {
1411                 f(impl_def_id);
1412             }
1413         }
1414     }
1415
1416     /// Iterate over every impl that could possibly match the
1417     /// self-type `self_ty`.
1418     pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
1419                                                    tcx: &ctxt<'tcx>,
1420                                                    self_ty: Ty<'tcx>,
1421                                                    mut f: F)
1422     {
1423         tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
1424
1425         for &impl_def_id in self.blanket_impls.borrow().iter() {
1426             f(impl_def_id);
1427         }
1428
1429         // simplify_type(.., false) basically replaces type parameters and
1430         // projections with infer-variables. This is, of course, done on
1431         // the impl trait-ref when it is instantiated, but not on the
1432         // predicate trait-ref which is passed here.
1433         //
1434         // for example, if we match `S: Copy` against an impl like
1435         // `impl<T:Copy> Copy for Option<T>`, we replace the type variable
1436         // in `Option<T>` with an infer variable, to `Option<_>` (this
1437         // doesn't actually change fast_reject output), but we don't
1438         // replace `S` with anything - this impl of course can't be
1439         // selected, and as there are hundreds of similar impls,
1440         // considering them would significantly harm performance.
1441         if let Some(simp) = fast_reject::simplify_type(tcx, self_ty, true) {
1442             if let Some(impls) = self.nonblanket_impls.borrow().get(&simp) {
1443                 for &impl_def_id in impls {
1444                     f(impl_def_id);
1445                 }
1446             }
1447         } else {
1448             for v in self.nonblanket_impls.borrow().values() {
1449                 for &impl_def_id in v {
1450                     f(impl_def_id);
1451                 }
1452             }
1453         }
1454     }
1455
1456 }
1457
1458 bitflags! {
1459     flags AdtFlags: u32 {
1460         const NO_ADT_FLAGS        = 0,
1461         const IS_ENUM             = 1 << 0,
1462         const IS_DTORCK           = 1 << 1, // is this a dtorck type?
1463         const IS_DTORCK_VALID     = 1 << 2,
1464         const IS_PHANTOM_DATA     = 1 << 3,
1465         const IS_SIMD             = 1 << 4,
1466         const IS_FUNDAMENTAL      = 1 << 5,
1467         const IS_NO_DROP_FLAG     = 1 << 6,
1468     }
1469 }
1470
1471 pub type AdtDef<'tcx> = &'tcx AdtDefData<'tcx, 'static>;
1472 pub type VariantDef<'tcx> = &'tcx VariantDefData<'tcx, 'static>;
1473 pub type FieldDef<'tcx> = &'tcx FieldDefData<'tcx, 'static>;
1474
1475 // See comment on AdtDefData for explanation
1476 pub type AdtDefMaster<'tcx> = &'tcx AdtDefData<'tcx, 'tcx>;
1477 pub type VariantDefMaster<'tcx> = &'tcx VariantDefData<'tcx, 'tcx>;
1478 pub type FieldDefMaster<'tcx> = &'tcx FieldDefData<'tcx, 'tcx>;
1479
1480 pub struct VariantDefData<'tcx, 'container: 'tcx> {
1481     pub did: DefId,
1482     pub name: Name, // struct's name if this is a struct
1483     pub disr_val: Disr,
1484     pub fields: Vec<FieldDefData<'tcx, 'container>>
1485 }
1486
1487 pub struct FieldDefData<'tcx, 'container: 'tcx> {
1488     /// The field's DefId. NOTE: the fields of tuple-like enum variants
1489     /// are not real items, and don't have entries in tcache etc.
1490     pub did: DefId,
1491     /// special_idents::unnamed_field.name
1492     /// if this is a tuple-like field
1493     pub name: Name,
1494     pub vis: hir::Visibility,
1495     /// TyIVar is used here to allow for variance (see the doc at
1496     /// AdtDefData).
1497     ty: ivar::TyIVar<'tcx, 'container>
1498 }
1499
1500 /// The definition of an abstract data type - a struct or enum.
1501 ///
1502 /// These are all interned (by intern_adt_def) into the adt_defs
1503 /// table.
1504 ///
1505 /// Because of the possibility of nested tcx-s, this type
1506 /// needs 2 lifetimes: the traditional variant lifetime ('tcx)
1507 /// bounding the lifetime of the inner types is of course necessary.
1508 /// However, it is not sufficient - types from a child tcx must
1509 /// not be leaked into the master tcx by being stored in an AdtDefData.
1510 ///
1511 /// The 'container lifetime ensures that by outliving the container
1512 /// tcx and preventing shorter-lived types from being inserted. When
1513 /// write access is not needed, the 'container lifetime can be
1514 /// erased to 'static, which can be done by the AdtDef wrapper.
1515 pub struct AdtDefData<'tcx, 'container: 'tcx> {
1516     pub did: DefId,
1517     pub variants: Vec<VariantDefData<'tcx, 'container>>,
1518     destructor: Cell<Option<DefId>>,
1519     flags: Cell<AdtFlags>,
1520 }
1521
1522 impl<'tcx, 'container> PartialEq for AdtDefData<'tcx, 'container> {
1523     // AdtDefData are always interned and this is part of TyS equality
1524     #[inline]
1525     fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ }
1526 }
1527
1528 impl<'tcx, 'container> Eq for AdtDefData<'tcx, 'container> {}
1529
1530 impl<'tcx, 'container> Hash for AdtDefData<'tcx, 'container> {
1531     #[inline]
1532     fn hash<H: Hasher>(&self, s: &mut H) {
1533         (self as *const AdtDefData).hash(s)
1534     }
1535 }
1536
1537
1538 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1539 pub enum AdtKind { Struct, Enum }
1540
1541 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1542 pub enum VariantKind { Dict, Tuple, Unit }
1543
1544 impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
1545     fn new(tcx: &ctxt<'tcx>,
1546            did: DefId,
1547            kind: AdtKind,
1548            variants: Vec<VariantDefData<'tcx, 'container>>) -> Self {
1549         let mut flags = AdtFlags::NO_ADT_FLAGS;
1550         let attrs = tcx.get_attrs(did);
1551         if attr::contains_name(&attrs, "fundamental") {
1552             flags = flags | AdtFlags::IS_FUNDAMENTAL;
1553         }
1554         if attr::contains_name(&attrs, "unsafe_no_drop_flag") {
1555             flags = flags | AdtFlags::IS_NO_DROP_FLAG;
1556         }
1557         if tcx.lookup_simd(did) {
1558             flags = flags | AdtFlags::IS_SIMD;
1559         }
1560         if Some(did) == tcx.lang_items.phantom_data() {
1561             flags = flags | AdtFlags::IS_PHANTOM_DATA;
1562         }
1563         if let AdtKind::Enum = kind {
1564             flags = flags | AdtFlags::IS_ENUM;
1565         }
1566         AdtDefData {
1567             did: did,
1568             variants: variants,
1569             flags: Cell::new(flags),
1570             destructor: Cell::new(None)
1571         }
1572     }
1573
1574     fn calculate_dtorck(&'tcx self, tcx: &ctxt<'tcx>) {
1575         if tcx.is_adt_dtorck(self) {
1576             self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK);
1577         }
1578         self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK_VALID)
1579     }
1580
1581     /// Returns the kind of the ADT - Struct or Enum.
1582     #[inline]
1583     pub fn adt_kind(&self) -> AdtKind {
1584         if self.flags.get().intersects(AdtFlags::IS_ENUM) {
1585             AdtKind::Enum
1586         } else {
1587             AdtKind::Struct
1588         }
1589     }
1590
1591     /// Returns whether this is a dtorck type. If this returns
1592     /// true, this type being safe for destruction requires it to be
1593     /// alive; Otherwise, only the contents are required to be.
1594     #[inline]
1595     pub fn is_dtorck(&'tcx self, tcx: &ctxt<'tcx>) -> bool {
1596         if !self.flags.get().intersects(AdtFlags::IS_DTORCK_VALID) {
1597             self.calculate_dtorck(tcx)
1598         }
1599         self.flags.get().intersects(AdtFlags::IS_DTORCK)
1600     }
1601
1602     /// Returns whether this type is #[fundamental] for the purposes
1603     /// of coherence checking.
1604     #[inline]
1605     pub fn is_fundamental(&self) -> bool {
1606         self.flags.get().intersects(AdtFlags::IS_FUNDAMENTAL)
1607     }
1608
1609     #[inline]
1610     pub fn is_simd(&self) -> bool {
1611         self.flags.get().intersects(AdtFlags::IS_SIMD)
1612     }
1613
1614     /// Returns true if this is PhantomData<T>.
1615     #[inline]
1616     pub fn is_phantom_data(&self) -> bool {
1617         self.flags.get().intersects(AdtFlags::IS_PHANTOM_DATA)
1618     }
1619
1620     /// Returns whether this type has a destructor.
1621     pub fn has_dtor(&self) -> bool {
1622         match self.dtor_kind() {
1623             NoDtor => false,
1624             TraitDtor(..) => true
1625         }
1626     }
1627
1628     /// Asserts this is a struct and returns the struct's unique
1629     /// variant.
1630     pub fn struct_variant(&self) -> &VariantDefData<'tcx, 'container> {
1631         assert!(self.adt_kind() == AdtKind::Struct);
1632         &self.variants[0]
1633     }
1634
1635     #[inline]
1636     pub fn type_scheme(&self, tcx: &ctxt<'tcx>) -> TypeScheme<'tcx> {
1637         tcx.lookup_item_type(self.did)
1638     }
1639
1640     #[inline]
1641     pub fn predicates(&self, tcx: &ctxt<'tcx>) -> GenericPredicates<'tcx> {
1642         tcx.lookup_predicates(self.did)
1643     }
1644
1645     /// Returns an iterator over all fields contained
1646     /// by this ADT.
1647     #[inline]
1648     pub fn all_fields(&self) ->
1649             iter::FlatMap<
1650                 slice::Iter<VariantDefData<'tcx, 'container>>,
1651                 slice::Iter<FieldDefData<'tcx, 'container>>,
1652                 for<'s> fn(&'s VariantDefData<'tcx, 'container>)
1653                     -> slice::Iter<'s, FieldDefData<'tcx, 'container>>
1654             > {
1655         self.variants.iter().flat_map(VariantDefData::fields_iter)
1656     }
1657
1658     #[inline]
1659     pub fn is_empty(&self) -> bool {
1660         self.variants.is_empty()
1661     }
1662
1663     #[inline]
1664     pub fn is_univariant(&self) -> bool {
1665         self.variants.len() == 1
1666     }
1667
1668     pub fn is_payloadfree(&self) -> bool {
1669         !self.variants.is_empty() &&
1670             self.variants.iter().all(|v| v.fields.is_empty())
1671     }
1672
1673     pub fn variant_with_id(&self, vid: DefId) -> &VariantDefData<'tcx, 'container> {
1674         self.variants
1675             .iter()
1676             .find(|v| v.did == vid)
1677             .expect("variant_with_id: unknown variant")
1678     }
1679
1680     pub fn variant_index_with_id(&self, vid: DefId) -> usize {
1681         self.variants
1682             .iter()
1683             .position(|v| v.did == vid)
1684             .expect("variant_index_with_id: unknown variant")
1685     }
1686
1687     pub fn variant_of_def(&self, def: def::Def) -> &VariantDefData<'tcx, 'container> {
1688         match def {
1689             def::DefVariant(_, vid, _) => self.variant_with_id(vid),
1690             def::DefStruct(..) | def::DefTy(..) => self.struct_variant(),
1691             _ => panic!("unexpected def {:?} in variant_of_def", def)
1692         }
1693     }
1694
1695     pub fn destructor(&self) -> Option<DefId> {
1696         self.destructor.get()
1697     }
1698
1699     pub fn set_destructor(&self, dtor: DefId) {
1700         assert!(self.destructor.get().is_none());
1701         self.destructor.set(Some(dtor));
1702     }
1703
1704     pub fn dtor_kind(&self) -> DtorKind {
1705         match self.destructor.get() {
1706             Some(_) => {
1707                 TraitDtor(!self.flags.get().intersects(AdtFlags::IS_NO_DROP_FLAG))
1708             }
1709             None => NoDtor,
1710         }
1711     }
1712 }
1713
1714 impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
1715     #[inline]
1716     fn fields_iter(&self) -> slice::Iter<FieldDefData<'tcx, 'container>> {
1717         self.fields.iter()
1718     }
1719
1720     pub fn kind(&self) -> VariantKind {
1721         match self.fields.get(0) {
1722             None => VariantKind::Unit,
1723             Some(&FieldDefData { name, .. }) if name == special_idents::unnamed_field.name => {
1724                 VariantKind::Tuple
1725             }
1726             Some(_) => VariantKind::Dict
1727         }
1728     }
1729
1730     pub fn is_tuple_struct(&self) -> bool {
1731         self.kind() == VariantKind::Tuple
1732     }
1733
1734     #[inline]
1735     pub fn find_field_named(&self,
1736                             name: ast::Name)
1737                             -> Option<&FieldDefData<'tcx, 'container>> {
1738         self.fields.iter().find(|f| f.name == name)
1739     }
1740
1741     #[inline]
1742     pub fn field_named(&self, name: ast::Name) -> &FieldDefData<'tcx, 'container> {
1743         self.find_field_named(name).unwrap()
1744     }
1745 }
1746
1747 impl<'tcx, 'container> FieldDefData<'tcx, 'container> {
1748     pub fn new(did: DefId,
1749                name: Name,
1750                vis: hir::Visibility) -> Self {
1751         FieldDefData {
1752             did: did,
1753             name: name,
1754             vis: vis,
1755             ty: ivar::TyIVar::new()
1756         }
1757     }
1758
1759     pub fn ty(&self, tcx: &ctxt<'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
1760         self.unsubst_ty().subst(tcx, subst)
1761     }
1762
1763     pub fn unsubst_ty(&self) -> Ty<'tcx> {
1764         self.ty.unwrap()
1765     }
1766
1767     pub fn fulfill_ty(&self, ty: Ty<'container>) {
1768         self.ty.fulfill(ty);
1769     }
1770 }
1771
1772 /// Records the substitutions used to translate the polytype for an
1773 /// item into the monotype of an item reference.
1774 #[derive(Clone)]
1775 pub struct ItemSubsts<'tcx> {
1776     pub substs: Substs<'tcx>,
1777 }
1778
1779 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
1780 pub enum ClosureKind {
1781     // Warning: Ordering is significant here! The ordering is chosen
1782     // because the trait Fn is a subtrait of FnMut and so in turn, and
1783     // hence we order it so that Fn < FnMut < FnOnce.
1784     FnClosureKind,
1785     FnMutClosureKind,
1786     FnOnceClosureKind,
1787 }
1788
1789 impl ClosureKind {
1790     pub fn trait_did(&self, cx: &ctxt) -> DefId {
1791         let result = match *self {
1792             FnClosureKind => cx.lang_items.require(FnTraitLangItem),
1793             FnMutClosureKind => {
1794                 cx.lang_items.require(FnMutTraitLangItem)
1795             }
1796             FnOnceClosureKind => {
1797                 cx.lang_items.require(FnOnceTraitLangItem)
1798             }
1799         };
1800         match result {
1801             Ok(trait_did) => trait_did,
1802             Err(err) => cx.sess.fatal(&err[..]),
1803         }
1804     }
1805
1806     /// True if this a type that impls this closure kind
1807     /// must also implement `other`.
1808     pub fn extends(self, other: ty::ClosureKind) -> bool {
1809         match (self, other) {
1810             (FnClosureKind, FnClosureKind) => true,
1811             (FnClosureKind, FnMutClosureKind) => true,
1812             (FnClosureKind, FnOnceClosureKind) => true,
1813             (FnMutClosureKind, FnMutClosureKind) => true,
1814             (FnMutClosureKind, FnOnceClosureKind) => true,
1815             (FnOnceClosureKind, FnOnceClosureKind) => true,
1816             _ => false,
1817         }
1818     }
1819 }
1820
1821 impl<'tcx> TyS<'tcx> {
1822     /// Iterator that walks `self` and any types reachable from
1823     /// `self`, in depth-first order. Note that just walks the types
1824     /// that appear in `self`, it does not descend into the fields of
1825     /// structs or variants. For example:
1826     ///
1827     /// ```notrust
1828     /// isize => { isize }
1829     /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
1830     /// [isize] => { [isize], isize }
1831     /// ```
1832     pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
1833         TypeWalker::new(self)
1834     }
1835
1836     /// Iterator that walks the immediate children of `self`.  Hence
1837     /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
1838     /// (but not `i32`, like `walk`).
1839     pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
1840         walk::walk_shallow(self)
1841     }
1842
1843     /// Walks `ty` and any types appearing within `ty`, invoking the
1844     /// callback `f` on each type. If the callback returns false, then the
1845     /// children of the current type are ignored.
1846     ///
1847     /// Note: prefer `ty.walk()` where possible.
1848     pub fn maybe_walk<F>(&'tcx self, mut f: F)
1849         where F : FnMut(Ty<'tcx>) -> bool
1850     {
1851         let mut walker = self.walk();
1852         while let Some(ty) = walker.next() {
1853             if !f(ty) {
1854                 walker.skip_current_subtree();
1855             }
1856         }
1857     }
1858 }
1859
1860 impl<'tcx> ItemSubsts<'tcx> {
1861     pub fn empty() -> ItemSubsts<'tcx> {
1862         ItemSubsts { substs: Substs::empty() }
1863     }
1864
1865     pub fn is_noop(&self) -> bool {
1866         self.substs.is_noop()
1867     }
1868 }
1869
1870 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1871 pub enum LvaluePreference {
1872     PreferMutLvalue,
1873     NoPreference
1874 }
1875
1876 impl LvaluePreference {
1877     pub fn from_mutbl(m: hir::Mutability) -> Self {
1878         match m {
1879             hir::MutMutable => PreferMutLvalue,
1880             hir::MutImmutable => NoPreference,
1881         }
1882     }
1883 }
1884
1885 /// Helper for looking things up in the various maps that are populated during
1886 /// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc).  All of
1887 /// these share the pattern that if the id is local, it should have been loaded
1888 /// into the map by the `typeck::collect` phase.  If the def-id is external,
1889 /// then we have to go consult the crate loading code (and cache the result for
1890 /// the future).
1891 fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
1892                                           def_id: DefId,
1893                                           map: &RefCell<DefIdMap<V>>,
1894                                           load_external: F) -> V where
1895     V: Clone,
1896     F: FnOnce() -> V,
1897 {
1898     match map.borrow().get(&def_id).cloned() {
1899         Some(v) => { return v; }
1900         None => { }
1901     }
1902
1903     if def_id.is_local() {
1904         panic!("No def'n found for {:?} in tcx.{}", def_id, descr);
1905     }
1906     let v = load_external();
1907     map.borrow_mut().insert(def_id, v.clone());
1908     v
1909 }
1910
1911 impl BorrowKind {
1912     pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
1913         match m {
1914             hir::MutMutable => MutBorrow,
1915             hir::MutImmutable => ImmBorrow,
1916         }
1917     }
1918
1919     /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
1920     /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
1921     /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
1922     /// question.
1923     pub fn to_mutbl_lossy(self) -> hir::Mutability {
1924         match self {
1925             MutBorrow => hir::MutMutable,
1926             ImmBorrow => hir::MutImmutable,
1927
1928             // We have no type corresponding to a unique imm borrow, so
1929             // use `&mut`. It gives all the capabilities of an `&uniq`
1930             // and hence is a safe "over approximation".
1931             UniqueImmBorrow => hir::MutMutable,
1932         }
1933     }
1934
1935     pub fn to_user_str(&self) -> &'static str {
1936         match *self {
1937             MutBorrow => "mutable",
1938             ImmBorrow => "immutable",
1939             UniqueImmBorrow => "uniquely immutable",
1940         }
1941     }
1942 }
1943
1944 impl<'tcx> ctxt<'tcx> {
1945     pub fn node_id_to_type(&self, id: NodeId) -> Ty<'tcx> {
1946         match self.node_id_to_type_opt(id) {
1947            Some(ty) => ty,
1948            None => self.sess.bug(
1949                &format!("node_id_to_type: no type for node `{}`",
1950                         self.map.node_to_string(id)))
1951         }
1952     }
1953
1954     pub fn node_id_to_type_opt(&self, id: NodeId) -> Option<Ty<'tcx>> {
1955         self.tables.borrow().node_types.get(&id).cloned()
1956     }
1957
1958     pub fn node_id_item_substs(&self, id: NodeId) -> ItemSubsts<'tcx> {
1959         match self.tables.borrow().item_substs.get(&id) {
1960             None => ItemSubsts::empty(),
1961             Some(ts) => ts.clone(),
1962         }
1963     }
1964
1965     // Returns the type of a pattern as a monotype. Like @expr_ty, this function
1966     // doesn't provide type parameter substitutions.
1967     pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
1968         self.node_id_to_type(pat.id)
1969     }
1970     pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
1971         self.node_id_to_type_opt(pat.id)
1972     }
1973
1974     // Returns the type of an expression as a monotype.
1975     //
1976     // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression.  That is, in
1977     // some cases, we insert `AutoAdjustment` annotations such as auto-deref or
1978     // auto-ref.  The type returned by this function does not consider such
1979     // adjustments.  See `expr_ty_adjusted()` instead.
1980     //
1981     // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
1982     // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
1983     // instead of "fn(ty) -> T with T = isize".
1984     pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
1985         self.node_id_to_type(expr.id)
1986     }
1987
1988     pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
1989         self.node_id_to_type_opt(expr.id)
1990     }
1991
1992     /// Returns the type of `expr`, considering any `AutoAdjustment`
1993     /// entry recorded for that expression.
1994     ///
1995     /// It would almost certainly be better to store the adjusted ty in with
1996     /// the `AutoAdjustment`, but I opted not to do this because it would
1997     /// require serializing and deserializing the type and, although that's not
1998     /// hard to do, I just hate that code so much I didn't want to touch it
1999     /// unless it was to fix it properly, which seemed a distraction from the
2000     /// thread at hand! -nmatsakis
2001     pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> Ty<'tcx> {
2002         self.expr_ty(expr)
2003             .adjust(self, expr.span, expr.id,
2004                     self.tables.borrow().adjustments.get(&expr.id),
2005                     |method_call| {
2006             self.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
2007         })
2008     }
2009
2010     pub fn expr_span(&self, id: NodeId) -> Span {
2011         match self.map.find(id) {
2012             Some(ast_map::NodeExpr(e)) => {
2013                 e.span
2014             }
2015             Some(f) => {
2016                 self.sess.bug(&format!("Node id {} is not an expr: {:?}",
2017                                        id, f));
2018             }
2019             None => {
2020                 self.sess.bug(&format!("Node id {} is not present \
2021                                         in the node map", id));
2022             }
2023         }
2024     }
2025
2026     pub fn local_var_name_str(&self, id: NodeId) -> InternedString {
2027         match self.map.find(id) {
2028             Some(ast_map::NodeLocal(pat)) => {
2029                 match pat.node {
2030                     hir::PatIdent(_, ref path1, _) => path1.node.name.as_str(),
2031                     _ => {
2032                         self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, pat));
2033                     },
2034                 }
2035             },
2036             r => self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, r)),
2037         }
2038     }
2039
2040     pub fn resolve_expr(&self, expr: &hir::Expr) -> def::Def {
2041         match self.def_map.borrow().get(&expr.id) {
2042             Some(def) => def.full_def(),
2043             None => {
2044                 self.sess.span_bug(expr.span, &format!(
2045                     "no def-map entry for expr {}", expr.id));
2046             }
2047         }
2048     }
2049
2050     pub fn expr_is_lval(&self, expr: &hir::Expr) -> bool {
2051          match expr.node {
2052             hir::ExprPath(..) => {
2053                 // We can't use resolve_expr here, as this needs to run on broken
2054                 // programs. We don't need to through - associated items are all
2055                 // rvalues.
2056                 match self.def_map.borrow().get(&expr.id) {
2057                     Some(&def::PathResolution {
2058                         base_def: def::DefStatic(..), ..
2059                     }) | Some(&def::PathResolution {
2060                         base_def: def::DefUpvar(..), ..
2061                     }) | Some(&def::PathResolution {
2062                         base_def: def::DefLocal(..), ..
2063                     }) => {
2064                         true
2065                     }
2066
2067                     Some(..) => false,
2068
2069                     None => self.sess.span_bug(expr.span, &format!(
2070                         "no def for path {}", expr.id))
2071                 }
2072             }
2073
2074             hir::ExprUnary(hir::UnDeref, _) |
2075             hir::ExprField(..) |
2076             hir::ExprTupField(..) |
2077             hir::ExprIndex(..) => {
2078                 true
2079             }
2080
2081             hir::ExprCall(..) |
2082             hir::ExprMethodCall(..) |
2083             hir::ExprStruct(..) |
2084             hir::ExprRange(..) |
2085             hir::ExprTup(..) |
2086             hir::ExprIf(..) |
2087             hir::ExprMatch(..) |
2088             hir::ExprClosure(..) |
2089             hir::ExprBlock(..) |
2090             hir::ExprRepeat(..) |
2091             hir::ExprVec(..) |
2092             hir::ExprBreak(..) |
2093             hir::ExprAgain(..) |
2094             hir::ExprRet(..) |
2095             hir::ExprWhile(..) |
2096             hir::ExprLoop(..) |
2097             hir::ExprAssign(..) |
2098             hir::ExprInlineAsm(..) |
2099             hir::ExprAssignOp(..) |
2100             hir::ExprLit(_) |
2101             hir::ExprUnary(..) |
2102             hir::ExprBox(..) |
2103             hir::ExprAddrOf(..) |
2104             hir::ExprBinary(..) |
2105             hir::ExprCast(..) => {
2106                 false
2107             }
2108
2109             hir::ExprParen(ref e) => self.expr_is_lval(e),
2110         }
2111     }
2112
2113     pub fn provided_source(&self, id: DefId) -> Option<DefId> {
2114         self.provided_method_sources.borrow().get(&id).cloned()
2115     }
2116
2117     pub fn provided_trait_methods(&self, id: DefId) -> Vec<Rc<Method<'tcx>>> {
2118         if id.is_local() {
2119             if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id.node).node {
2120                 ms.iter().filter_map(|ti| {
2121                     if let hir::MethodTraitItem(_, Some(_)) = ti.node {
2122                         match self.impl_or_trait_item(DefId::local(ti.id)) {
2123                             MethodTraitItem(m) => Some(m),
2124                             _ => {
2125                                 self.sess.bug("provided_trait_methods(): \
2126                                                non-method item found from \
2127                                                looking up provided method?!")
2128                             }
2129                         }
2130                     } else {
2131                         None
2132                     }
2133                 }).collect()
2134             } else {
2135                 self.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
2136             }
2137         } else {
2138             csearch::get_provided_trait_methods(self, id)
2139         }
2140     }
2141
2142     pub fn associated_consts(&self, id: DefId) -> Vec<Rc<AssociatedConst<'tcx>>> {
2143         if id.is_local() {
2144             match self.map.expect_item(id.node).node {
2145                 ItemTrait(_, _, _, ref tis) => {
2146                     tis.iter().filter_map(|ti| {
2147                         if let hir::ConstTraitItem(_, _) = ti.node {
2148                             match self.impl_or_trait_item(DefId::local(ti.id)) {
2149                                 ConstTraitItem(ac) => Some(ac),
2150                                 _ => {
2151                                     self.sess.bug("associated_consts(): \
2152                                                    non-const item found from \
2153                                                    looking up a constant?!")
2154                                 }
2155                             }
2156                         } else {
2157                             None
2158                         }
2159                     }).collect()
2160                 }
2161                 ItemImpl(_, _, _, _, _, ref iis) => {
2162                     iis.iter().filter_map(|ii| {
2163                         if let hir::ConstImplItem(_, _) = ii.node {
2164                             match self.impl_or_trait_item(DefId::local(ii.id)) {
2165                                 ConstTraitItem(ac) => Some(ac),
2166                                 _ => {
2167                                     self.sess.bug("associated_consts(): \
2168                                                    non-const item found from \
2169                                                    looking up a constant?!")
2170                                 }
2171                             }
2172                         } else {
2173                             None
2174                         }
2175                     }).collect()
2176                 }
2177                 _ => {
2178                     self.sess.bug(&format!("associated_consts: `{:?}` is not a trait \
2179                                             or impl", id))
2180                 }
2181             }
2182         } else {
2183             csearch::get_associated_consts(self, id)
2184         }
2185     }
2186
2187     pub fn trait_items(&self, trait_did: DefId) -> Rc<Vec<ImplOrTraitItem<'tcx>>> {
2188         let mut trait_items = self.trait_items_cache.borrow_mut();
2189         match trait_items.get(&trait_did).cloned() {
2190             Some(trait_items) => trait_items,
2191             None => {
2192                 let def_ids = self.trait_item_def_ids(trait_did);
2193                 let items: Rc<Vec<ImplOrTraitItem>> =
2194                     Rc::new(def_ids.iter()
2195                                    .map(|d| self.impl_or_trait_item(d.def_id()))
2196                                    .collect());
2197                 trait_items.insert(trait_did, items.clone());
2198                 items
2199             }
2200         }
2201     }
2202
2203     pub fn trait_impl_polarity(&self, id: DefId) -> Option<hir::ImplPolarity> {
2204         if id.is_local() {
2205             match self.map.find(id.node) {
2206                 Some(ast_map::NodeItem(item)) => {
2207                     match item.node {
2208                         hir::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
2209                         _ => None
2210                     }
2211                 }
2212                 _ => None
2213             }
2214         } else {
2215             csearch::get_impl_polarity(self, id)
2216         }
2217     }
2218
2219     pub fn custom_coerce_unsized_kind(&self, did: DefId) -> adjustment::CustomCoerceUnsized {
2220         memoized(&self.custom_coerce_unsized_kinds, did, |did: DefId| {
2221             let (kind, src) = if did.krate != LOCAL_CRATE {
2222                 (csearch::get_custom_coerce_unsized_kind(self, did), "external")
2223             } else {
2224                 (None, "local")
2225             };
2226
2227             match kind {
2228                 Some(kind) => kind,
2229                 None => {
2230                     self.sess.bug(&format!("custom_coerce_unsized_kind: \
2231                                             {} impl `{}` is missing its kind",
2232                                            src, self.item_path_str(did)));
2233                 }
2234             }
2235         })
2236     }
2237
2238     pub fn impl_or_trait_item(&self, id: DefId) -> ImplOrTraitItem<'tcx> {
2239         lookup_locally_or_in_crate_store(
2240             "impl_or_trait_items", id, &self.impl_or_trait_items,
2241             || csearch::get_impl_or_trait_item(self, id))
2242     }
2243
2244     pub fn trait_item_def_ids(&self, id: DefId) -> Rc<Vec<ImplOrTraitItemId>> {
2245         lookup_locally_or_in_crate_store(
2246             "trait_item_def_ids", id, &self.trait_item_def_ids,
2247             || Rc::new(csearch::get_trait_item_def_ids(&self.sess.cstore, id)))
2248     }
2249
2250     /// Returns the trait-ref corresponding to a given impl, or None if it is
2251     /// an inherent impl.
2252     pub fn impl_trait_ref(&self, id: DefId) -> Option<TraitRef<'tcx>> {
2253         lookup_locally_or_in_crate_store(
2254             "impl_trait_refs", id, &self.impl_trait_refs,
2255             || csearch::get_impl_trait(self, id))
2256     }
2257
2258     /// Returns whether this DefId refers to an impl
2259     pub fn is_impl(&self, id: DefId) -> bool {
2260         if id.is_local() {
2261             if let Some(ast_map::NodeItem(
2262                 &hir::Item { node: hir::ItemImpl(..), .. })) = self.map.find(id.node) {
2263                 true
2264             } else {
2265                 false
2266             }
2267         } else {
2268             csearch::is_impl(&self.sess.cstore, id)
2269         }
2270     }
2271
2272     pub fn trait_ref_to_def_id(&self, tr: &hir::TraitRef) -> DefId {
2273         self.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
2274     }
2275
2276     pub fn item_path_str(&self, id: DefId) -> String {
2277         self.with_path(id, |path| ast_map::path_to_string(path))
2278     }
2279
2280     pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
2281         F: FnOnce(ast_map::PathElems) -> T,
2282     {
2283         if id.is_local() {
2284             self.map.with_path(id.node, f)
2285         } else {
2286             f(csearch::get_item_path(self, id).iter().cloned().chain(LinkedPath::empty()))
2287         }
2288     }
2289
2290     pub fn item_name(&self, id: DefId) -> ast::Name {
2291         if id.is_local() {
2292             self.map.get_path_elem(id.node).name()
2293         } else {
2294             csearch::get_item_name(self, id)
2295         }
2296     }
2297
2298     // Register a given item type
2299     pub fn register_item_type(&self, did: DefId, ty: TypeScheme<'tcx>) {
2300         self.tcache.borrow_mut().insert(did, ty);
2301     }
2302
2303     // If the given item is in an external crate, looks up its type and adds it to
2304     // the type cache. Returns the type parameters and type.
2305     pub fn lookup_item_type(&self, did: DefId) -> TypeScheme<'tcx> {
2306         lookup_locally_or_in_crate_store(
2307             "tcache", did, &self.tcache,
2308             || csearch::get_type(self, did))
2309     }
2310
2311     /// Given the did of a trait, returns its canonical trait ref.
2312     pub fn lookup_trait_def(&self, did: DefId) -> &'tcx TraitDef<'tcx> {
2313         lookup_locally_or_in_crate_store(
2314             "trait_defs", did, &self.trait_defs,
2315             || self.alloc_trait_def(csearch::get_trait_def(self, did))
2316         )
2317     }
2318
2319     /// Given the did of an ADT, return a master reference to its
2320     /// definition. Unless you are planning on fulfilling the ADT's fields,
2321     /// use lookup_adt_def instead.
2322     pub fn lookup_adt_def_master(&self, did: DefId) -> AdtDefMaster<'tcx> {
2323         lookup_locally_or_in_crate_store(
2324             "adt_defs", did, &self.adt_defs,
2325             || csearch::get_adt_def(self, did)
2326         )
2327     }
2328
2329     /// Given the did of an ADT, return a reference to its definition.
2330     pub fn lookup_adt_def(&self, did: DefId) -> AdtDef<'tcx> {
2331         // when reverse-variance goes away, a transmute::<AdtDefMaster,AdtDef>
2332         // woud be needed here.
2333         self.lookup_adt_def_master(did)
2334     }
2335
2336     /// Return the list of all interned ADT definitions
2337     pub fn adt_defs(&self) -> Vec<AdtDef<'tcx>> {
2338         self.adt_defs.borrow().values().cloned().collect()
2339     }
2340
2341     /// Given the did of an item, returns its full set of predicates.
2342     pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
2343         lookup_locally_or_in_crate_store(
2344             "predicates", did, &self.predicates,
2345             || csearch::get_predicates(self, did))
2346     }
2347
2348     /// Given the did of a trait, returns its superpredicates.
2349     pub fn lookup_super_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
2350         lookup_locally_or_in_crate_store(
2351             "super_predicates", did, &self.super_predicates,
2352             || csearch::get_super_predicates(self, did))
2353     }
2354
2355     /// Get the attributes of a definition.
2356     pub fn get_attrs(&self, did: DefId) -> Cow<'tcx, [hir::Attribute]> {
2357         if did.is_local() {
2358             Cow::Borrowed(self.map.attrs(did.node))
2359         } else {
2360             Cow::Owned(csearch::get_item_attrs(&self.sess.cstore, did))
2361         }
2362     }
2363
2364     /// Determine whether an item is annotated with an attribute
2365     pub fn has_attr(&self, did: DefId, attr: &str) -> bool {
2366         self.get_attrs(did).iter().any(|item| item.check_name(attr))
2367     }
2368
2369     /// Determine whether an item is annotated with `#[repr(packed)]`
2370     pub fn lookup_packed(&self, did: DefId) -> bool {
2371         self.lookup_repr_hints(did).contains(&attr::ReprPacked)
2372     }
2373
2374     /// Determine whether an item is annotated with `#[simd]`
2375     pub fn lookup_simd(&self, did: DefId) -> bool {
2376         self.has_attr(did, "simd")
2377             || self.lookup_repr_hints(did).contains(&attr::ReprSimd)
2378     }
2379
2380     /// Obtain the representation annotation for a struct definition.
2381     pub fn lookup_repr_hints(&self, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
2382         memoized(&self.repr_hint_cache, did, |did: DefId| {
2383             Rc::new(if did.is_local() {
2384                 self.get_attrs(did).iter().flat_map(|meta| {
2385                     attr::find_repr_attrs(self.sess.diagnostic(), meta).into_iter()
2386                 }).collect()
2387             } else {
2388                 csearch::get_repr_attrs(&self.sess.cstore, did)
2389             })
2390         })
2391     }
2392
2393     pub fn item_variances(&self, item_id: DefId) -> Rc<ItemVariances> {
2394         lookup_locally_or_in_crate_store(
2395             "item_variance_map", item_id, &self.item_variance_map,
2396             || Rc::new(csearch::get_item_variances(&self.sess.cstore, item_id)))
2397     }
2398
2399     pub fn trait_has_default_impl(&self, trait_def_id: DefId) -> bool {
2400         self.populate_implementations_for_trait_if_necessary(trait_def_id);
2401
2402         let def = self.lookup_trait_def(trait_def_id);
2403         def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
2404     }
2405
2406     /// Records a trait-to-implementation mapping.
2407     pub fn record_trait_has_default_impl(&self, trait_def_id: DefId) {
2408         let def = self.lookup_trait_def(trait_def_id);
2409         def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
2410     }
2411
2412     /// Load primitive inherent implementations if necessary
2413     pub fn populate_implementations_for_primitive_if_necessary(&self,
2414                                                                primitive_def_id: DefId) {
2415         if primitive_def_id.is_local() {
2416             return
2417         }
2418
2419         if self.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
2420             return
2421         }
2422
2423         debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
2424                primitive_def_id);
2425
2426         let impl_items = csearch::get_impl_items(&self.sess.cstore, primitive_def_id);
2427
2428         // Store the implementation info.
2429         self.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
2430         self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
2431     }
2432
2433     /// Populates the type context with all the inherent implementations for
2434     /// the given type if necessary.
2435     pub fn populate_inherent_implementations_for_type_if_necessary(&self,
2436                                                                    type_id: DefId) {
2437         if type_id.is_local() {
2438             return
2439         }
2440
2441         if self.populated_external_types.borrow().contains(&type_id) {
2442             return
2443         }
2444
2445         debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
2446                type_id);
2447
2448         let mut inherent_impls = Vec::new();
2449         csearch::each_inherent_implementation_for_type(&self.sess.cstore, type_id, |impl_def_id| {
2450             // Record the implementation.
2451             inherent_impls.push(impl_def_id);
2452
2453             // Store the implementation info.
2454             let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
2455             self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
2456         });
2457
2458         self.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls));
2459         self.populated_external_types.borrow_mut().insert(type_id);
2460     }
2461
2462     /// Populates the type context with all the implementations for the given
2463     /// trait if necessary.
2464     pub fn populate_implementations_for_trait_if_necessary(&self, trait_id: DefId) {
2465         if trait_id.is_local() {
2466             return
2467         }
2468
2469         let def = self.lookup_trait_def(trait_id);
2470         if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
2471             return;
2472         }
2473
2474         debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
2475
2476         if csearch::is_defaulted_trait(&self.sess.cstore, trait_id) {
2477             self.record_trait_has_default_impl(trait_id);
2478         }
2479
2480         csearch::each_implementation_for_trait(&self.sess.cstore, trait_id, |impl_def_id| {
2481             let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
2482             let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
2483             // Record the trait->implementation mapping.
2484             def.record_impl(self, impl_def_id, trait_ref);
2485
2486             // For any methods that use a default implementation, add them to
2487             // the map. This is a bit unfortunate.
2488             for impl_item_def_id in &impl_items {
2489                 let method_def_id = impl_item_def_id.def_id();
2490                 match self.impl_or_trait_item(method_def_id) {
2491                     MethodTraitItem(method) => {
2492                         if let Some(source) = method.provided_source {
2493                             self.provided_method_sources
2494                                 .borrow_mut()
2495                                 .insert(method_def_id, source);
2496                         }
2497                     }
2498                     _ => {}
2499                 }
2500             }
2501
2502             // Store the implementation info.
2503             self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
2504         });
2505
2506         def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
2507     }
2508
2509     /// Given the def_id of an impl, return the def_id of the trait it implements.
2510     /// If it implements no trait, return `None`.
2511     pub fn trait_id_of_impl(&self, def_id: DefId) -> Option<DefId> {
2512         self.impl_trait_ref(def_id).map(|tr| tr.def_id)
2513     }
2514
2515     /// If the given def ID describes a method belonging to an impl, return the
2516     /// ID of the impl that the method belongs to. Otherwise, return `None`.
2517     pub fn impl_of_method(&self, def_id: DefId) -> Option<DefId> {
2518         if def_id.krate != LOCAL_CRATE {
2519             return match csearch::get_impl_or_trait_item(self,
2520                                                          def_id).container() {
2521                 TraitContainer(_) => None,
2522                 ImplContainer(def_id) => Some(def_id),
2523             };
2524         }
2525         match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
2526             Some(trait_item) => {
2527                 match trait_item.container() {
2528                     TraitContainer(_) => None,
2529                     ImplContainer(def_id) => Some(def_id),
2530                 }
2531             }
2532             None => None
2533         }
2534     }
2535
2536     /// If the given def ID describes an item belonging to a trait (either a
2537     /// default method or an implementation of a trait method), return the ID of
2538     /// the trait that the method belongs to. Otherwise, return `None`.
2539     pub fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
2540         if def_id.krate != LOCAL_CRATE {
2541             return csearch::get_trait_of_item(&self.sess.cstore, def_id, self);
2542         }
2543         match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
2544             Some(impl_or_trait_item) => {
2545                 match impl_or_trait_item.container() {
2546                     TraitContainer(def_id) => Some(def_id),
2547                     ImplContainer(def_id) => self.trait_id_of_impl(def_id),
2548                 }
2549             }
2550             None => None
2551         }
2552     }
2553
2554     /// If the given def ID describes an item belonging to a trait, (either a
2555     /// default method or an implementation of a trait method), return the ID of
2556     /// the method inside trait definition (this means that if the given def ID
2557     /// is already that of the original trait method, then the return value is
2558     /// the same).
2559     /// Otherwise, return `None`.
2560     pub fn trait_item_of_item(&self, def_id: DefId) -> Option<ImplOrTraitItemId> {
2561         let impl_item = match self.impl_or_trait_items.borrow().get(&def_id) {
2562             Some(m) => m.clone(),
2563             None => return None,
2564         };
2565         let name = impl_item.name();
2566         match self.trait_of_item(def_id) {
2567             Some(trait_did) => {
2568                 self.trait_items(trait_did).iter()
2569                     .find(|item| item.name() == name)
2570                     .map(|item| item.id())
2571             }
2572             None => None
2573         }
2574     }
2575
2576     /// Construct a parameter environment suitable for static contexts or other contexts where there
2577     /// are no free type/lifetime parameters in scope.
2578     pub fn empty_parameter_environment<'a>(&'a self)
2579                                            -> ParameterEnvironment<'a,'tcx> {
2580         ty::ParameterEnvironment { tcx: self,
2581                                    free_substs: Substs::empty(),
2582                                    caller_bounds: Vec::new(),
2583                                    implicit_region_bound: ty::ReEmpty,
2584                                    selection_cache: traits::SelectionCache::new(),
2585
2586                                    // for an empty parameter
2587                                    // environment, there ARE no free
2588                                    // regions, so it shouldn't matter
2589                                    // what we use for the free id
2590                                    free_id: ast::DUMMY_NODE_ID }
2591     }
2592
2593     /// Constructs and returns a substitution that can be applied to move from
2594     /// the "outer" view of a type or method to the "inner" view.
2595     /// In general, this means converting from bound parameters to
2596     /// free parameters. Since we currently represent bound/free type
2597     /// parameters in the same way, this only has an effect on regions.
2598     pub fn construct_free_substs(&self, generics: &Generics<'tcx>,
2599                                  free_id: NodeId) -> Substs<'tcx> {
2600         // map T => T
2601         let mut types = VecPerParamSpace::empty();
2602         for def in generics.types.as_slice() {
2603             debug!("construct_parameter_environment(): push_types_from_defs: def={:?}",
2604                     def);
2605             types.push(def.space, self.mk_param_from_def(def));
2606         }
2607
2608         let free_id_outlive = self.region_maps.item_extent(free_id);
2609
2610         // map bound 'a => free 'a
2611         let mut regions = VecPerParamSpace::empty();
2612         for def in generics.regions.as_slice() {
2613             let region =
2614                 ReFree(FreeRegion { scope: free_id_outlive,
2615                                     bound_region: BrNamed(def.def_id, def.name) });
2616             debug!("push_region_params {:?}", region);
2617             regions.push(def.space, region);
2618         }
2619
2620         Substs {
2621             types: types,
2622             regions: subst::NonerasedRegions(regions)
2623         }
2624     }
2625
2626     /// See `ParameterEnvironment` struct def'n for details
2627     pub fn construct_parameter_environment<'a>(&'a self,
2628                                                span: Span,
2629                                                generics: &ty::Generics<'tcx>,
2630                                                generic_predicates: &ty::GenericPredicates<'tcx>,
2631                                                free_id: NodeId)
2632                                                -> ParameterEnvironment<'a, 'tcx>
2633     {
2634         //
2635         // Construct the free substs.
2636         //
2637
2638         let free_substs = self.construct_free_substs(generics, free_id);
2639         let free_id_outlive = self.region_maps.item_extent(free_id);
2640
2641         //
2642         // Compute the bounds on Self and the type parameters.
2643         //
2644
2645         let bounds = generic_predicates.instantiate(self, &free_substs);
2646         let bounds = self.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds));
2647         let predicates = bounds.predicates.into_vec();
2648
2649         debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
2650                free_id,
2651                free_substs,
2652                predicates);
2653
2654         //
2655         // Finally, we have to normalize the bounds in the environment, in
2656         // case they contain any associated type projections. This process
2657         // can yield errors if the put in illegal associated types, like
2658         // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
2659         // report these errors right here; this doesn't actually feel
2660         // right to me, because constructing the environment feels like a
2661         // kind of a "idempotent" action, but I'm not sure where would be
2662         // a better place. In practice, we construct environments for
2663         // every fn once during type checking, and we'll abort if there
2664         // are any errors at that point, so after type checking you can be
2665         // sure that this will succeed without errors anyway.
2666         //
2667
2668         let unnormalized_env = ty::ParameterEnvironment {
2669             tcx: self,
2670             free_substs: free_substs,
2671             implicit_region_bound: ty::ReScope(free_id_outlive),
2672             caller_bounds: predicates,
2673             selection_cache: traits::SelectionCache::new(),
2674             free_id: free_id,
2675         };
2676
2677         let cause = traits::ObligationCause::misc(span, free_id);
2678         traits::normalize_param_env_or_error(unnormalized_env, cause)
2679     }
2680
2681     pub fn is_method_call(&self, expr_id: NodeId) -> bool {
2682         self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id))
2683     }
2684
2685     pub fn is_overloaded_autoderef(&self, expr_id: NodeId, autoderefs: u32) -> bool {
2686         self.tables.borrow().method_map.contains_key(&MethodCall::autoderef(expr_id,
2687                                                                             autoderefs))
2688     }
2689
2690     pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
2691         Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
2692     }
2693 }
2694
2695 /// The category of explicit self.
2696 #[derive(Clone, Copy, Eq, PartialEq, Debug)]
2697 pub enum ExplicitSelfCategory {
2698     StaticExplicitSelfCategory,
2699     ByValueExplicitSelfCategory,
2700     ByReferenceExplicitSelfCategory(Region, hir::Mutability),
2701     ByBoxExplicitSelfCategory,
2702 }
2703
2704 /// A free variable referred to in a function.
2705 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
2706 pub struct Freevar {
2707     /// The variable being accessed free.
2708     pub def: def::Def,
2709
2710     // First span where it is accessed (there can be multiple).
2711     pub span: Span
2712 }
2713
2714 pub type FreevarMap = NodeMap<Vec<Freevar>>;
2715
2716 pub type CaptureModeMap = NodeMap<hir::CaptureClause>;
2717
2718 // Trait method resolution
2719 pub type TraitMap = NodeMap<Vec<DefId>>;
2720
2721 // Map from the NodeId of a glob import to a list of items which are actually
2722 // imported.
2723 pub type GlobMap = HashMap<NodeId, HashSet<Name>>;
2724
2725 impl<'tcx> ctxt<'tcx> {
2726     pub fn with_freevars<T, F>(&self, fid: NodeId, f: F) -> T where
2727         F: FnOnce(&[Freevar]) -> T,
2728     {
2729         match self.freevars.borrow().get(&fid) {
2730             None => f(&[]),
2731             Some(d) => f(&d[..])
2732         }
2733     }
2734
2735     pub fn make_substs_for_receiver_types(&self,
2736                                           trait_ref: &ty::TraitRef<'tcx>,
2737                                           method: &ty::Method<'tcx>)
2738                                           -> subst::Substs<'tcx>
2739     {
2740         /*!
2741          * Substitutes the values for the receiver's type parameters
2742          * that are found in method, leaving the method's type parameters
2743          * intact.
2744          */
2745
2746         let meth_tps: Vec<Ty> =
2747             method.generics.types.get_slice(subst::FnSpace)
2748                   .iter()
2749                   .map(|def| self.mk_param_from_def(def))
2750                   .collect();
2751         let meth_regions: Vec<ty::Region> =
2752             method.generics.regions.get_slice(subst::FnSpace)
2753                   .iter()
2754                   .map(|def| def.to_early_bound_region())
2755                   .collect();
2756         trait_ref.substs.clone().with_method(meth_tps, meth_regions)
2757     }
2758 }
2759
2760 /// An "escaping region" is a bound region whose binder is not part of `t`.
2761 ///
2762 /// So, for example, consider a type like the following, which has two binders:
2763 ///
2764 ///    for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
2765 ///    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
2766 ///                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~  inner scope
2767 ///
2768 /// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
2769 /// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
2770 /// fn type*, that type has an escaping region: `'a`.
2771 ///
2772 /// Note that what I'm calling an "escaping region" is often just called a "free region". However,
2773 /// we already use the term "free region". It refers to the regions that we use to represent bound
2774 /// regions on a fn definition while we are typechecking its body.
2775 ///
2776 /// To clarify, conceptually there is no particular difference between an "escaping" region and a
2777 /// "free" region. However, there is a big difference in practice. Basically, when "entering" a
2778 /// binding level, one is generally required to do some sort of processing to a bound region, such
2779 /// as replacing it with a fresh/skolemized region, or making an entry in the environment to
2780 /// represent the scope to which it is attached, etc. An escaping region represents a bound region
2781 /// for which this processing has not yet been done.
2782 pub trait RegionEscape {
2783     fn has_escaping_regions(&self) -> bool {
2784         self.has_regions_escaping_depth(0)
2785     }
2786
2787     fn has_regions_escaping_depth(&self, depth: u32) -> bool;
2788 }
2789
2790 pub trait HasTypeFlags {
2791     fn has_type_flags(&self, flags: TypeFlags) -> bool;
2792     fn has_projection_types(&self) -> bool {
2793         self.has_type_flags(TypeFlags::HAS_PROJECTION)
2794     }
2795     fn references_error(&self) -> bool {
2796         self.has_type_flags(TypeFlags::HAS_TY_ERR)
2797     }
2798     fn has_param_types(&self) -> bool {
2799         self.has_type_flags(TypeFlags::HAS_PARAMS)
2800     }
2801     fn has_self_ty(&self) -> bool {
2802         self.has_type_flags(TypeFlags::HAS_SELF)
2803     }
2804     fn has_infer_types(&self) -> bool {
2805         self.has_type_flags(TypeFlags::HAS_TY_INFER)
2806     }
2807     fn needs_infer(&self) -> bool {
2808         self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
2809     }
2810     fn needs_subst(&self) -> bool {
2811         self.has_type_flags(TypeFlags::NEEDS_SUBST)
2812     }
2813     fn has_closure_types(&self) -> bool {
2814         self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
2815     }
2816     fn has_erasable_regions(&self) -> bool {
2817         self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND |
2818                             TypeFlags::HAS_RE_INFER |
2819                             TypeFlags::HAS_FREE_REGIONS)
2820     }
2821     /// Indicates whether this value references only 'global'
2822     /// types/lifetimes that are the same regardless of what fn we are
2823     /// in. This is used for caching. Errs on the side of returning
2824     /// false.
2825     fn is_global(&self) -> bool {
2826         !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES)
2827     }
2828 }