]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/ty/mod.rs
a8adb3886442442093073996d76d26d4adf32c96
[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 to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
983         match *self {
984             Predicate::Trait(ref t) => {
985                 Some(t.to_poly_trait_ref())
986             }
987             Predicate::Projection(..) |
988             Predicate::Equate(..) |
989             Predicate::RegionOutlives(..) |
990             Predicate::WellFormed(..) |
991             Predicate::ObjectSafe(..) |
992             Predicate::TypeOutlives(..) => {
993                 None
994             }
995         }
996     }
997 }
998
999 /// Represents the bounds declared on a particular set of type
1000 /// parameters.  Should eventually be generalized into a flag list of
1001 /// where clauses.  You can obtain a `InstantiatedPredicates` list from a
1002 /// `GenericPredicates` by using the `instantiate` method. Note that this method
1003 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
1004 /// the `GenericPredicates` are expressed in terms of the bound type
1005 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
1006 /// represented a set of bounds for some particular instantiation,
1007 /// meaning that the generic parameters have been substituted with
1008 /// their values.
1009 ///
1010 /// Example:
1011 ///
1012 ///     struct Foo<T,U:Bar<T>> { ... }
1013 ///
1014 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
1015 /// `[[], [U:Bar<T>]]`.  Now if there were some particular reference
1016 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
1017 /// [usize:Bar<isize>]]`.
1018 #[derive(Clone)]
1019 pub struct InstantiatedPredicates<'tcx> {
1020     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
1021 }
1022
1023 impl<'tcx> InstantiatedPredicates<'tcx> {
1024     pub fn empty() -> InstantiatedPredicates<'tcx> {
1025         InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
1026     }
1027
1028     pub fn is_empty(&self) -> bool {
1029         self.predicates.is_empty()
1030     }
1031 }
1032
1033 impl<'tcx> TraitRef<'tcx> {
1034     pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
1035         TraitRef { def_id: def_id, substs: substs }
1036     }
1037
1038     pub fn self_ty(&self) -> Ty<'tcx> {
1039         self.substs.self_ty().unwrap()
1040     }
1041
1042     pub fn input_types(&self) -> &[Ty<'tcx>] {
1043         // Select only the "input types" from a trait-reference. For
1044         // now this is all the types that appear in the
1045         // trait-reference, but it should eventually exclude
1046         // associated types.
1047         self.substs.types.as_slice()
1048     }
1049 }
1050
1051 /// When type checking, we use the `ParameterEnvironment` to track
1052 /// details about the type/lifetime parameters that are in scope.
1053 /// It primarily stores the bounds information.
1054 ///
1055 /// Note: This information might seem to be redundant with the data in
1056 /// `tcx.ty_param_defs`, but it is not. That table contains the
1057 /// parameter definitions from an "outside" perspective, but this
1058 /// struct will contain the bounds for a parameter as seen from inside
1059 /// the function body. Currently the only real distinction is that
1060 /// bound lifetime parameters are replaced with free ones, but in the
1061 /// future I hope to refine the representation of types so as to make
1062 /// more distinctions clearer.
1063 #[derive(Clone)]
1064 pub struct ParameterEnvironment<'a, 'tcx:'a> {
1065     pub tcx: &'a ctxt<'tcx>,
1066
1067     /// See `construct_free_substs` for details.
1068     pub free_substs: Substs<'tcx>,
1069
1070     /// Each type parameter has an implicit region bound that
1071     /// indicates it must outlive at least the function body (the user
1072     /// may specify stronger requirements). This field indicates the
1073     /// region of the callee.
1074     pub implicit_region_bound: ty::Region,
1075
1076     /// Obligations that the caller must satisfy. This is basically
1077     /// the set of bounds on the in-scope type parameters, translated
1078     /// into Obligations, and elaborated and normalized.
1079     pub caller_bounds: Vec<ty::Predicate<'tcx>>,
1080
1081     /// Caches the results of trait selection. This cache is used
1082     /// for things that have to do with the parameters in scope.
1083     pub selection_cache: traits::SelectionCache<'tcx>,
1084
1085     /// Scope that is attached to free regions for this scope. This
1086     /// is usually the id of the fn body, but for more abstract scopes
1087     /// like structs we often use the node-id of the struct.
1088     ///
1089     /// FIXME(#3696). It would be nice to refactor so that free
1090     /// regions don't have this implicit scope and instead introduce
1091     /// relationships in the environment.
1092     pub free_id: ast::NodeId,
1093 }
1094
1095 impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
1096     pub fn with_caller_bounds(&self,
1097                               caller_bounds: Vec<ty::Predicate<'tcx>>)
1098                               -> ParameterEnvironment<'a,'tcx>
1099     {
1100         ParameterEnvironment {
1101             tcx: self.tcx,
1102             free_substs: self.free_substs.clone(),
1103             implicit_region_bound: self.implicit_region_bound,
1104             caller_bounds: caller_bounds,
1105             selection_cache: traits::SelectionCache::new(),
1106             free_id: self.free_id,
1107         }
1108     }
1109
1110     pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
1111         match cx.map.find(id) {
1112             Some(ast_map::NodeImplItem(ref impl_item)) => {
1113                 match impl_item.node {
1114                     hir::TypeImplItem(_) => {
1115                         // associated types don't have their own entry (for some reason),
1116                         // so for now just grab environment for the impl
1117                         let impl_id = cx.map.get_parent(id);
1118                         let impl_def_id = DefId::local(impl_id);
1119                         let scheme = cx.lookup_item_type(impl_def_id);
1120                         let predicates = cx.lookup_predicates(impl_def_id);
1121                         cx.construct_parameter_environment(impl_item.span,
1122                                                            &scheme.generics,
1123                                                            &predicates,
1124                                                            id)
1125                     }
1126                     hir::ConstImplItem(_, _) => {
1127                         let def_id = DefId::local(id);
1128                         let scheme = cx.lookup_item_type(def_id);
1129                         let predicates = cx.lookup_predicates(def_id);
1130                         cx.construct_parameter_environment(impl_item.span,
1131                                                            &scheme.generics,
1132                                                            &predicates,
1133                                                            id)
1134                     }
1135                     hir::MethodImplItem(_, ref body) => {
1136                         let method_def_id = DefId::local(id);
1137                         match cx.impl_or_trait_item(method_def_id) {
1138                             MethodTraitItem(ref method_ty) => {
1139                                 let method_generics = &method_ty.generics;
1140                                 let method_bounds = &method_ty.predicates;
1141                                 cx.construct_parameter_environment(
1142                                     impl_item.span,
1143                                     method_generics,
1144                                     method_bounds,
1145                                     body.id)
1146                             }
1147                             _ => {
1148                                 cx.sess
1149                                   .bug("ParameterEnvironment::for_item(): \
1150                                         got non-method item from impl method?!")
1151                             }
1152                         }
1153                     }
1154                 }
1155             }
1156             Some(ast_map::NodeTraitItem(trait_item)) => {
1157                 match trait_item.node {
1158                     hir::TypeTraitItem(..) => {
1159                         // associated types don't have their own entry (for some reason),
1160                         // so for now just grab environment for the trait
1161                         let trait_id = cx.map.get_parent(id);
1162                         let trait_def_id = DefId::local(trait_id);
1163                         let trait_def = cx.lookup_trait_def(trait_def_id);
1164                         let predicates = cx.lookup_predicates(trait_def_id);
1165                         cx.construct_parameter_environment(trait_item.span,
1166                                                            &trait_def.generics,
1167                                                            &predicates,
1168                                                            id)
1169                     }
1170                     hir::ConstTraitItem(..) => {
1171                         let def_id = DefId::local(id);
1172                         let scheme = cx.lookup_item_type(def_id);
1173                         let predicates = cx.lookup_predicates(def_id);
1174                         cx.construct_parameter_environment(trait_item.span,
1175                                                            &scheme.generics,
1176                                                            &predicates,
1177                                                            id)
1178                     }
1179                     hir::MethodTraitItem(_, ref body) => {
1180                         // for the body-id, use the id of the body
1181                         // block, unless this is a trait method with
1182                         // no default, then fallback to the method id.
1183                         let body_id = body.as_ref().map(|b| b.id).unwrap_or(id);
1184                         let method_def_id = DefId::local(id);
1185
1186                         match cx.impl_or_trait_item(method_def_id) {
1187                             MethodTraitItem(ref method_ty) => {
1188                                 let method_generics = &method_ty.generics;
1189                                 let method_bounds = &method_ty.predicates;
1190                                 cx.construct_parameter_environment(
1191                                     trait_item.span,
1192                                     method_generics,
1193                                     method_bounds,
1194                                     body_id)
1195                             }
1196                             _ => {
1197                                 cx.sess
1198                                   .bug("ParameterEnvironment::for_item(): \
1199                                         got non-method item from provided \
1200                                         method?!")
1201                             }
1202                         }
1203                     }
1204                 }
1205             }
1206             Some(ast_map::NodeItem(item)) => {
1207                 match item.node {
1208                     hir::ItemFn(_, _, _, _, _, ref body) => {
1209                         // We assume this is a function.
1210                         let fn_def_id = DefId::local(id);
1211                         let fn_scheme = cx.lookup_item_type(fn_def_id);
1212                         let fn_predicates = cx.lookup_predicates(fn_def_id);
1213
1214                         cx.construct_parameter_environment(item.span,
1215                                                            &fn_scheme.generics,
1216                                                            &fn_predicates,
1217                                                            body.id)
1218                     }
1219                     hir::ItemEnum(..) |
1220                     hir::ItemStruct(..) |
1221                     hir::ItemImpl(..) |
1222                     hir::ItemConst(..) |
1223                     hir::ItemStatic(..) => {
1224                         let def_id = DefId::local(id);
1225                         let scheme = cx.lookup_item_type(def_id);
1226                         let predicates = cx.lookup_predicates(def_id);
1227                         cx.construct_parameter_environment(item.span,
1228                                                            &scheme.generics,
1229                                                            &predicates,
1230                                                            id)
1231                     }
1232                     hir::ItemTrait(..) => {
1233                         let def_id = DefId::local(id);
1234                         let trait_def = cx.lookup_trait_def(def_id);
1235                         let predicates = cx.lookup_predicates(def_id);
1236                         cx.construct_parameter_environment(item.span,
1237                                                            &trait_def.generics,
1238                                                            &predicates,
1239                                                            id)
1240                     }
1241                     _ => {
1242                         cx.sess.span_bug(item.span,
1243                                          "ParameterEnvironment::from_item():
1244                                           can't create a parameter \
1245                                           environment for this kind of item")
1246                     }
1247                 }
1248             }
1249             Some(ast_map::NodeExpr(..)) => {
1250                 // This is a convenience to allow closures to work.
1251                 ParameterEnvironment::for_item(cx, cx.map.get_parent(id))
1252             }
1253             _ => {
1254                 cx.sess.bug(&format!("ParameterEnvironment::from_item(): \
1255                                      `{}` is not an item",
1256                                     cx.map.node_to_string(id)))
1257             }
1258         }
1259     }
1260 }
1261
1262 /// A "type scheme", in ML terminology, is a type combined with some
1263 /// set of generic types that the type is, well, generic over. In Rust
1264 /// terms, it is the "type" of a fn item or struct -- this type will
1265 /// include various generic parameters that must be substituted when
1266 /// the item/struct is referenced. That is called converting the type
1267 /// scheme to a monotype.
1268 ///
1269 /// - `generics`: the set of type parameters and their bounds
1270 /// - `ty`: the base types, which may reference the parameters defined
1271 ///   in `generics`
1272 ///
1273 /// Note that TypeSchemes are also sometimes called "polytypes" (and
1274 /// in fact this struct used to carry that name, so you may find some
1275 /// stray references in a comment or something). We try to reserve the
1276 /// "poly" prefix to refer to higher-ranked things, as in
1277 /// `PolyTraitRef`.
1278 ///
1279 /// Note that each item also comes with predicates, see
1280 /// `lookup_predicates`.
1281 #[derive(Clone, Debug)]
1282 pub struct TypeScheme<'tcx> {
1283     pub generics: Generics<'tcx>,
1284     pub ty: Ty<'tcx>,
1285 }
1286
1287 bitflags! {
1288     flags TraitFlags: u32 {
1289         const NO_TRAIT_FLAGS        = 0,
1290         const HAS_DEFAULT_IMPL      = 1 << 0,
1291         const IS_OBJECT_SAFE        = 1 << 1,
1292         const OBJECT_SAFETY_VALID   = 1 << 2,
1293         const IMPLS_VALID           = 1 << 3,
1294     }
1295 }
1296
1297 /// As `TypeScheme` but for a trait ref.
1298 pub struct TraitDef<'tcx> {
1299     pub unsafety: hir::Unsafety,
1300
1301     /// If `true`, then this trait had the `#[rustc_paren_sugar]`
1302     /// attribute, indicating that it should be used with `Foo()`
1303     /// sugar. This is a temporary thing -- eventually any trait wil
1304     /// be usable with the sugar (or without it).
1305     pub paren_sugar: bool,
1306
1307     /// Generic type definitions. Note that `Self` is listed in here
1308     /// as having a single bound, the trait itself (e.g., in the trait
1309     /// `Eq`, there is a single bound `Self : Eq`). This is so that
1310     /// default methods get to assume that the `Self` parameters
1311     /// implements the trait.
1312     pub generics: Generics<'tcx>,
1313
1314     pub trait_ref: TraitRef<'tcx>,
1315
1316     /// A list of the associated types defined in this trait. Useful
1317     /// for resolving `X::Foo` type markers.
1318     pub associated_type_names: Vec<Name>,
1319
1320     // Impls of this trait. To allow for quicker lookup, the impls are indexed
1321     // by a simplified version of their Self type: impls with a simplifiable
1322     // Self are stored in nonblanket_impls keyed by it, while all other impls
1323     // are stored in blanket_impls.
1324
1325     /// Impls of the trait.
1326     pub nonblanket_impls: RefCell<
1327         FnvHashMap<fast_reject::SimplifiedType, Vec<DefId>>
1328     >,
1329
1330     /// Blanket impls associated with the trait.
1331     pub blanket_impls: RefCell<Vec<DefId>>,
1332
1333     /// Various flags
1334     pub flags: Cell<TraitFlags>
1335 }
1336
1337 impl<'tcx> TraitDef<'tcx> {
1338     // returns None if not yet calculated
1339     pub fn object_safety(&self) -> Option<bool> {
1340         if self.flags.get().intersects(TraitFlags::OBJECT_SAFETY_VALID) {
1341             Some(self.flags.get().intersects(TraitFlags::IS_OBJECT_SAFE))
1342         } else {
1343             None
1344         }
1345     }
1346
1347     pub fn set_object_safety(&self, is_safe: bool) {
1348         assert!(self.object_safety().map(|cs| cs == is_safe).unwrap_or(true));
1349         self.flags.set(
1350             self.flags.get() | if is_safe {
1351                 TraitFlags::OBJECT_SAFETY_VALID | TraitFlags::IS_OBJECT_SAFE
1352             } else {
1353                 TraitFlags::OBJECT_SAFETY_VALID
1354             }
1355         );
1356     }
1357
1358     /// Records a trait-to-implementation mapping.
1359     pub fn record_impl(&self,
1360                        tcx: &ctxt<'tcx>,
1361                        impl_def_id: DefId,
1362                        impl_trait_ref: TraitRef<'tcx>) {
1363         debug!("TraitDef::record_impl for {:?}, from {:?}",
1364                self, impl_trait_ref);
1365
1366         // We don't want to borrow_mut after we already populated all impls,
1367         // so check if an impl is present with an immutable borrow first.
1368         if let Some(sty) = fast_reject::simplify_type(tcx,
1369                                                       impl_trait_ref.self_ty(), false) {
1370             if let Some(is) = self.nonblanket_impls.borrow().get(&sty) {
1371                 if is.contains(&impl_def_id) {
1372                     return // duplicate - skip
1373                 }
1374             }
1375
1376             self.nonblanket_impls.borrow_mut().entry(sty).or_insert(vec![]).push(impl_def_id)
1377         } else {
1378             if self.blanket_impls.borrow().contains(&impl_def_id) {
1379                 return // duplicate - skip
1380             }
1381             self.blanket_impls.borrow_mut().push(impl_def_id)
1382         }
1383     }
1384
1385
1386     pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: &ctxt<'tcx>, mut f: F)  {
1387         tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
1388
1389         for &impl_def_id in self.blanket_impls.borrow().iter() {
1390             f(impl_def_id);
1391         }
1392
1393         for v in self.nonblanket_impls.borrow().values() {
1394             for &impl_def_id in v {
1395                 f(impl_def_id);
1396             }
1397         }
1398     }
1399
1400     /// Iterate over every impl that could possibly match the
1401     /// self-type `self_ty`.
1402     pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
1403                                                    tcx: &ctxt<'tcx>,
1404                                                    self_ty: Ty<'tcx>,
1405                                                    mut f: F)
1406     {
1407         tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
1408
1409         for &impl_def_id in self.blanket_impls.borrow().iter() {
1410             f(impl_def_id);
1411         }
1412
1413         // simplify_type(.., false) basically replaces type parameters and
1414         // projections with infer-variables. This is, of course, done on
1415         // the impl trait-ref when it is instantiated, but not on the
1416         // predicate trait-ref which is passed here.
1417         //
1418         // for example, if we match `S: Copy` against an impl like
1419         // `impl<T:Copy> Copy for Option<T>`, we replace the type variable
1420         // in `Option<T>` with an infer variable, to `Option<_>` (this
1421         // doesn't actually change fast_reject output), but we don't
1422         // replace `S` with anything - this impl of course can't be
1423         // selected, and as there are hundreds of similar impls,
1424         // considering them would significantly harm performance.
1425         if let Some(simp) = fast_reject::simplify_type(tcx, self_ty, true) {
1426             if let Some(impls) = self.nonblanket_impls.borrow().get(&simp) {
1427                 for &impl_def_id in impls {
1428                     f(impl_def_id);
1429                 }
1430             }
1431         } else {
1432             for v in self.nonblanket_impls.borrow().values() {
1433                 for &impl_def_id in v {
1434                     f(impl_def_id);
1435                 }
1436             }
1437         }
1438     }
1439
1440 }
1441
1442 bitflags! {
1443     flags AdtFlags: u32 {
1444         const NO_ADT_FLAGS        = 0,
1445         const IS_ENUM             = 1 << 0,
1446         const IS_DTORCK           = 1 << 1, // is this a dtorck type?
1447         const IS_DTORCK_VALID     = 1 << 2,
1448         const IS_PHANTOM_DATA     = 1 << 3,
1449         const IS_SIMD             = 1 << 4,
1450         const IS_FUNDAMENTAL      = 1 << 5,
1451         const IS_NO_DROP_FLAG     = 1 << 6,
1452     }
1453 }
1454
1455 pub type AdtDef<'tcx> = &'tcx AdtDefData<'tcx, 'static>;
1456 pub type VariantDef<'tcx> = &'tcx VariantDefData<'tcx, 'static>;
1457 pub type FieldDef<'tcx> = &'tcx FieldDefData<'tcx, 'static>;
1458
1459 // See comment on AdtDefData for explanation
1460 pub type AdtDefMaster<'tcx> = &'tcx AdtDefData<'tcx, 'tcx>;
1461 pub type VariantDefMaster<'tcx> = &'tcx VariantDefData<'tcx, 'tcx>;
1462 pub type FieldDefMaster<'tcx> = &'tcx FieldDefData<'tcx, 'tcx>;
1463
1464 pub struct VariantDefData<'tcx, 'container: 'tcx> {
1465     pub did: DefId,
1466     pub name: Name, // struct's name if this is a struct
1467     pub disr_val: Disr,
1468     pub fields: Vec<FieldDefData<'tcx, 'container>>
1469 }
1470
1471 pub struct FieldDefData<'tcx, 'container: 'tcx> {
1472     /// The field's DefId. NOTE: the fields of tuple-like enum variants
1473     /// are not real items, and don't have entries in tcache etc.
1474     pub did: DefId,
1475     /// special_idents::unnamed_field.name
1476     /// if this is a tuple-like field
1477     pub name: Name,
1478     pub vis: hir::Visibility,
1479     /// TyIVar is used here to allow for variance (see the doc at
1480     /// AdtDefData).
1481     ty: ivar::TyIVar<'tcx, 'container>
1482 }
1483
1484 /// The definition of an abstract data type - a struct or enum.
1485 ///
1486 /// These are all interned (by intern_adt_def) into the adt_defs
1487 /// table.
1488 ///
1489 /// Because of the possibility of nested tcx-s, this type
1490 /// needs 2 lifetimes: the traditional variant lifetime ('tcx)
1491 /// bounding the lifetime of the inner types is of course necessary.
1492 /// However, it is not sufficient - types from a child tcx must
1493 /// not be leaked into the master tcx by being stored in an AdtDefData.
1494 ///
1495 /// The 'container lifetime ensures that by outliving the container
1496 /// tcx and preventing shorter-lived types from being inserted. When
1497 /// write access is not needed, the 'container lifetime can be
1498 /// erased to 'static, which can be done by the AdtDef wrapper.
1499 pub struct AdtDefData<'tcx, 'container: 'tcx> {
1500     pub did: DefId,
1501     pub variants: Vec<VariantDefData<'tcx, 'container>>,
1502     destructor: Cell<Option<DefId>>,
1503     flags: Cell<AdtFlags>,
1504 }
1505
1506 impl<'tcx, 'container> PartialEq for AdtDefData<'tcx, 'container> {
1507     // AdtDefData are always interned and this is part of TyS equality
1508     #[inline]
1509     fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ }
1510 }
1511
1512 impl<'tcx, 'container> Eq for AdtDefData<'tcx, 'container> {}
1513
1514 impl<'tcx, 'container> Hash for AdtDefData<'tcx, 'container> {
1515     #[inline]
1516     fn hash<H: Hasher>(&self, s: &mut H) {
1517         (self as *const AdtDefData).hash(s)
1518     }
1519 }
1520
1521
1522 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1523 pub enum AdtKind { Struct, Enum }
1524
1525 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1526 pub enum VariantKind { Dict, Tuple, Unit }
1527
1528 impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
1529     fn new(tcx: &ctxt<'tcx>,
1530            did: DefId,
1531            kind: AdtKind,
1532            variants: Vec<VariantDefData<'tcx, 'container>>) -> Self {
1533         let mut flags = AdtFlags::NO_ADT_FLAGS;
1534         let attrs = tcx.get_attrs(did);
1535         if attr::contains_name(&attrs, "fundamental") {
1536             flags = flags | AdtFlags::IS_FUNDAMENTAL;
1537         }
1538         if attr::contains_name(&attrs, "unsafe_no_drop_flag") {
1539             flags = flags | AdtFlags::IS_NO_DROP_FLAG;
1540         }
1541         if tcx.lookup_simd(did) {
1542             flags = flags | AdtFlags::IS_SIMD;
1543         }
1544         if Some(did) == tcx.lang_items.phantom_data() {
1545             flags = flags | AdtFlags::IS_PHANTOM_DATA;
1546         }
1547         if let AdtKind::Enum = kind {
1548             flags = flags | AdtFlags::IS_ENUM;
1549         }
1550         AdtDefData {
1551             did: did,
1552             variants: variants,
1553             flags: Cell::new(flags),
1554             destructor: Cell::new(None)
1555         }
1556     }
1557
1558     fn calculate_dtorck(&'tcx self, tcx: &ctxt<'tcx>) {
1559         if tcx.is_adt_dtorck(self) {
1560             self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK);
1561         }
1562         self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK_VALID)
1563     }
1564
1565     /// Returns the kind of the ADT - Struct or Enum.
1566     #[inline]
1567     pub fn adt_kind(&self) -> AdtKind {
1568         if self.flags.get().intersects(AdtFlags::IS_ENUM) {
1569             AdtKind::Enum
1570         } else {
1571             AdtKind::Struct
1572         }
1573     }
1574
1575     /// Returns whether this is a dtorck type. If this returns
1576     /// true, this type being safe for destruction requires it to be
1577     /// alive; Otherwise, only the contents are required to be.
1578     #[inline]
1579     pub fn is_dtorck(&'tcx self, tcx: &ctxt<'tcx>) -> bool {
1580         if !self.flags.get().intersects(AdtFlags::IS_DTORCK_VALID) {
1581             self.calculate_dtorck(tcx)
1582         }
1583         self.flags.get().intersects(AdtFlags::IS_DTORCK)
1584     }
1585
1586     /// Returns whether this type is #[fundamental] for the purposes
1587     /// of coherence checking.
1588     #[inline]
1589     pub fn is_fundamental(&self) -> bool {
1590         self.flags.get().intersects(AdtFlags::IS_FUNDAMENTAL)
1591     }
1592
1593     #[inline]
1594     pub fn is_simd(&self) -> bool {
1595         self.flags.get().intersects(AdtFlags::IS_SIMD)
1596     }
1597
1598     /// Returns true if this is PhantomData<T>.
1599     #[inline]
1600     pub fn is_phantom_data(&self) -> bool {
1601         self.flags.get().intersects(AdtFlags::IS_PHANTOM_DATA)
1602     }
1603
1604     /// Returns whether this type has a destructor.
1605     pub fn has_dtor(&self) -> bool {
1606         match self.dtor_kind() {
1607             NoDtor => false,
1608             TraitDtor(..) => true
1609         }
1610     }
1611
1612     /// Asserts this is a struct and returns the struct's unique
1613     /// variant.
1614     pub fn struct_variant(&self) -> &VariantDefData<'tcx, 'container> {
1615         assert!(self.adt_kind() == AdtKind::Struct);
1616         &self.variants[0]
1617     }
1618
1619     #[inline]
1620     pub fn type_scheme(&self, tcx: &ctxt<'tcx>) -> TypeScheme<'tcx> {
1621         tcx.lookup_item_type(self.did)
1622     }
1623
1624     #[inline]
1625     pub fn predicates(&self, tcx: &ctxt<'tcx>) -> GenericPredicates<'tcx> {
1626         tcx.lookup_predicates(self.did)
1627     }
1628
1629     /// Returns an iterator over all fields contained
1630     /// by this ADT.
1631     #[inline]
1632     pub fn all_fields(&self) ->
1633             iter::FlatMap<
1634                 slice::Iter<VariantDefData<'tcx, 'container>>,
1635                 slice::Iter<FieldDefData<'tcx, 'container>>,
1636                 for<'s> fn(&'s VariantDefData<'tcx, 'container>)
1637                     -> slice::Iter<'s, FieldDefData<'tcx, 'container>>
1638             > {
1639         self.variants.iter().flat_map(VariantDefData::fields_iter)
1640     }
1641
1642     #[inline]
1643     pub fn is_empty(&self) -> bool {
1644         self.variants.is_empty()
1645     }
1646
1647     #[inline]
1648     pub fn is_univariant(&self) -> bool {
1649         self.variants.len() == 1
1650     }
1651
1652     pub fn is_payloadfree(&self) -> bool {
1653         !self.variants.is_empty() &&
1654             self.variants.iter().all(|v| v.fields.is_empty())
1655     }
1656
1657     pub fn variant_with_id(&self, vid: DefId) -> &VariantDefData<'tcx, 'container> {
1658         self.variants
1659             .iter()
1660             .find(|v| v.did == vid)
1661             .expect("variant_with_id: unknown variant")
1662     }
1663
1664     pub fn variant_index_with_id(&self, vid: DefId) -> usize {
1665         self.variants
1666             .iter()
1667             .position(|v| v.did == vid)
1668             .expect("variant_index_with_id: unknown variant")
1669     }
1670
1671     pub fn variant_of_def(&self, def: def::Def) -> &VariantDefData<'tcx, 'container> {
1672         match def {
1673             def::DefVariant(_, vid, _) => self.variant_with_id(vid),
1674             def::DefStruct(..) | def::DefTy(..) => self.struct_variant(),
1675             _ => panic!("unexpected def {:?} in variant_of_def", def)
1676         }
1677     }
1678
1679     pub fn destructor(&self) -> Option<DefId> {
1680         self.destructor.get()
1681     }
1682
1683     pub fn set_destructor(&self, dtor: DefId) {
1684         assert!(self.destructor.get().is_none());
1685         self.destructor.set(Some(dtor));
1686     }
1687
1688     pub fn dtor_kind(&self) -> DtorKind {
1689         match self.destructor.get() {
1690             Some(_) => {
1691                 TraitDtor(!self.flags.get().intersects(AdtFlags::IS_NO_DROP_FLAG))
1692             }
1693             None => NoDtor,
1694         }
1695     }
1696 }
1697
1698 impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
1699     #[inline]
1700     fn fields_iter(&self) -> slice::Iter<FieldDefData<'tcx, 'container>> {
1701         self.fields.iter()
1702     }
1703
1704     pub fn kind(&self) -> VariantKind {
1705         match self.fields.get(0) {
1706             None => VariantKind::Unit,
1707             Some(&FieldDefData { name, .. }) if name == special_idents::unnamed_field.name => {
1708                 VariantKind::Tuple
1709             }
1710             Some(_) => VariantKind::Dict
1711         }
1712     }
1713
1714     pub fn is_tuple_struct(&self) -> bool {
1715         self.kind() == VariantKind::Tuple
1716     }
1717
1718     #[inline]
1719     pub fn find_field_named(&self,
1720                             name: ast::Name)
1721                             -> Option<&FieldDefData<'tcx, 'container>> {
1722         self.fields.iter().find(|f| f.name == name)
1723     }
1724
1725     #[inline]
1726     pub fn field_named(&self, name: ast::Name) -> &FieldDefData<'tcx, 'container> {
1727         self.find_field_named(name).unwrap()
1728     }
1729 }
1730
1731 impl<'tcx, 'container> FieldDefData<'tcx, 'container> {
1732     pub fn new(did: DefId,
1733                name: Name,
1734                vis: hir::Visibility) -> Self {
1735         FieldDefData {
1736             did: did,
1737             name: name,
1738             vis: vis,
1739             ty: ivar::TyIVar::new()
1740         }
1741     }
1742
1743     pub fn ty(&self, tcx: &ctxt<'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
1744         self.unsubst_ty().subst(tcx, subst)
1745     }
1746
1747     pub fn unsubst_ty(&self) -> Ty<'tcx> {
1748         self.ty.unwrap()
1749     }
1750
1751     pub fn fulfill_ty(&self, ty: Ty<'container>) {
1752         self.ty.fulfill(ty);
1753     }
1754 }
1755
1756 /// Records the substitutions used to translate the polytype for an
1757 /// item into the monotype of an item reference.
1758 #[derive(Clone)]
1759 pub struct ItemSubsts<'tcx> {
1760     pub substs: Substs<'tcx>,
1761 }
1762
1763 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
1764 pub enum ClosureKind {
1765     // Warning: Ordering is significant here! The ordering is chosen
1766     // because the trait Fn is a subtrait of FnMut and so in turn, and
1767     // hence we order it so that Fn < FnMut < FnOnce.
1768     FnClosureKind,
1769     FnMutClosureKind,
1770     FnOnceClosureKind,
1771 }
1772
1773 impl ClosureKind {
1774     pub fn trait_did(&self, cx: &ctxt) -> DefId {
1775         let result = match *self {
1776             FnClosureKind => cx.lang_items.require(FnTraitLangItem),
1777             FnMutClosureKind => {
1778                 cx.lang_items.require(FnMutTraitLangItem)
1779             }
1780             FnOnceClosureKind => {
1781                 cx.lang_items.require(FnOnceTraitLangItem)
1782             }
1783         };
1784         match result {
1785             Ok(trait_did) => trait_did,
1786             Err(err) => cx.sess.fatal(&err[..]),
1787         }
1788     }
1789
1790     /// True if this a type that impls this closure kind
1791     /// must also implement `other`.
1792     pub fn extends(self, other: ty::ClosureKind) -> bool {
1793         match (self, other) {
1794             (FnClosureKind, FnClosureKind) => true,
1795             (FnClosureKind, FnMutClosureKind) => true,
1796             (FnClosureKind, FnOnceClosureKind) => true,
1797             (FnMutClosureKind, FnMutClosureKind) => true,
1798             (FnMutClosureKind, FnOnceClosureKind) => true,
1799             (FnOnceClosureKind, FnOnceClosureKind) => true,
1800             _ => false,
1801         }
1802     }
1803 }
1804
1805 impl<'tcx> TyS<'tcx> {
1806     /// Iterator that walks `self` and any types reachable from
1807     /// `self`, in depth-first order. Note that just walks the types
1808     /// that appear in `self`, it does not descend into the fields of
1809     /// structs or variants. For example:
1810     ///
1811     /// ```notrust
1812     /// isize => { isize }
1813     /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
1814     /// [isize] => { [isize], isize }
1815     /// ```
1816     pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
1817         TypeWalker::new(self)
1818     }
1819
1820     /// Iterator that walks the immediate children of `self`.  Hence
1821     /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
1822     /// (but not `i32`, like `walk`).
1823     pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
1824         walk::walk_shallow(self)
1825     }
1826
1827     /// Walks `ty` and any types appearing within `ty`, invoking the
1828     /// callback `f` on each type. If the callback returns false, then the
1829     /// children of the current type are ignored.
1830     ///
1831     /// Note: prefer `ty.walk()` where possible.
1832     pub fn maybe_walk<F>(&'tcx self, mut f: F)
1833         where F : FnMut(Ty<'tcx>) -> bool
1834     {
1835         let mut walker = self.walk();
1836         while let Some(ty) = walker.next() {
1837             if !f(ty) {
1838                 walker.skip_current_subtree();
1839             }
1840         }
1841     }
1842 }
1843
1844 impl<'tcx> ItemSubsts<'tcx> {
1845     pub fn empty() -> ItemSubsts<'tcx> {
1846         ItemSubsts { substs: Substs::empty() }
1847     }
1848
1849     pub fn is_noop(&self) -> bool {
1850         self.substs.is_noop()
1851     }
1852 }
1853
1854 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1855 pub enum LvaluePreference {
1856     PreferMutLvalue,
1857     NoPreference
1858 }
1859
1860 impl LvaluePreference {
1861     pub fn from_mutbl(m: hir::Mutability) -> Self {
1862         match m {
1863             hir::MutMutable => PreferMutLvalue,
1864             hir::MutImmutable => NoPreference,
1865         }
1866     }
1867 }
1868
1869 /// Helper for looking things up in the various maps that are populated during
1870 /// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc).  All of
1871 /// these share the pattern that if the id is local, it should have been loaded
1872 /// into the map by the `typeck::collect` phase.  If the def-id is external,
1873 /// then we have to go consult the crate loading code (and cache the result for
1874 /// the future).
1875 fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
1876                                           def_id: DefId,
1877                                           map: &RefCell<DefIdMap<V>>,
1878                                           load_external: F) -> V where
1879     V: Clone,
1880     F: FnOnce() -> V,
1881 {
1882     match map.borrow().get(&def_id).cloned() {
1883         Some(v) => { return v; }
1884         None => { }
1885     }
1886
1887     if def_id.is_local() {
1888         panic!("No def'n found for {:?} in tcx.{}", def_id, descr);
1889     }
1890     let v = load_external();
1891     map.borrow_mut().insert(def_id, v.clone());
1892     v
1893 }
1894
1895 impl BorrowKind {
1896     pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
1897         match m {
1898             hir::MutMutable => MutBorrow,
1899             hir::MutImmutable => ImmBorrow,
1900         }
1901     }
1902
1903     /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
1904     /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
1905     /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
1906     /// question.
1907     pub fn to_mutbl_lossy(self) -> hir::Mutability {
1908         match self {
1909             MutBorrow => hir::MutMutable,
1910             ImmBorrow => hir::MutImmutable,
1911
1912             // We have no type corresponding to a unique imm borrow, so
1913             // use `&mut`. It gives all the capabilities of an `&uniq`
1914             // and hence is a safe "over approximation".
1915             UniqueImmBorrow => hir::MutMutable,
1916         }
1917     }
1918
1919     pub fn to_user_str(&self) -> &'static str {
1920         match *self {
1921             MutBorrow => "mutable",
1922             ImmBorrow => "immutable",
1923             UniqueImmBorrow => "uniquely immutable",
1924         }
1925     }
1926 }
1927
1928 impl<'tcx> ctxt<'tcx> {
1929     pub fn node_id_to_type(&self, id: NodeId) -> Ty<'tcx> {
1930         match self.node_id_to_type_opt(id) {
1931            Some(ty) => ty,
1932            None => self.sess.bug(
1933                &format!("node_id_to_type: no type for node `{}`",
1934                         self.map.node_to_string(id)))
1935         }
1936     }
1937
1938     pub fn node_id_to_type_opt(&self, id: NodeId) -> Option<Ty<'tcx>> {
1939         self.tables.borrow().node_types.get(&id).cloned()
1940     }
1941
1942     pub fn node_id_item_substs(&self, id: NodeId) -> ItemSubsts<'tcx> {
1943         match self.tables.borrow().item_substs.get(&id) {
1944             None => ItemSubsts::empty(),
1945             Some(ts) => ts.clone(),
1946         }
1947     }
1948
1949     // Returns the type of a pattern as a monotype. Like @expr_ty, this function
1950     // doesn't provide type parameter substitutions.
1951     pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
1952         self.node_id_to_type(pat.id)
1953     }
1954     pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
1955         self.node_id_to_type_opt(pat.id)
1956     }
1957
1958     // Returns the type of an expression as a monotype.
1959     //
1960     // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression.  That is, in
1961     // some cases, we insert `AutoAdjustment` annotations such as auto-deref or
1962     // auto-ref.  The type returned by this function does not consider such
1963     // adjustments.  See `expr_ty_adjusted()` instead.
1964     //
1965     // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
1966     // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
1967     // instead of "fn(ty) -> T with T = isize".
1968     pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
1969         self.node_id_to_type(expr.id)
1970     }
1971
1972     pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
1973         self.node_id_to_type_opt(expr.id)
1974     }
1975
1976     /// Returns the type of `expr`, considering any `AutoAdjustment`
1977     /// entry recorded for that expression.
1978     ///
1979     /// It would almost certainly be better to store the adjusted ty in with
1980     /// the `AutoAdjustment`, but I opted not to do this because it would
1981     /// require serializing and deserializing the type and, although that's not
1982     /// hard to do, I just hate that code so much I didn't want to touch it
1983     /// unless it was to fix it properly, which seemed a distraction from the
1984     /// thread at hand! -nmatsakis
1985     pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> Ty<'tcx> {
1986         self.expr_ty(expr)
1987             .adjust(self, expr.span, expr.id,
1988                     self.tables.borrow().adjustments.get(&expr.id),
1989                     |method_call| {
1990             self.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
1991         })
1992     }
1993
1994     pub fn expr_span(&self, id: NodeId) -> Span {
1995         match self.map.find(id) {
1996             Some(ast_map::NodeExpr(e)) => {
1997                 e.span
1998             }
1999             Some(f) => {
2000                 self.sess.bug(&format!("Node id {} is not an expr: {:?}",
2001                                        id, f));
2002             }
2003             None => {
2004                 self.sess.bug(&format!("Node id {} is not present \
2005                                         in the node map", id));
2006             }
2007         }
2008     }
2009
2010     pub fn local_var_name_str(&self, id: NodeId) -> InternedString {
2011         match self.map.find(id) {
2012             Some(ast_map::NodeLocal(pat)) => {
2013                 match pat.node {
2014                     hir::PatIdent(_, ref path1, _) => path1.node.name.as_str(),
2015                     _ => {
2016                         self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, pat));
2017                     },
2018                 }
2019             },
2020             r => self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, r)),
2021         }
2022     }
2023
2024     pub fn resolve_expr(&self, expr: &hir::Expr) -> def::Def {
2025         match self.def_map.borrow().get(&expr.id) {
2026             Some(def) => def.full_def(),
2027             None => {
2028                 self.sess.span_bug(expr.span, &format!(
2029                     "no def-map entry for expr {}", expr.id));
2030             }
2031         }
2032     }
2033
2034     pub fn expr_is_lval(&self, expr: &hir::Expr) -> bool {
2035          match expr.node {
2036             hir::ExprPath(..) => {
2037                 // We can't use resolve_expr here, as this needs to run on broken
2038                 // programs. We don't need to through - associated items are all
2039                 // rvalues.
2040                 match self.def_map.borrow().get(&expr.id) {
2041                     Some(&def::PathResolution {
2042                         base_def: def::DefStatic(..), ..
2043                     }) | Some(&def::PathResolution {
2044                         base_def: def::DefUpvar(..), ..
2045                     }) | Some(&def::PathResolution {
2046                         base_def: def::DefLocal(..), ..
2047                     }) => {
2048                         true
2049                     }
2050
2051                     Some(..) => false,
2052
2053                     None => self.sess.span_bug(expr.span, &format!(
2054                         "no def for path {}", expr.id))
2055                 }
2056             }
2057
2058             hir::ExprUnary(hir::UnDeref, _) |
2059             hir::ExprField(..) |
2060             hir::ExprTupField(..) |
2061             hir::ExprIndex(..) => {
2062                 true
2063             }
2064
2065             hir::ExprCall(..) |
2066             hir::ExprMethodCall(..) |
2067             hir::ExprStruct(..) |
2068             hir::ExprRange(..) |
2069             hir::ExprTup(..) |
2070             hir::ExprIf(..) |
2071             hir::ExprMatch(..) |
2072             hir::ExprClosure(..) |
2073             hir::ExprBlock(..) |
2074             hir::ExprRepeat(..) |
2075             hir::ExprVec(..) |
2076             hir::ExprBreak(..) |
2077             hir::ExprAgain(..) |
2078             hir::ExprRet(..) |
2079             hir::ExprWhile(..) |
2080             hir::ExprLoop(..) |
2081             hir::ExprAssign(..) |
2082             hir::ExprInlineAsm(..) |
2083             hir::ExprAssignOp(..) |
2084             hir::ExprLit(_) |
2085             hir::ExprUnary(..) |
2086             hir::ExprBox(..) |
2087             hir::ExprAddrOf(..) |
2088             hir::ExprBinary(..) |
2089             hir::ExprCast(..) => {
2090                 false
2091             }
2092
2093             hir::ExprParen(ref e) => self.expr_is_lval(e),
2094         }
2095     }
2096
2097     pub fn provided_source(&self, id: DefId) -> Option<DefId> {
2098         self.provided_method_sources.borrow().get(&id).cloned()
2099     }
2100
2101     pub fn provided_trait_methods(&self, id: DefId) -> Vec<Rc<Method<'tcx>>> {
2102         if id.is_local() {
2103             if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id.node).node {
2104                 ms.iter().filter_map(|ti| {
2105                     if let hir::MethodTraitItem(_, Some(_)) = ti.node {
2106                         match self.impl_or_trait_item(DefId::local(ti.id)) {
2107                             MethodTraitItem(m) => Some(m),
2108                             _ => {
2109                                 self.sess.bug("provided_trait_methods(): \
2110                                                non-method item found from \
2111                                                looking up provided method?!")
2112                             }
2113                         }
2114                     } else {
2115                         None
2116                     }
2117                 }).collect()
2118             } else {
2119                 self.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
2120             }
2121         } else {
2122             csearch::get_provided_trait_methods(self, id)
2123         }
2124     }
2125
2126     pub fn associated_consts(&self, id: DefId) -> Vec<Rc<AssociatedConst<'tcx>>> {
2127         if id.is_local() {
2128             match self.map.expect_item(id.node).node {
2129                 ItemTrait(_, _, _, ref tis) => {
2130                     tis.iter().filter_map(|ti| {
2131                         if let hir::ConstTraitItem(_, _) = ti.node {
2132                             match self.impl_or_trait_item(DefId::local(ti.id)) {
2133                                 ConstTraitItem(ac) => Some(ac),
2134                                 _ => {
2135                                     self.sess.bug("associated_consts(): \
2136                                                    non-const item found from \
2137                                                    looking up a constant?!")
2138                                 }
2139                             }
2140                         } else {
2141                             None
2142                         }
2143                     }).collect()
2144                 }
2145                 ItemImpl(_, _, _, _, _, ref iis) => {
2146                     iis.iter().filter_map(|ii| {
2147                         if let hir::ConstImplItem(_, _) = ii.node {
2148                             match self.impl_or_trait_item(DefId::local(ii.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                 _ => {
2162                     self.sess.bug(&format!("associated_consts: `{:?}` is not a trait \
2163                                             or impl", id))
2164                 }
2165             }
2166         } else {
2167             csearch::get_associated_consts(self, id)
2168         }
2169     }
2170
2171     pub fn trait_items(&self, trait_did: DefId) -> Rc<Vec<ImplOrTraitItem<'tcx>>> {
2172         let mut trait_items = self.trait_items_cache.borrow_mut();
2173         match trait_items.get(&trait_did).cloned() {
2174             Some(trait_items) => trait_items,
2175             None => {
2176                 let def_ids = self.trait_item_def_ids(trait_did);
2177                 let items: Rc<Vec<ImplOrTraitItem>> =
2178                     Rc::new(def_ids.iter()
2179                                    .map(|d| self.impl_or_trait_item(d.def_id()))
2180                                    .collect());
2181                 trait_items.insert(trait_did, items.clone());
2182                 items
2183             }
2184         }
2185     }
2186
2187     pub fn trait_impl_polarity(&self, id: DefId) -> Option<hir::ImplPolarity> {
2188         if id.is_local() {
2189             match self.map.find(id.node) {
2190                 Some(ast_map::NodeItem(item)) => {
2191                     match item.node {
2192                         hir::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
2193                         _ => None
2194                     }
2195                 }
2196                 _ => None
2197             }
2198         } else {
2199             csearch::get_impl_polarity(self, id)
2200         }
2201     }
2202
2203     pub fn custom_coerce_unsized_kind(&self, did: DefId) -> adjustment::CustomCoerceUnsized {
2204         memoized(&self.custom_coerce_unsized_kinds, did, |did: DefId| {
2205             let (kind, src) = if did.krate != LOCAL_CRATE {
2206                 (csearch::get_custom_coerce_unsized_kind(self, did), "external")
2207             } else {
2208                 (None, "local")
2209             };
2210
2211             match kind {
2212                 Some(kind) => kind,
2213                 None => {
2214                     self.sess.bug(&format!("custom_coerce_unsized_kind: \
2215                                             {} impl `{}` is missing its kind",
2216                                            src, self.item_path_str(did)));
2217                 }
2218             }
2219         })
2220     }
2221
2222     pub fn impl_or_trait_item(&self, id: DefId) -> ImplOrTraitItem<'tcx> {
2223         lookup_locally_or_in_crate_store(
2224             "impl_or_trait_items", id, &self.impl_or_trait_items,
2225             || csearch::get_impl_or_trait_item(self, id))
2226     }
2227
2228     pub fn trait_item_def_ids(&self, id: DefId) -> Rc<Vec<ImplOrTraitItemId>> {
2229         lookup_locally_or_in_crate_store(
2230             "trait_item_def_ids", id, &self.trait_item_def_ids,
2231             || Rc::new(csearch::get_trait_item_def_ids(&self.sess.cstore, id)))
2232     }
2233
2234     /// Returns the trait-ref corresponding to a given impl, or None if it is
2235     /// an inherent impl.
2236     pub fn impl_trait_ref(&self, id: DefId) -> Option<TraitRef<'tcx>> {
2237         lookup_locally_or_in_crate_store(
2238             "impl_trait_refs", id, &self.impl_trait_refs,
2239             || csearch::get_impl_trait(self, id))
2240     }
2241
2242     /// Returns whether this DefId refers to an impl
2243     pub fn is_impl(&self, id: DefId) -> bool {
2244         if id.is_local() {
2245             if let Some(ast_map::NodeItem(
2246                 &hir::Item { node: hir::ItemImpl(..), .. })) = self.map.find(id.node) {
2247                 true
2248             } else {
2249                 false
2250             }
2251         } else {
2252             csearch::is_impl(&self.sess.cstore, id)
2253         }
2254     }
2255
2256     pub fn trait_ref_to_def_id(&self, tr: &hir::TraitRef) -> DefId {
2257         self.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
2258     }
2259
2260     pub fn item_path_str(&self, id: DefId) -> String {
2261         self.with_path(id, |path| ast_map::path_to_string(path))
2262     }
2263
2264     pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
2265         F: FnOnce(ast_map::PathElems) -> T,
2266     {
2267         if id.is_local() {
2268             self.map.with_path(id.node, f)
2269         } else {
2270             f(csearch::get_item_path(self, id).iter().cloned().chain(LinkedPath::empty()))
2271         }
2272     }
2273
2274     pub fn item_name(&self, id: DefId) -> ast::Name {
2275         if id.is_local() {
2276             self.map.get_path_elem(id.node).name()
2277         } else {
2278             csearch::get_item_name(self, id)
2279         }
2280     }
2281
2282     // Register a given item type
2283     pub fn register_item_type(&self, did: DefId, ty: TypeScheme<'tcx>) {
2284         self.tcache.borrow_mut().insert(did, ty);
2285     }
2286
2287     // If the given item is in an external crate, looks up its type and adds it to
2288     // the type cache. Returns the type parameters and type.
2289     pub fn lookup_item_type(&self, did: DefId) -> TypeScheme<'tcx> {
2290         lookup_locally_or_in_crate_store(
2291             "tcache", did, &self.tcache,
2292             || csearch::get_type(self, did))
2293     }
2294
2295     /// Given the did of a trait, returns its canonical trait ref.
2296     pub fn lookup_trait_def(&self, did: DefId) -> &'tcx TraitDef<'tcx> {
2297         lookup_locally_or_in_crate_store(
2298             "trait_defs", did, &self.trait_defs,
2299             || self.alloc_trait_def(csearch::get_trait_def(self, did))
2300         )
2301     }
2302
2303     /// Given the did of an ADT, return a master reference to its
2304     /// definition. Unless you are planning on fulfilling the ADT's fields,
2305     /// use lookup_adt_def instead.
2306     pub fn lookup_adt_def_master(&self, did: DefId) -> AdtDefMaster<'tcx> {
2307         lookup_locally_or_in_crate_store(
2308             "adt_defs", did, &self.adt_defs,
2309             || csearch::get_adt_def(self, did)
2310         )
2311     }
2312
2313     /// Given the did of an ADT, return a reference to its definition.
2314     pub fn lookup_adt_def(&self, did: DefId) -> AdtDef<'tcx> {
2315         // when reverse-variance goes away, a transmute::<AdtDefMaster,AdtDef>
2316         // woud be needed here.
2317         self.lookup_adt_def_master(did)
2318     }
2319
2320     /// Return the list of all interned ADT definitions
2321     pub fn adt_defs(&self) -> Vec<AdtDef<'tcx>> {
2322         self.adt_defs.borrow().values().cloned().collect()
2323     }
2324
2325     /// Given the did of an item, returns its full set of predicates.
2326     pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
2327         lookup_locally_or_in_crate_store(
2328             "predicates", did, &self.predicates,
2329             || csearch::get_predicates(self, did))
2330     }
2331
2332     /// Given the did of a trait, returns its superpredicates.
2333     pub fn lookup_super_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
2334         lookup_locally_or_in_crate_store(
2335             "super_predicates", did, &self.super_predicates,
2336             || csearch::get_super_predicates(self, did))
2337     }
2338
2339     /// Get the attributes of a definition.
2340     pub fn get_attrs(&self, did: DefId) -> Cow<'tcx, [hir::Attribute]> {
2341         if did.is_local() {
2342             Cow::Borrowed(self.map.attrs(did.node))
2343         } else {
2344             Cow::Owned(csearch::get_item_attrs(&self.sess.cstore, did))
2345         }
2346     }
2347
2348     /// Determine whether an item is annotated with an attribute
2349     pub fn has_attr(&self, did: DefId, attr: &str) -> bool {
2350         self.get_attrs(did).iter().any(|item| item.check_name(attr))
2351     }
2352
2353     /// Determine whether an item is annotated with `#[repr(packed)]`
2354     pub fn lookup_packed(&self, did: DefId) -> bool {
2355         self.lookup_repr_hints(did).contains(&attr::ReprPacked)
2356     }
2357
2358     /// Determine whether an item is annotated with `#[simd]`
2359     pub fn lookup_simd(&self, did: DefId) -> bool {
2360         self.has_attr(did, "simd")
2361             || self.lookup_repr_hints(did).contains(&attr::ReprSimd)
2362     }
2363
2364     /// Obtain the representation annotation for a struct definition.
2365     pub fn lookup_repr_hints(&self, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
2366         memoized(&self.repr_hint_cache, did, |did: DefId| {
2367             Rc::new(if did.is_local() {
2368                 self.get_attrs(did).iter().flat_map(|meta| {
2369                     attr::find_repr_attrs(self.sess.diagnostic(), meta).into_iter()
2370                 }).collect()
2371             } else {
2372                 csearch::get_repr_attrs(&self.sess.cstore, did)
2373             })
2374         })
2375     }
2376
2377     pub fn item_variances(&self, item_id: DefId) -> Rc<ItemVariances> {
2378         lookup_locally_or_in_crate_store(
2379             "item_variance_map", item_id, &self.item_variance_map,
2380             || Rc::new(csearch::get_item_variances(&self.sess.cstore, item_id)))
2381     }
2382
2383     pub fn trait_has_default_impl(&self, trait_def_id: DefId) -> bool {
2384         self.populate_implementations_for_trait_if_necessary(trait_def_id);
2385
2386         let def = self.lookup_trait_def(trait_def_id);
2387         def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
2388     }
2389
2390     /// Records a trait-to-implementation mapping.
2391     pub fn record_trait_has_default_impl(&self, trait_def_id: DefId) {
2392         let def = self.lookup_trait_def(trait_def_id);
2393         def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
2394     }
2395
2396     /// Load primitive inherent implementations if necessary
2397     pub fn populate_implementations_for_primitive_if_necessary(&self,
2398                                                                primitive_def_id: DefId) {
2399         if primitive_def_id.is_local() {
2400             return
2401         }
2402
2403         if self.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
2404             return
2405         }
2406
2407         debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
2408                primitive_def_id);
2409
2410         let impl_items = csearch::get_impl_items(&self.sess.cstore, primitive_def_id);
2411
2412         // Store the implementation info.
2413         self.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
2414         self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
2415     }
2416
2417     /// Populates the type context with all the inherent implementations for
2418     /// the given type if necessary.
2419     pub fn populate_inherent_implementations_for_type_if_necessary(&self,
2420                                                                    type_id: DefId) {
2421         if type_id.is_local() {
2422             return
2423         }
2424
2425         if self.populated_external_types.borrow().contains(&type_id) {
2426             return
2427         }
2428
2429         debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
2430                type_id);
2431
2432         let mut inherent_impls = Vec::new();
2433         csearch::each_inherent_implementation_for_type(&self.sess.cstore, type_id, |impl_def_id| {
2434             // Record the implementation.
2435             inherent_impls.push(impl_def_id);
2436
2437             // Store the implementation info.
2438             let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
2439             self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
2440         });
2441
2442         self.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls));
2443         self.populated_external_types.borrow_mut().insert(type_id);
2444     }
2445
2446     /// Populates the type context with all the implementations for the given
2447     /// trait if necessary.
2448     pub fn populate_implementations_for_trait_if_necessary(&self, trait_id: DefId) {
2449         if trait_id.is_local() {
2450             return
2451         }
2452
2453         let def = self.lookup_trait_def(trait_id);
2454         if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
2455             return;
2456         }
2457
2458         debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
2459
2460         if csearch::is_defaulted_trait(&self.sess.cstore, trait_id) {
2461             self.record_trait_has_default_impl(trait_id);
2462         }
2463
2464         csearch::each_implementation_for_trait(&self.sess.cstore, trait_id, |impl_def_id| {
2465             let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
2466             let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
2467             // Record the trait->implementation mapping.
2468             def.record_impl(self, impl_def_id, trait_ref);
2469
2470             // For any methods that use a default implementation, add them to
2471             // the map. This is a bit unfortunate.
2472             for impl_item_def_id in &impl_items {
2473                 let method_def_id = impl_item_def_id.def_id();
2474                 match self.impl_or_trait_item(method_def_id) {
2475                     MethodTraitItem(method) => {
2476                         if let Some(source) = method.provided_source {
2477                             self.provided_method_sources
2478                                 .borrow_mut()
2479                                 .insert(method_def_id, source);
2480                         }
2481                     }
2482                     _ => {}
2483                 }
2484             }
2485
2486             // Store the implementation info.
2487             self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
2488         });
2489
2490         def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
2491     }
2492
2493     /// Given the def_id of an impl, return the def_id of the trait it implements.
2494     /// If it implements no trait, return `None`.
2495     pub fn trait_id_of_impl(&self, def_id: DefId) -> Option<DefId> {
2496         self.impl_trait_ref(def_id).map(|tr| tr.def_id)
2497     }
2498
2499     /// If the given def ID describes a method belonging to an impl, return the
2500     /// ID of the impl that the method belongs to. Otherwise, return `None`.
2501     pub fn impl_of_method(&self, def_id: DefId) -> Option<DefId> {
2502         if def_id.krate != LOCAL_CRATE {
2503             return match csearch::get_impl_or_trait_item(self,
2504                                                          def_id).container() {
2505                 TraitContainer(_) => None,
2506                 ImplContainer(def_id) => Some(def_id),
2507             };
2508         }
2509         match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
2510             Some(trait_item) => {
2511                 match trait_item.container() {
2512                     TraitContainer(_) => None,
2513                     ImplContainer(def_id) => Some(def_id),
2514                 }
2515             }
2516             None => None
2517         }
2518     }
2519
2520     /// If the given def ID describes an item belonging to a trait (either a
2521     /// default method or an implementation of a trait method), return the ID of
2522     /// the trait that the method belongs to. Otherwise, return `None`.
2523     pub fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
2524         if def_id.krate != LOCAL_CRATE {
2525             return csearch::get_trait_of_item(&self.sess.cstore, def_id, self);
2526         }
2527         match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
2528             Some(impl_or_trait_item) => {
2529                 match impl_or_trait_item.container() {
2530                     TraitContainer(def_id) => Some(def_id),
2531                     ImplContainer(def_id) => self.trait_id_of_impl(def_id),
2532                 }
2533             }
2534             None => None
2535         }
2536     }
2537
2538     /// If the given def ID describes an item belonging to a trait, (either a
2539     /// default method or an implementation of a trait method), return the ID of
2540     /// the method inside trait definition (this means that if the given def ID
2541     /// is already that of the original trait method, then the return value is
2542     /// the same).
2543     /// Otherwise, return `None`.
2544     pub fn trait_item_of_item(&self, def_id: DefId) -> Option<ImplOrTraitItemId> {
2545         let impl_item = match self.impl_or_trait_items.borrow().get(&def_id) {
2546             Some(m) => m.clone(),
2547             None => return None,
2548         };
2549         let name = impl_item.name();
2550         match self.trait_of_item(def_id) {
2551             Some(trait_did) => {
2552                 self.trait_items(trait_did).iter()
2553                     .find(|item| item.name() == name)
2554                     .map(|item| item.id())
2555             }
2556             None => None
2557         }
2558     }
2559
2560     /// Construct a parameter environment suitable for static contexts or other contexts where there
2561     /// are no free type/lifetime parameters in scope.
2562     pub fn empty_parameter_environment<'a>(&'a self)
2563                                            -> ParameterEnvironment<'a,'tcx> {
2564         ty::ParameterEnvironment { tcx: self,
2565                                    free_substs: Substs::empty(),
2566                                    caller_bounds: Vec::new(),
2567                                    implicit_region_bound: ty::ReEmpty,
2568                                    selection_cache: traits::SelectionCache::new(),
2569
2570                                    // for an empty parameter
2571                                    // environment, there ARE no free
2572                                    // regions, so it shouldn't matter
2573                                    // what we use for the free id
2574                                    free_id: ast::DUMMY_NODE_ID }
2575     }
2576
2577     /// Constructs and returns a substitution that can be applied to move from
2578     /// the "outer" view of a type or method to the "inner" view.
2579     /// In general, this means converting from bound parameters to
2580     /// free parameters. Since we currently represent bound/free type
2581     /// parameters in the same way, this only has an effect on regions.
2582     pub fn construct_free_substs(&self, generics: &Generics<'tcx>,
2583                                  free_id: NodeId) -> Substs<'tcx> {
2584         // map T => T
2585         let mut types = VecPerParamSpace::empty();
2586         for def in generics.types.as_slice() {
2587             debug!("construct_parameter_environment(): push_types_from_defs: def={:?}",
2588                     def);
2589             types.push(def.space, self.mk_param_from_def(def));
2590         }
2591
2592         let free_id_outlive = self.region_maps.item_extent(free_id);
2593
2594         // map bound 'a => free 'a
2595         let mut regions = VecPerParamSpace::empty();
2596         for def in generics.regions.as_slice() {
2597             let region =
2598                 ReFree(FreeRegion { scope: free_id_outlive,
2599                                     bound_region: BrNamed(def.def_id, def.name) });
2600             debug!("push_region_params {:?}", region);
2601             regions.push(def.space, region);
2602         }
2603
2604         Substs {
2605             types: types,
2606             regions: subst::NonerasedRegions(regions)
2607         }
2608     }
2609
2610     /// See `ParameterEnvironment` struct def'n for details
2611     pub fn construct_parameter_environment<'a>(&'a self,
2612                                                span: Span,
2613                                                generics: &ty::Generics<'tcx>,
2614                                                generic_predicates: &ty::GenericPredicates<'tcx>,
2615                                                free_id: NodeId)
2616                                                -> ParameterEnvironment<'a, 'tcx>
2617     {
2618         //
2619         // Construct the free substs.
2620         //
2621
2622         let free_substs = self.construct_free_substs(generics, free_id);
2623         let free_id_outlive = self.region_maps.item_extent(free_id);
2624
2625         //
2626         // Compute the bounds on Self and the type parameters.
2627         //
2628
2629         let bounds = generic_predicates.instantiate(self, &free_substs);
2630         let bounds = self.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds));
2631         let predicates = bounds.predicates.into_vec();
2632
2633         debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
2634                free_id,
2635                free_substs,
2636                predicates);
2637
2638         //
2639         // Finally, we have to normalize the bounds in the environment, in
2640         // case they contain any associated type projections. This process
2641         // can yield errors if the put in illegal associated types, like
2642         // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
2643         // report these errors right here; this doesn't actually feel
2644         // right to me, because constructing the environment feels like a
2645         // kind of a "idempotent" action, but I'm not sure where would be
2646         // a better place. In practice, we construct environments for
2647         // every fn once during type checking, and we'll abort if there
2648         // are any errors at that point, so after type checking you can be
2649         // sure that this will succeed without errors anyway.
2650         //
2651
2652         let unnormalized_env = ty::ParameterEnvironment {
2653             tcx: self,
2654             free_substs: free_substs,
2655             implicit_region_bound: ty::ReScope(free_id_outlive),
2656             caller_bounds: predicates,
2657             selection_cache: traits::SelectionCache::new(),
2658             free_id: free_id,
2659         };
2660
2661         let cause = traits::ObligationCause::misc(span, free_id);
2662         traits::normalize_param_env_or_error(unnormalized_env, cause)
2663     }
2664
2665     pub fn is_method_call(&self, expr_id: NodeId) -> bool {
2666         self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id))
2667     }
2668
2669     pub fn is_overloaded_autoderef(&self, expr_id: NodeId, autoderefs: u32) -> bool {
2670         self.tables.borrow().method_map.contains_key(&MethodCall::autoderef(expr_id,
2671                                                                             autoderefs))
2672     }
2673
2674     pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
2675         Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
2676     }
2677 }
2678
2679 /// The category of explicit self.
2680 #[derive(Clone, Copy, Eq, PartialEq, Debug)]
2681 pub enum ExplicitSelfCategory {
2682     StaticExplicitSelfCategory,
2683     ByValueExplicitSelfCategory,
2684     ByReferenceExplicitSelfCategory(Region, hir::Mutability),
2685     ByBoxExplicitSelfCategory,
2686 }
2687
2688 /// A free variable referred to in a function.
2689 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
2690 pub struct Freevar {
2691     /// The variable being accessed free.
2692     pub def: def::Def,
2693
2694     // First span where it is accessed (there can be multiple).
2695     pub span: Span
2696 }
2697
2698 pub type FreevarMap = NodeMap<Vec<Freevar>>;
2699
2700 pub type CaptureModeMap = NodeMap<hir::CaptureClause>;
2701
2702 // Trait method resolution
2703 pub type TraitMap = NodeMap<Vec<DefId>>;
2704
2705 // Map from the NodeId of a glob import to a list of items which are actually
2706 // imported.
2707 pub type GlobMap = HashMap<NodeId, HashSet<Name>>;
2708
2709 impl<'tcx> ctxt<'tcx> {
2710     pub fn with_freevars<T, F>(&self, fid: NodeId, f: F) -> T where
2711         F: FnOnce(&[Freevar]) -> T,
2712     {
2713         match self.freevars.borrow().get(&fid) {
2714             None => f(&[]),
2715             Some(d) => f(&d[..])
2716         }
2717     }
2718
2719     pub fn make_substs_for_receiver_types(&self,
2720                                           trait_ref: &ty::TraitRef<'tcx>,
2721                                           method: &ty::Method<'tcx>)
2722                                           -> subst::Substs<'tcx>
2723     {
2724         /*!
2725          * Substitutes the values for the receiver's type parameters
2726          * that are found in method, leaving the method's type parameters
2727          * intact.
2728          */
2729
2730         let meth_tps: Vec<Ty> =
2731             method.generics.types.get_slice(subst::FnSpace)
2732                   .iter()
2733                   .map(|def| self.mk_param_from_def(def))
2734                   .collect();
2735         let meth_regions: Vec<ty::Region> =
2736             method.generics.regions.get_slice(subst::FnSpace)
2737                   .iter()
2738                   .map(|def| def.to_early_bound_region())
2739                   .collect();
2740         trait_ref.substs.clone().with_method(meth_tps, meth_regions)
2741     }
2742 }
2743
2744 /// An "escaping region" is a bound region whose binder is not part of `t`.
2745 ///
2746 /// So, for example, consider a type like the following, which has two binders:
2747 ///
2748 ///    for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
2749 ///    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
2750 ///                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~  inner scope
2751 ///
2752 /// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
2753 /// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
2754 /// fn type*, that type has an escaping region: `'a`.
2755 ///
2756 /// Note that what I'm calling an "escaping region" is often just called a "free region". However,
2757 /// we already use the term "free region". It refers to the regions that we use to represent bound
2758 /// regions on a fn definition while we are typechecking its body.
2759 ///
2760 /// To clarify, conceptually there is no particular difference between an "escaping" region and a
2761 /// "free" region. However, there is a big difference in practice. Basically, when "entering" a
2762 /// binding level, one is generally required to do some sort of processing to a bound region, such
2763 /// as replacing it with a fresh/skolemized region, or making an entry in the environment to
2764 /// represent the scope to which it is attached, etc. An escaping region represents a bound region
2765 /// for which this processing has not yet been done.
2766 pub trait RegionEscape {
2767     fn has_escaping_regions(&self) -> bool {
2768         self.has_regions_escaping_depth(0)
2769     }
2770
2771     fn has_regions_escaping_depth(&self, depth: u32) -> bool;
2772 }
2773
2774 pub trait HasTypeFlags {
2775     fn has_type_flags(&self, flags: TypeFlags) -> bool;
2776     fn has_projection_types(&self) -> bool {
2777         self.has_type_flags(TypeFlags::HAS_PROJECTION)
2778     }
2779     fn references_error(&self) -> bool {
2780         self.has_type_flags(TypeFlags::HAS_TY_ERR)
2781     }
2782     fn has_param_types(&self) -> bool {
2783         self.has_type_flags(TypeFlags::HAS_PARAMS)
2784     }
2785     fn has_self_ty(&self) -> bool {
2786         self.has_type_flags(TypeFlags::HAS_SELF)
2787     }
2788     fn has_infer_types(&self) -> bool {
2789         self.has_type_flags(TypeFlags::HAS_TY_INFER)
2790     }
2791     fn needs_infer(&self) -> bool {
2792         self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
2793     }
2794     fn needs_subst(&self) -> bool {
2795         self.has_type_flags(TypeFlags::NEEDS_SUBST)
2796     }
2797     fn has_closure_types(&self) -> bool {
2798         self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
2799     }
2800     fn has_erasable_regions(&self) -> bool {
2801         self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND |
2802                             TypeFlags::HAS_RE_INFER |
2803                             TypeFlags::HAS_FREE_REGIONS)
2804     }
2805     /// Indicates whether this value references only 'global'
2806     /// types/lifetimes that are the same regardless of what fn we are
2807     /// in. This is used for caching. Errs on the side of returning
2808     /// false.
2809     fn is_global(&self) -> bool {
2810         !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES)
2811     }
2812 }