]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/ty.rs
3497a8d690479b78a90749692003fa0b292c5fc6
[rust.git] / src / librustc / middle / ty.rs
1 // Copyright 2012-2014 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 #![allow(non_camel_case_types)]
12
13 pub use self::terr_vstore_kind::*;
14 pub use self::type_err::*;
15 pub use self::InferTy::*;
16 pub use self::InferRegion::*;
17 pub use self::ImplOrTraitItemId::*;
18 pub use self::ClosureKind::*;
19 pub use self::Variance::*;
20 pub use self::AutoAdjustment::*;
21 pub use self::Representability::*;
22 pub use self::AutoRef::*;
23 pub use self::DtorKind::*;
24 pub use self::ExplicitSelfCategory::*;
25 pub use self::FnOutput::*;
26 pub use self::Region::*;
27 pub use self::ImplOrTraitItemContainer::*;
28 pub use self::BorrowKind::*;
29 pub use self::ImplOrTraitItem::*;
30 pub use self::BoundRegion::*;
31 pub use self::TypeVariants::*;
32 pub use self::IntVarValue::*;
33 pub use self::MethodOrigin::*;
34 pub use self::CopyImplementationError::*;
35
36 pub use self::BuiltinBound::Send as BoundSend;
37 pub use self::BuiltinBound::Sized as BoundSized;
38 pub use self::BuiltinBound::Copy as BoundCopy;
39 pub use self::BuiltinBound::Sync as BoundSync;
40
41 use ast_map::{self, LinkedPath};
42 use back::svh::Svh;
43 use session::Session;
44 use lint;
45 use metadata::csearch;
46 use middle;
47 use middle::cast;
48 use middle::check_const;
49 use middle::const_eval;
50 use middle::def::{self, DefMap, ExportMap};
51 use middle::dependency_format;
52 use middle::fast_reject;
53 use middle::free_region::FreeRegionMap;
54 use middle::infer::error_reporting::note_and_explain_region;
55 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
56 use middle::mem_categorization as mc;
57 use middle::region;
58 use middle::resolve_lifetime;
59 use middle::infer;
60 use middle::pat_util;
61 use middle::region::RegionMaps;
62 use middle::stability;
63 use middle::subst::{self, ParamSpace, Subst, Substs, VecPerParamSpace};
64 use middle::traits;
65 use middle::ty;
66 use middle::ty_fold::{self, TypeFoldable, TypeFolder};
67 use middle::ty_walk::{self, TypeWalker};
68 use util::common::{memoized, ErrorReported};
69 use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
70 use util::nodemap::FnvHashMap;
71 use util::num::ToPrimitive;
72
73 use arena::TypedArena;
74 use std::borrow::{Borrow, Cow};
75 use std::cell::{Cell, RefCell, Ref};
76 use std::cmp;
77 use std::fmt;
78 use std::hash::{Hash, SipHasher, Hasher};
79 use std::mem;
80 use std::ops;
81 use std::rc::Rc;
82 use std::vec::IntoIter;
83 use collections::enum_set::{self, EnumSet, CLike};
84 use std::collections::{HashMap, HashSet};
85 use syntax::abi;
86 use syntax::ast::{CrateNum, DefId, ItemImpl, ItemTrait, LOCAL_CRATE};
87 use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
88 use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility};
89 use syntax::ast_util::{self, is_local, local_def};
90 use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
91 use syntax::codemap::Span;
92 use syntax::parse::token::{self, InternedString, special_idents};
93 use syntax::print::pprust;
94 use syntax::ptr::P;
95 use syntax::ast;
96
97 pub type Disr = u64;
98
99 pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
100
101 // Data types
102
103 /// The complete set of all analyses described in this module. This is
104 /// produced by the driver and fed to trans and later passes.
105 pub struct CrateAnalysis {
106     pub export_map: ExportMap,
107     pub exported_items: middle::privacy::ExportedItems,
108     pub public_items: middle::privacy::PublicItems,
109     pub reachable: NodeSet,
110     pub name: String,
111     pub glob_map: Option<GlobMap>,
112 }
113
114 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
115 pub struct field<'tcx> {
116     pub name: ast::Name,
117     pub mt: mt<'tcx>
118 }
119
120 #[derive(Clone, Copy, Debug)]
121 pub enum ImplOrTraitItemContainer {
122     TraitContainer(ast::DefId),
123     ImplContainer(ast::DefId),
124 }
125
126 impl ImplOrTraitItemContainer {
127     pub fn id(&self) -> ast::DefId {
128         match *self {
129             TraitContainer(id) => id,
130             ImplContainer(id) => id,
131         }
132     }
133 }
134
135 #[derive(Clone)]
136 pub enum ImplOrTraitItem<'tcx> {
137     ConstTraitItem(Rc<AssociatedConst<'tcx>>),
138     MethodTraitItem(Rc<Method<'tcx>>),
139     TypeTraitItem(Rc<AssociatedType<'tcx>>),
140 }
141
142 impl<'tcx> ImplOrTraitItem<'tcx> {
143     fn id(&self) -> ImplOrTraitItemId {
144         match *self {
145             ConstTraitItem(ref associated_const) => {
146                 ConstTraitItemId(associated_const.def_id)
147             }
148             MethodTraitItem(ref method) => MethodTraitItemId(method.def_id),
149             TypeTraitItem(ref associated_type) => {
150                 TypeTraitItemId(associated_type.def_id)
151             }
152         }
153     }
154
155     pub fn def_id(&self) -> ast::DefId {
156         match *self {
157             ConstTraitItem(ref associated_const) => associated_const.def_id,
158             MethodTraitItem(ref method) => method.def_id,
159             TypeTraitItem(ref associated_type) => associated_type.def_id,
160         }
161     }
162
163     pub fn name(&self) -> ast::Name {
164         match *self {
165             ConstTraitItem(ref associated_const) => associated_const.name,
166             MethodTraitItem(ref method) => method.name,
167             TypeTraitItem(ref associated_type) => associated_type.name,
168         }
169     }
170
171     pub fn vis(&self) -> ast::Visibility {
172         match *self {
173             ConstTraitItem(ref associated_const) => associated_const.vis,
174             MethodTraitItem(ref method) => method.vis,
175             TypeTraitItem(ref associated_type) => associated_type.vis,
176         }
177     }
178
179     pub fn container(&self) -> ImplOrTraitItemContainer {
180         match *self {
181             ConstTraitItem(ref associated_const) => associated_const.container,
182             MethodTraitItem(ref method) => method.container,
183             TypeTraitItem(ref associated_type) => associated_type.container,
184         }
185     }
186
187     pub fn as_opt_method(&self) -> Option<Rc<Method<'tcx>>> {
188         match *self {
189             MethodTraitItem(ref m) => Some((*m).clone()),
190             _ => None,
191         }
192     }
193 }
194
195 #[derive(Clone, Copy, Debug)]
196 pub enum ImplOrTraitItemId {
197     ConstTraitItemId(ast::DefId),
198     MethodTraitItemId(ast::DefId),
199     TypeTraitItemId(ast::DefId),
200 }
201
202 impl ImplOrTraitItemId {
203     pub fn def_id(&self) -> ast::DefId {
204         match *self {
205             ConstTraitItemId(def_id) => def_id,
206             MethodTraitItemId(def_id) => def_id,
207             TypeTraitItemId(def_id) => def_id,
208         }
209     }
210 }
211
212 #[derive(Clone, Debug)]
213 pub struct Method<'tcx> {
214     pub name: ast::Name,
215     pub generics: Generics<'tcx>,
216     pub predicates: GenericPredicates<'tcx>,
217     pub fty: BareFnTy<'tcx>,
218     pub explicit_self: ExplicitSelfCategory,
219     pub vis: ast::Visibility,
220     pub def_id: ast::DefId,
221     pub container: ImplOrTraitItemContainer,
222
223     // If this method is provided, we need to know where it came from
224     pub provided_source: Option<ast::DefId>
225 }
226
227 impl<'tcx> Method<'tcx> {
228     pub fn new(name: ast::Name,
229                generics: ty::Generics<'tcx>,
230                predicates: GenericPredicates<'tcx>,
231                fty: BareFnTy<'tcx>,
232                explicit_self: ExplicitSelfCategory,
233                vis: ast::Visibility,
234                def_id: ast::DefId,
235                container: ImplOrTraitItemContainer,
236                provided_source: Option<ast::DefId>)
237                -> Method<'tcx> {
238        Method {
239             name: name,
240             generics: generics,
241             predicates: predicates,
242             fty: fty,
243             explicit_self: explicit_self,
244             vis: vis,
245             def_id: def_id,
246             container: container,
247             provided_source: provided_source
248         }
249     }
250
251     pub fn container_id(&self) -> ast::DefId {
252         match self.container {
253             TraitContainer(id) => id,
254             ImplContainer(id) => id,
255         }
256     }
257 }
258
259 #[derive(Clone, Copy, Debug)]
260 pub struct AssociatedConst<'tcx> {
261     pub name: ast::Name,
262     pub ty: Ty<'tcx>,
263     pub vis: ast::Visibility,
264     pub def_id: ast::DefId,
265     pub container: ImplOrTraitItemContainer,
266     pub default: Option<ast::DefId>,
267 }
268
269 #[derive(Clone, Copy, Debug)]
270 pub struct AssociatedType<'tcx> {
271     pub name: ast::Name,
272     pub ty: Option<Ty<'tcx>>,
273     pub vis: ast::Visibility,
274     pub def_id: ast::DefId,
275     pub container: ImplOrTraitItemContainer,
276 }
277
278 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
279 pub struct mt<'tcx> {
280     pub ty: Ty<'tcx>,
281     pub mutbl: ast::Mutability,
282 }
283
284 #[derive(Clone, Copy, Debug)]
285 pub struct field_ty {
286     pub name: Name,
287     pub id: DefId,
288     pub vis: ast::Visibility,
289     pub origin: ast::DefId,  // The DefId of the struct in which the field is declared.
290 }
291
292 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
293 pub struct ItemVariances {
294     pub types: VecPerParamSpace<Variance>,
295     pub regions: VecPerParamSpace<Variance>,
296 }
297
298 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
299 pub enum Variance {
300     Covariant,      // T<A> <: T<B> iff A <: B -- e.g., function return type
301     Invariant,      // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
302     Contravariant,  // T<A> <: T<B> iff B <: A -- e.g., function param type
303     Bivariant,      // T<A> <: T<B>            -- e.g., unused type parameter
304 }
305
306 #[derive(Copy, Clone)]
307 pub enum AutoAdjustment<'tcx> {
308     AdjustReifyFnPointer,   // go from a fn-item type to a fn-pointer type
309     AdjustUnsafeFnPointer,  // go from a safe fn pointer to an unsafe fn pointer
310     AdjustDerefRef(AutoDerefRef<'tcx>),
311 }
312
313 /// Represents coercing a pointer to a different kind of pointer - where 'kind'
314 /// here means either or both of raw vs borrowed vs unique and fat vs thin.
315 ///
316 /// We transform pointers by following the following steps in order:
317 /// 1. Deref the pointer `self.autoderefs` times (may be 0).
318 /// 2. If `autoref` is `Some(_)`, then take the address and produce either a
319 ///    `&` or `*` pointer.
320 /// 3. If `unsize` is `Some(_)`, then apply the unsize transformation,
321 ///    which will do things like convert thin pointers to fat
322 ///    pointers, or convert structs containing thin pointers to
323 ///    structs containing fat pointers, or convert between fat
324 ///    pointers.  We don't store the details of how the transform is
325 ///    done (in fact, we don't know that, because it might depend on
326 ///    the precise type parameters). We just store the target
327 ///    type. Trans figures out what has to be done at monomorphization
328 ///    time based on the precise source/target type at hand.
329 ///
330 /// To make that more concrete, here are some common scenarios:
331 ///
332 /// 1. The simplest cases are where the pointer is not adjusted fat vs thin.
333 /// Here the pointer will be dereferenced N times (where a dereference can
334 /// happen to to raw or borrowed pointers or any smart pointer which implements
335 /// Deref, including Box<_>). The number of dereferences is given by
336 /// `autoderefs`.  It can then be auto-referenced zero or one times, indicated
337 /// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
338 /// None.
339 ///
340 /// 2. A thin-to-fat coercon involves unsizing the underlying data. We start
341 /// with a thin pointer, deref a number of times, unsize the underlying data,
342 /// then autoref. The 'unsize' phase may change a fixed length array to a
343 /// dynamically sized one, a concrete object to a trait object, or statically
344 /// sized struct to a dyncamically sized one. E.g., &[i32; 4] -> &[i32] is
345 /// represented by:
346 ///
347 /// ```
348 /// AutoDerefRef {
349 ///     autoderefs: 1,          // &[i32; 4] -> [i32; 4]
350 ///     autoref: Some(AutoPtr), // [i32] -> &[i32]
351 ///     unsize: Some([i32]),    // [i32; 4] -> [i32]
352 /// }
353 /// ```
354 ///
355 /// Note that for a struct, the 'deep' unsizing of the struct is not recorded.
356 /// E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
357 /// The autoderef and -ref are the same as in the above example, but the type
358 /// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
359 /// the underlying conversions from `[i32; 4]` to `[i32]`.
360 ///
361 /// 3. Coercing a `Box<T>` to `Box<Trait>` is an interesting special case.  In
362 /// that case, we have the pointer we need coming in, so there are no
363 /// autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
364 /// At some point, of course, `Box` should move out of the compiler, in which
365 /// case this is analogous to transformating a struct. E.g., Box<[i32; 4]> ->
366 /// Box<[i32]> is represented by:
367 ///
368 /// ```
369 /// AutoDerefRef {
370 ///     autoderefs: 0,
371 ///     autoref: None,
372 ///     unsize: Some(Box<[i32]>),
373 /// }
374 /// ```
375 #[derive(Copy, Clone)]
376 pub struct AutoDerefRef<'tcx> {
377     /// Step 1. Apply a number of dereferences, producing an lvalue.
378     pub autoderefs: usize,
379
380     /// Step 2. Optionally produce a pointer/reference from the value.
381     pub autoref: Option<AutoRef<'tcx>>,
382
383     /// Step 3. Unsize a pointer/reference value, e.g. `&[T; n]` to
384     /// `&[T]`. The stored type is the target pointer type. Note that
385     /// the source could be a thin or fat pointer.
386     pub unsize: Option<Ty<'tcx>>,
387 }
388
389 #[derive(Copy, Clone, PartialEq, Debug)]
390 pub enum AutoRef<'tcx> {
391     /// Convert from T to &T.
392     AutoPtr(&'tcx Region, ast::Mutability),
393
394     /// Convert from T to *T.
395     /// Value to thin pointer.
396     AutoUnsafe(ast::Mutability),
397 }
398
399 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
400 pub enum CustomCoerceUnsized {
401     /// Records the index of the field being coerced.
402     Struct(usize)
403 }
404
405 #[derive(Clone)]
406 pub enum MethodOrigin<'tcx> {
407     // fully statically resolved method
408     MethodStatic(ast::DefId),
409
410     // fully statically resolved closure invocation
411     MethodStaticClosure(ast::DefId),
412
413     // method invoked on a type parameter with a bounded trait
414     MethodTypeParam(MethodParam<'tcx>),
415
416     // method invoked on a trait instance
417     MethodTraitObject(MethodObject<'tcx>),
418
419 }
420
421 // details for a method invoked with a receiver whose type is a type parameter
422 // with a bounded trait.
423 #[derive(Clone)]
424 pub struct MethodParam<'tcx> {
425     // the precise trait reference that occurs as a bound -- this may
426     // be a supertrait of what the user actually typed. Note that it
427     // never contains bound regions; those regions should have been
428     // instantiated with fresh variables at this point.
429     pub trait_ref: ty::TraitRef<'tcx>,
430
431     // index of usize in the list of trait items. Note that this is NOT
432     // the index into the vtable, because the list of trait items
433     // includes associated types.
434     pub method_num: usize,
435
436     /// The impl for the trait from which the method comes. This
437     /// should only be used for certain linting/heuristic purposes
438     /// since there is no guarantee that this is Some in every
439     /// situation that it could/should be.
440     pub impl_def_id: Option<ast::DefId>,
441 }
442
443 // details for a method invoked with a receiver whose type is an object
444 #[derive(Clone)]
445 pub struct MethodObject<'tcx> {
446     // the (super)trait containing the method to be invoked
447     pub trait_ref: TraitRef<'tcx>,
448
449     // the actual base trait id of the object
450     pub object_trait_id: ast::DefId,
451
452     // index of the method to be invoked amongst the trait's items
453     pub method_num: usize,
454
455     // index into the actual runtime vtable.
456     // the vtable is formed by concatenating together the method lists of
457     // the base object trait and all supertraits; this is the index into
458     // that vtable
459     pub vtable_index: usize,
460 }
461
462 #[derive(Clone, Debug)]
463 pub struct MethodCallee<'tcx> {
464     pub origin: MethodOrigin<'tcx>,
465     pub ty: Ty<'tcx>,
466     pub substs: subst::Substs<'tcx>
467 }
468
469 /// With method calls, we store some extra information in
470 /// side tables (i.e method_map). We use
471 /// MethodCall as a key to index into these tables instead of
472 /// just directly using the expression's NodeId. The reason
473 /// for this being that we may apply adjustments (coercions)
474 /// with the resulting expression also needing to use the
475 /// side tables. The problem with this is that we don't
476 /// assign a separate NodeId to this new expression
477 /// and so it would clash with the base expression if both
478 /// needed to add to the side tables. Thus to disambiguate
479 /// we also keep track of whether there's an adjustment in
480 /// our key.
481 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
482 pub struct MethodCall {
483     pub expr_id: ast::NodeId,
484     pub autoderef: u32
485 }
486
487 impl MethodCall {
488     pub fn expr(id: ast::NodeId) -> MethodCall {
489         MethodCall {
490             expr_id: id,
491             autoderef: 0
492         }
493     }
494
495     pub fn autoderef(expr_id: ast::NodeId, autoderef: u32) -> MethodCall {
496         MethodCall {
497             expr_id: expr_id,
498             autoderef: 1 + autoderef
499         }
500     }
501 }
502
503 // maps from an expression id that corresponds to a method call to the details
504 // of the method to be invoked
505 pub type MethodMap<'tcx> = RefCell<FnvHashMap<MethodCall, MethodCallee<'tcx>>>;
506
507 // Contains information needed to resolve types and (in the future) look up
508 // the types of AST nodes.
509 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
510 pub struct creader_cache_key {
511     pub cnum: CrateNum,
512     pub pos: usize,
513     pub len: usize
514 }
515
516 /// A restriction that certain types must be the same size. The use of
517 /// `transmute` gives rise to these restrictions. These generally
518 /// cannot be checked until trans; therefore, each call to `transmute`
519 /// will push one or more such restriction into the
520 /// `transmute_restrictions` vector during `intrinsicck`. They are
521 /// then checked during `trans` by the fn `check_intrinsics`.
522 #[derive(Copy, Clone)]
523 pub struct TransmuteRestriction<'tcx> {
524     /// The span whence the restriction comes.
525     pub span: Span,
526
527     /// The type being transmuted from.
528     pub original_from: Ty<'tcx>,
529
530     /// The type being transmuted to.
531     pub original_to: Ty<'tcx>,
532
533     /// The type being transmuted from, with all type parameters
534     /// substituted for an arbitrary representative. Not to be shown
535     /// to the end user.
536     pub substituted_from: Ty<'tcx>,
537
538     /// The type being transmuted to, with all type parameters
539     /// substituted for an arbitrary representative. Not to be shown
540     /// to the end user.
541     pub substituted_to: Ty<'tcx>,
542
543     /// NodeId of the transmute intrinsic.
544     pub id: ast::NodeId,
545 }
546
547 /// Internal storage
548 pub struct CtxtArenas<'tcx> {
549     // internings
550     type_: TypedArena<TyS<'tcx>>,
551     substs: TypedArena<Substs<'tcx>>,
552     bare_fn: TypedArena<BareFnTy<'tcx>>,
553     region: TypedArena<Region>,
554     stability: TypedArena<attr::Stability>,
555
556     // references
557     trait_defs: TypedArena<TraitDef<'tcx>>,
558 }
559
560 impl<'tcx> CtxtArenas<'tcx> {
561     pub fn new() -> CtxtArenas<'tcx> {
562         CtxtArenas {
563             type_: TypedArena::new(),
564             substs: TypedArena::new(),
565             bare_fn: TypedArena::new(),
566             region: TypedArena::new(),
567             stability: TypedArena::new(),
568
569             trait_defs: TypedArena::new()
570         }
571     }
572 }
573
574 pub struct CommonTypes<'tcx> {
575     pub bool: Ty<'tcx>,
576     pub char: Ty<'tcx>,
577     pub isize: Ty<'tcx>,
578     pub i8: Ty<'tcx>,
579     pub i16: Ty<'tcx>,
580     pub i32: Ty<'tcx>,
581     pub i64: Ty<'tcx>,
582     pub usize: Ty<'tcx>,
583     pub u8: Ty<'tcx>,
584     pub u16: Ty<'tcx>,
585     pub u32: Ty<'tcx>,
586     pub u64: Ty<'tcx>,
587     pub f32: Ty<'tcx>,
588     pub f64: Ty<'tcx>,
589     pub err: Ty<'tcx>,
590 }
591
592 /// The data structure to keep track of all the information that typechecker
593 /// generates so that so that it can be reused and doesn't have to be redone
594 /// later on.
595 pub struct ctxt<'tcx> {
596     /// The arenas that types etc are allocated from.
597     arenas: &'tcx CtxtArenas<'tcx>,
598
599     /// Specifically use a speedy hash algorithm for this hash map, it's used
600     /// quite often.
601     // FIXME(eddyb) use a FnvHashSet<InternedTy<'tcx>> when equivalent keys can
602     // queried from a HashSet.
603     interner: RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>,
604
605     // FIXME as above, use a hashset if equivalent elements can be queried.
606     substs_interner: RefCell<FnvHashMap<&'tcx Substs<'tcx>, &'tcx Substs<'tcx>>>,
607     bare_fn_interner: RefCell<FnvHashMap<&'tcx BareFnTy<'tcx>, &'tcx BareFnTy<'tcx>>>,
608     region_interner: RefCell<FnvHashMap<&'tcx Region, &'tcx Region>>,
609     stability_interner: RefCell<FnvHashMap<&'tcx attr::Stability, &'tcx attr::Stability>>,
610
611     /// Common types, pre-interned for your convenience.
612     pub types: CommonTypes<'tcx>,
613
614     pub sess: Session,
615     pub def_map: DefMap,
616
617     pub named_region_map: resolve_lifetime::NamedRegionMap,
618
619     pub region_maps: RegionMaps,
620
621     // For each fn declared in the local crate, type check stores the
622     // free-region relationships that were deduced from its where
623     // clauses and parameter types. These are then read-again by
624     // borrowck. (They are not used during trans, and hence are not
625     // serialized or needed for cross-crate fns.)
626     free_region_maps: RefCell<NodeMap<FreeRegionMap>>,
627
628     /// Stores the types for various nodes in the AST.  Note that this table
629     /// is not guaranteed to be populated until after typeck.  See
630     /// typeck::check::fn_ctxt for details.
631     node_types: RefCell<NodeMap<Ty<'tcx>>>,
632
633     /// Stores the type parameters which were substituted to obtain the type
634     /// of this node.  This only applies to nodes that refer to entities
635     /// parameterized by type parameters, such as generic fns, types, or
636     /// other items.
637     pub item_substs: RefCell<NodeMap<ItemSubsts<'tcx>>>,
638
639     /// Maps from a trait item to the trait item "descriptor"
640     pub impl_or_trait_items: RefCell<DefIdMap<ImplOrTraitItem<'tcx>>>,
641
642     /// Maps from a trait def-id to a list of the def-ids of its trait items
643     pub trait_item_def_ids: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItemId>>>>,
644
645     /// A cache for the trait_items() routine
646     pub trait_items_cache: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItem<'tcx>>>>>,
647
648     pub impl_trait_refs: RefCell<DefIdMap<Option<TraitRef<'tcx>>>>,
649     pub trait_defs: RefCell<DefIdMap<&'tcx TraitDef<'tcx>>>,
650
651     /// Maps from the def-id of an item (trait/struct/enum/fn) to its
652     /// associated predicates.
653     pub predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
654
655     /// Maps from the def-id of a trait to the list of
656     /// super-predicates. This is a subset of the full list of
657     /// predicates. We store these in a separate map because we must
658     /// evaluate them even during type conversion, often before the
659     /// full predicates are available (note that supertraits have
660     /// additional acyclicity requirements).
661     pub super_predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
662
663     pub map: ast_map::Map<'tcx>,
664     pub freevars: RefCell<FreevarMap>,
665     pub tcache: RefCell<DefIdMap<TypeScheme<'tcx>>>,
666     pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
667     pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, TypeContents>>,
668     pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
669     pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
670     pub ty_param_defs: RefCell<NodeMap<TypeParameterDef<'tcx>>>,
671     pub adjustments: RefCell<NodeMap<AutoAdjustment<'tcx>>>,
672     pub normalized_cache: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
673     pub lang_items: middle::lang_items::LanguageItems,
674     /// A mapping of fake provided method def_ids to the default implementation
675     pub provided_method_sources: RefCell<DefIdMap<ast::DefId>>,
676     pub struct_fields: RefCell<DefIdMap<Rc<Vec<field_ty>>>>,
677
678     /// Maps from def-id of a type or region parameter to its
679     /// (inferred) variance.
680     pub item_variance_map: RefCell<DefIdMap<Rc<ItemVariances>>>,
681
682     /// True if the variance has been computed yet; false otherwise.
683     pub variance_computed: Cell<bool>,
684
685     /// A mapping from the def ID of an enum or struct type to the def ID
686     /// of the method that implements its destructor. If the type is not
687     /// present in this map, it does not have a destructor. This map is
688     /// populated during the coherence phase of typechecking.
689     pub destructor_for_type: RefCell<DefIdMap<ast::DefId>>,
690
691     /// A method will be in this list if and only if it is a destructor.
692     pub destructors: RefCell<DefIdSet>,
693
694     /// Maps a DefId of a type to a list of its inherent impls.
695     /// Contains implementations of methods that are inherent to a type.
696     /// Methods in these implementations don't need to be exported.
697     pub inherent_impls: RefCell<DefIdMap<Rc<Vec<ast::DefId>>>>,
698
699     /// Maps a DefId of an impl to a list of its items.
700     /// Note that this contains all of the impls that we know about,
701     /// including ones in other crates. It's not clear that this is the best
702     /// way to do it.
703     pub impl_items: RefCell<DefIdMap<Vec<ImplOrTraitItemId>>>,
704
705     /// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
706     /// present in this set can be warned about.
707     pub used_unsafe: RefCell<NodeSet>,
708
709     /// Set of nodes which mark locals as mutable which end up getting used at
710     /// some point. Local variable definitions not in this set can be warned
711     /// about.
712     pub used_mut_nodes: RefCell<NodeSet>,
713
714     /// The set of external nominal types whose implementations have been read.
715     /// This is used for lazy resolution of methods.
716     pub populated_external_types: RefCell<DefIdSet>,
717     /// The set of external primitive types whose implementations have been read.
718     /// FIXME(arielb1): why is this separate from populated_external_types?
719     pub populated_external_primitive_impls: RefCell<DefIdSet>,
720
721     /// Borrows
722     pub upvar_capture_map: RefCell<UpvarCaptureMap>,
723
724     /// These caches are used by const_eval when decoding external constants.
725     pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
726     pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
727     pub extern_const_fns: RefCell<DefIdMap<ast::NodeId>>,
728
729     pub method_map: MethodMap<'tcx>,
730
731     pub dependency_formats: RefCell<dependency_format::Dependencies>,
732
733     /// Records the type of each closure. The def ID is the ID of the
734     /// expression defining the closure.
735     pub closure_kinds: RefCell<DefIdMap<ClosureKind>>,
736
737     /// Records the type of each closure. The def ID is the ID of the
738     /// expression defining the closure.
739     pub closure_tys: RefCell<DefIdMap<ClosureTy<'tcx>>>,
740
741     pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
742                                               lint::LevelSource>>,
743
744     /// The types that must be asserted to be the same size for `transmute`
745     /// to be valid. We gather up these restrictions in the intrinsicck pass
746     /// and check them in trans.
747     pub transmute_restrictions: RefCell<Vec<TransmuteRestriction<'tcx>>>,
748
749     /// Maps any item's def-id to its stability index.
750     pub stability: RefCell<stability::Index<'tcx>>,
751
752     /// Caches the results of trait selection. This cache is used
753     /// for things that do not have to do with the parameters in scope.
754     pub selection_cache: traits::SelectionCache<'tcx>,
755
756     /// A set of predicates that have been fulfilled *somewhere*.
757     /// This is used to avoid duplicate work. Predicates are only
758     /// added to this set when they mention only "global" names
759     /// (i.e., no type or lifetime parameters).
760     pub fulfilled_predicates: RefCell<traits::FulfilledPredicates<'tcx>>,
761
762     /// Caches the representation hints for struct definitions.
763     pub repr_hint_cache: RefCell<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
764
765     /// Maps Expr NodeId's to their constant qualification.
766     pub const_qualif_map: RefCell<NodeMap<check_const::ConstQualif>>,
767
768     /// Caches CoerceUnsized kinds for impls on custom types.
769     pub custom_coerce_unsized_kinds: RefCell<DefIdMap<CustomCoerceUnsized>>,
770
771     /// Maps a cast expression to its kind. This is keyed on the
772     /// *from* expression of the cast, not the cast itself.
773     pub cast_kinds: RefCell<NodeMap<cast::CastKind>>,
774 }
775
776 impl<'tcx> ctxt<'tcx> {
777     pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> { self.node_types.borrow() }
778     pub fn node_type_insert(&self, id: NodeId, ty: Ty<'tcx>) {
779         self.node_types.borrow_mut().insert(id, ty);
780     }
781
782     pub fn intern_trait_def(&self, def: TraitDef<'tcx>) -> &'tcx TraitDef<'tcx> {
783         let did = def.trait_ref.def_id;
784         let interned = self.arenas.trait_defs.alloc(def);
785         self.trait_defs.borrow_mut().insert(did, interned);
786         interned
787     }
788
789     pub fn intern_stability(&self, stab: attr::Stability) -> &'tcx attr::Stability {
790         if let Some(st) = self.stability_interner.borrow().get(&stab) {
791             return st;
792         }
793
794         let interned = self.arenas.stability.alloc(stab);
795         self.stability_interner.borrow_mut().insert(interned, interned);
796         interned
797     }
798
799     pub fn store_free_region_map(&self, id: NodeId, map: FreeRegionMap) {
800         self.free_region_maps.borrow_mut()
801                              .insert(id, map);
802     }
803
804     pub fn free_region_map(&self, id: NodeId) -> FreeRegionMap {
805         self.free_region_maps.borrow()[&id].clone()
806     }
807
808     pub fn lift<T: ?Sized + Lift<'tcx>>(&self, value: &T) -> Option<T::Lifted> {
809         value.lift_to_tcx(self)
810     }
811 }
812
813 /// A trait implemented for all X<'a> types which can be safely and
814 /// efficiently converted to X<'tcx> as long as they are part of the
815 /// provided ty::ctxt<'tcx>.
816 /// This can be done, for example, for Ty<'tcx> or &'tcx Substs<'tcx>
817 /// by looking them up in their respective interners.
818 /// None is returned if the value or one of the components is not part
819 /// of the provided context.
820 /// For Ty, None can be returned if either the type interner doesn't
821 /// contain the TypeVariants key or if the address of the interned
822 /// pointer differs. The latter case is possible if a primitive type,
823 /// e.g. `()` or `u8`, was interned in a different context.
824 pub trait Lift<'tcx> {
825     type Lifted;
826     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted>;
827 }
828
829 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
830     type Lifted = (A::Lifted, B::Lifted);
831     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted> {
832         tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
833     }
834 }
835
836 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
837     type Lifted = Vec<T::Lifted>;
838     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted> {
839         let mut result = Vec::with_capacity(self.len());
840         for x in self {
841             if let Some(value) = tcx.lift(x) {
842                 result.push(value);
843             } else {
844                 return None;
845             }
846         }
847         Some(result)
848     }
849 }
850
851 impl<'tcx> Lift<'tcx> for Region {
852     type Lifted = Self;
853     fn lift_to_tcx(&self, _: &ctxt<'tcx>) -> Option<Region> {
854         Some(*self)
855     }
856 }
857
858 impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
859     type Lifted = Ty<'tcx>;
860     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Ty<'tcx>> {
861         if let Some(&ty) = tcx.interner.borrow().get(&self.sty) {
862             if *self as *const _ == ty as *const _ {
863                 return Some(ty);
864             }
865         }
866         None
867     }
868 }
869
870 impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
871     type Lifted = &'tcx Substs<'tcx>;
872     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<&'tcx Substs<'tcx>> {
873         if let Some(&substs) = tcx.substs_interner.borrow().get(*self) {
874             if *self as *const _ == substs as *const _ {
875                 return Some(substs);
876             }
877         }
878         None
879     }
880 }
881
882 impl<'a, 'tcx> Lift<'tcx> for TraitRef<'a> {
883     type Lifted = TraitRef<'tcx>;
884     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<TraitRef<'tcx>> {
885         tcx.lift(&self.substs).map(|substs| TraitRef {
886             def_id: self.def_id,
887             substs: substs
888         })
889     }
890 }
891
892 impl<'a, 'tcx> Lift<'tcx> for TraitPredicate<'a> {
893     type Lifted = TraitPredicate<'tcx>;
894     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<TraitPredicate<'tcx>> {
895         tcx.lift(&self.trait_ref).map(|trait_ref| TraitPredicate {
896             trait_ref: trait_ref
897         })
898     }
899 }
900
901 impl<'a, 'tcx> Lift<'tcx> for EquatePredicate<'a> {
902     type Lifted = EquatePredicate<'tcx>;
903     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<EquatePredicate<'tcx>> {
904         tcx.lift(&(self.0, self.1)).map(|(a, b)| EquatePredicate(a, b))
905     }
906 }
907
908 impl<'tcx, A: Copy+Lift<'tcx>, B: Copy+Lift<'tcx>> Lift<'tcx> for OutlivesPredicate<A, B> {
909     type Lifted = OutlivesPredicate<A::Lifted, B::Lifted>;
910     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted> {
911         tcx.lift(&(self.0, self.1)).map(|(a, b)| OutlivesPredicate(a, b))
912     }
913 }
914
915 impl<'a, 'tcx> Lift<'tcx> for ProjectionPredicate<'a> {
916     type Lifted = ProjectionPredicate<'tcx>;
917     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<ProjectionPredicate<'tcx>> {
918         tcx.lift(&(self.projection_ty.trait_ref, self.ty)).map(|(trait_ref, ty)| {
919             ProjectionPredicate {
920                 projection_ty: ProjectionTy {
921                     trait_ref: trait_ref,
922                     item_name: self.projection_ty.item_name
923                 },
924                 ty: ty
925             }
926         })
927     }
928 }
929
930 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Binder<T> {
931     type Lifted = Binder<T::Lifted>;
932     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted> {
933         tcx.lift(&self.0).map(|x| Binder(x))
934     }
935 }
936
937 pub mod tls {
938     use ast_map;
939     use middle::ty;
940     use session::Session;
941
942     use std::fmt;
943     use syntax::ast;
944     use syntax::codemap;
945
946     /// Marker type used for the scoped TLS slot.
947     /// The type context cannot be used directly because the scoped TLS
948     /// in libstd doesn't allow types generic over lifetimes.
949     struct ThreadLocalTyCx;
950
951     scoped_thread_local!(static TLS_TCX: ThreadLocalTyCx);
952
953     fn def_id_debug(def_id: ast::DefId, f: &mut fmt::Formatter) -> fmt::Result {
954         // Unfortunately, there seems to be no way to attempt to print
955         // a path for a def-id, so I'll just make a best effort for now
956         // and otherwise fallback to just printing the crate/node pair
957         with(|tcx| {
958             if def_id.krate == ast::LOCAL_CRATE {
959                 match tcx.map.find(def_id.node) {
960                     Some(ast_map::NodeItem(..)) |
961                     Some(ast_map::NodeForeignItem(..)) |
962                     Some(ast_map::NodeImplItem(..)) |
963                     Some(ast_map::NodeTraitItem(..)) |
964                     Some(ast_map::NodeVariant(..)) |
965                     Some(ast_map::NodeStructCtor(..)) => {
966                         return write!(f, "{}", ty::item_path_str(tcx, def_id));
967                     }
968                     _ => {}
969                 }
970             }
971             Ok(())
972         })
973     }
974
975     fn span_debug(span: codemap::Span, f: &mut fmt::Formatter) -> fmt::Result {
976         with(|tcx| {
977             write!(f, "{}", tcx.sess.codemap().span_to_string(span))
978         })
979     }
980
981     pub fn enter<'tcx, F: FnOnce(&ty::ctxt<'tcx>) -> R, R>(tcx: ty::ctxt<'tcx>, f: F)
982                                                            -> (Session, R) {
983         let result = ast::DEF_ID_DEBUG.with(|def_id_dbg| {
984             codemap::SPAN_DEBUG.with(|span_dbg| {
985                 let original_def_id_debug = def_id_dbg.get();
986                 def_id_dbg.set(def_id_debug);
987                 let original_span_debug = span_dbg.get();
988                 span_dbg.set(span_debug);
989                 let tls_ptr = &tcx as *const _ as *const ThreadLocalTyCx;
990                 let result = TLS_TCX.set(unsafe { &*tls_ptr }, || f(&tcx));
991                 def_id_dbg.set(original_def_id_debug);
992                 span_dbg.set(original_span_debug);
993                 result
994             })
995         });
996         (tcx.sess, result)
997     }
998
999     pub fn with<F: FnOnce(&ty::ctxt) -> R, R>(f: F) -> R {
1000         TLS_TCX.with(|tcx| f(unsafe { &*(tcx as *const _ as *const ty::ctxt) }))
1001     }
1002 }
1003
1004 // Flags that we track on types. These flags are propagated upwards
1005 // through the type during type construction, so that we can quickly
1006 // check whether the type has various kinds of types in it without
1007 // recursing over the type itself.
1008 bitflags! {
1009     flags TypeFlags: u32 {
1010         const HAS_PARAMS         = 1 << 0,
1011         const HAS_SELF           = 1 << 1,
1012         const HAS_TY_INFER       = 1 << 2,
1013         const HAS_RE_INFER       = 1 << 3,
1014         const HAS_RE_EARLY_BOUND = 1 << 4,
1015         const HAS_FREE_REGIONS   = 1 << 5,
1016         const HAS_TY_ERR         = 1 << 6,
1017         const HAS_PROJECTION     = 1 << 7,
1018         const HAS_TY_CLOSURE     = 1 << 8,
1019
1020         // true if there are "names" of types and regions and so forth
1021         // that are local to a particular fn
1022         const HAS_LOCAL_NAMES   = 1 << 9,
1023
1024         const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
1025                                    TypeFlags::HAS_SELF.bits |
1026                                    TypeFlags::HAS_RE_EARLY_BOUND.bits,
1027
1028         // Flags representing the nominal content of a type,
1029         // computed by FlagsComputation. If you add a new nominal
1030         // flag, it should be added here too.
1031         const NOMINAL_FLAGS     = TypeFlags::HAS_PARAMS.bits |
1032                                   TypeFlags::HAS_SELF.bits |
1033                                   TypeFlags::HAS_TY_INFER.bits |
1034                                   TypeFlags::HAS_RE_INFER.bits |
1035                                   TypeFlags::HAS_RE_EARLY_BOUND.bits |
1036                                   TypeFlags::HAS_FREE_REGIONS.bits |
1037                                   TypeFlags::HAS_TY_ERR.bits |
1038                                   TypeFlags::HAS_PROJECTION.bits |
1039                                   TypeFlags::HAS_TY_CLOSURE.bits |
1040                                   TypeFlags::HAS_LOCAL_NAMES.bits,
1041
1042         // Caches for type_is_sized, type_moves_by_default
1043         const SIZEDNESS_CACHED  = 1 << 16,
1044         const IS_SIZED          = 1 << 17,
1045         const MOVENESS_CACHED   = 1 << 18,
1046         const MOVES_BY_DEFAULT  = 1 << 19,
1047     }
1048 }
1049
1050 macro_rules! sty_debug_print {
1051     ($ctxt: expr, $($variant: ident),*) => {{
1052         // curious inner module to allow variant names to be used as
1053         // variable names.
1054         #[allow(non_snake_case)]
1055         mod inner {
1056             use middle::ty;
1057             #[derive(Copy, Clone)]
1058             struct DebugStat {
1059                 total: usize,
1060                 region_infer: usize,
1061                 ty_infer: usize,
1062                 both_infer: usize,
1063             }
1064
1065             pub fn go(tcx: &ty::ctxt) {
1066                 let mut total = DebugStat {
1067                     total: 0,
1068                     region_infer: 0, ty_infer: 0, both_infer: 0,
1069                 };
1070                 $(let mut $variant = total;)*
1071
1072
1073                 for (_, t) in tcx.interner.borrow().iter() {
1074                     let variant = match t.sty {
1075                         ty::TyBool | ty::TyChar | ty::TyInt(..) | ty::TyUint(..) |
1076                             ty::TyFloat(..) | ty::TyStr => continue,
1077                         ty::TyError => /* unimportant */ continue,
1078                         $(ty::$variant(..) => &mut $variant,)*
1079                     };
1080                     let region = t.flags.get().intersects(ty::TypeFlags::HAS_RE_INFER);
1081                     let ty = t.flags.get().intersects(ty::TypeFlags::HAS_TY_INFER);
1082
1083                     variant.total += 1;
1084                     total.total += 1;
1085                     if region { total.region_infer += 1; variant.region_infer += 1 }
1086                     if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1087                     if region && ty { total.both_infer += 1; variant.both_infer += 1 }
1088                 }
1089                 println!("Ty interner             total           ty region  both");
1090                 $(println!("    {:18}: {uses:6} {usespc:4.1}%, \
1091 {ty:4.1}% {region:5.1}% {both:4.1}%",
1092                            stringify!($variant),
1093                            uses = $variant.total,
1094                            usespc = $variant.total as f64 * 100.0 / total.total as f64,
1095                            ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
1096                            region = $variant.region_infer as f64 * 100.0  / total.total as f64,
1097                            both = $variant.both_infer as f64 * 100.0  / total.total as f64);
1098                   )*
1099                 println!("                  total {uses:6}        \
1100 {ty:4.1}% {region:5.1}% {both:4.1}%",
1101                          uses = total.total,
1102                          ty = total.ty_infer as f64 * 100.0  / total.total as f64,
1103                          region = total.region_infer as f64 * 100.0  / total.total as f64,
1104                          both = total.both_infer as f64 * 100.0  / total.total as f64)
1105             }
1106         }
1107
1108         inner::go($ctxt)
1109     }}
1110 }
1111
1112 impl<'tcx> ctxt<'tcx> {
1113     pub fn print_debug_stats(&self) {
1114         sty_debug_print!(
1115             self,
1116             TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyBareFn, TyTrait,
1117             TyStruct, TyClosure, TyTuple, TyParam, TyInfer, TyProjection);
1118
1119         println!("Substs interner: #{}", self.substs_interner.borrow().len());
1120         println!("BareFnTy interner: #{}", self.bare_fn_interner.borrow().len());
1121         println!("Region interner: #{}", self.region_interner.borrow().len());
1122         println!("Stability interner: #{}", self.stability_interner.borrow().len());
1123     }
1124 }
1125
1126 pub struct TyS<'tcx> {
1127     pub sty: TypeVariants<'tcx>,
1128     pub flags: Cell<TypeFlags>,
1129
1130     // the maximal depth of any bound regions appearing in this type.
1131     region_depth: u32,
1132 }
1133
1134 impl fmt::Debug for TypeFlags {
1135     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1136         write!(f, "{}", self.bits)
1137     }
1138 }
1139
1140 impl<'tcx> PartialEq for TyS<'tcx> {
1141     #[inline]
1142     fn eq(&self, other: &TyS<'tcx>) -> bool {
1143         // (self as *const _) == (other as *const _)
1144         (self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
1145     }
1146 }
1147 impl<'tcx> Eq for TyS<'tcx> {}
1148
1149 impl<'tcx> Hash for TyS<'tcx> {
1150     fn hash<H: Hasher>(&self, s: &mut H) {
1151         (self as *const TyS).hash(s)
1152     }
1153 }
1154
1155 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
1156
1157 /// An entry in the type interner.
1158 pub struct InternedTy<'tcx> {
1159     ty: Ty<'tcx>
1160 }
1161
1162 // NB: An InternedTy compares and hashes as a sty.
1163 impl<'tcx> PartialEq for InternedTy<'tcx> {
1164     fn eq(&self, other: &InternedTy<'tcx>) -> bool {
1165         self.ty.sty == other.ty.sty
1166     }
1167 }
1168
1169 impl<'tcx> Eq for InternedTy<'tcx> {}
1170
1171 impl<'tcx> Hash for InternedTy<'tcx> {
1172     fn hash<H: Hasher>(&self, s: &mut H) {
1173         self.ty.sty.hash(s)
1174     }
1175 }
1176
1177 impl<'tcx> Borrow<TypeVariants<'tcx>> for InternedTy<'tcx> {
1178     fn borrow<'a>(&'a self) -> &'a TypeVariants<'tcx> {
1179         &self.ty.sty
1180     }
1181 }
1182
1183 pub fn type_has_params(ty: Ty) -> bool {
1184     ty.flags.get().intersects(TypeFlags::HAS_PARAMS)
1185 }
1186 pub fn type_has_self(ty: Ty) -> bool {
1187     ty.flags.get().intersects(TypeFlags::HAS_SELF)
1188 }
1189 pub fn type_has_ty_infer(ty: Ty) -> bool {
1190     ty.flags.get().intersects(TypeFlags::HAS_TY_INFER)
1191 }
1192 pub fn type_needs_infer(ty: Ty) -> bool {
1193     ty.flags.get().intersects(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
1194 }
1195 pub fn type_is_global(ty: Ty) -> bool {
1196     !ty.flags.get().intersects(TypeFlags::HAS_LOCAL_NAMES)
1197 }
1198 pub fn type_has_projection(ty: Ty) -> bool {
1199     ty.flags.get().intersects(TypeFlags::HAS_PROJECTION)
1200 }
1201 pub fn type_has_ty_closure(ty: Ty) -> bool {
1202     ty.flags.get().intersects(TypeFlags::HAS_TY_CLOSURE)
1203 }
1204
1205 pub fn type_has_erasable_regions(ty: Ty) -> bool {
1206     ty.flags.get().intersects(TypeFlags::HAS_RE_EARLY_BOUND |
1207                               TypeFlags::HAS_RE_INFER |
1208                               TypeFlags::HAS_FREE_REGIONS)
1209 }
1210
1211 /// An "escaping region" is a bound region whose binder is not part of `t`.
1212 ///
1213 /// So, for example, consider a type like the following, which has two binders:
1214 ///
1215 ///    for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
1216 ///    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
1217 ///                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~  inner scope
1218 ///
1219 /// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
1220 /// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
1221 /// fn type*, that type has an escaping region: `'a`.
1222 ///
1223 /// Note that what I'm calling an "escaping region" is often just called a "free region". However,
1224 /// we already use the term "free region". It refers to the regions that we use to represent bound
1225 /// regions on a fn definition while we are typechecking its body.
1226 ///
1227 /// To clarify, conceptually there is no particular difference between an "escaping" region and a
1228 /// "free" region. However, there is a big difference in practice. Basically, when "entering" a
1229 /// binding level, one is generally required to do some sort of processing to a bound region, such
1230 /// as replacing it with a fresh/skolemized region, or making an entry in the environment to
1231 /// represent the scope to which it is attached, etc. An escaping region represents a bound region
1232 /// for which this processing has not yet been done.
1233 pub fn type_has_escaping_regions(ty: Ty) -> bool {
1234     type_escapes_depth(ty, 0)
1235 }
1236
1237 pub fn type_escapes_depth(ty: Ty, depth: u32) -> bool {
1238     ty.region_depth > depth
1239 }
1240
1241 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1242 pub struct BareFnTy<'tcx> {
1243     pub unsafety: ast::Unsafety,
1244     pub abi: abi::Abi,
1245     pub sig: PolyFnSig<'tcx>,
1246 }
1247
1248 #[derive(Clone, PartialEq, Eq, Hash)]
1249 pub struct ClosureTy<'tcx> {
1250     pub unsafety: ast::Unsafety,
1251     pub abi: abi::Abi,
1252     pub sig: PolyFnSig<'tcx>,
1253 }
1254
1255 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1256 pub enum FnOutput<'tcx> {
1257     FnConverging(Ty<'tcx>),
1258     FnDiverging
1259 }
1260
1261 impl<'tcx> FnOutput<'tcx> {
1262     pub fn diverges(&self) -> bool {
1263         *self == FnDiverging
1264     }
1265
1266     pub fn unwrap(self) -> Ty<'tcx> {
1267         match self {
1268             ty::FnConverging(t) => t,
1269             ty::FnDiverging => unreachable!()
1270         }
1271     }
1272
1273     pub fn unwrap_or(self, def: Ty<'tcx>) -> Ty<'tcx> {
1274         match self {
1275             ty::FnConverging(t) => t,
1276             ty::FnDiverging => def
1277         }
1278     }
1279 }
1280
1281 pub type PolyFnOutput<'tcx> = Binder<FnOutput<'tcx>>;
1282
1283 impl<'tcx> PolyFnOutput<'tcx> {
1284     pub fn diverges(&self) -> bool {
1285         self.0.diverges()
1286     }
1287 }
1288
1289 /// Signature of a function type, which I have arbitrarily
1290 /// decided to use to refer to the input/output types.
1291 ///
1292 /// - `inputs` is the list of arguments and their modes.
1293 /// - `output` is the return type.
1294 /// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
1295 #[derive(Clone, PartialEq, Eq, Hash)]
1296 pub struct FnSig<'tcx> {
1297     pub inputs: Vec<Ty<'tcx>>,
1298     pub output: FnOutput<'tcx>,
1299     pub variadic: bool
1300 }
1301
1302 pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
1303
1304 impl<'tcx> PolyFnSig<'tcx> {
1305     pub fn inputs(&self) -> ty::Binder<Vec<Ty<'tcx>>> {
1306         self.map_bound_ref(|fn_sig| fn_sig.inputs.clone())
1307     }
1308     pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
1309         self.map_bound_ref(|fn_sig| fn_sig.inputs[index])
1310     }
1311     pub fn output(&self) -> ty::Binder<FnOutput<'tcx>> {
1312         self.map_bound_ref(|fn_sig| fn_sig.output.clone())
1313     }
1314     pub fn variadic(&self) -> bool {
1315         self.skip_binder().variadic
1316     }
1317 }
1318
1319 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1320 pub struct ParamTy {
1321     pub space: subst::ParamSpace,
1322     pub idx: u32,
1323     pub name: ast::Name,
1324 }
1325
1326 /// A [De Bruijn index][dbi] is a standard means of representing
1327 /// regions (and perhaps later types) in a higher-ranked setting. In
1328 /// particular, imagine a type like this:
1329 ///
1330 ///     for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
1331 ///     ^          ^            |        |         |
1332 ///     |          |            |        |         |
1333 ///     |          +------------+ 1      |         |
1334 ///     |                                |         |
1335 ///     +--------------------------------+ 2       |
1336 ///     |                                          |
1337 ///     +------------------------------------------+ 1
1338 ///
1339 /// In this type, there are two binders (the outer fn and the inner
1340 /// fn). We need to be able to determine, for any given region, which
1341 /// fn type it is bound by, the inner or the outer one. There are
1342 /// various ways you can do this, but a De Bruijn index is one of the
1343 /// more convenient and has some nice properties. The basic idea is to
1344 /// count the number of binders, inside out. Some examples should help
1345 /// clarify what I mean.
1346 ///
1347 /// Let's start with the reference type `&'b isize` that is the first
1348 /// argument to the inner function. This region `'b` is assigned a De
1349 /// Bruijn index of 1, meaning "the innermost binder" (in this case, a
1350 /// fn). The region `'a` that appears in the second argument type (`&'a
1351 /// isize`) would then be assigned a De Bruijn index of 2, meaning "the
1352 /// second-innermost binder". (These indices are written on the arrays
1353 /// in the diagram).
1354 ///
1355 /// What is interesting is that De Bruijn index attached to a particular
1356 /// variable will vary depending on where it appears. For example,
1357 /// the final type `&'a char` also refers to the region `'a` declared on
1358 /// the outermost fn. But this time, this reference is not nested within
1359 /// any other binders (i.e., it is not an argument to the inner fn, but
1360 /// rather the outer one). Therefore, in this case, it is assigned a
1361 /// De Bruijn index of 1, because the innermost binder in that location
1362 /// is the outer fn.
1363 ///
1364 /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
1365 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, Copy)]
1366 pub struct DebruijnIndex {
1367     // We maintain the invariant that this is never 0. So 1 indicates
1368     // the innermost binder. To ensure this, create with `DebruijnIndex::new`.
1369     pub depth: u32,
1370 }
1371
1372 /// Representation of regions:
1373 #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Copy)]
1374 pub enum Region {
1375     // Region bound in a type or fn declaration which will be
1376     // substituted 'early' -- that is, at the same time when type
1377     // parameters are substituted.
1378     ReEarlyBound(EarlyBoundRegion),
1379
1380     // Region bound in a function scope, which will be substituted when the
1381     // function is called.
1382     ReLateBound(DebruijnIndex, BoundRegion),
1383
1384     /// When checking a function body, the types of all arguments and so forth
1385     /// that refer to bound region parameters are modified to refer to free
1386     /// region parameters.
1387     ReFree(FreeRegion),
1388
1389     /// A concrete region naming some statically determined extent
1390     /// (e.g. an expression or sequence of statements) within the
1391     /// current function.
1392     ReScope(region::CodeExtent),
1393
1394     /// Static data that has an "infinite" lifetime. Top in the region lattice.
1395     ReStatic,
1396
1397     /// A region variable.  Should not exist after typeck.
1398     ReInfer(InferRegion),
1399
1400     /// Empty lifetime is for data that is never accessed.
1401     /// Bottom in the region lattice. We treat ReEmpty somewhat
1402     /// specially; at least right now, we do not generate instances of
1403     /// it during the GLB computations, but rather
1404     /// generate an error instead. This is to improve error messages.
1405     /// The only way to get an instance of ReEmpty is to have a region
1406     /// variable with no constraints.
1407     ReEmpty,
1408 }
1409
1410 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
1411 pub struct EarlyBoundRegion {
1412     pub param_id: ast::NodeId,
1413     pub space: subst::ParamSpace,
1414     pub index: u32,
1415     pub name: ast::Name,
1416 }
1417
1418 /// Upvars do not get their own node-id. Instead, we use the pair of
1419 /// the original var id (that is, the root variable that is referenced
1420 /// by the upvar) and the id of the closure expression.
1421 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1422 pub struct UpvarId {
1423     pub var_id: ast::NodeId,
1424     pub closure_expr_id: ast::NodeId,
1425 }
1426
1427 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
1428 pub enum BorrowKind {
1429     /// Data must be immutable and is aliasable.
1430     ImmBorrow,
1431
1432     /// Data must be immutable but not aliasable.  This kind of borrow
1433     /// cannot currently be expressed by the user and is used only in
1434     /// implicit closure bindings. It is needed when you the closure
1435     /// is borrowing or mutating a mutable referent, e.g.:
1436     ///
1437     ///    let x: &mut isize = ...;
1438     ///    let y = || *x += 5;
1439     ///
1440     /// If we were to try to translate this closure into a more explicit
1441     /// form, we'd encounter an error with the code as written:
1442     ///
1443     ///    struct Env { x: & &mut isize }
1444     ///    let x: &mut isize = ...;
1445     ///    let y = (&mut Env { &x }, fn_ptr);  // Closure is pair of env and fn
1446     ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
1447     ///
1448     /// This is then illegal because you cannot mutate a `&mut` found
1449     /// in an aliasable location. To solve, you'd have to translate with
1450     /// an `&mut` borrow:
1451     ///
1452     ///    struct Env { x: & &mut isize }
1453     ///    let x: &mut isize = ...;
1454     ///    let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
1455     ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
1456     ///
1457     /// Now the assignment to `**env.x` is legal, but creating a
1458     /// mutable pointer to `x` is not because `x` is not mutable. We
1459     /// could fix this by declaring `x` as `let mut x`. This is ok in
1460     /// user code, if awkward, but extra weird for closures, since the
1461     /// borrow is hidden.
1462     ///
1463     /// So we introduce a "unique imm" borrow -- the referent is
1464     /// immutable, but not aliasable. This solves the problem. For
1465     /// simplicity, we don't give users the way to express this
1466     /// borrow, it's just used when translating closures.
1467     UniqueImmBorrow,
1468
1469     /// Data is mutable and not aliasable.
1470     MutBorrow
1471 }
1472
1473 /// Information describing the capture of an upvar. This is computed
1474 /// during `typeck`, specifically by `regionck`.
1475 #[derive(PartialEq, Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
1476 pub enum UpvarCapture {
1477     /// Upvar is captured by value. This is always true when the
1478     /// closure is labeled `move`, but can also be true in other cases
1479     /// depending on inference.
1480     ByValue,
1481
1482     /// Upvar is captured by reference.
1483     ByRef(UpvarBorrow),
1484 }
1485
1486 #[derive(PartialEq, Clone, RustcEncodable, RustcDecodable, Copy)]
1487 pub struct UpvarBorrow {
1488     /// The kind of borrow: by-ref upvars have access to shared
1489     /// immutable borrows, which are not part of the normal language
1490     /// syntax.
1491     pub kind: BorrowKind,
1492
1493     /// Region of the resulting reference.
1494     pub region: ty::Region,
1495 }
1496
1497 pub type UpvarCaptureMap = FnvHashMap<UpvarId, UpvarCapture>;
1498
1499 impl Region {
1500     pub fn is_global(&self) -> bool {
1501         // does this represent a region that can be named in a global
1502         // way? used in fulfillment caching.
1503         match *self {
1504             ty::ReStatic | ty::ReEmpty => true,
1505             _ => false,
1506         }
1507     }
1508
1509     pub fn is_bound(&self) -> bool {
1510         match *self {
1511             ty::ReEarlyBound(..) => true,
1512             ty::ReLateBound(..) => true,
1513             _ => false
1514         }
1515     }
1516
1517     pub fn escapes_depth(&self, depth: u32) -> bool {
1518         match *self {
1519             ty::ReLateBound(debruijn, _) => debruijn.depth > depth,
1520             _ => false,
1521         }
1522     }
1523 }
1524
1525 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
1526          RustcEncodable, RustcDecodable, Copy)]
1527 /// A "free" region `fr` can be interpreted as "some region
1528 /// at least as big as the scope `fr.scope`".
1529 pub struct FreeRegion {
1530     pub scope: region::DestructionScopeData,
1531     pub bound_region: BoundRegion
1532 }
1533
1534 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
1535          RustcEncodable, RustcDecodable, Copy, Debug)]
1536 pub enum BoundRegion {
1537     /// An anonymous region parameter for a given fn (&T)
1538     BrAnon(u32),
1539
1540     /// Named region parameters for functions (a in &'a T)
1541     ///
1542     /// The def-id is needed to distinguish free regions in
1543     /// the event of shadowing.
1544     BrNamed(ast::DefId, ast::Name),
1545
1546     /// Fresh bound identifiers created during GLB computations.
1547     BrFresh(u32),
1548
1549     // Anonymous region for the implicit env pointer parameter
1550     // to a closure
1551     BrEnv
1552 }
1553
1554 // NB: If you change this, you'll probably want to change the corresponding
1555 // AST structure in libsyntax/ast.rs as well.
1556 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1557 pub enum TypeVariants<'tcx> {
1558     /// The primitive boolean type. Written as `bool`.
1559     TyBool,
1560
1561     /// The primitive character type; holds a Unicode scalar value
1562     /// (a non-surrogate code point).  Written as `char`.
1563     TyChar,
1564
1565     /// A primitive signed integer type. For example, `i32`.
1566     TyInt(ast::IntTy),
1567
1568     /// A primitive unsigned integer type. For example, `u32`.
1569     TyUint(ast::UintTy),
1570
1571     /// A primitive floating-point type. For example, `f64`.
1572     TyFloat(ast::FloatTy),
1573
1574     /// An enumerated type, defined with `enum`.
1575     ///
1576     /// Substs here, possibly against intuition, *may* contain `TyParam`s.
1577     /// That is, even after substitution it is possible that there are type
1578     /// variables. This happens when the `TyEnum` corresponds to an enum
1579     /// definition and not a concrete use of it. To get the correct `TyEnum`
1580     /// from the tcx, use the `NodeId` from the `ast::Ty` and look it up in
1581     /// the `ast_ty_to_ty_cache`. This is probably true for `TyStruct` as
1582     /// well.
1583     TyEnum(DefId, &'tcx Substs<'tcx>),
1584
1585     /// A structure type, defined with `struct`.
1586     ///
1587     /// See warning about substitutions for enumerated types.
1588     TyStruct(DefId, &'tcx Substs<'tcx>),
1589
1590     /// `Box<T>`; this is nominally a struct in the documentation, but is
1591     /// special-cased internally. For example, it is possible to implicitly
1592     /// move the contents of a box out of that box, and methods of any type
1593     /// can have type `Box<Self>`.
1594     TyBox(Ty<'tcx>),
1595
1596     /// The pointee of a string slice. Written as `str`.
1597     TyStr,
1598
1599     /// An array with the given length. Written as `[T; n]`.
1600     TyArray(Ty<'tcx>, usize),
1601
1602     /// The pointee of an array slice.  Written as `[T]`.
1603     TySlice(Ty<'tcx>),
1604
1605     /// A raw pointer. Written as `*mut T` or `*const T`
1606     TyRawPtr(mt<'tcx>),
1607
1608     /// A reference; a pointer with an associated lifetime. Written as
1609     /// `&a mut T` or `&'a T`.
1610     TyRef(&'tcx Region, mt<'tcx>),
1611
1612     /// If the def-id is Some(_), then this is the type of a specific
1613     /// fn item. Otherwise, if None(_), it a fn pointer type.
1614     ///
1615     /// FIXME: Conflating function pointers and the type of a
1616     /// function is probably a terrible idea; a function pointer is a
1617     /// value with a specific type, but a function can be polymorphic
1618     /// or dynamically dispatched.
1619     TyBareFn(Option<DefId>, &'tcx BareFnTy<'tcx>),
1620
1621     /// A trait, defined with `trait`.
1622     TyTrait(Box<TraitTy<'tcx>>),
1623
1624     /// The anonymous type of a closure. Used to represent the type of
1625     /// `|a| a`.
1626     TyClosure(DefId, &'tcx Substs<'tcx>),
1627
1628     /// A tuple type.  For example, `(i32, bool)`.
1629     TyTuple(Vec<Ty<'tcx>>),
1630
1631     /// The projection of an associated type.  For example,
1632     /// `<T as Trait<..>>::N`.
1633     TyProjection(ProjectionTy<'tcx>),
1634
1635     /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
1636     TyParam(ParamTy),
1637
1638     /// A type variable used during type-checking.
1639     TyInfer(InferTy),
1640
1641     /// A placeholder for a type which could not be computed; this is
1642     /// propagated to avoid useless error messages.
1643     TyError,
1644 }
1645
1646 #[derive(Clone, PartialEq, Eq, Hash)]
1647 pub struct TraitTy<'tcx> {
1648     pub principal: ty::PolyTraitRef<'tcx>,
1649     pub bounds: ExistentialBounds<'tcx>,
1650 }
1651
1652 impl<'tcx> TraitTy<'tcx> {
1653     pub fn principal_def_id(&self) -> ast::DefId {
1654         self.principal.0.def_id
1655     }
1656
1657     /// Object types don't have a self-type specified. Therefore, when
1658     /// we convert the principal trait-ref into a normal trait-ref,
1659     /// you must give *some* self-type. A common choice is `mk_err()`
1660     /// or some skolemized type.
1661     pub fn principal_trait_ref_with_self_ty(&self,
1662                                             tcx: &ctxt<'tcx>,
1663                                             self_ty: Ty<'tcx>)
1664                                             -> ty::PolyTraitRef<'tcx>
1665     {
1666         // otherwise the escaping regions would be captured by the binder
1667         assert!(!self_ty.has_escaping_regions());
1668
1669         ty::Binder(TraitRef {
1670             def_id: self.principal.0.def_id,
1671             substs: tcx.mk_substs(self.principal.0.substs.with_self_ty(self_ty)),
1672         })
1673     }
1674
1675     pub fn projection_bounds_with_self_ty(&self,
1676                                           tcx: &ctxt<'tcx>,
1677                                           self_ty: Ty<'tcx>)
1678                                           -> Vec<ty::PolyProjectionPredicate<'tcx>>
1679     {
1680         // otherwise the escaping regions would be captured by the binders
1681         assert!(!self_ty.has_escaping_regions());
1682
1683         self.bounds.projection_bounds.iter()
1684             .map(|in_poly_projection_predicate| {
1685                 let in_projection_ty = &in_poly_projection_predicate.0.projection_ty;
1686                 let substs = tcx.mk_substs(in_projection_ty.trait_ref.substs.with_self_ty(self_ty));
1687                 let trait_ref = ty::TraitRef::new(in_projection_ty.trait_ref.def_id,
1688                                               substs);
1689                 let projection_ty = ty::ProjectionTy {
1690                     trait_ref: trait_ref,
1691                     item_name: in_projection_ty.item_name
1692                 };
1693                 ty::Binder(ty::ProjectionPredicate {
1694                     projection_ty: projection_ty,
1695                     ty: in_poly_projection_predicate.0.ty
1696                 })
1697             })
1698             .collect()
1699     }
1700 }
1701
1702 /// A complete reference to a trait. These take numerous guises in syntax,
1703 /// but perhaps the most recognizable form is in a where clause:
1704 ///
1705 ///     T : Foo<U>
1706 ///
1707 /// This would be represented by a trait-reference where the def-id is the
1708 /// def-id for the trait `Foo` and the substs defines `T` as parameter 0 in the
1709 /// `SelfSpace` and `U` as parameter 0 in the `TypeSpace`.
1710 ///
1711 /// Trait references also appear in object types like `Foo<U>`, but in
1712 /// that case the `Self` parameter is absent from the substitutions.
1713 ///
1714 /// Note that a `TraitRef` introduces a level of region binding, to
1715 /// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
1716 /// U>` or higher-ranked object types.
1717 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
1718 pub struct TraitRef<'tcx> {
1719     pub def_id: DefId,
1720     pub substs: &'tcx Substs<'tcx>,
1721 }
1722
1723 pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
1724
1725 impl<'tcx> PolyTraitRef<'tcx> {
1726     pub fn self_ty(&self) -> Ty<'tcx> {
1727         self.0.self_ty()
1728     }
1729
1730     pub fn def_id(&self) -> ast::DefId {
1731         self.0.def_id
1732     }
1733
1734     pub fn substs(&self) -> &'tcx Substs<'tcx> {
1735         // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
1736         self.0.substs
1737     }
1738
1739     pub fn input_types(&self) -> &[Ty<'tcx>] {
1740         // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
1741         self.0.input_types()
1742     }
1743
1744     pub fn to_poly_trait_predicate(&self) -> PolyTraitPredicate<'tcx> {
1745         // Note that we preserve binding levels
1746         Binder(TraitPredicate { trait_ref: self.0.clone() })
1747     }
1748 }
1749
1750 /// Binder is a binder for higher-ranked lifetimes. It is part of the
1751 /// compiler's representation for things like `for<'a> Fn(&'a isize)`
1752 /// (which would be represented by the type `PolyTraitRef ==
1753 /// Binder<TraitRef>`). Note that when we skolemize, instantiate,
1754 /// erase, or otherwise "discharge" these bound regions, we change the
1755 /// type from `Binder<T>` to just `T` (see
1756 /// e.g. `liberate_late_bound_regions`).
1757 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
1758 pub struct Binder<T>(pub T);
1759
1760 impl<T> Binder<T> {
1761     /// Skips the binder and returns the "bound" value. This is a
1762     /// risky thing to do because it's easy to get confused about
1763     /// debruijn indices and the like. It is usually better to
1764     /// discharge the binder using `no_late_bound_regions` or
1765     /// `replace_late_bound_regions` or something like
1766     /// that. `skip_binder` is only valid when you are either
1767     /// extracting data that has nothing to do with bound regions, you
1768     /// are doing some sort of test that does not involve bound
1769     /// regions, or you are being very careful about your depth
1770     /// accounting.
1771     ///
1772     /// Some examples where `skip_binder` is reasonable:
1773     /// - extracting the def-id from a PolyTraitRef;
1774     /// - comparing the self type of a PolyTraitRef to see if it is equal to
1775     ///   a type parameter `X`, since the type `X`  does not reference any regions
1776     pub fn skip_binder(&self) -> &T {
1777         &self.0
1778     }
1779
1780     pub fn as_ref(&self) -> Binder<&T> {
1781         ty::Binder(&self.0)
1782     }
1783
1784     pub fn map_bound_ref<F,U>(&self, f: F) -> Binder<U>
1785         where F: FnOnce(&T) -> U
1786     {
1787         self.as_ref().map_bound(f)
1788     }
1789
1790     pub fn map_bound<F,U>(self, f: F) -> Binder<U>
1791         where F: FnOnce(T) -> U
1792     {
1793         ty::Binder(f(self.0))
1794     }
1795 }
1796
1797 #[derive(Clone, Copy, PartialEq)]
1798 pub enum IntVarValue {
1799     IntType(ast::IntTy),
1800     UintType(ast::UintTy),
1801 }
1802
1803 #[derive(Clone, Copy, Debug)]
1804 pub enum terr_vstore_kind {
1805     terr_vec,
1806     terr_str,
1807     terr_fn,
1808     terr_trait
1809 }
1810
1811 #[derive(Clone, Copy, Debug)]
1812 pub struct expected_found<T> {
1813     pub expected: T,
1814     pub found: T
1815 }
1816
1817 // Data structures used in type unification
1818 #[derive(Clone, Copy, Debug)]
1819 pub enum type_err<'tcx> {
1820     terr_mismatch,
1821     terr_unsafety_mismatch(expected_found<ast::Unsafety>),
1822     terr_abi_mismatch(expected_found<abi::Abi>),
1823     terr_mutability,
1824     terr_box_mutability,
1825     terr_ptr_mutability,
1826     terr_ref_mutability,
1827     terr_vec_mutability,
1828     terr_tuple_size(expected_found<usize>),
1829     terr_fixed_array_size(expected_found<usize>),
1830     terr_ty_param_size(expected_found<usize>),
1831     terr_arg_count,
1832     terr_regions_does_not_outlive(Region, Region),
1833     terr_regions_not_same(Region, Region),
1834     terr_regions_no_overlap(Region, Region),
1835     terr_regions_insufficiently_polymorphic(BoundRegion, Region),
1836     terr_regions_overly_polymorphic(BoundRegion, Region),
1837     terr_sorts(expected_found<Ty<'tcx>>),
1838     terr_integer_as_char,
1839     terr_int_mismatch(expected_found<IntVarValue>),
1840     terr_float_mismatch(expected_found<ast::FloatTy>),
1841     terr_traits(expected_found<ast::DefId>),
1842     terr_builtin_bounds(expected_found<BuiltinBounds>),
1843     terr_variadic_mismatch(expected_found<bool>),
1844     terr_cyclic_ty,
1845     terr_convergence_mismatch(expected_found<bool>),
1846     terr_projection_name_mismatched(expected_found<ast::Name>),
1847     terr_projection_bounds_length(expected_found<usize>),
1848 }
1849
1850 /// Bounds suitable for a named type parameter like `A` in `fn foo<A>`
1851 /// as well as the existential type parameter in an object type.
1852 #[derive(PartialEq, Eq, Hash, Clone)]
1853 pub struct ParamBounds<'tcx> {
1854     pub region_bounds: Vec<ty::Region>,
1855     pub builtin_bounds: BuiltinBounds,
1856     pub trait_bounds: Vec<PolyTraitRef<'tcx>>,
1857     pub projection_bounds: Vec<PolyProjectionPredicate<'tcx>>,
1858 }
1859
1860 /// Bounds suitable for an existentially quantified type parameter
1861 /// such as those that appear in object types or closure types. The
1862 /// major difference between this case and `ParamBounds` is that
1863 /// general purpose trait bounds are omitted and there must be
1864 /// *exactly one* region.
1865 #[derive(PartialEq, Eq, Hash, Clone)]
1866 pub struct ExistentialBounds<'tcx> {
1867     pub region_bound: ty::Region,
1868     pub builtin_bounds: BuiltinBounds,
1869     pub projection_bounds: Vec<PolyProjectionPredicate<'tcx>>,
1870 }
1871
1872 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1873 pub struct BuiltinBounds(EnumSet<BuiltinBound>);
1874
1875 impl BuiltinBounds {
1876     pub fn empty() -> BuiltinBounds {
1877         BuiltinBounds(EnumSet::new())
1878     }
1879
1880     pub fn iter(&self) -> enum_set::Iter<BuiltinBound> {
1881         self.into_iter()
1882     }
1883 }
1884
1885 impl ops::Deref for BuiltinBounds {
1886     type Target = EnumSet<BuiltinBound>;
1887     fn deref(&self) -> &Self::Target { &self.0 }
1888 }
1889
1890 impl ops::DerefMut for BuiltinBounds {
1891     fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
1892 }
1893
1894 impl<'a> IntoIterator for &'a BuiltinBounds {
1895     type Item = BuiltinBound;
1896     type IntoIter = enum_set::Iter<BuiltinBound>;
1897     fn into_iter(self) -> Self::IntoIter {
1898         (**self).into_iter()
1899     }
1900 }
1901
1902 #[derive(Clone, RustcEncodable, PartialEq, Eq, RustcDecodable, Hash,
1903            Debug, Copy)]
1904 #[repr(usize)]
1905 pub enum BuiltinBound {
1906     Send,
1907     Sized,
1908     Copy,
1909     Sync,
1910 }
1911
1912 /// An existential bound that does not implement any traits.
1913 pub fn region_existential_bound<'tcx>(r: ty::Region) -> ExistentialBounds<'tcx> {
1914     ty::ExistentialBounds { region_bound: r,
1915                             builtin_bounds: BuiltinBounds::empty(),
1916                             projection_bounds: Vec::new() }
1917 }
1918
1919 impl CLike for BuiltinBound {
1920     fn to_usize(&self) -> usize {
1921         *self as usize
1922     }
1923     fn from_usize(v: usize) -> BuiltinBound {
1924         unsafe { mem::transmute(v) }
1925     }
1926 }
1927
1928 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1929 pub struct TyVid {
1930     pub index: u32
1931 }
1932
1933 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1934 pub struct IntVid {
1935     pub index: u32
1936 }
1937
1938 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1939 pub struct FloatVid {
1940     pub index: u32
1941 }
1942
1943 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1944 pub struct RegionVid {
1945     pub index: u32
1946 }
1947
1948 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
1949 pub enum InferTy {
1950     TyVar(TyVid),
1951     IntVar(IntVid),
1952     FloatVar(FloatVid),
1953
1954     /// A `FreshTy` is one that is generated as a replacement for an
1955     /// unbound type variable. This is convenient for caching etc. See
1956     /// `middle::infer::freshen` for more details.
1957     FreshTy(u32),
1958     FreshIntTy(u32),
1959     FreshFloatTy(u32)
1960 }
1961
1962 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
1963 pub enum UnconstrainedNumeric {
1964     UnconstrainedFloat,
1965     UnconstrainedInt,
1966     Neither,
1967 }
1968
1969
1970 #[derive(Clone, RustcEncodable, RustcDecodable, Eq, Hash, Debug, Copy)]
1971 pub enum InferRegion {
1972     ReVar(RegionVid),
1973     ReSkolemized(u32, BoundRegion)
1974 }
1975
1976 impl cmp::PartialEq for InferRegion {
1977     fn eq(&self, other: &InferRegion) -> bool {
1978         match ((*self), *other) {
1979             (ReVar(rva), ReVar(rvb)) => {
1980                 rva == rvb
1981             }
1982             (ReSkolemized(rva, _), ReSkolemized(rvb, _)) => {
1983                 rva == rvb
1984             }
1985             _ => false
1986         }
1987     }
1988     fn ne(&self, other: &InferRegion) -> bool {
1989         !((*self) == (*other))
1990     }
1991 }
1992
1993 impl fmt::Debug for TyVid {
1994     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1995         write!(f, "_#{}t", self.index)
1996     }
1997 }
1998
1999 impl fmt::Debug for IntVid {
2000     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2001         write!(f, "_#{}i", self.index)
2002     }
2003 }
2004
2005 impl fmt::Debug for FloatVid {
2006     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2007         write!(f, "_#{}f", self.index)
2008     }
2009 }
2010
2011 impl fmt::Debug for RegionVid {
2012     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2013         write!(f, "'_#{}r", self.index)
2014     }
2015 }
2016
2017 impl<'tcx> fmt::Debug for FnSig<'tcx> {
2018     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2019         write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output)
2020     }
2021 }
2022
2023 impl fmt::Debug for InferTy {
2024     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2025         match *self {
2026             TyVar(ref v) => v.fmt(f),
2027             IntVar(ref v) => v.fmt(f),
2028             FloatVar(ref v) => v.fmt(f),
2029             FreshTy(v) => write!(f, "FreshTy({:?})", v),
2030             FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
2031             FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
2032         }
2033     }
2034 }
2035
2036 impl fmt::Debug for IntVarValue {
2037     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2038         match *self {
2039             IntType(ref v) => v.fmt(f),
2040             UintType(ref v) => v.fmt(f),
2041         }
2042     }
2043 }
2044
2045 /// Default region to use for the bound of objects that are
2046 /// supplied as the value for this type parameter. This is derived
2047 /// from `T:'a` annotations appearing in the type definition.  If
2048 /// this is `None`, then the default is inherited from the
2049 /// surrounding context. See RFC #599 for details.
2050 #[derive(Copy, Clone)]
2051 pub enum ObjectLifetimeDefault {
2052     /// Require an explicit annotation. Occurs when multiple
2053     /// `T:'a` constraints are found.
2054     Ambiguous,
2055
2056     /// Use the given region as the default.
2057     Specific(Region),
2058 }
2059
2060 #[derive(Clone)]
2061 pub struct TypeParameterDef<'tcx> {
2062     pub name: ast::Name,
2063     pub def_id: ast::DefId,
2064     pub space: subst::ParamSpace,
2065     pub index: u32,
2066     pub default: Option<Ty<'tcx>>,
2067     pub object_lifetime_default: Option<ObjectLifetimeDefault>,
2068 }
2069
2070 #[derive(RustcEncodable, RustcDecodable, Clone, Debug)]
2071 pub struct RegionParameterDef {
2072     pub name: ast::Name,
2073     pub def_id: ast::DefId,
2074     pub space: subst::ParamSpace,
2075     pub index: u32,
2076     pub bounds: Vec<ty::Region>,
2077 }
2078
2079 impl RegionParameterDef {
2080     pub fn to_early_bound_region(&self) -> ty::Region {
2081         ty::ReEarlyBound(ty::EarlyBoundRegion {
2082             param_id: self.def_id.node,
2083             space: self.space,
2084             index: self.index,
2085             name: self.name,
2086         })
2087     }
2088     pub fn to_bound_region(&self) -> ty::BoundRegion {
2089         ty::BoundRegion::BrNamed(self.def_id, self.name)
2090     }
2091 }
2092
2093 /// Information about the formal type/lifetime parameters associated
2094 /// with an item or method. Analogous to ast::Generics.
2095 #[derive(Clone, Debug)]
2096 pub struct Generics<'tcx> {
2097     pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
2098     pub regions: VecPerParamSpace<RegionParameterDef>,
2099 }
2100
2101 impl<'tcx> Generics<'tcx> {
2102     pub fn empty() -> Generics<'tcx> {
2103         Generics {
2104             types: VecPerParamSpace::empty(),
2105             regions: VecPerParamSpace::empty(),
2106         }
2107     }
2108
2109     pub fn is_empty(&self) -> bool {
2110         self.types.is_empty() && self.regions.is_empty()
2111     }
2112
2113     pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
2114         !self.types.is_empty_in(space)
2115     }
2116
2117     pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
2118         !self.regions.is_empty_in(space)
2119     }
2120 }
2121
2122 /// Bounds on generics.
2123 #[derive(Clone)]
2124 pub struct GenericPredicates<'tcx> {
2125     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
2126 }
2127
2128 impl<'tcx> GenericPredicates<'tcx> {
2129     pub fn empty() -> GenericPredicates<'tcx> {
2130         GenericPredicates {
2131             predicates: VecPerParamSpace::empty(),
2132         }
2133     }
2134
2135     pub fn instantiate(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>)
2136                        -> InstantiatedPredicates<'tcx> {
2137         InstantiatedPredicates {
2138             predicates: self.predicates.subst(tcx, substs),
2139         }
2140     }
2141
2142     pub fn instantiate_supertrait(&self,
2143                                   tcx: &ty::ctxt<'tcx>,
2144                                   poly_trait_ref: &ty::PolyTraitRef<'tcx>)
2145                                   -> InstantiatedPredicates<'tcx>
2146     {
2147         InstantiatedPredicates {
2148             predicates: self.predicates.map(|pred| pred.subst_supertrait(tcx, poly_trait_ref))
2149         }
2150     }
2151 }
2152
2153 #[derive(Clone, PartialEq, Eq, Hash)]
2154 pub enum Predicate<'tcx> {
2155     /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
2156     /// the `Self` type of the trait reference and `A`, `B`, and `C`
2157     /// would be the parameters in the `TypeSpace`.
2158     Trait(PolyTraitPredicate<'tcx>),
2159
2160     /// where `T1 == T2`.
2161     Equate(PolyEquatePredicate<'tcx>),
2162
2163     /// where 'a : 'b
2164     RegionOutlives(PolyRegionOutlivesPredicate),
2165
2166     /// where T : 'a
2167     TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
2168
2169     /// where <T as TraitRef>::Name == X, approximately.
2170     /// See `ProjectionPredicate` struct for details.
2171     Projection(PolyProjectionPredicate<'tcx>),
2172 }
2173
2174 impl<'tcx> Predicate<'tcx> {
2175     /// Performs a substitution suitable for going from a
2176     /// poly-trait-ref to supertraits that must hold if that
2177     /// poly-trait-ref holds. This is slightly different from a normal
2178     /// substitution in terms of what happens with bound regions.  See
2179     /// lengthy comment below for details.
2180     pub fn subst_supertrait(&self,
2181                             tcx: &ty::ctxt<'tcx>,
2182                             trait_ref: &ty::PolyTraitRef<'tcx>)
2183                             -> ty::Predicate<'tcx>
2184     {
2185         // The interaction between HRTB and supertraits is not entirely
2186         // obvious. Let me walk you (and myself) through an example.
2187         //
2188         // Let's start with an easy case. Consider two traits:
2189         //
2190         //     trait Foo<'a> : Bar<'a,'a> { }
2191         //     trait Bar<'b,'c> { }
2192         //
2193         // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
2194         // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
2195         // knew that `Foo<'x>` (for any 'x) then we also know that
2196         // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
2197         // normal substitution.
2198         //
2199         // In terms of why this is sound, the idea is that whenever there
2200         // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
2201         // holds.  So if there is an impl of `T:Foo<'a>` that applies to
2202         // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
2203         // `'a`.
2204         //
2205         // Another example to be careful of is this:
2206         //
2207         //     trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
2208         //     trait Bar1<'b,'c> { }
2209         //
2210         // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
2211         // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
2212         // reason is similar to the previous example: any impl of
2213         // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`.  So
2214         // basically we would want to collapse the bound lifetimes from
2215         // the input (`trait_ref`) and the supertraits.
2216         //
2217         // To achieve this in practice is fairly straightforward. Let's
2218         // consider the more complicated scenario:
2219         //
2220         // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
2221         //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
2222         //   where both `'x` and `'b` would have a DB index of 1.
2223         //   The substitution from the input trait-ref is therefore going to be
2224         //   `'a => 'x` (where `'x` has a DB index of 1).
2225         // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
2226         //   early-bound parameter and `'b' is a late-bound parameter with a
2227         //   DB index of 1.
2228         // - If we replace `'a` with `'x` from the input, it too will have
2229         //   a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
2230         //   just as we wanted.
2231         //
2232         // There is only one catch. If we just apply the substitution `'a
2233         // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
2234         // adjust the DB index because we substituting into a binder (it
2235         // tries to be so smart...) resulting in `for<'x> for<'b>
2236         // Bar1<'x,'b>` (we have no syntax for this, so use your
2237         // imagination). Basically the 'x will have DB index of 2 and 'b
2238         // will have DB index of 1. Not quite what we want. So we apply
2239         // the substitution to the *contents* of the trait reference,
2240         // rather than the trait reference itself (put another way, the
2241         // substitution code expects equal binding levels in the values
2242         // from the substitution and the value being substituted into, and
2243         // this trick achieves that).
2244
2245         let substs = &trait_ref.0.substs;
2246         match *self {
2247             Predicate::Trait(ty::Binder(ref data)) =>
2248                 Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
2249             Predicate::Equate(ty::Binder(ref data)) =>
2250                 Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
2251             Predicate::RegionOutlives(ty::Binder(ref data)) =>
2252                 Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))),
2253             Predicate::TypeOutlives(ty::Binder(ref data)) =>
2254                 Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))),
2255             Predicate::Projection(ty::Binder(ref data)) =>
2256                 Predicate::Projection(ty::Binder(data.subst(tcx, substs))),
2257         }
2258     }
2259
2260     // Indicates whether this predicate references only 'global'
2261     // types/lifetimes that are the same regardless of what fn we are
2262     // in. This is used for caching. Errs on the side of returning
2263     // false.
2264     pub fn is_global(&self) -> bool {
2265         match *self {
2266             ty::Predicate::Trait(ref data) => {
2267                 let substs = data.skip_binder().trait_ref.substs;
2268
2269                 substs.types.iter().all(|t| ty::type_is_global(t)) && {
2270                     match substs.regions {
2271                         subst::ErasedRegions => true,
2272                         subst::NonerasedRegions(ref r) => r.iter().all(|r| r.is_global()),
2273                     }
2274                 }
2275             }
2276
2277             _ => {
2278                 false
2279             }
2280         }
2281     }
2282 }
2283
2284 #[derive(Clone, PartialEq, Eq, Hash)]
2285 pub struct TraitPredicate<'tcx> {
2286     pub trait_ref: TraitRef<'tcx>
2287 }
2288 pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
2289
2290 impl<'tcx> TraitPredicate<'tcx> {
2291     pub fn def_id(&self) -> ast::DefId {
2292         self.trait_ref.def_id
2293     }
2294
2295     pub fn input_types(&self) -> &[Ty<'tcx>] {
2296         self.trait_ref.substs.types.as_slice()
2297     }
2298
2299     pub fn self_ty(&self) -> Ty<'tcx> {
2300         self.trait_ref.self_ty()
2301     }
2302 }
2303
2304 impl<'tcx> PolyTraitPredicate<'tcx> {
2305     pub fn def_id(&self) -> ast::DefId {
2306         self.0.def_id()
2307     }
2308 }
2309
2310 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
2311 pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
2312 pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
2313
2314 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
2315 pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
2316 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
2317 pub type PolyRegionOutlivesPredicate = PolyOutlivesPredicate<ty::Region, ty::Region>;
2318 pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region>;
2319
2320 /// This kind of predicate has no *direct* correspondent in the
2321 /// syntax, but it roughly corresponds to the syntactic forms:
2322 ///
2323 /// 1. `T : TraitRef<..., Item=Type>`
2324 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
2325 ///
2326 /// In particular, form #1 is "desugared" to the combination of a
2327 /// normal trait predicate (`T : TraitRef<...>`) and one of these
2328 /// predicates. Form #2 is a broader form in that it also permits
2329 /// equality between arbitrary types. Processing an instance of Form
2330 /// #2 eventually yields one of these `ProjectionPredicate`
2331 /// instances to normalize the LHS.
2332 #[derive(Clone, PartialEq, Eq, Hash)]
2333 pub struct ProjectionPredicate<'tcx> {
2334     pub projection_ty: ProjectionTy<'tcx>,
2335     pub ty: Ty<'tcx>,
2336 }
2337
2338 pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
2339
2340 impl<'tcx> PolyProjectionPredicate<'tcx> {
2341     pub fn item_name(&self) -> ast::Name {
2342         self.0.projection_ty.item_name // safe to skip the binder to access a name
2343     }
2344
2345     pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
2346         self.0.projection_ty.sort_key()
2347     }
2348 }
2349
2350 /// Represents the projection of an associated type. In explicit UFCS
2351 /// form this would be written `<T as Trait<..>>::N`.
2352 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
2353 pub struct ProjectionTy<'tcx> {
2354     /// The trait reference `T as Trait<..>`.
2355     pub trait_ref: ty::TraitRef<'tcx>,
2356
2357     /// The name `N` of the associated type.
2358     pub item_name: ast::Name,
2359 }
2360
2361 impl<'tcx> ProjectionTy<'tcx> {
2362     pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
2363         (self.trait_ref.def_id, self.item_name)
2364     }
2365 }
2366
2367 pub trait ToPolyTraitRef<'tcx> {
2368     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
2369 }
2370
2371 impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
2372     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
2373         assert!(!self.has_escaping_regions());
2374         ty::Binder(self.clone())
2375     }
2376 }
2377
2378 impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
2379     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
2380         self.map_bound_ref(|trait_pred| trait_pred.trait_ref.clone())
2381     }
2382 }
2383
2384 impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
2385     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
2386         // Note: unlike with TraitRef::to_poly_trait_ref(),
2387         // self.0.trait_ref is permitted to have escaping regions.
2388         // This is because here `self` has a `Binder` and so does our
2389         // return value, so we are preserving the number of binding
2390         // levels.
2391         ty::Binder(self.0.projection_ty.trait_ref.clone())
2392     }
2393 }
2394
2395 pub trait AsPredicate<'tcx> {
2396     fn as_predicate(&self) -> Predicate<'tcx>;
2397 }
2398
2399 impl<'tcx> AsPredicate<'tcx> for TraitRef<'tcx> {
2400     fn as_predicate(&self) -> Predicate<'tcx> {
2401         // we're about to add a binder, so let's check that we don't
2402         // accidentally capture anything, or else that might be some
2403         // weird debruijn accounting.
2404         assert!(!self.has_escaping_regions());
2405
2406         ty::Predicate::Trait(ty::Binder(ty::TraitPredicate {
2407             trait_ref: self.clone()
2408         }))
2409     }
2410 }
2411
2412 impl<'tcx> AsPredicate<'tcx> for PolyTraitRef<'tcx> {
2413     fn as_predicate(&self) -> Predicate<'tcx> {
2414         ty::Predicate::Trait(self.to_poly_trait_predicate())
2415     }
2416 }
2417
2418 impl<'tcx> AsPredicate<'tcx> for PolyEquatePredicate<'tcx> {
2419     fn as_predicate(&self) -> Predicate<'tcx> {
2420         Predicate::Equate(self.clone())
2421     }
2422 }
2423
2424 impl<'tcx> AsPredicate<'tcx> for PolyRegionOutlivesPredicate {
2425     fn as_predicate(&self) -> Predicate<'tcx> {
2426         Predicate::RegionOutlives(self.clone())
2427     }
2428 }
2429
2430 impl<'tcx> AsPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
2431     fn as_predicate(&self) -> Predicate<'tcx> {
2432         Predicate::TypeOutlives(self.clone())
2433     }
2434 }
2435
2436 impl<'tcx> AsPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
2437     fn as_predicate(&self) -> Predicate<'tcx> {
2438         Predicate::Projection(self.clone())
2439     }
2440 }
2441
2442 impl<'tcx> Predicate<'tcx> {
2443     /// Iterates over the types in this predicate. Note that in all
2444     /// cases this is skipping over a binder, so late-bound regions
2445     /// with depth 0 are bound by the predicate.
2446     pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
2447         let vec: Vec<_> = match *self {
2448             ty::Predicate::Trait(ref data) => {
2449                 data.0.trait_ref.substs.types.as_slice().to_vec()
2450             }
2451             ty::Predicate::Equate(ty::Binder(ref data)) => {
2452                 vec![data.0, data.1]
2453             }
2454             ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
2455                 vec![data.0]
2456             }
2457             ty::Predicate::RegionOutlives(..) => {
2458                 vec![]
2459             }
2460             ty::Predicate::Projection(ref data) => {
2461                 let trait_inputs = data.0.projection_ty.trait_ref.substs.types.as_slice();
2462                 trait_inputs.iter()
2463                             .cloned()
2464                             .chain(Some(data.0.ty))
2465                             .collect()
2466             }
2467         };
2468
2469         // The only reason to collect into a vector here is that I was
2470         // too lazy to make the full (somewhat complicated) iterator
2471         // type that would be needed here. But I wanted this fn to
2472         // return an iterator conceptually, rather than a `Vec`, so as
2473         // to be closer to `Ty::walk`.
2474         vec.into_iter()
2475     }
2476
2477     pub fn has_escaping_regions(&self) -> bool {
2478         match *self {
2479             Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(),
2480             Predicate::Equate(ref p) => p.has_escaping_regions(),
2481             Predicate::RegionOutlives(ref p) => p.has_escaping_regions(),
2482             Predicate::TypeOutlives(ref p) => p.has_escaping_regions(),
2483             Predicate::Projection(ref p) => p.has_escaping_regions(),
2484         }
2485     }
2486
2487     pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
2488         match *self {
2489             Predicate::Trait(ref t) => {
2490                 Some(t.to_poly_trait_ref())
2491             }
2492             Predicate::Projection(..) |
2493             Predicate::Equate(..) |
2494             Predicate::RegionOutlives(..) |
2495             Predicate::TypeOutlives(..) => {
2496                 None
2497             }
2498         }
2499     }
2500 }
2501
2502 /// Represents the bounds declared on a particular set of type
2503 /// parameters.  Should eventually be generalized into a flag list of
2504 /// where clauses.  You can obtain a `InstantiatedPredicates` list from a
2505 /// `GenericPredicates` by using the `instantiate` method. Note that this method
2506 /// reflects an important semantic invariant of `InstantiatedPredicates`: while
2507 /// the `GenericPredicates` are expressed in terms of the bound type
2508 /// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
2509 /// represented a set of bounds for some particular instantiation,
2510 /// meaning that the generic parameters have been substituted with
2511 /// their values.
2512 ///
2513 /// Example:
2514 ///
2515 ///     struct Foo<T,U:Bar<T>> { ... }
2516 ///
2517 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
2518 /// `[[], [U:Bar<T>]]`.  Now if there were some particular reference
2519 /// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
2520 /// [usize:Bar<isize>]]`.
2521 #[derive(Clone)]
2522 pub struct InstantiatedPredicates<'tcx> {
2523     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
2524 }
2525
2526 impl<'tcx> InstantiatedPredicates<'tcx> {
2527     pub fn empty() -> InstantiatedPredicates<'tcx> {
2528         InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
2529     }
2530
2531     pub fn has_escaping_regions(&self) -> bool {
2532         self.predicates.any(|p| p.has_escaping_regions())
2533     }
2534
2535     pub fn is_empty(&self) -> bool {
2536         self.predicates.is_empty()
2537     }
2538 }
2539
2540 impl<'tcx> TraitRef<'tcx> {
2541     pub fn new(def_id: ast::DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
2542         TraitRef { def_id: def_id, substs: substs }
2543     }
2544
2545     pub fn self_ty(&self) -> Ty<'tcx> {
2546         self.substs.self_ty().unwrap()
2547     }
2548
2549     pub fn input_types(&self) -> &[Ty<'tcx>] {
2550         // Select only the "input types" from a trait-reference. For
2551         // now this is all the types that appear in the
2552         // trait-reference, but it should eventually exclude
2553         // associated types.
2554         self.substs.types.as_slice()
2555     }
2556 }
2557
2558 /// When type checking, we use the `ParameterEnvironment` to track
2559 /// details about the type/lifetime parameters that are in scope.
2560 /// It primarily stores the bounds information.
2561 ///
2562 /// Note: This information might seem to be redundant with the data in
2563 /// `tcx.ty_param_defs`, but it is not. That table contains the
2564 /// parameter definitions from an "outside" perspective, but this
2565 /// struct will contain the bounds for a parameter as seen from inside
2566 /// the function body. Currently the only real distinction is that
2567 /// bound lifetime parameters are replaced with free ones, but in the
2568 /// future I hope to refine the representation of types so as to make
2569 /// more distinctions clearer.
2570 #[derive(Clone)]
2571 pub struct ParameterEnvironment<'a, 'tcx:'a> {
2572     pub tcx: &'a ctxt<'tcx>,
2573
2574     /// See `construct_free_substs` for details.
2575     pub free_substs: Substs<'tcx>,
2576
2577     /// Each type parameter has an implicit region bound that
2578     /// indicates it must outlive at least the function body (the user
2579     /// may specify stronger requirements). This field indicates the
2580     /// region of the callee.
2581     pub implicit_region_bound: ty::Region,
2582
2583     /// Obligations that the caller must satisfy. This is basically
2584     /// the set of bounds on the in-scope type parameters, translated
2585     /// into Obligations, and elaborated and normalized.
2586     pub caller_bounds: Vec<ty::Predicate<'tcx>>,
2587
2588     /// Caches the results of trait selection. This cache is used
2589     /// for things that have to do with the parameters in scope.
2590     pub selection_cache: traits::SelectionCache<'tcx>,
2591 }
2592
2593 impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2594     pub fn with_caller_bounds(&self,
2595                               caller_bounds: Vec<ty::Predicate<'tcx>>)
2596                               -> ParameterEnvironment<'a,'tcx>
2597     {
2598         ParameterEnvironment {
2599             tcx: self.tcx,
2600             free_substs: self.free_substs.clone(),
2601             implicit_region_bound: self.implicit_region_bound,
2602             caller_bounds: caller_bounds,
2603             selection_cache: traits::SelectionCache::new(),
2604         }
2605     }
2606
2607     pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
2608         match cx.map.find(id) {
2609             Some(ast_map::NodeImplItem(ref impl_item)) => {
2610                 match impl_item.node {
2611                     ast::ConstImplItem(_, _) => {
2612                         let def_id = ast_util::local_def(id);
2613                         let scheme = lookup_item_type(cx, def_id);
2614                         let predicates = lookup_predicates(cx, def_id);
2615                         construct_parameter_environment(cx,
2616                                                         impl_item.span,
2617                                                         &scheme.generics,
2618                                                         &predicates,
2619                                                         id)
2620                     }
2621                     ast::MethodImplItem(_, ref body) => {
2622                         let method_def_id = ast_util::local_def(id);
2623                         match ty::impl_or_trait_item(cx, method_def_id) {
2624                             MethodTraitItem(ref method_ty) => {
2625                                 let method_generics = &method_ty.generics;
2626                                 let method_bounds = &method_ty.predicates;
2627                                 construct_parameter_environment(
2628                                     cx,
2629                                     impl_item.span,
2630                                     method_generics,
2631                                     method_bounds,
2632                                     body.id)
2633                             }
2634                             _ => {
2635                                 cx.sess
2636                                   .bug("ParameterEnvironment::for_item(): \
2637                                         got non-method item from impl method?!")
2638                             }
2639                         }
2640                     }
2641                     ast::TypeImplItem(_) => {
2642                         cx.sess.bug("ParameterEnvironment::for_item(): \
2643                                      can't create a parameter environment \
2644                                      for type impl items")
2645                     }
2646                     ast::MacImplItem(_) => cx.sess.bug("unexpanded macro")
2647                 }
2648             }
2649             Some(ast_map::NodeTraitItem(trait_item)) => {
2650                 match trait_item.node {
2651                     ast::ConstTraitItem(_, ref default) => {
2652                         match *default {
2653                             Some(_) => {
2654                                 let def_id = ast_util::local_def(id);
2655                                 let scheme = lookup_item_type(cx, def_id);
2656                                 let predicates = lookup_predicates(cx, def_id);
2657                                 construct_parameter_environment(cx,
2658                                                                 trait_item.span,
2659                                                                 &scheme.generics,
2660                                                                 &predicates,
2661                                                                 id)
2662                             }
2663                             None => {
2664                                 cx.sess.bug("ParameterEnvironment::from_item(): \
2665                                              can't create a parameter environment \
2666                                              for const trait items without defaults")
2667                             }
2668                         }
2669                     }
2670                     ast::MethodTraitItem(_, None) => {
2671                         cx.sess.span_bug(trait_item.span,
2672                                          "ParameterEnvironment::for_item():
2673                                           can't create a parameter \
2674                                           environment for required trait \
2675                                           methods")
2676                     }
2677                     ast::MethodTraitItem(_, Some(ref body)) => {
2678                         let method_def_id = ast_util::local_def(id);
2679                         match ty::impl_or_trait_item(cx, method_def_id) {
2680                             MethodTraitItem(ref method_ty) => {
2681                                 let method_generics = &method_ty.generics;
2682                                 let method_bounds = &method_ty.predicates;
2683                                 construct_parameter_environment(
2684                                     cx,
2685                                     trait_item.span,
2686                                     method_generics,
2687                                     method_bounds,
2688                                     body.id)
2689                             }
2690                             _ => {
2691                                 cx.sess
2692                                   .bug("ParameterEnvironment::for_item(): \
2693                                         got non-method item from provided \
2694                                         method?!")
2695                             }
2696                         }
2697                     }
2698                     ast::TypeTraitItem(..) => {
2699                         cx.sess.bug("ParameterEnvironment::from_item(): \
2700                                      can't create a parameter environment \
2701                                      for type trait items")
2702                     }
2703                 }
2704             }
2705             Some(ast_map::NodeItem(item)) => {
2706                 match item.node {
2707                     ast::ItemFn(_, _, _, _, _, ref body) => {
2708                         // We assume this is a function.
2709                         let fn_def_id = ast_util::local_def(id);
2710                         let fn_scheme = lookup_item_type(cx, fn_def_id);
2711                         let fn_predicates = lookup_predicates(cx, fn_def_id);
2712
2713                         construct_parameter_environment(cx,
2714                                                         item.span,
2715                                                         &fn_scheme.generics,
2716                                                         &fn_predicates,
2717                                                         body.id)
2718                     }
2719                     ast::ItemEnum(..) |
2720                     ast::ItemStruct(..) |
2721                     ast::ItemImpl(..) |
2722                     ast::ItemConst(..) |
2723                     ast::ItemStatic(..) => {
2724                         let def_id = ast_util::local_def(id);
2725                         let scheme = lookup_item_type(cx, def_id);
2726                         let predicates = lookup_predicates(cx, def_id);
2727                         construct_parameter_environment(cx,
2728                                                         item.span,
2729                                                         &scheme.generics,
2730                                                         &predicates,
2731                                                         id)
2732                     }
2733                     _ => {
2734                         cx.sess.span_bug(item.span,
2735                                          "ParameterEnvironment::from_item():
2736                                           can't create a parameter \
2737                                           environment for this kind of item")
2738                     }
2739                 }
2740             }
2741             Some(ast_map::NodeExpr(..)) => {
2742                 // This is a convenience to allow closures to work.
2743                 ParameterEnvironment::for_item(cx, cx.map.get_parent(id))
2744             }
2745             _ => {
2746                 cx.sess.bug(&format!("ParameterEnvironment::from_item(): \
2747                                      `{}` is not an item",
2748                                     cx.map.node_to_string(id)))
2749             }
2750         }
2751     }
2752 }
2753
2754 /// A "type scheme", in ML terminology, is a type combined with some
2755 /// set of generic types that the type is, well, generic over. In Rust
2756 /// terms, it is the "type" of a fn item or struct -- this type will
2757 /// include various generic parameters that must be substituted when
2758 /// the item/struct is referenced. That is called converting the type
2759 /// scheme to a monotype.
2760 ///
2761 /// - `generics`: the set of type parameters and their bounds
2762 /// - `ty`: the base types, which may reference the parameters defined
2763 ///   in `generics`
2764 ///
2765 /// Note that TypeSchemes are also sometimes called "polytypes" (and
2766 /// in fact this struct used to carry that name, so you may find some
2767 /// stray references in a comment or something). We try to reserve the
2768 /// "poly" prefix to refer to higher-ranked things, as in
2769 /// `PolyTraitRef`.
2770 ///
2771 /// Note that each item also comes with predicates, see
2772 /// `lookup_predicates`.
2773 #[derive(Clone, Debug)]
2774 pub struct TypeScheme<'tcx> {
2775     pub generics: Generics<'tcx>,
2776     pub ty: Ty<'tcx>,
2777 }
2778
2779 bitflags! {
2780     flags TraitFlags: u32 {
2781         const NO_TRAIT_FLAGS        = 0,
2782         const HAS_DEFAULT_IMPL      = 1 << 0,
2783         const IS_OBJECT_SAFE        = 1 << 1,
2784         const OBJECT_SAFETY_VALID   = 1 << 2,
2785         const IMPLS_VALID           = 1 << 3,
2786     }
2787 }
2788
2789 /// As `TypeScheme` but for a trait ref.
2790 pub struct TraitDef<'tcx> {
2791     pub unsafety: ast::Unsafety,
2792
2793     /// If `true`, then this trait had the `#[rustc_paren_sugar]`
2794     /// attribute, indicating that it should be used with `Foo()`
2795     /// sugar. This is a temporary thing -- eventually any trait wil
2796     /// be usable with the sugar (or without it).
2797     pub paren_sugar: bool,
2798
2799     /// Generic type definitions. Note that `Self` is listed in here
2800     /// as having a single bound, the trait itself (e.g., in the trait
2801     /// `Eq`, there is a single bound `Self : Eq`). This is so that
2802     /// default methods get to assume that the `Self` parameters
2803     /// implements the trait.
2804     pub generics: Generics<'tcx>,
2805
2806     pub trait_ref: TraitRef<'tcx>,
2807
2808     /// A list of the associated types defined in this trait. Useful
2809     /// for resolving `X::Foo` type markers.
2810     pub associated_type_names: Vec<ast::Name>,
2811
2812     // Impls of this trait. To allow for quicker lookup, the impls are indexed
2813     // by a simplified version of their Self type: impls with a simplifiable
2814     // Self are stored in nonblanket_impls keyed by it, while all other impls
2815     // are stored in blanket_impls.
2816
2817     /// Impls of the trait.
2818     pub nonblanket_impls: RefCell<
2819         FnvHashMap<fast_reject::SimplifiedType, Vec<DefId>>
2820     >,
2821
2822     /// Blanket impls associated with the trait.
2823     pub blanket_impls: RefCell<Vec<DefId>>,
2824
2825     /// Various flags
2826     pub flags: Cell<TraitFlags>
2827 }
2828
2829 impl<'tcx> TraitDef<'tcx> {
2830     // returns None if not yet calculated
2831     pub fn object_safety(&self) -> Option<bool> {
2832         if self.flags.get().intersects(TraitFlags::OBJECT_SAFETY_VALID) {
2833             Some(self.flags.get().intersects(TraitFlags::IS_OBJECT_SAFE))
2834         } else {
2835             None
2836         }
2837     }
2838
2839     pub fn set_object_safety(&self, is_safe: bool) {
2840         assert!(self.object_safety().map(|cs| cs == is_safe).unwrap_or(true));
2841         self.flags.set(
2842             self.flags.get() | if is_safe {
2843                 TraitFlags::OBJECT_SAFETY_VALID | TraitFlags::IS_OBJECT_SAFE
2844             } else {
2845                 TraitFlags::OBJECT_SAFETY_VALID
2846             }
2847         );
2848     }
2849
2850     /// Records a trait-to-implementation mapping.
2851     pub fn record_impl(&self,
2852                        tcx: &ctxt<'tcx>,
2853                        impl_def_id: DefId,
2854                        impl_trait_ref: TraitRef<'tcx>) {
2855         debug!("TraitDef::record_impl for {:?}, from {:?}",
2856                self, impl_trait_ref);
2857
2858         // We don't want to borrow_mut after we already populated all impls,
2859         // so check if an impl is present with an immutable borrow first.
2860         if let Some(sty) = fast_reject::simplify_type(tcx,
2861                                                       impl_trait_ref.self_ty(), false) {
2862             if let Some(is) = self.nonblanket_impls.borrow().get(&sty) {
2863                 if is.contains(&impl_def_id) {
2864                     return // duplicate - skip
2865                 }
2866             }
2867
2868             self.nonblanket_impls.borrow_mut().entry(sty).or_insert(vec![]).push(impl_def_id)
2869         } else {
2870             if self.blanket_impls.borrow().contains(&impl_def_id) {
2871                 return // duplicate - skip
2872             }
2873             self.blanket_impls.borrow_mut().push(impl_def_id)
2874         }
2875     }
2876
2877
2878     pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: &ctxt<'tcx>, mut f: F)  {
2879         ty::populate_implementations_for_trait_if_necessary(tcx, self.trait_ref.def_id);
2880
2881         for &impl_def_id in self.blanket_impls.borrow().iter() {
2882             f(impl_def_id);
2883         }
2884
2885         for v in self.nonblanket_impls.borrow().values() {
2886             for &impl_def_id in v {
2887                 f(impl_def_id);
2888             }
2889         }
2890     }
2891
2892     pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
2893                                                    tcx: &ctxt<'tcx>,
2894                                                    self_ty: Ty<'tcx>,
2895                                                    mut f: F)
2896     {
2897         ty::populate_implementations_for_trait_if_necessary(tcx, self.trait_ref.def_id);
2898
2899         for &impl_def_id in self.blanket_impls.borrow().iter() {
2900             f(impl_def_id);
2901         }
2902
2903         if let Some(simp) = fast_reject::simplify_type(tcx, self_ty, false) {
2904             if let Some(impls) = self.nonblanket_impls.borrow().get(&simp) {
2905                 for &impl_def_id in impls {
2906                     f(impl_def_id);
2907                 }
2908                 return; // we don't need to process the other non-blanket impls
2909             }
2910         }
2911
2912         for v in self.nonblanket_impls.borrow().values() {
2913             for &impl_def_id in v {
2914                 f(impl_def_id);
2915             }
2916         }
2917     }
2918
2919 }
2920
2921 /// Records the substitutions used to translate the polytype for an
2922 /// item into the monotype of an item reference.
2923 #[derive(Clone)]
2924 pub struct ItemSubsts<'tcx> {
2925     pub substs: Substs<'tcx>,
2926 }
2927
2928 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
2929 pub enum ClosureKind {
2930     // Warning: Ordering is significant here! The ordering is chosen
2931     // because the trait Fn is a subtrait of FnMut and so in turn, and
2932     // hence we order it so that Fn < FnMut < FnOnce.
2933     FnClosureKind,
2934     FnMutClosureKind,
2935     FnOnceClosureKind,
2936 }
2937
2938 impl ClosureKind {
2939     pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
2940         let result = match *self {
2941             FnClosureKind => cx.lang_items.require(FnTraitLangItem),
2942             FnMutClosureKind => {
2943                 cx.lang_items.require(FnMutTraitLangItem)
2944             }
2945             FnOnceClosureKind => {
2946                 cx.lang_items.require(FnOnceTraitLangItem)
2947             }
2948         };
2949         match result {
2950             Ok(trait_did) => trait_did,
2951             Err(err) => cx.sess.fatal(&err[..]),
2952         }
2953     }
2954
2955     /// True if this a type that impls this closure kind
2956     /// must also implement `other`.
2957     pub fn extends(self, other: ty::ClosureKind) -> bool {
2958         match (self, other) {
2959             (FnClosureKind, FnClosureKind) => true,
2960             (FnClosureKind, FnMutClosureKind) => true,
2961             (FnClosureKind, FnOnceClosureKind) => true,
2962             (FnMutClosureKind, FnMutClosureKind) => true,
2963             (FnMutClosureKind, FnOnceClosureKind) => true,
2964             (FnOnceClosureKind, FnOnceClosureKind) => true,
2965             _ => false,
2966         }
2967     }
2968 }
2969
2970 pub trait ClosureTyper<'tcx> {
2971     fn tcx(&self) -> &ty::ctxt<'tcx> {
2972         self.param_env().tcx
2973     }
2974
2975     fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
2976
2977     /// Is this a `Fn`, `FnMut` or `FnOnce` closure? During typeck,
2978     /// returns `None` if the kind of this closure has not yet been
2979     /// inferred.
2980     fn closure_kind(&self,
2981                     def_id: ast::DefId)
2982                     -> Option<ty::ClosureKind>;
2983
2984     /// Returns the argument/return types of this closure.
2985     fn closure_type(&self,
2986                     def_id: ast::DefId,
2987                     substs: &subst::Substs<'tcx>)
2988                     -> ty::ClosureTy<'tcx>;
2989
2990     /// Returns the set of all upvars and their transformed
2991     /// types. During typeck, maybe return `None` if the upvar types
2992     /// have not yet been inferred.
2993     fn closure_upvars(&self,
2994                       def_id: ast::DefId,
2995                       substs: &Substs<'tcx>)
2996                       -> Option<Vec<ClosureUpvar<'tcx>>>;
2997 }
2998
2999 impl<'tcx> CommonTypes<'tcx> {
3000     fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
3001            interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>)
3002            -> CommonTypes<'tcx>
3003     {
3004         CommonTypes {
3005             bool: intern_ty(arena, interner, TyBool),
3006             char: intern_ty(arena, interner, TyChar),
3007             err: intern_ty(arena, interner, TyError),
3008             isize: intern_ty(arena, interner, TyInt(ast::TyIs)),
3009             i8: intern_ty(arena, interner, TyInt(ast::TyI8)),
3010             i16: intern_ty(arena, interner, TyInt(ast::TyI16)),
3011             i32: intern_ty(arena, interner, TyInt(ast::TyI32)),
3012             i64: intern_ty(arena, interner, TyInt(ast::TyI64)),
3013             usize: intern_ty(arena, interner, TyUint(ast::TyUs)),
3014             u8: intern_ty(arena, interner, TyUint(ast::TyU8)),
3015             u16: intern_ty(arena, interner, TyUint(ast::TyU16)),
3016             u32: intern_ty(arena, interner, TyUint(ast::TyU32)),
3017             u64: intern_ty(arena, interner, TyUint(ast::TyU64)),
3018             f32: intern_ty(arena, interner, TyFloat(ast::TyF32)),
3019             f64: intern_ty(arena, interner, TyFloat(ast::TyF64)),
3020         }
3021     }
3022 }
3023
3024 /// Create a type context and call the closure with a `&ty::ctxt` reference
3025 /// to the context. The closure enforces that the type context and any interned
3026 /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
3027 /// reference to the context, to allow formatting values that need it.
3028 pub fn with_ctxt<'tcx, F, R>(s: Session,
3029                              arenas: &'tcx CtxtArenas<'tcx>,
3030                              def_map: DefMap,
3031                              named_region_map: resolve_lifetime::NamedRegionMap,
3032                              map: ast_map::Map<'tcx>,
3033                              freevars: RefCell<FreevarMap>,
3034                              region_maps: RegionMaps,
3035                              lang_items: middle::lang_items::LanguageItems,
3036                              stability: stability::Index<'tcx>,
3037                              f: F) -> (Session, R)
3038                              where F: FnOnce(&ctxt<'tcx>) -> R
3039 {
3040     let mut interner = FnvHashMap();
3041     let common_types = CommonTypes::new(&arenas.type_, &mut interner);
3042
3043     tls::enter(ctxt {
3044         arenas: arenas,
3045         interner: RefCell::new(interner),
3046         substs_interner: RefCell::new(FnvHashMap()),
3047         bare_fn_interner: RefCell::new(FnvHashMap()),
3048         region_interner: RefCell::new(FnvHashMap()),
3049         stability_interner: RefCell::new(FnvHashMap()),
3050         types: common_types,
3051         named_region_map: named_region_map,
3052         region_maps: region_maps,
3053         free_region_maps: RefCell::new(FnvHashMap()),
3054         item_variance_map: RefCell::new(DefIdMap()),
3055         variance_computed: Cell::new(false),
3056         sess: s,
3057         def_map: def_map,
3058         node_types: RefCell::new(FnvHashMap()),
3059         item_substs: RefCell::new(NodeMap()),
3060         impl_trait_refs: RefCell::new(DefIdMap()),
3061         trait_defs: RefCell::new(DefIdMap()),
3062         predicates: RefCell::new(DefIdMap()),
3063         super_predicates: RefCell::new(DefIdMap()),
3064         fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()),
3065         map: map,
3066         freevars: freevars,
3067         tcache: RefCell::new(DefIdMap()),
3068         rcache: RefCell::new(FnvHashMap()),
3069         tc_cache: RefCell::new(FnvHashMap()),
3070         ast_ty_to_ty_cache: RefCell::new(NodeMap()),
3071         enum_var_cache: RefCell::new(DefIdMap()),
3072         impl_or_trait_items: RefCell::new(DefIdMap()),
3073         trait_item_def_ids: RefCell::new(DefIdMap()),
3074         trait_items_cache: RefCell::new(DefIdMap()),
3075         ty_param_defs: RefCell::new(NodeMap()),
3076         adjustments: RefCell::new(NodeMap()),
3077         normalized_cache: RefCell::new(FnvHashMap()),
3078         lang_items: lang_items,
3079         provided_method_sources: RefCell::new(DefIdMap()),
3080         struct_fields: RefCell::new(DefIdMap()),
3081         destructor_for_type: RefCell::new(DefIdMap()),
3082         destructors: RefCell::new(DefIdSet()),
3083         inherent_impls: RefCell::new(DefIdMap()),
3084         impl_items: RefCell::new(DefIdMap()),
3085         used_unsafe: RefCell::new(NodeSet()),
3086         used_mut_nodes: RefCell::new(NodeSet()),
3087         populated_external_types: RefCell::new(DefIdSet()),
3088         populated_external_primitive_impls: RefCell::new(DefIdSet()),
3089         upvar_capture_map: RefCell::new(FnvHashMap()),
3090         extern_const_statics: RefCell::new(DefIdMap()),
3091         extern_const_variants: RefCell::new(DefIdMap()),
3092         extern_const_fns: RefCell::new(DefIdMap()),
3093         method_map: RefCell::new(FnvHashMap()),
3094         dependency_formats: RefCell::new(FnvHashMap()),
3095         closure_kinds: RefCell::new(DefIdMap()),
3096         closure_tys: RefCell::new(DefIdMap()),
3097         node_lint_levels: RefCell::new(FnvHashMap()),
3098         transmute_restrictions: RefCell::new(Vec::new()),
3099         stability: RefCell::new(stability),
3100         selection_cache: traits::SelectionCache::new(),
3101         repr_hint_cache: RefCell::new(DefIdMap()),
3102         const_qualif_map: RefCell::new(NodeMap()),
3103         custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
3104         cast_kinds: RefCell::new(NodeMap()),
3105    }, f)
3106 }
3107
3108 // Type constructors
3109
3110 impl<'tcx> ctxt<'tcx> {
3111     pub fn mk_substs(&self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> {
3112         if let Some(substs) = self.substs_interner.borrow().get(&substs) {
3113             return *substs;
3114         }
3115
3116         let substs = self.arenas.substs.alloc(substs);
3117         self.substs_interner.borrow_mut().insert(substs, substs);
3118         substs
3119     }
3120
3121     /// Create an unsafe fn ty based on a safe fn ty.
3122     pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
3123         assert_eq!(bare_fn.unsafety, ast::Unsafety::Normal);
3124         let unsafe_fn_ty_a = self.mk_bare_fn(ty::BareFnTy {
3125             unsafety: ast::Unsafety::Unsafe,
3126             abi: bare_fn.abi,
3127             sig: bare_fn.sig.clone()
3128         });
3129         ty::mk_bare_fn(self, None, unsafe_fn_ty_a)
3130     }
3131
3132     pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
3133         if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) {
3134             return *bare_fn;
3135         }
3136
3137         let bare_fn = self.arenas.bare_fn.alloc(bare_fn);
3138         self.bare_fn_interner.borrow_mut().insert(bare_fn, bare_fn);
3139         bare_fn
3140     }
3141
3142     pub fn mk_region(&self, region: Region) -> &'tcx Region {
3143         if let Some(region) = self.region_interner.borrow().get(&region) {
3144             return *region;
3145         }
3146
3147         let region = self.arenas.region.alloc(region);
3148         self.region_interner.borrow_mut().insert(region, region);
3149         region
3150     }
3151
3152     pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
3153         *self.closure_kinds.borrow().get(&def_id).unwrap()
3154     }
3155
3156     pub fn closure_type(&self,
3157                         def_id: ast::DefId,
3158                         substs: &subst::Substs<'tcx>)
3159                         -> ty::ClosureTy<'tcx>
3160     {
3161         self.closure_tys.borrow().get(&def_id).unwrap().subst(self, substs)
3162     }
3163
3164     pub fn type_parameter_def(&self,
3165                               node_id: ast::NodeId)
3166                               -> TypeParameterDef<'tcx>
3167     {
3168         self.ty_param_defs.borrow().get(&node_id).unwrap().clone()
3169     }
3170
3171     pub fn pat_contains_ref_binding(&self, pat: &ast::Pat) -> Option<ast::Mutability> {
3172         pat_util::pat_contains_ref_binding(&self.def_map, pat)
3173     }
3174
3175     pub fn arm_contains_ref_binding(&self, arm: &ast::Arm) -> Option<ast::Mutability> {
3176         pat_util::arm_contains_ref_binding(&self.def_map, arm)
3177     }
3178 }
3179
3180 // Interns a type/name combination, stores the resulting box in cx.interner,
3181 // and returns the box as cast to an unsafe ptr (see comments for Ty above).
3182 pub fn mk_t<'tcx>(cx: &ctxt<'tcx>, st: TypeVariants<'tcx>) -> Ty<'tcx> {
3183     let mut interner = cx.interner.borrow_mut();
3184     intern_ty(&cx.arenas.type_, &mut *interner, st)
3185 }
3186
3187 fn intern_ty<'tcx>(type_arena: &'tcx TypedArena<TyS<'tcx>>,
3188                    interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>,
3189                    st: TypeVariants<'tcx>)
3190                    -> Ty<'tcx>
3191 {
3192     match interner.get(&st) {
3193         Some(ty) => return *ty,
3194         _ => ()
3195     }
3196
3197     let flags = FlagComputation::for_sty(&st);
3198
3199     let ty = match () {
3200         () => type_arena.alloc(TyS { sty: st,
3201                                      flags: Cell::new(flags.flags),
3202                                      region_depth: flags.depth, }),
3203     };
3204
3205     debug!("Interned type: {:?} Pointer: {:?}",
3206            ty, ty as *const TyS);
3207
3208     interner.insert(InternedTy { ty: ty }, ty);
3209
3210     ty
3211 }
3212
3213 struct FlagComputation {
3214     flags: TypeFlags,
3215
3216     // maximum depth of any bound region that we have seen thus far
3217     depth: u32,
3218 }
3219
3220 impl FlagComputation {
3221     fn new() -> FlagComputation {
3222         FlagComputation { flags: TypeFlags::empty(), depth: 0 }
3223     }
3224
3225     fn for_sty(st: &TypeVariants) -> FlagComputation {
3226         let mut result = FlagComputation::new();
3227         result.add_sty(st);
3228         result
3229     }
3230
3231     fn add_flags(&mut self, flags: TypeFlags) {
3232         self.flags = self.flags | (flags & TypeFlags::NOMINAL_FLAGS);
3233     }
3234
3235     fn add_depth(&mut self, depth: u32) {
3236         if depth > self.depth {
3237             self.depth = depth;
3238         }
3239     }
3240
3241     /// Adds the flags/depth from a set of types that appear within the current type, but within a
3242     /// region binder.
3243     fn add_bound_computation(&mut self, computation: &FlagComputation) {
3244         self.add_flags(computation.flags);
3245
3246         // The types that contributed to `computation` occurred within
3247         // a region binder, so subtract one from the region depth
3248         // within when adding the depth to `self`.
3249         let depth = computation.depth;
3250         if depth > 0 {
3251             self.add_depth(depth - 1);
3252         }
3253     }
3254
3255     fn add_sty(&mut self, st: &TypeVariants) {
3256         match st {
3257             &TyBool |
3258             &TyChar |
3259             &TyInt(_) |
3260             &TyFloat(_) |
3261             &TyUint(_) |
3262             &TyStr => {
3263             }
3264
3265             // You might think that we could just return TyError for
3266             // any type containing TyError as a component, and get
3267             // rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
3268             // the exception of function types that return bot).
3269             // But doing so caused sporadic memory corruption, and
3270             // neither I (tjc) nor nmatsakis could figure out why,
3271             // so we're doing it this way.
3272             &TyError => {
3273                 self.add_flags(TypeFlags::HAS_TY_ERR)
3274             }
3275
3276             &TyParam(ref p) => {
3277                 self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
3278                 if p.space == subst::SelfSpace {
3279                     self.add_flags(TypeFlags::HAS_SELF);
3280                 } else {
3281                     self.add_flags(TypeFlags::HAS_PARAMS);
3282                 }
3283             }
3284
3285             &TyClosure(_, substs) => {
3286                 self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
3287                 self.add_substs(substs);
3288             }
3289
3290             &TyInfer(_) => {
3291                 self.add_flags(TypeFlags::HAS_LOCAL_NAMES); // it might, right?
3292                 self.add_flags(TypeFlags::HAS_TY_INFER)
3293             }
3294
3295             &TyEnum(_, substs) | &TyStruct(_, substs) => {
3296                 self.add_substs(substs);
3297             }
3298
3299             &TyProjection(ref data) => {
3300                 self.add_flags(TypeFlags::HAS_PROJECTION);
3301                 self.add_projection_ty(data);
3302             }
3303
3304             &TyTrait(box TraitTy { ref principal, ref bounds }) => {
3305                 let mut computation = FlagComputation::new();
3306                 computation.add_substs(principal.0.substs);
3307                 for projection_bound in &bounds.projection_bounds {
3308                     let mut proj_computation = FlagComputation::new();
3309                     proj_computation.add_projection_predicate(&projection_bound.0);
3310                     self.add_bound_computation(&proj_computation);
3311                 }
3312                 self.add_bound_computation(&computation);
3313
3314                 self.add_bounds(bounds);
3315             }
3316
3317             &TyBox(tt) | &TyArray(tt, _) | &TySlice(tt) => {
3318                 self.add_ty(tt)
3319             }
3320
3321             &TyRawPtr(ref m) => {
3322                 self.add_ty(m.ty);
3323             }
3324
3325             &TyRef(r, ref m) => {
3326                 self.add_region(*r);
3327                 self.add_ty(m.ty);
3328             }
3329
3330             &TyTuple(ref ts) => {
3331                 self.add_tys(&ts[..]);
3332             }
3333
3334             &TyBareFn(_, ref f) => {
3335                 self.add_fn_sig(&f.sig);
3336             }
3337         }
3338     }
3339
3340     fn add_ty(&mut self, ty: Ty) {
3341         self.add_flags(ty.flags.get());
3342         self.add_depth(ty.region_depth);
3343     }
3344
3345     fn add_tys(&mut self, tys: &[Ty]) {
3346         for &ty in tys {
3347             self.add_ty(ty);
3348         }
3349     }
3350
3351     fn add_fn_sig(&mut self, fn_sig: &PolyFnSig) {
3352         let mut computation = FlagComputation::new();
3353
3354         computation.add_tys(&fn_sig.0.inputs);
3355
3356         if let ty::FnConverging(output) = fn_sig.0.output {
3357             computation.add_ty(output);
3358         }
3359
3360         self.add_bound_computation(&computation);
3361     }
3362
3363     fn add_region(&mut self, r: Region) {
3364         match r {
3365             ty::ReInfer(_) => { self.add_flags(TypeFlags::HAS_RE_INFER); }
3366             ty::ReLateBound(debruijn, _) => { self.add_depth(debruijn.depth); }
3367             ty::ReEarlyBound(..) => { self.add_flags(TypeFlags::HAS_RE_EARLY_BOUND); }
3368             ty::ReStatic => {}
3369             _ => { self.add_flags(TypeFlags::HAS_FREE_REGIONS); }
3370         }
3371
3372         if !r.is_global() {
3373             self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
3374         }
3375     }
3376
3377     fn add_projection_predicate(&mut self, projection_predicate: &ProjectionPredicate) {
3378         self.add_projection_ty(&projection_predicate.projection_ty);
3379         self.add_ty(projection_predicate.ty);
3380     }
3381
3382     fn add_projection_ty(&mut self, projection_ty: &ProjectionTy) {
3383         self.add_substs(projection_ty.trait_ref.substs);
3384     }
3385
3386     fn add_substs(&mut self, substs: &Substs) {
3387         self.add_tys(substs.types.as_slice());
3388         match substs.regions {
3389             subst::ErasedRegions => {}
3390             subst::NonerasedRegions(ref regions) => {
3391                 for &r in regions {
3392                     self.add_region(r);
3393                 }
3394             }
3395         }
3396     }
3397
3398     fn add_bounds(&mut self, bounds: &ExistentialBounds) {
3399         self.add_region(bounds.region_bound);
3400     }
3401 }
3402
3403 pub fn mk_mach_int<'tcx>(tcx: &ctxt<'tcx>, tm: ast::IntTy) -> Ty<'tcx> {
3404     match tm {
3405         ast::TyIs   => tcx.types.isize,
3406         ast::TyI8   => tcx.types.i8,
3407         ast::TyI16  => tcx.types.i16,
3408         ast::TyI32  => tcx.types.i32,
3409         ast::TyI64  => tcx.types.i64,
3410     }
3411 }
3412
3413 pub fn mk_mach_uint<'tcx>(tcx: &ctxt<'tcx>, tm: ast::UintTy) -> Ty<'tcx> {
3414     match tm {
3415         ast::TyUs   => tcx.types.usize,
3416         ast::TyU8   => tcx.types.u8,
3417         ast::TyU16  => tcx.types.u16,
3418         ast::TyU32  => tcx.types.u32,
3419         ast::TyU64  => tcx.types.u64,
3420     }
3421 }
3422
3423 pub fn mk_mach_float<'tcx>(tcx: &ctxt<'tcx>, tm: ast::FloatTy) -> Ty<'tcx> {
3424     match tm {
3425         ast::TyF32  => tcx.types.f32,
3426         ast::TyF64  => tcx.types.f64,
3427     }
3428 }
3429
3430 pub fn mk_str<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3431     mk_t(cx, TyStr)
3432 }
3433
3434 pub fn mk_str_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, m: ast::Mutability) -> Ty<'tcx> {
3435     mk_rptr(cx, r,
3436             mt {
3437                 ty: mk_t(cx, TyStr),
3438                 mutbl: m
3439             })
3440 }
3441
3442 pub fn mk_enum<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
3443     // take a copy of substs so that we own the vectors inside
3444     mk_t(cx, TyEnum(did, substs))
3445 }
3446
3447 pub fn mk_uniq<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, TyBox(ty)) }
3448
3449 pub fn mk_ptr<'tcx>(cx: &ctxt<'tcx>, tm: mt<'tcx>) -> Ty<'tcx> { mk_t(cx, TyRawPtr(tm)) }
3450
3451 pub fn mk_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> {
3452     mk_t(cx, TyRef(r, tm))
3453 }
3454
3455 pub fn mk_mut_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
3456     mk_rptr(cx, r, mt {ty: ty, mutbl: ast::MutMutable})
3457 }
3458 pub fn mk_imm_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
3459     mk_rptr(cx, r, mt {ty: ty, mutbl: ast::MutImmutable})
3460 }
3461
3462 pub fn mk_mut_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3463     mk_ptr(cx, mt {ty: ty, mutbl: ast::MutMutable})
3464 }
3465
3466 pub fn mk_imm_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3467     mk_ptr(cx, mt {ty: ty, mutbl: ast::MutImmutable})
3468 }
3469
3470 pub fn mk_nil_ptr<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3471     mk_ptr(cx, mt {ty: mk_nil(cx), mutbl: ast::MutImmutable})
3472 }
3473
3474 pub fn mk_vec<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, sz: Option<usize>) -> Ty<'tcx> {
3475     match sz {
3476         Some(n) => mk_t(cx, TyArray(ty, n)),
3477         None => mk_t(cx, TySlice(ty))
3478     }
3479 }
3480
3481 pub fn mk_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> {
3482     mk_rptr(cx, r,
3483             mt {
3484                 ty: mk_vec(cx, tm.ty, None),
3485                 mutbl: tm.mutbl
3486             })
3487 }
3488
3489 pub fn mk_tup<'tcx>(cx: &ctxt<'tcx>, ts: Vec<Ty<'tcx>>) -> Ty<'tcx> {
3490     mk_t(cx, TyTuple(ts))
3491 }
3492
3493 pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3494     mk_tup(cx, Vec::new())
3495 }
3496
3497 pub fn mk_bool<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3498     mk_t(cx, TyBool)
3499 }
3500
3501 pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
3502                         opt_def_id: Option<ast::DefId>,
3503                         fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
3504     mk_t(cx, TyBareFn(opt_def_id, fty))
3505 }
3506
3507 pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
3508                         def_id: ast::DefId,
3509                         input_tys: &[Ty<'tcx>],
3510                         output: Ty<'tcx>) -> Ty<'tcx> {
3511     let input_args = input_tys.iter().cloned().collect();
3512     mk_bare_fn(cx,
3513                Some(def_id),
3514                cx.mk_bare_fn(BareFnTy {
3515                    unsafety: ast::Unsafety::Normal,
3516                    abi: abi::Rust,
3517                    sig: ty::Binder(FnSig {
3518                     inputs: input_args,
3519                     output: ty::FnConverging(output),
3520                     variadic: false
3521                    })
3522                 }))
3523 }
3524
3525 pub fn mk_trait<'tcx>(cx: &ctxt<'tcx>,
3526                       principal: ty::PolyTraitRef<'tcx>,
3527                       bounds: ExistentialBounds<'tcx>)
3528                       -> Ty<'tcx>
3529 {
3530     assert!(bound_list_is_sorted(&bounds.projection_bounds));
3531
3532     let inner = box TraitTy {
3533         principal: principal,
3534         bounds: bounds
3535     };
3536     mk_t(cx, TyTrait(inner))
3537 }
3538
3539 fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool {
3540     bounds.is_empty() ||
3541         bounds[1..].iter().enumerate().all(
3542             |(index, bound)| bounds[index].sort_key() <= bound.sort_key())
3543 }
3544
3545 pub fn sort_bounds_list(bounds: &mut [ty::PolyProjectionPredicate]) {
3546     bounds.sort_by(|a, b| a.sort_key().cmp(&b.sort_key()))
3547 }
3548
3549 pub fn mk_projection<'tcx>(cx: &ctxt<'tcx>,
3550                            trait_ref: TraitRef<'tcx>,
3551                            item_name: ast::Name)
3552                            -> Ty<'tcx> {
3553     // take a copy of substs so that we own the vectors inside
3554     let inner = ProjectionTy { trait_ref: trait_ref, item_name: item_name };
3555     mk_t(cx, TyProjection(inner))
3556 }
3557
3558 pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId,
3559                        substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
3560     // take a copy of substs so that we own the vectors inside
3561     mk_t(cx, TyStruct(struct_id, substs))
3562 }
3563
3564 pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>)
3565                         -> Ty<'tcx> {
3566     mk_t(cx, TyClosure(closure_id, substs))
3567 }
3568
3569 pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
3570     mk_infer(cx, TyVar(v))
3571 }
3572
3573 pub fn mk_int_var<'tcx>(cx: &ctxt<'tcx>, v: IntVid) -> Ty<'tcx> {
3574     mk_infer(cx, IntVar(v))
3575 }
3576
3577 pub fn mk_float_var<'tcx>(cx: &ctxt<'tcx>, v: FloatVid) -> Ty<'tcx> {
3578     mk_infer(cx, FloatVar(v))
3579 }
3580
3581 pub fn mk_infer<'tcx>(cx: &ctxt<'tcx>, it: InferTy) -> Ty<'tcx> {
3582     mk_t(cx, TyInfer(it))
3583 }
3584
3585 pub fn mk_param<'tcx>(cx: &ctxt<'tcx>,
3586                       space: subst::ParamSpace,
3587                       index: u32,
3588                       name: ast::Name) -> Ty<'tcx> {
3589     mk_t(cx, TyParam(ParamTy { space: space, idx: index, name: name }))
3590 }
3591
3592 pub fn mk_self_type<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3593     mk_param(cx, subst::SelfSpace, 0, special_idents::type_self.name)
3594 }
3595
3596 pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'tcx> {
3597     mk_param(cx, def.space, def.index, def.name)
3598 }
3599
3600 impl<'tcx> TyS<'tcx> {
3601     /// Iterator that walks `self` and any types reachable from
3602     /// `self`, in depth-first order. Note that just walks the types
3603     /// that appear in `self`, it does not descend into the fields of
3604     /// structs or variants. For example:
3605     ///
3606     /// ```notrust
3607     /// isize => { isize }
3608     /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
3609     /// [isize] => { [isize], isize }
3610     /// ```
3611     pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
3612         TypeWalker::new(self)
3613     }
3614
3615     /// Iterator that walks the immediate children of `self`.  Hence
3616     /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
3617     /// (but not `i32`, like `walk`).
3618     pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
3619         ty_walk::walk_shallow(self)
3620     }
3621
3622     pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
3623         match self.sty {
3624             ty::TyParam(ref d) => Some(d.clone()),
3625             _ => None,
3626         }
3627     }
3628
3629     pub fn is_param(&self, space: ParamSpace, index: u32) -> bool {
3630         match self.sty {
3631             ty::TyParam(ref data) => data.space == space && data.idx == index,
3632             _ => false,
3633         }
3634     }
3635 }
3636
3637 pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F)
3638     where F: FnMut(Ty<'tcx>),
3639 {
3640     for ty in ty_root.walk() {
3641         f(ty);
3642     }
3643 }
3644
3645 /// Walks `ty` and any types appearing within `ty`, invoking the
3646 /// callback `f` on each type. If the callback returns false, then the
3647 /// children of the current type are ignored.
3648 ///
3649 /// Note: prefer `ty.walk()` where possible.
3650 pub fn maybe_walk_ty<'tcx,F>(ty_root: Ty<'tcx>, mut f: F)
3651     where F : FnMut(Ty<'tcx>) -> bool
3652 {
3653     let mut walker = ty_root.walk();
3654     while let Some(ty) = walker.next() {
3655         if !f(ty) {
3656             walker.skip_current_subtree();
3657         }
3658     }
3659 }
3660
3661 // Folds types from the bottom up.
3662 pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
3663                         fldop: F)
3664                         -> Ty<'tcx> where
3665     F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
3666 {
3667     let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop};
3668     f.fold_ty(t0)
3669 }
3670
3671 impl ParamTy {
3672     pub fn new(space: subst::ParamSpace,
3673                index: u32,
3674                name: ast::Name)
3675                -> ParamTy {
3676         ParamTy { space: space, idx: index, name: name }
3677     }
3678
3679     pub fn for_self() -> ParamTy {
3680         ParamTy::new(subst::SelfSpace, 0, special_idents::type_self.name)
3681     }
3682
3683     pub fn for_def(def: &TypeParameterDef) -> ParamTy {
3684         ParamTy::new(def.space, def.index, def.name)
3685     }
3686
3687     pub fn to_ty<'tcx>(self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
3688         ty::mk_param(tcx, self.space, self.idx, self.name)
3689     }
3690
3691     pub fn is_self(&self) -> bool {
3692         self.space == subst::SelfSpace && self.idx == 0
3693     }
3694 }
3695
3696 impl<'tcx> ItemSubsts<'tcx> {
3697     pub fn empty() -> ItemSubsts<'tcx> {
3698         ItemSubsts { substs: Substs::empty() }
3699     }
3700
3701     pub fn is_noop(&self) -> bool {
3702         self.substs.is_noop()
3703     }
3704 }
3705
3706 impl<'tcx> ParamBounds<'tcx> {
3707     pub fn empty() -> ParamBounds<'tcx> {
3708         ParamBounds {
3709             builtin_bounds: BuiltinBounds::empty(),
3710             trait_bounds: Vec::new(),
3711             region_bounds: Vec::new(),
3712             projection_bounds: Vec::new(),
3713         }
3714     }
3715 }
3716
3717 // Type utilities
3718
3719 pub fn type_is_nil(ty: Ty) -> bool {
3720     match ty.sty {
3721         TyTuple(ref tys) => tys.is_empty(),
3722         _ => false
3723     }
3724 }
3725
3726 pub fn type_is_error(ty: Ty) -> bool {
3727     ty.flags.get().intersects(TypeFlags::HAS_TY_ERR)
3728 }
3729
3730 pub fn type_needs_subst(ty: Ty) -> bool {
3731     ty.flags.get().intersects(TypeFlags::NEEDS_SUBST)
3732 }
3733
3734 pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool {
3735     tref.substs.types.any(|&ty| type_is_error(ty))
3736 }
3737
3738 pub fn type_is_ty_var(ty: Ty) -> bool {
3739     match ty.sty {
3740         TyInfer(TyVar(_)) => true,
3741         _ => false
3742     }
3743 }
3744
3745 pub fn type_is_bool(ty: Ty) -> bool { ty.sty == TyBool }
3746
3747 pub fn type_is_self(ty: Ty) -> bool {
3748     match ty.sty {
3749         TyParam(ref p) => p.space == subst::SelfSpace,
3750         _ => false
3751     }
3752 }
3753
3754 fn type_is_slice(ty: Ty) -> bool {
3755     match ty.sty {
3756         TyRawPtr(mt) | TyRef(_, mt) => match mt.ty.sty {
3757             TySlice(_) | TyStr => true,
3758             _ => false,
3759         },
3760         _ => false
3761     }
3762 }
3763
3764 pub fn type_is_structural(ty: Ty) -> bool {
3765     match ty.sty {
3766       TyStruct(..) | TyTuple(_) | TyEnum(..) |
3767       TyArray(..) | TyClosure(..) => true,
3768       _ => type_is_slice(ty) | type_is_trait(ty)
3769     }
3770 }
3771
3772 pub fn type_is_simd(cx: &ctxt, ty: Ty) -> bool {
3773     match ty.sty {
3774         TyStruct(did, _) => lookup_simd(cx, did),
3775         _ => false
3776     }
3777 }
3778
3779 pub fn sequence_element_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3780     match ty.sty {
3781         TyArray(ty, _) | TySlice(ty) => ty,
3782         TyStr => mk_mach_uint(cx, ast::TyU8),
3783         _ => cx.sess.bug(&format!("sequence_element_type called on non-sequence value: {}",
3784                                   ty)),
3785     }
3786 }
3787
3788 pub fn simd_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3789     match ty.sty {
3790         TyStruct(did, substs) => {
3791             let fields = lookup_struct_fields(cx, did);
3792             lookup_field_type(cx, did, fields[0].id, substs)
3793         }
3794         _ => panic!("simd_type called on invalid type")
3795     }
3796 }
3797
3798 pub fn simd_size(cx: &ctxt, ty: Ty) -> usize {
3799     match ty.sty {
3800         TyStruct(did, _) => {
3801             let fields = lookup_struct_fields(cx, did);
3802             fields.len()
3803         }
3804         _ => panic!("simd_size called on invalid type")
3805     }
3806 }
3807
3808 pub fn type_is_region_ptr(ty: Ty) -> bool {
3809     match ty.sty {
3810         TyRef(..) => true,
3811         _ => false
3812     }
3813 }
3814
3815 pub fn type_is_unsafe_ptr(ty: Ty) -> bool {
3816     match ty.sty {
3817       TyRawPtr(_) => return true,
3818       _ => return false
3819     }
3820 }
3821
3822 pub fn type_is_unique(ty: Ty) -> bool {
3823     match ty.sty {
3824         TyBox(_) => true,
3825         _ => false
3826     }
3827 }
3828
3829 /*
3830  A scalar type is one that denotes an atomic datum, with no sub-components.
3831  (A TyRawPtr is scalar because it represents a non-managed pointer, so its
3832  contents are abstract to rustc.)
3833 */
3834 pub fn type_is_scalar(ty: Ty) -> bool {
3835     match ty.sty {
3836       TyBool | TyChar | TyInt(_) | TyFloat(_) | TyUint(_) |
3837       TyInfer(IntVar(_)) | TyInfer(FloatVar(_)) |
3838       TyBareFn(..) | TyRawPtr(_) => true,
3839       _ => false
3840     }
3841 }
3842
3843 /// Returns true if this type is a floating point type and false otherwise.
3844 pub fn type_is_floating_point(ty: Ty) -> bool {
3845     match ty.sty {
3846         TyFloat(_) |
3847         TyInfer(FloatVar(_)) =>
3848             true,
3849
3850         _ =>
3851             false,
3852     }
3853 }
3854
3855 /// Type contents is how the type checker reasons about kinds.
3856 /// They track what kinds of things are found within a type.  You can
3857 /// think of them as kind of an "anti-kind".  They track the kinds of values
3858 /// and thinks that are contained in types.  Having a larger contents for
3859 /// a type tends to rule that type *out* from various kinds.  For example,
3860 /// a type that contains a reference is not sendable.
3861 ///
3862 /// The reason we compute type contents and not kinds is that it is
3863 /// easier for me (nmatsakis) to think about what is contained within
3864 /// a type than to think about what is *not* contained within a type.
3865 #[derive(Clone, Copy)]
3866 pub struct TypeContents {
3867     pub bits: u64
3868 }
3869
3870 macro_rules! def_type_content_sets {
3871     (mod $mname:ident { $($name:ident = $bits:expr),+ }) => {
3872         #[allow(non_snake_case)]
3873         mod $mname {
3874             use middle::ty::TypeContents;
3875             $(
3876                 #[allow(non_upper_case_globals)]
3877                 pub const $name: TypeContents = TypeContents { bits: $bits };
3878              )+
3879         }
3880     }
3881 }
3882
3883 def_type_content_sets! {
3884     mod TC {
3885         None                                = 0b0000_0000__0000_0000__0000,
3886
3887         // Things that are interior to the value (first nibble):
3888         InteriorUnsized                     = 0b0000_0000__0000_0000__0001,
3889         InteriorUnsafe                      = 0b0000_0000__0000_0000__0010,
3890         InteriorParam                       = 0b0000_0000__0000_0000__0100,
3891         // InteriorAll                         = 0b00000000__00000000__1111,
3892
3893         // Things that are owned by the value (second and third nibbles):
3894         OwnsOwned                           = 0b0000_0000__0000_0001__0000,
3895         OwnsDtor                            = 0b0000_0000__0000_0010__0000,
3896         OwnsAll                             = 0b0000_0000__1111_1111__0000,
3897
3898         // Things that are reachable by the value in any way (fourth nibble):
3899         ReachesBorrowed                     = 0b0000_0010__0000_0000__0000,
3900         ReachesMutable                      = 0b0000_1000__0000_0000__0000,
3901         ReachesFfiUnsafe                    = 0b0010_0000__0000_0000__0000,
3902         ReachesAll                          = 0b0011_1111__0000_0000__0000,
3903
3904         // Things that mean drop glue is necessary
3905         NeedsDrop                           = 0b0000_0000__0000_0111__0000,
3906
3907         // Things that prevent values from being considered sized
3908         Nonsized                            = 0b0000_0000__0000_0000__0001,
3909
3910         // All bits
3911         All                                 = 0b1111_1111__1111_1111__1111
3912     }
3913 }
3914
3915 impl TypeContents {
3916     pub fn when(&self, cond: bool) -> TypeContents {
3917         if cond {*self} else {TC::None}
3918     }
3919
3920     pub fn intersects(&self, tc: TypeContents) -> bool {
3921         (self.bits & tc.bits) != 0
3922     }
3923
3924     pub fn owns_owned(&self) -> bool {
3925         self.intersects(TC::OwnsOwned)
3926     }
3927
3928     pub fn is_sized(&self, _: &ctxt) -> bool {
3929         !self.intersects(TC::Nonsized)
3930     }
3931
3932     pub fn interior_param(&self) -> bool {
3933         self.intersects(TC::InteriorParam)
3934     }
3935
3936     pub fn interior_unsafe(&self) -> bool {
3937         self.intersects(TC::InteriorUnsafe)
3938     }
3939
3940     pub fn interior_unsized(&self) -> bool {
3941         self.intersects(TC::InteriorUnsized)
3942     }
3943
3944     pub fn needs_drop(&self, _: &ctxt) -> bool {
3945         self.intersects(TC::NeedsDrop)
3946     }
3947
3948     /// Includes only those bits that still apply when indirected through a `Box` pointer
3949     pub fn owned_pointer(&self) -> TypeContents {
3950         TC::OwnsOwned | (
3951             *self & (TC::OwnsAll | TC::ReachesAll))
3952     }
3953
3954     /// Includes only those bits that still apply when indirected through a reference (`&`)
3955     pub fn reference(&self, bits: TypeContents) -> TypeContents {
3956         bits | (
3957             *self & TC::ReachesAll)
3958     }
3959
3960     /// Includes only those bits that still apply when indirected through a raw pointer (`*`)
3961     pub fn unsafe_pointer(&self) -> TypeContents {
3962         *self & TC::ReachesAll
3963     }
3964
3965     pub fn union<T, F>(v: &[T], mut f: F) -> TypeContents where
3966         F: FnMut(&T) -> TypeContents,
3967     {
3968         v.iter().fold(TC::None, |tc, ty| tc | f(ty))
3969     }
3970
3971     pub fn has_dtor(&self) -> bool {
3972         self.intersects(TC::OwnsDtor)
3973     }
3974 }
3975
3976 impl ops::BitOr for TypeContents {
3977     type Output = TypeContents;
3978
3979     fn bitor(self, other: TypeContents) -> TypeContents {
3980         TypeContents {bits: self.bits | other.bits}
3981     }
3982 }
3983
3984 impl ops::BitAnd for TypeContents {
3985     type Output = TypeContents;
3986
3987     fn bitand(self, other: TypeContents) -> TypeContents {
3988         TypeContents {bits: self.bits & other.bits}
3989     }
3990 }
3991
3992 impl ops::Sub for TypeContents {
3993     type Output = TypeContents;
3994
3995     fn sub(self, other: TypeContents) -> TypeContents {
3996         TypeContents {bits: self.bits & !other.bits}
3997     }
3998 }
3999
4000 impl fmt::Debug for TypeContents {
4001     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4002         write!(f, "TypeContents({:b})", self.bits)
4003     }
4004 }
4005
4006 pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
4007     return memoized(&cx.tc_cache, ty, |ty| {
4008         tc_ty(cx, ty, &mut FnvHashMap())
4009     });
4010
4011     fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
4012                    ty: Ty<'tcx>,
4013                    cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
4014     {
4015         // Subtle: Note that we are *not* using cx.tc_cache here but rather a
4016         // private cache for this walk.  This is needed in the case of cyclic
4017         // types like:
4018         //
4019         //     struct List { next: Box<Option<List>>, ... }
4020         //
4021         // When computing the type contents of such a type, we wind up deeply
4022         // recursing as we go.  So when we encounter the recursive reference
4023         // to List, we temporarily use TC::None as its contents.  Later we'll
4024         // patch up the cache with the correct value, once we've computed it
4025         // (this is basically a co-inductive process, if that helps).  So in
4026         // the end we'll compute TC::OwnsOwned, in this case.
4027         //
4028         // The problem is, as we are doing the computation, we will also
4029         // compute an *intermediate* contents for, e.g., Option<List> of
4030         // TC::None.  This is ok during the computation of List itself, but if
4031         // we stored this intermediate value into cx.tc_cache, then later
4032         // requests for the contents of Option<List> would also yield TC::None
4033         // which is incorrect.  This value was computed based on the crutch
4034         // value for the type contents of list.  The correct value is
4035         // TC::OwnsOwned.  This manifested as issue #4821.
4036         match cache.get(&ty) {
4037             Some(tc) => { return *tc; }
4038             None => {}
4039         }
4040         match cx.tc_cache.borrow().get(&ty) {    // Must check both caches!
4041             Some(tc) => { return *tc; }
4042             None => {}
4043         }
4044         cache.insert(ty, TC::None);
4045
4046         let result = match ty.sty {
4047             // usize and isize are ffi-unsafe
4048             TyUint(ast::TyUs) | TyInt(ast::TyIs) => {
4049                 TC::ReachesFfiUnsafe
4050             }
4051
4052             // Scalar and unique types are sendable, and durable
4053             TyInfer(ty::FreshIntTy(_)) | TyInfer(ty::FreshFloatTy(_)) |
4054             TyBool | TyInt(_) | TyUint(_) | TyFloat(_) |
4055             TyBareFn(..) | ty::TyChar => {
4056                 TC::None
4057             }
4058
4059             TyBox(typ) => {
4060                 TC::ReachesFfiUnsafe | match typ.sty {
4061                     TyStr => TC::OwnsOwned,
4062                     _ => tc_ty(cx, typ, cache).owned_pointer(),
4063                 }
4064             }
4065
4066             TyTrait(box TraitTy { ref bounds, .. }) => {
4067                 object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized
4068             }
4069
4070             TyRawPtr(ref mt) => {
4071                 tc_ty(cx, mt.ty, cache).unsafe_pointer()
4072             }
4073
4074             TyRef(r, ref mt) => {
4075                 TC::ReachesFfiUnsafe | match mt.ty.sty {
4076                     TyStr => borrowed_contents(*r, ast::MutImmutable),
4077                     TyArray(..) |
4078                     TySlice(_) => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r,
4079                                                                                       mt.mutbl)),
4080                     _ => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r, mt.mutbl)),
4081                 }
4082             }
4083
4084             TyArray(ty, _) => {
4085                 tc_ty(cx, ty, cache)
4086             }
4087
4088             TySlice(ty) => {
4089                 tc_ty(cx, ty, cache) | TC::Nonsized
4090             }
4091             TyStr => TC::Nonsized,
4092
4093             TyStruct(did, substs) => {
4094                 let flds = struct_fields(cx, did, substs);
4095                 let mut res =
4096                     TypeContents::union(&flds[..],
4097                                         |f| tc_mt(cx, f.mt, cache));
4098
4099                 if !lookup_repr_hints(cx, did).contains(&attr::ReprExtern) {
4100                     res = res | TC::ReachesFfiUnsafe;
4101                 }
4102
4103                 if ty::has_dtor(cx, did) {
4104                     res = res | TC::OwnsDtor;
4105                 }
4106                 apply_lang_items(cx, did, res)
4107             }
4108
4109             TyClosure(did, substs) => {
4110                 // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
4111                 let param_env = ty::empty_parameter_environment(cx);
4112                 let upvars = closure_upvars(&param_env, did, substs).unwrap();
4113                 TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache))
4114             }
4115
4116             TyTuple(ref tys) => {
4117                 TypeContents::union(&tys[..],
4118                                     |ty| tc_ty(cx, *ty, cache))
4119             }
4120
4121             TyEnum(did, substs) => {
4122                 let variants = substd_enum_variants(cx, did, substs);
4123                 let mut res =
4124                     TypeContents::union(&variants[..], |variant| {
4125                         TypeContents::union(&variant.args,
4126                                             |arg_ty| {
4127                             tc_ty(cx, *arg_ty, cache)
4128                         })
4129                     });
4130
4131                 if ty::has_dtor(cx, did) {
4132                     res = res | TC::OwnsDtor;
4133                 }
4134
4135                 if !variants.is_empty() {
4136                     let repr_hints = lookup_repr_hints(cx, did);
4137                     if repr_hints.len() > 1 {
4138                         // this is an error later on, but this type isn't safe
4139                         res = res | TC::ReachesFfiUnsafe;
4140                     }
4141
4142                     match repr_hints.get(0) {
4143                         Some(h) => if !h.is_ffi_safe() {
4144                             res = res | TC::ReachesFfiUnsafe;
4145                         },
4146                         // ReprAny
4147                         None => {
4148                             res = res | TC::ReachesFfiUnsafe;
4149
4150                             // We allow ReprAny enums if they are eligible for
4151                             // the nullable pointer optimization and the
4152                             // contained type is an `extern fn`
4153
4154                             if variants.len() == 2 {
4155                                 let mut data_idx = 0;
4156
4157                                 if variants[0].args.is_empty() {
4158                                     data_idx = 1;
4159                                 }
4160
4161                                 if variants[data_idx].args.len() == 1 {
4162                                     match variants[data_idx].args[0].sty {
4163                                         TyBareFn(..) => { res = res - TC::ReachesFfiUnsafe; }
4164                                         _ => { }
4165                                     }
4166                                 }
4167                             }
4168                         }
4169                     }
4170                 }
4171
4172
4173                 apply_lang_items(cx, did, res)
4174             }
4175
4176             TyProjection(..) |
4177             TyParam(_) => {
4178                 TC::All
4179             }
4180
4181             TyInfer(_) |
4182             TyError => {
4183                 cx.sess.bug("asked to compute contents of error type");
4184             }
4185         };
4186
4187         cache.insert(ty, result);
4188         result
4189     }
4190
4191     fn tc_mt<'tcx>(cx: &ctxt<'tcx>,
4192                    mt: mt<'tcx>,
4193                    cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
4194     {
4195         let mc = TC::ReachesMutable.when(mt.mutbl == MutMutable);
4196         mc | tc_ty(cx, mt.ty, cache)
4197     }
4198
4199     fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents)
4200                         -> TypeContents {
4201         if Some(did) == cx.lang_items.unsafe_cell_type() {
4202             tc | TC::InteriorUnsafe
4203         } else {
4204             tc
4205         }
4206     }
4207
4208     /// Type contents due to containing a reference with the region `region` and borrow kind `bk`
4209     fn borrowed_contents(region: ty::Region,
4210                          mutbl: ast::Mutability)
4211                          -> TypeContents {
4212         let b = match mutbl {
4213             ast::MutMutable => TC::ReachesMutable,
4214             ast::MutImmutable => TC::None,
4215         };
4216         b | (TC::ReachesBorrowed).when(region != ty::ReStatic)
4217     }
4218
4219     fn object_contents(bounds: &ExistentialBounds) -> TypeContents {
4220         // These are the type contents of the (opaque) interior. We
4221         // make no assumptions (other than that it cannot have an
4222         // in-scope type parameter within, which makes no sense).
4223         let mut tc = TC::All - TC::InteriorParam;
4224         for bound in &bounds.builtin_bounds {
4225             tc = tc - match bound {
4226                 BoundSync | BoundSend | BoundCopy => TC::None,
4227                 BoundSized => TC::Nonsized,
4228             };
4229         }
4230         return tc;
4231     }
4232 }
4233
4234 fn type_impls_bound<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
4235                              tcx: &ty::ctxt<'tcx>,
4236                              ty: Ty<'tcx>,
4237                              bound: ty::BuiltinBound,
4238                              span: Span)
4239                              -> bool
4240 {
4241     let pe;
4242     let param_env = match param_env {
4243         Some(e) => e,
4244         None => {
4245             pe = empty_parameter_environment(tcx);
4246             &pe
4247         }
4248     };
4249     let infcx = infer::new_infer_ctxt(tcx);
4250
4251     let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, ty, bound, span);
4252
4253     debug!("type_impls_bound({:?}, {:?}) = {:?}",
4254            ty,
4255            bound,
4256            is_impld);
4257
4258     is_impld
4259 }
4260
4261 pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
4262                                       span: Span,
4263                                       ty: Ty<'tcx>)
4264                                       -> bool
4265 {
4266     if ty.flags.get().intersects(TypeFlags::MOVENESS_CACHED) {
4267         return ty.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
4268     }
4269
4270     assert!(!ty::type_needs_infer(ty));
4271
4272     // Fast-path for primitive types
4273     let result = match ty.sty {
4274         TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
4275         TyRawPtr(..) | TyBareFn(..) | TyRef(_, mt {
4276             mutbl: ast::MutImmutable, ..
4277         }) => Some(false),
4278
4279         TyStr | TyBox(..) | TyRef(_, mt {
4280             mutbl: ast::MutMutable, ..
4281         }) => Some(true),
4282
4283         TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) |
4284         TyClosure(..) | TyEnum(..) | TyStruct(..) |
4285         TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
4286     }.unwrap_or_else(|| !type_impls_bound(Some(param_env),
4287                                           param_env.tcx,
4288                                           ty,
4289                                           ty::BoundCopy,
4290                                           span));
4291
4292     if !type_has_params(ty) && !type_has_self(ty) {
4293         ty.flags.set(ty.flags.get() | if result {
4294             TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT
4295         } else {
4296             TypeFlags::MOVENESS_CACHED
4297         });
4298     }
4299
4300     result
4301 }
4302
4303 #[inline]
4304 pub fn type_is_sized<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
4305                               tcx: &ty::ctxt<'tcx>,
4306                               span: Span,
4307                               ty: Ty<'tcx>)
4308                               -> bool
4309 {
4310     if ty.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) {
4311         let result = ty.flags.get().intersects(TypeFlags::IS_SIZED);
4312         return result;
4313     }
4314
4315     type_is_sized_uncached(param_env, tcx, span, ty)
4316 }
4317
4318 fn type_is_sized_uncached<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
4319                                    tcx: &ty::ctxt<'tcx>,
4320                                    span: Span,
4321                                    ty: Ty<'tcx>) -> bool {
4322     assert!(!ty::type_needs_infer(ty));
4323
4324     // Fast-path for primitive types
4325     let result = match ty.sty {
4326         TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
4327         TyBox(..) | TyRawPtr(..) | TyRef(..) | TyBareFn(..) |
4328         TyArray(..) | TyTuple(..) | TyClosure(..) => Some(true),
4329
4330         TyStr | TyTrait(..) | TySlice(_) => Some(false),
4331
4332         TyEnum(..) | TyStruct(..) | TyProjection(..) | TyParam(..) |
4333         TyInfer(..) | TyError => None
4334     }.unwrap_or_else(|| type_impls_bound(param_env, tcx, ty, ty::BoundSized, span));
4335
4336     if !type_has_params(ty) && !type_has_self(ty) {
4337         ty.flags.set(ty.flags.get() | if result {
4338             TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED
4339         } else {
4340             TypeFlags::SIZEDNESS_CACHED
4341         });
4342     }
4343
4344     result
4345 }
4346
4347 pub fn is_ffi_safe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
4348     !type_contents(cx, ty).intersects(TC::ReachesFfiUnsafe)
4349 }
4350
4351 // True if instantiating an instance of `r_ty` requires an instance of `r_ty`.
4352 pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
4353     fn type_requires<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
4354                            r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
4355         debug!("type_requires({:?}, {:?})?",
4356                r_ty, ty);
4357
4358         let r = r_ty == ty || subtypes_require(cx, seen, r_ty, ty);
4359
4360         debug!("type_requires({:?}, {:?})? {:?}",
4361                r_ty, ty, r);
4362         return r;
4363     }
4364
4365     fn subtypes_require<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
4366                               r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
4367         debug!("subtypes_require({:?}, {:?})?",
4368                r_ty, ty);
4369
4370         let r = match ty.sty {
4371             // fixed length vectors need special treatment compared to
4372             // normal vectors, since they don't necessarily have the
4373             // possibility to have length zero.
4374             TyArray(_, 0) => false, // don't need no contents
4375             TyArray(ty, _) => type_requires(cx, seen, r_ty, ty),
4376
4377             TyBool |
4378             TyChar |
4379             TyInt(_) |
4380             TyUint(_) |
4381             TyFloat(_) |
4382             TyStr |
4383             TyBareFn(..) |
4384             TyParam(_) |
4385             TyProjection(_) |
4386             TySlice(_) => {
4387                 false
4388             }
4389             TyBox(typ) => {
4390                 type_requires(cx, seen, r_ty, typ)
4391             }
4392             TyRef(_, ref mt) => {
4393                 type_requires(cx, seen, r_ty, mt.ty)
4394             }
4395
4396             TyRawPtr(..) => {
4397                 false           // unsafe ptrs can always be NULL
4398             }
4399
4400             TyTrait(..) => {
4401                 false
4402             }
4403
4404             TyStruct(ref did, _) if seen.contains(did) => {
4405                 false
4406             }
4407
4408             TyStruct(did, substs) => {
4409                 seen.push(did);
4410                 let fields = struct_fields(cx, did, substs);
4411                 let r = fields.iter().any(|f| type_requires(cx, seen, r_ty, f.mt.ty));
4412                 seen.pop().unwrap();
4413                 r
4414             }
4415
4416             TyError |
4417             TyInfer(_) |
4418             TyClosure(..) => {
4419                 // this check is run on type definitions, so we don't expect to see
4420                 // inference by-products or closure types
4421                 cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
4422             }
4423
4424             TyTuple(ref ts) => {
4425                 ts.iter().any(|ty| type_requires(cx, seen, r_ty, *ty))
4426             }
4427
4428             TyEnum(ref did, _) if seen.contains(did) => {
4429                 false
4430             }
4431
4432             TyEnum(did, substs) => {
4433                 seen.push(did);
4434                 let vs = enum_variants(cx, did);
4435                 let r = !vs.is_empty() && vs.iter().all(|variant| {
4436                     variant.args.iter().any(|aty| {
4437                         let sty = aty.subst(cx, substs);
4438                         type_requires(cx, seen, r_ty, sty)
4439                     })
4440                 });
4441                 seen.pop().unwrap();
4442                 r
4443             }
4444         };
4445
4446         debug!("subtypes_require({:?}, {:?})? {:?}",
4447                r_ty, ty, r);
4448
4449         return r;
4450     }
4451
4452     let mut seen = Vec::new();
4453     !subtypes_require(cx, &mut seen, r_ty, r_ty)
4454 }
4455
4456 /// Describes whether a type is representable. For types that are not
4457 /// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
4458 /// distinguish between types that are recursive with themselves and types that
4459 /// contain a different recursive type. These cases can therefore be treated
4460 /// differently when reporting errors.
4461 ///
4462 /// The ordering of the cases is significant. They are sorted so that cmp::max
4463 /// will keep the "more erroneous" of two values.
4464 #[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
4465 pub enum Representability {
4466     Representable,
4467     ContainsRecursive,
4468     SelfRecursive,
4469 }
4470
4471 /// Check whether a type is representable. This means it cannot contain unboxed
4472 /// structural recursion. This check is needed for structs and enums.
4473 pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
4474                                    -> Representability {
4475
4476     // Iterate until something non-representable is found
4477     fn find_nonrepresentable<'tcx, It: Iterator<Item=Ty<'tcx>>>(cx: &ctxt<'tcx>, sp: Span,
4478                                                                 seen: &mut Vec<Ty<'tcx>>,
4479                                                                 iter: It)
4480                                                                 -> Representability {
4481         iter.fold(Representable,
4482                   |r, ty| cmp::max(r, is_type_structurally_recursive(cx, sp, seen, ty)))
4483     }
4484
4485     fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
4486                                        seen: &mut Vec<Ty<'tcx>>, ty: Ty<'tcx>)
4487                                        -> Representability {
4488         match ty.sty {
4489             TyTuple(ref ts) => {
4490                 find_nonrepresentable(cx, sp, seen, ts.iter().cloned())
4491             }
4492             // Fixed-length vectors.
4493             // FIXME(#11924) Behavior undecided for zero-length vectors.
4494             TyArray(ty, _) => {
4495                 is_type_structurally_recursive(cx, sp, seen, ty)
4496             }
4497             TyStruct(did, substs) => {
4498                 let fields = struct_fields(cx, did, substs);
4499                 find_nonrepresentable(cx, sp, seen, fields.iter().map(|f| f.mt.ty))
4500             }
4501             TyEnum(did, substs) => {
4502                 let vs = enum_variants(cx, did);
4503                 let iter = vs.iter()
4504                     .flat_map(|variant| &variant.args)
4505                     .map(|aty| { aty.subst_spanned(cx, substs, Some(sp)) });
4506
4507                 find_nonrepresentable(cx, sp, seen, iter)
4508             }
4509             TyClosure(..) => {
4510                 // this check is run on type definitions, so we don't expect
4511                 // to see closure types
4512                 cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
4513             }
4514             _ => Representable,
4515         }
4516     }
4517
4518     fn same_struct_or_enum_def_id(ty: Ty, did: DefId) -> bool {
4519         match ty.sty {
4520             TyStruct(ty_did, _) | TyEnum(ty_did, _) => {
4521                  ty_did == did
4522             }
4523             _ => false
4524         }
4525     }
4526
4527     fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
4528         match (&a.sty, &b.sty) {
4529             (&TyStruct(did_a, ref substs_a), &TyStruct(did_b, ref substs_b)) |
4530             (&TyEnum(did_a, ref substs_a), &TyEnum(did_b, ref substs_b)) => {
4531                 if did_a != did_b {
4532                     return false;
4533                 }
4534
4535                 let types_a = substs_a.types.get_slice(subst::TypeSpace);
4536                 let types_b = substs_b.types.get_slice(subst::TypeSpace);
4537
4538                 let mut pairs = types_a.iter().zip(types_b);
4539
4540                 pairs.all(|(&a, &b)| same_type(a, b))
4541             }
4542             _ => {
4543                 a == b
4544             }
4545         }
4546     }
4547
4548     // Does the type `ty` directly (without indirection through a pointer)
4549     // contain any types on stack `seen`?
4550     fn is_type_structurally_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
4551                                             seen: &mut Vec<Ty<'tcx>>,
4552                                             ty: Ty<'tcx>) -> Representability {
4553         debug!("is_type_structurally_recursive: {:?}", ty);
4554
4555         match ty.sty {
4556             TyStruct(did, _) | TyEnum(did, _) => {
4557                 {
4558                     // Iterate through stack of previously seen types.
4559                     let mut iter = seen.iter();
4560
4561                     // The first item in `seen` is the type we are actually curious about.
4562                     // We want to return SelfRecursive if this type contains itself.
4563                     // It is important that we DON'T take generic parameters into account
4564                     // for this check, so that Bar<T> in this example counts as SelfRecursive:
4565                     //
4566                     // struct Foo;
4567                     // struct Bar<T> { x: Bar<Foo> }
4568
4569                     match iter.next() {
4570                         Some(&seen_type) => {
4571                             if same_struct_or_enum_def_id(seen_type, did) {
4572                                 debug!("SelfRecursive: {:?} contains {:?}",
4573                                        seen_type,
4574                                        ty);
4575                                 return SelfRecursive;
4576                             }
4577                         }
4578                         None => {}
4579                     }
4580
4581                     // We also need to know whether the first item contains other types that
4582                     // are structurally recursive. If we don't catch this case, we will recurse
4583                     // infinitely for some inputs.
4584                     //
4585                     // It is important that we DO take generic parameters into account here,
4586                     // so that code like this is considered SelfRecursive, not ContainsRecursive:
4587                     //
4588                     // struct Foo { Option<Option<Foo>> }
4589
4590                     for &seen_type in iter {
4591                         if same_type(ty, seen_type) {
4592                             debug!("ContainsRecursive: {:?} contains {:?}",
4593                                    seen_type,
4594                                    ty);
4595                             return ContainsRecursive;
4596                         }
4597                     }
4598                 }
4599
4600                 // For structs and enums, track all previously seen types by pushing them
4601                 // onto the 'seen' stack.
4602                 seen.push(ty);
4603                 let out = are_inner_types_recursive(cx, sp, seen, ty);
4604                 seen.pop();
4605                 out
4606             }
4607             _ => {
4608                 // No need to push in other cases.
4609                 are_inner_types_recursive(cx, sp, seen, ty)
4610             }
4611         }
4612     }
4613
4614     debug!("is_type_representable: {:?}", ty);
4615
4616     // To avoid a stack overflow when checking an enum variant or struct that
4617     // contains a different, structurally recursive type, maintain a stack
4618     // of seen types and check recursion for each of them (issues #3008, #3779).
4619     let mut seen: Vec<Ty> = Vec::new();
4620     let r = is_type_structurally_recursive(cx, sp, &mut seen, ty);
4621     debug!("is_type_representable: {:?} is {:?}", ty, r);
4622     r
4623 }
4624
4625 pub fn type_is_trait(ty: Ty) -> bool {
4626     match ty.sty {
4627         TyTrait(..) => true,
4628         _ => false
4629     }
4630 }
4631
4632 pub fn type_is_integral(ty: Ty) -> bool {
4633     match ty.sty {
4634       TyInfer(IntVar(_)) | TyInt(_) | TyUint(_) => true,
4635       _ => false
4636     }
4637 }
4638
4639 pub fn type_is_fresh(ty: Ty) -> bool {
4640     match ty.sty {
4641       TyInfer(FreshTy(_)) => true,
4642       TyInfer(FreshIntTy(_)) => true,
4643       TyInfer(FreshFloatTy(_)) => true,
4644       _ => false
4645     }
4646 }
4647
4648 pub fn type_is_uint(ty: Ty) -> bool {
4649     match ty.sty {
4650       TyInfer(IntVar(_)) | TyUint(ast::TyUs) => true,
4651       _ => false
4652     }
4653 }
4654
4655 pub fn type_is_char(ty: Ty) -> bool {
4656     match ty.sty {
4657         TyChar => true,
4658         _ => false
4659     }
4660 }
4661
4662 pub fn type_is_bare_fn(ty: Ty) -> bool {
4663     match ty.sty {
4664         TyBareFn(..) => true,
4665         _ => false
4666     }
4667 }
4668
4669 pub fn type_is_bare_fn_item(ty: Ty) -> bool {
4670     match ty.sty {
4671         TyBareFn(Some(_), _) => true,
4672         _ => false
4673     }
4674 }
4675
4676 pub fn type_is_fp(ty: Ty) -> bool {
4677     match ty.sty {
4678       TyInfer(FloatVar(_)) | TyFloat(_) => true,
4679       _ => false
4680     }
4681 }
4682
4683 pub fn type_is_numeric(ty: Ty) -> bool {
4684     return type_is_integral(ty) || type_is_fp(ty);
4685 }
4686
4687 pub fn type_is_signed(ty: Ty) -> bool {
4688     match ty.sty {
4689       TyInt(_) => true,
4690       _ => false
4691     }
4692 }
4693
4694 pub fn type_is_machine(ty: Ty) -> bool {
4695     match ty.sty {
4696         TyInt(ast::TyIs) | TyUint(ast::TyUs) => false,
4697         TyInt(..) | TyUint(..) | TyFloat(..) => true,
4698         _ => false
4699     }
4700 }
4701
4702 // Whether a type is enum like, that is an enum type with only nullary
4703 // constructors
4704 pub fn type_is_c_like_enum(cx: &ctxt, ty: Ty) -> bool {
4705     match ty.sty {
4706         TyEnum(did, _) => {
4707             let variants = enum_variants(cx, did);
4708             if variants.is_empty() {
4709                 false
4710             } else {
4711                 variants.iter().all(|v| v.args.is_empty())
4712             }
4713         }
4714         _ => false
4715     }
4716 }
4717
4718 // Returns the type and mutability of *ty.
4719 //
4720 // The parameter `explicit` indicates if this is an *explicit* dereference.
4721 // Some types---notably unsafe ptrs---can only be dereferenced explicitly.
4722 pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
4723     match ty.sty {
4724         TyBox(ty) => {
4725             Some(mt {
4726                 ty: ty,
4727                 mutbl: ast::MutImmutable,
4728             })
4729         },
4730         TyRef(_, mt) => Some(mt),
4731         TyRawPtr(mt) if explicit => Some(mt),
4732         _ => None
4733     }
4734 }
4735
4736 pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
4737     match ty.sty {
4738         TyBox(ty) => ty,
4739         TyRef(_, mt) | TyRawPtr(mt) => mt.ty,
4740         _ => ty
4741     }
4742 }
4743
4744 // Returns the type of ty[i]
4745 pub fn index<'tcx>(ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
4746     match ty.sty {
4747         TyArray(ty, _) | TySlice(ty) => Some(ty),
4748         _ => None
4749     }
4750 }
4751
4752 // Returns the type of elements contained within an 'array-like' type.
4753 // This is exactly the same as the above, except it supports strings,
4754 // which can't actually be indexed.
4755 pub fn array_element_ty<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
4756     match ty.sty {
4757         TyArray(ty, _) | TySlice(ty) => Some(ty),
4758         TyStr => Some(tcx.types.u8),
4759         _ => None
4760     }
4761 }
4762
4763 /// Returns the type of element at index `i` in tuple or tuple-like type `t`.
4764 /// For an enum `t`, `variant` is None only if `t` is a univariant enum.
4765 pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>,
4766                                    ty: Ty<'tcx>,
4767                                    i: usize,
4768                                    variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
4769
4770     match (&ty.sty, variant) {
4771         (&TyTuple(ref v), None) => v.get(i).cloned(),
4772
4773
4774         (&TyStruct(def_id, substs), None) => lookup_struct_fields(cx, def_id)
4775             .get(i)
4776             .map(|&t|lookup_item_type(cx, t.id).ty.subst(cx, substs)),
4777
4778         (&TyEnum(def_id, substs), Some(variant_def_id)) => {
4779             let variant_info = enum_variant_with_id(cx, def_id, variant_def_id);
4780             variant_info.args.get(i).map(|t|t.subst(cx, substs))
4781         }
4782
4783         (&TyEnum(def_id, substs), None) => {
4784             assert!(enum_is_univariant(cx, def_id));
4785             let enum_variants = enum_variants(cx, def_id);
4786             let variant_info = &(*enum_variants)[0];
4787             variant_info.args.get(i).map(|t|t.subst(cx, substs))
4788         }
4789
4790         _ => None
4791     }
4792 }
4793
4794 /// Returns the type of element at field `n` in struct or struct-like type `t`.
4795 /// For an enum `t`, `variant` must be some def id.
4796 pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>,
4797                               ty: Ty<'tcx>,
4798                               n: ast::Name,
4799                               variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
4800
4801     match (&ty.sty, variant) {
4802         (&TyStruct(def_id, substs), None) => {
4803             let r = lookup_struct_fields(cx, def_id);
4804             r.iter().find(|f| f.name == n)
4805                 .map(|&f| lookup_field_type(cx, def_id, f.id, substs))
4806         }
4807         (&TyEnum(def_id, substs), Some(variant_def_id)) => {
4808             let variant_info = enum_variant_with_id(cx, def_id, variant_def_id);
4809             variant_info.arg_names.as_ref()
4810                 .expect("must have struct enum variant if accessing a named fields")
4811                 .iter().zip(&variant_info.args)
4812                 .find(|&(&name, _)| name == n)
4813                 .map(|(_name, arg_t)| arg_t.subst(cx, substs))
4814         }
4815         _ => None
4816     }
4817 }
4818
4819 pub fn node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Ty<'tcx> {
4820     match node_id_to_type_opt(cx, id) {
4821        Some(ty) => ty,
4822        None => cx.sess.bug(
4823            &format!("node_id_to_type: no type for node `{}`",
4824                    cx.map.node_to_string(id)))
4825     }
4826 }
4827
4828 pub fn node_id_to_type_opt<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Option<Ty<'tcx>> {
4829     match cx.node_types.borrow().get(&id) {
4830        Some(&ty) => Some(ty),
4831        None => None
4832     }
4833 }
4834
4835 pub fn node_id_item_substs<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> ItemSubsts<'tcx> {
4836     match cx.item_substs.borrow().get(&id) {
4837       None => ItemSubsts::empty(),
4838       Some(ts) => ts.clone(),
4839     }
4840 }
4841
4842 pub fn fn_is_variadic(fty: Ty) -> bool {
4843     match fty.sty {
4844         TyBareFn(_, ref f) => f.sig.0.variadic,
4845         ref s => {
4846             panic!("fn_is_variadic() called on non-fn type: {:?}", s)
4847         }
4848     }
4849 }
4850
4851 pub fn ty_fn_sig<'tcx>(fty: Ty<'tcx>) -> &'tcx PolyFnSig<'tcx> {
4852     match fty.sty {
4853         TyBareFn(_, ref f) => &f.sig,
4854         ref s => {
4855             panic!("ty_fn_sig() called on non-fn type: {:?}", s)
4856         }
4857     }
4858 }
4859
4860 /// Returns the ABI of the given function.
4861 pub fn ty_fn_abi(fty: Ty) -> abi::Abi {
4862     match fty.sty {
4863         TyBareFn(_, ref f) => f.abi,
4864         _ => panic!("ty_fn_abi() called on non-fn type"),
4865     }
4866 }
4867
4868 // Type accessors for substructures of types
4869 pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> ty::Binder<Vec<Ty<'tcx>>> {
4870     ty_fn_sig(fty).inputs()
4871 }
4872
4873 pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> Binder<FnOutput<'tcx>> {
4874     match fty.sty {
4875         TyBareFn(_, ref f) => f.sig.output(),
4876         ref s => {
4877             panic!("ty_fn_ret() called on non-fn type: {:?}", s)
4878         }
4879     }
4880 }
4881
4882 pub fn is_fn_ty(fty: Ty) -> bool {
4883     match fty.sty {
4884         TyBareFn(..) => true,
4885         _ => false
4886     }
4887 }
4888
4889 pub fn ty_region(tcx: &ctxt,
4890                  span: Span,
4891                  ty: Ty) -> Region {
4892     match ty.sty {
4893         TyRef(r, _) => *r,
4894         ref s => {
4895             tcx.sess.span_bug(
4896                 span,
4897                 &format!("ty_region() invoked on an inappropriate ty: {:?}",
4898                         s));
4899         }
4900     }
4901 }
4902
4903 pub fn free_region_from_def(outlives_extent: region::DestructionScopeData,
4904                             def: &RegionParameterDef)
4905     -> ty::Region
4906 {
4907     let ret =
4908         ty::ReFree(ty::FreeRegion { scope: outlives_extent,
4909                                     bound_region: ty::BrNamed(def.def_id,
4910                                                               def.name) });
4911     debug!("free_region_from_def returns {:?}", ret);
4912     ret
4913 }
4914
4915 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
4916 // doesn't provide type parameter substitutions.
4917 pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> {
4918     return node_id_to_type(cx, pat.id);
4919 }
4920 pub fn pat_ty_opt<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Option<Ty<'tcx>> {
4921     return node_id_to_type_opt(cx, pat.id);
4922 }
4923
4924
4925 // Returns the type of an expression as a monotype.
4926 //
4927 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression.  That is, in
4928 // some cases, we insert `AutoAdjustment` annotations such as auto-deref or
4929 // auto-ref.  The type returned by this function does not consider such
4930 // adjustments.  See `expr_ty_adjusted()` instead.
4931 //
4932 // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
4933 // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
4934 // instead of "fn(ty) -> T with T = isize".
4935 pub fn expr_ty<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
4936     return node_id_to_type(cx, expr.id);
4937 }
4938
4939 pub fn expr_ty_opt<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Option<Ty<'tcx>> {
4940     return node_id_to_type_opt(cx, expr.id);
4941 }
4942
4943 /// Returns the type of `expr`, considering any `AutoAdjustment`
4944 /// entry recorded for that expression.
4945 ///
4946 /// It would almost certainly be better to store the adjusted ty in with
4947 /// the `AutoAdjustment`, but I opted not to do this because it would
4948 /// require serializing and deserializing the type and, although that's not
4949 /// hard to do, I just hate that code so much I didn't want to touch it
4950 /// unless it was to fix it properly, which seemed a distraction from the
4951 /// thread at hand! -nmatsakis
4952 pub fn expr_ty_adjusted<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
4953     adjust_ty(cx, expr.span, expr.id, expr_ty(cx, expr),
4954               cx.adjustments.borrow().get(&expr.id),
4955               |method_call| cx.method_map.borrow().get(&method_call).map(|method| method.ty))
4956 }
4957
4958 pub fn expr_span(cx: &ctxt, id: NodeId) -> Span {
4959     match cx.map.find(id) {
4960         Some(ast_map::NodeExpr(e)) => {
4961             e.span
4962         }
4963         Some(f) => {
4964             cx.sess.bug(&format!("Node id {} is not an expr: {:?}",
4965                                 id,
4966                                 f));
4967         }
4968         None => {
4969             cx.sess.bug(&format!("Node id {} is not present \
4970                                 in the node map", id));
4971         }
4972     }
4973 }
4974
4975 pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString {
4976     match cx.map.find(id) {
4977         Some(ast_map::NodeLocal(pat)) => {
4978             match pat.node {
4979                 ast::PatIdent(_, ref path1, _) => {
4980                     token::get_ident(path1.node)
4981                 }
4982                 _ => {
4983                     cx.sess.bug(
4984                         &format!("Variable id {} maps to {:?}, not local",
4985                                 id,
4986                                 pat));
4987                 }
4988             }
4989         }
4990         r => {
4991             cx.sess.bug(&format!("Variable id {} maps to {:?}, not local",
4992                                 id,
4993                                 r));
4994         }
4995     }
4996 }
4997
4998 /// See `expr_ty_adjusted`
4999 pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
5000                           span: Span,
5001                           expr_id: ast::NodeId,
5002                           unadjusted_ty: Ty<'tcx>,
5003                           adjustment: Option<&AutoAdjustment<'tcx>>,
5004                           mut method_type: F)
5005                           -> Ty<'tcx> where
5006     F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
5007 {
5008     if let TyError = unadjusted_ty.sty {
5009         return unadjusted_ty;
5010     }
5011
5012     return match adjustment {
5013         Some(adjustment) => {
5014             match *adjustment {
5015                AdjustReifyFnPointer => {
5016                     match unadjusted_ty.sty {
5017                         ty::TyBareFn(Some(_), b) => {
5018                             ty::mk_bare_fn(cx, None, b)
5019                         }
5020                         _ => {
5021                             cx.sess.bug(
5022                                 &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
5023                                           {:?}", unadjusted_ty));
5024                         }
5025                     }
5026                 }
5027
5028                AdjustUnsafeFnPointer => {
5029                     match unadjusted_ty.sty {
5030                         ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b),
5031                         ref b => {
5032                             cx.sess.bug(
5033                                 &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
5034                                          {:?}",
5035                                         b));
5036                         }
5037                     }
5038                }
5039
5040                 AdjustDerefRef(ref adj) => {
5041                     let mut adjusted_ty = unadjusted_ty;
5042
5043                     if !ty::type_is_error(adjusted_ty) {
5044                         for i in 0..adj.autoderefs {
5045                             let method_call = MethodCall::autoderef(expr_id, i as u32);
5046                             match method_type(method_call) {
5047                                 Some(method_ty) => {
5048                                     // Overloaded deref operators have all late-bound
5049                                     // regions fully instantiated and coverge.
5050                                     let fn_ret =
5051                                         ty::no_late_bound_regions(cx,
5052                                                                   &ty_fn_ret(method_ty)).unwrap();
5053                                     adjusted_ty = fn_ret.unwrap();
5054                                 }
5055                                 None => {}
5056                             }
5057                             match deref(adjusted_ty, true) {
5058                                 Some(mt) => { adjusted_ty = mt.ty; }
5059                                 None => {
5060                                     cx.sess.span_bug(
5061                                         span,
5062                                         &format!("the {}th autoderef failed: {}",
5063                                                 i,
5064                                                  adjusted_ty)
5065                                         );
5066                                 }
5067                             }
5068                         }
5069                     }
5070
5071                     if let Some(target) = adj.unsize {
5072                         target
5073                     } else {
5074                         adjust_ty_for_autoref(cx, adjusted_ty, adj.autoref)
5075                     }
5076                 }
5077             }
5078         }
5079         None => unadjusted_ty
5080     };
5081 }
5082
5083 pub fn adjust_ty_for_autoref<'tcx>(cx: &ctxt<'tcx>,
5084                                    ty: Ty<'tcx>,
5085                                    autoref: Option<AutoRef<'tcx>>)
5086                                    -> Ty<'tcx> {
5087     match autoref {
5088         None => ty,
5089         Some(AutoPtr(r, m)) => {
5090             mk_rptr(cx, r, mt { ty: ty, mutbl: m })
5091         }
5092         Some(AutoUnsafe(m)) => {
5093             mk_ptr(cx, mt { ty: ty, mutbl: m })
5094         }
5095     }
5096 }
5097
5098 pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
5099     match tcx.def_map.borrow().get(&expr.id) {
5100         Some(def) => def.full_def(),
5101         None => {
5102             tcx.sess.span_bug(expr.span, &format!(
5103                 "no def-map entry for expr {}", expr.id));
5104         }
5105     }
5106 }
5107
5108 pub fn expr_is_lval(tcx: &ctxt, expr: &ast::Expr) -> bool {
5109      match expr.node {
5110         ast::ExprPath(..) => {
5111             // We can't use resolve_expr here, as this needs to run on broken
5112             // programs. We don't need to through - associated items are all
5113             // rvalues.
5114             match tcx.def_map.borrow().get(&expr.id) {
5115                 Some(&def::PathResolution {
5116                     base_def: def::DefStatic(..), ..
5117                 }) | Some(&def::PathResolution {
5118                     base_def: def::DefUpvar(..), ..
5119                 }) | Some(&def::PathResolution {
5120                     base_def: def::DefLocal(..), ..
5121                 }) => {
5122                     true
5123                 }
5124
5125                 Some(..) => false,
5126
5127                 None => tcx.sess.span_bug(expr.span, &format!(
5128                     "no def for path {}", expr.id))
5129             }
5130         }
5131
5132         ast::ExprUnary(ast::UnDeref, _) |
5133         ast::ExprField(..) |
5134         ast::ExprTupField(..) |
5135         ast::ExprIndex(..) => {
5136             true
5137         }
5138
5139         ast::ExprCall(..) |
5140         ast::ExprMethodCall(..) |
5141         ast::ExprStruct(..) |
5142         ast::ExprRange(..) |
5143         ast::ExprTup(..) |
5144         ast::ExprIf(..) |
5145         ast::ExprMatch(..) |
5146         ast::ExprClosure(..) |
5147         ast::ExprBlock(..) |
5148         ast::ExprRepeat(..) |
5149         ast::ExprVec(..) |
5150         ast::ExprBreak(..) |
5151         ast::ExprAgain(..) |
5152         ast::ExprRet(..) |
5153         ast::ExprWhile(..) |
5154         ast::ExprLoop(..) |
5155         ast::ExprAssign(..) |
5156         ast::ExprInlineAsm(..) |
5157         ast::ExprAssignOp(..) |
5158         ast::ExprLit(_) |
5159         ast::ExprUnary(..) |
5160         ast::ExprBox(..) |
5161         ast::ExprAddrOf(..) |
5162         ast::ExprBinary(..) |
5163         ast::ExprCast(..) => {
5164             false
5165         }
5166
5167         ast::ExprParen(ref e) => expr_is_lval(tcx, e),
5168
5169         ast::ExprIfLet(..) |
5170         ast::ExprWhileLet(..) |
5171         ast::ExprForLoop(..) |
5172         ast::ExprMac(..) => {
5173             tcx.sess.span_bug(
5174                 expr.span,
5175                 "macro expression remains after expansion");
5176         }
5177     }
5178 }
5179
5180 pub fn stmt_node_id(s: &ast::Stmt) -> ast::NodeId {
5181     match s.node {
5182       ast::StmtDecl(_, id) | StmtExpr(_, id) | StmtSemi(_, id) => {
5183         return id;
5184       }
5185       ast::StmtMac(..) => panic!("unexpanded macro in trans")
5186     }
5187 }
5188
5189 pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
5190                      -> usize {
5191     let mut i = 0;
5192     for f in fields { if f.name == name { return i; } i += 1; }
5193     tcx.sess.bug(&format!(
5194         "no field named `{}` found in the list of fields `{:?}`",
5195         token::get_name(name),
5196         fields.iter()
5197               .map(|f| token::get_name(f.name).to_string())
5198               .collect::<Vec<String>>()));
5199 }
5200
5201 pub fn impl_or_trait_item_idx(id: ast::Name, trait_items: &[ImplOrTraitItem])
5202                               -> Option<usize> {
5203     trait_items.iter().position(|m| m.name() == id)
5204 }
5205
5206 pub fn ty_sort_string(cx: &ctxt, ty: Ty) -> String {
5207     match ty.sty {
5208         TyBool | TyChar | TyInt(_) |
5209         TyUint(_) | TyFloat(_) | TyStr => ty.to_string(),
5210         TyTuple(ref tys) if tys.is_empty() => ty.to_string(),
5211
5212         TyEnum(id, _) => format!("enum `{}`", item_path_str(cx, id)),
5213         TyBox(_) => "box".to_string(),
5214         TyArray(_, n) => format!("array of {} elements", n),
5215         TySlice(_) => "slice".to_string(),
5216         TyRawPtr(_) => "*-ptr".to_string(),
5217         TyRef(_, _) => "&-ptr".to_string(),
5218         TyBareFn(Some(_), _) => format!("fn item"),
5219         TyBareFn(None, _) => "fn pointer".to_string(),
5220         TyTrait(ref inner) => {
5221             format!("trait {}", item_path_str(cx, inner.principal_def_id()))
5222         }
5223         TyStruct(id, _) => {
5224             format!("struct `{}`", item_path_str(cx, id))
5225         }
5226         TyClosure(..) => "closure".to_string(),
5227         TyTuple(_) => "tuple".to_string(),
5228         TyInfer(TyVar(_)) => "inferred type".to_string(),
5229         TyInfer(IntVar(_)) => "integral variable".to_string(),
5230         TyInfer(FloatVar(_)) => "floating-point variable".to_string(),
5231         TyInfer(FreshTy(_)) => "skolemized type".to_string(),
5232         TyInfer(FreshIntTy(_)) => "skolemized integral type".to_string(),
5233         TyInfer(FreshFloatTy(_)) => "skolemized floating-point type".to_string(),
5234         TyProjection(_) => "associated type".to_string(),
5235         TyParam(ref p) => {
5236             if p.space == subst::SelfSpace {
5237                 "Self".to_string()
5238             } else {
5239                 "type parameter".to_string()
5240             }
5241         }
5242         TyError => "type error".to_string(),
5243     }
5244 }
5245
5246 /// Explains the source of a type err in a short, human readable way. This is meant to be placed
5247 /// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
5248 /// afterwards to present additional details, particularly when it comes to lifetime-related
5249 /// errors.
5250 impl<'tcx> fmt::Display for type_err<'tcx> {
5251     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5252         match *self {
5253             terr_cyclic_ty => write!(f, "cyclic type of infinite size"),
5254             terr_mismatch => write!(f, "types differ"),
5255             terr_unsafety_mismatch(values) => {
5256                 write!(f, "expected {} fn, found {} fn",
5257                        values.expected,
5258                        values.found)
5259             }
5260             terr_abi_mismatch(values) => {
5261                 write!(f, "expected {} fn, found {} fn",
5262                        values.expected,
5263                        values.found)
5264             }
5265             terr_mutability => write!(f, "values differ in mutability"),
5266             terr_box_mutability => {
5267                 write!(f, "boxed values differ in mutability")
5268             }
5269             terr_vec_mutability => write!(f, "vectors differ in mutability"),
5270             terr_ptr_mutability => write!(f, "pointers differ in mutability"),
5271             terr_ref_mutability => write!(f, "references differ in mutability"),
5272             terr_ty_param_size(values) => {
5273                 write!(f, "expected a type with {} type params, \
5274                            found one with {} type params",
5275                        values.expected,
5276                        values.found)
5277             }
5278             terr_fixed_array_size(values) => {
5279                 write!(f, "expected an array with a fixed size of {} elements, \
5280                            found one with {} elements",
5281                        values.expected,
5282                        values.found)
5283             }
5284             terr_tuple_size(values) => {
5285                 write!(f, "expected a tuple with {} elements, \
5286                            found one with {} elements",
5287                        values.expected,
5288                        values.found)
5289             }
5290             terr_arg_count => {
5291                 write!(f, "incorrect number of function parameters")
5292             }
5293             terr_regions_does_not_outlive(..) => {
5294                 write!(f, "lifetime mismatch")
5295             }
5296             terr_regions_not_same(..) => {
5297                 write!(f, "lifetimes are not the same")
5298             }
5299             terr_regions_no_overlap(..) => {
5300                 write!(f, "lifetimes do not intersect")
5301             }
5302             terr_regions_insufficiently_polymorphic(br, _) => {
5303                 write!(f, "expected bound lifetime parameter {}, \
5304                            found concrete lifetime", br)
5305             }
5306             terr_regions_overly_polymorphic(br, _) => {
5307                 write!(f, "expected concrete lifetime, \
5308                            found bound lifetime parameter {}", br)
5309             }
5310             terr_sorts(values) => tls::with(|tcx| {
5311                 // A naive approach to making sure that we're not reporting silly errors such as:
5312                 // (expected closure, found closure).
5313                 let expected_str = ty_sort_string(tcx, values.expected);
5314                 let found_str = ty_sort_string(tcx, values.found);
5315                 if expected_str == found_str {
5316                     write!(f, "expected {}, found a different {}", expected_str, found_str)
5317                 } else {
5318                     write!(f, "expected {}, found {}", expected_str, found_str)
5319                 }
5320             }),
5321             terr_traits(values) => tls::with(|tcx| {
5322                 write!(f, "expected trait `{}`, found trait `{}`",
5323                        item_path_str(tcx, values.expected),
5324                        item_path_str(tcx, values.found))
5325             }),
5326             terr_builtin_bounds(values) => {
5327                 if values.expected.is_empty() {
5328                     write!(f, "expected no bounds, found `{}`",
5329                            values.found)
5330                 } else if values.found.is_empty() {
5331                     write!(f, "expected bounds `{}`, found no bounds",
5332                            values.expected)
5333                 } else {
5334                     write!(f, "expected bounds `{}`, found bounds `{}`",
5335                            values.expected,
5336                            values.found)
5337                 }
5338             }
5339             terr_integer_as_char => {
5340                 write!(f, "expected an integral type, found `char`")
5341             }
5342             terr_int_mismatch(ref values) => {
5343                 write!(f, "expected `{:?}`, found `{:?}`",
5344                        values.expected,
5345                        values.found)
5346             }
5347             terr_float_mismatch(ref values) => {
5348                 write!(f, "expected `{:?}`, found `{:?}`",
5349                        values.expected,
5350                        values.found)
5351             }
5352             terr_variadic_mismatch(ref values) => {
5353                 write!(f, "expected {} fn, found {} function",
5354                        if values.expected { "variadic" } else { "non-variadic" },
5355                        if values.found { "variadic" } else { "non-variadic" })
5356             }
5357             terr_convergence_mismatch(ref values) => {
5358                 write!(f, "expected {} fn, found {} function",
5359                        if values.expected { "converging" } else { "diverging" },
5360                        if values.found { "converging" } else { "diverging" })
5361             }
5362             terr_projection_name_mismatched(ref values) => {
5363                 write!(f, "expected {}, found {}",
5364                        values.expected,
5365                        values.found)
5366             }
5367             terr_projection_bounds_length(ref values) => {
5368                 write!(f, "expected {} associated type bindings, found {}",
5369                        values.expected,
5370                        values.found)
5371             }
5372         }
5373     }
5374 }
5375
5376 pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>, sp: Span) {
5377     match *err {
5378         terr_regions_does_not_outlive(subregion, superregion) => {
5379             note_and_explain_region(cx, "", subregion, "...");
5380             note_and_explain_region(cx, "...does not necessarily outlive ",
5381                                     superregion, "");
5382         }
5383         terr_regions_not_same(region1, region2) => {
5384             note_and_explain_region(cx, "", region1, "...");
5385             note_and_explain_region(cx, "...is not the same lifetime as ",
5386                                     region2, "");
5387         }
5388         terr_regions_no_overlap(region1, region2) => {
5389             note_and_explain_region(cx, "", region1, "...");
5390             note_and_explain_region(cx, "...does not overlap ",
5391                                     region2, "");
5392         }
5393         terr_regions_insufficiently_polymorphic(_, conc_region) => {
5394             note_and_explain_region(cx,
5395                                     "concrete lifetime that was found is ",
5396                                     conc_region, "");
5397         }
5398         terr_regions_overly_polymorphic(_, ty::ReInfer(ty::ReVar(_))) => {
5399             // don't bother to print out the message below for
5400             // inference variables, it's not very illuminating.
5401         }
5402         terr_regions_overly_polymorphic(_, conc_region) => {
5403             note_and_explain_region(cx,
5404                                     "expected concrete lifetime is ",
5405                                     conc_region, "");
5406         }
5407         terr_sorts(values) => {
5408             let expected_str = ty_sort_string(cx, values.expected);
5409             let found_str = ty_sort_string(cx, values.found);
5410             if expected_str == found_str && expected_str == "closure" {
5411                 cx.sess.span_note(sp, &format!("no two closures, even if identical, have the same \
5412                                                 type"));
5413                 cx.sess.span_help(sp, &format!("consider boxing your closure and/or \
5414                                         using it as a trait object"));
5415             }
5416         }
5417         _ => {}
5418     }
5419 }
5420
5421 pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option<ast::DefId> {
5422     cx.provided_method_sources.borrow().get(&id).cloned()
5423 }
5424
5425 pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5426                                     -> Vec<Rc<Method<'tcx>>> {
5427     if is_local(id) {
5428         if let ItemTrait(_, _, _, ref ms) = cx.map.expect_item(id.node).node {
5429             ms.iter().filter_map(|ti| {
5430                 if let ast::MethodTraitItem(_, Some(_)) = ti.node {
5431                     match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
5432                         MethodTraitItem(m) => Some(m),
5433                         _ => {
5434                             cx.sess.bug("provided_trait_methods(): \
5435                                          non-method item found from \
5436                                          looking up provided method?!")
5437                         }
5438                     }
5439                 } else {
5440                     None
5441                 }
5442             }).collect()
5443         } else {
5444             cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
5445         }
5446     } else {
5447         csearch::get_provided_trait_methods(cx, id)
5448     }
5449 }
5450
5451 pub fn associated_consts<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5452                                -> Vec<Rc<AssociatedConst<'tcx>>> {
5453     if is_local(id) {
5454         match cx.map.expect_item(id.node).node {
5455             ItemTrait(_, _, _, ref tis) => {
5456                 tis.iter().filter_map(|ti| {
5457                     if let ast::ConstTraitItem(_, _) = ti.node {
5458                         match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
5459                             ConstTraitItem(ac) => Some(ac),
5460                             _ => {
5461                                 cx.sess.bug("associated_consts(): \
5462                                              non-const item found from \
5463                                              looking up a constant?!")
5464                             }
5465                         }
5466                     } else {
5467                         None
5468                     }
5469                 }).collect()
5470             }
5471             ItemImpl(_, _, _, _, _, ref iis) => {
5472                 iis.iter().filter_map(|ii| {
5473                     if let ast::ConstImplItem(_, _) = ii.node {
5474                         match impl_or_trait_item(cx, ast_util::local_def(ii.id)) {
5475                             ConstTraitItem(ac) => Some(ac),
5476                             _ => {
5477                                 cx.sess.bug("associated_consts(): \
5478                                              non-const item found from \
5479                                              looking up a constant?!")
5480                             }
5481                         }
5482                     } else {
5483                         None
5484                     }
5485                 }).collect()
5486             }
5487             _ => {
5488                 cx.sess.bug(&format!("associated_consts: `{:?}` is not a trait \
5489                                       or impl", id))
5490             }
5491         }
5492     } else {
5493         csearch::get_associated_consts(cx, id)
5494     }
5495 }
5496
5497 /// Helper for looking things up in the various maps that are populated during
5498 /// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc).  All of
5499 /// these share the pattern that if the id is local, it should have been loaded
5500 /// into the map by the `typeck::collect` phase.  If the def-id is external,
5501 /// then we have to go consult the crate loading code (and cache the result for
5502 /// the future).
5503 fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
5504                                           def_id: ast::DefId,
5505                                           map: &RefCell<DefIdMap<V>>,
5506                                           load_external: F) -> V where
5507     V: Clone,
5508     F: FnOnce() -> V,
5509 {
5510     match map.borrow().get(&def_id).cloned() {
5511         Some(v) => { return v; }
5512         None => { }
5513     }
5514
5515     if def_id.krate == ast::LOCAL_CRATE {
5516         panic!("No def'n found for {:?} in tcx.{}", def_id, descr);
5517     }
5518     let v = load_external();
5519     map.borrow_mut().insert(def_id, v.clone());
5520     v
5521 }
5522
5523 pub fn trait_item<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId, idx: usize)
5524                         -> ImplOrTraitItem<'tcx> {
5525     let method_def_id = (*ty::trait_item_def_ids(cx, trait_did))[idx].def_id();
5526     impl_or_trait_item(cx, method_def_id)
5527 }
5528
5529 pub fn trait_items<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId)
5530                          -> Rc<Vec<ImplOrTraitItem<'tcx>>> {
5531     let mut trait_items = cx.trait_items_cache.borrow_mut();
5532     match trait_items.get(&trait_did).cloned() {
5533         Some(trait_items) => trait_items,
5534         None => {
5535             let def_ids = ty::trait_item_def_ids(cx, trait_did);
5536             let items: Rc<Vec<ImplOrTraitItem>> =
5537                 Rc::new(def_ids.iter()
5538                                .map(|d| impl_or_trait_item(cx, d.def_id()))
5539                                .collect());
5540             trait_items.insert(trait_did, items.clone());
5541             items
5542         }
5543     }
5544 }
5545
5546 pub fn trait_impl_polarity<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5547                             -> Option<ast::ImplPolarity> {
5548      if id.krate == ast::LOCAL_CRATE {
5549          match cx.map.find(id.node) {
5550              Some(ast_map::NodeItem(item)) => {
5551                  match item.node {
5552                      ast::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
5553                      _ => None
5554                  }
5555              }
5556              _ => None
5557          }
5558      } else {
5559          csearch::get_impl_polarity(cx, id)
5560      }
5561 }
5562
5563 pub fn custom_coerce_unsized_kind<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
5564                                         -> CustomCoerceUnsized {
5565     memoized(&cx.custom_coerce_unsized_kinds, did, |did: DefId| {
5566         let (kind, src) = if did.krate != ast::LOCAL_CRATE {
5567             (csearch::get_custom_coerce_unsized_kind(cx, did), "external")
5568         } else {
5569             (None, "local")
5570         };
5571
5572         match kind {
5573             Some(kind) => kind,
5574             None => {
5575                 cx.sess.bug(&format!("custom_coerce_unsized_kind: \
5576                                       {} impl `{}` is missing its kind",
5577                                      src, item_path_str(cx, did)));
5578             }
5579         }
5580     })
5581 }
5582
5583 pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5584                                 -> ImplOrTraitItem<'tcx> {
5585     lookup_locally_or_in_crate_store(
5586         "impl_or_trait_items", id, &cx.impl_or_trait_items,
5587         || csearch::get_impl_or_trait_item(cx, id))
5588 }
5589
5590 /// Returns the parameter index that the given associated type corresponds to.
5591 pub fn associated_type_parameter_index(cx: &ctxt,
5592                                        trait_def: &TraitDef,
5593                                        associated_type_id: ast::DefId)
5594                                        -> usize {
5595     for type_parameter_def in &trait_def.generics.types {
5596         if type_parameter_def.def_id == associated_type_id {
5597             return type_parameter_def.index as usize
5598         }
5599     }
5600     cx.sess.bug("couldn't find associated type parameter index")
5601 }
5602
5603 pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
5604                           -> Rc<Vec<ImplOrTraitItemId>> {
5605     lookup_locally_or_in_crate_store(
5606         "trait_item_def_ids", id, &cx.trait_item_def_ids,
5607         || Rc::new(csearch::get_trait_item_def_ids(&cx.sess.cstore, id)))
5608 }
5609
5610 /// Returns the trait-ref corresponding to a given impl, or None if it is
5611 /// an inherent impl.
5612 pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5613                             -> Option<TraitRef<'tcx>>
5614 {
5615     lookup_locally_or_in_crate_store(
5616         "impl_trait_refs", id, &cx.impl_trait_refs,
5617         || csearch::get_impl_trait(cx, id))
5618 }
5619
5620 /// Returns whether this DefId refers to an impl
5621 pub fn is_impl<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) -> bool {
5622     if id.krate == ast::LOCAL_CRATE {
5623         if let Some(ast_map::NodeItem(
5624             &ast::Item { node: ast::ItemImpl(..), .. })) = cx.map.find(id.node) {
5625             true
5626         } else {
5627             false
5628         }
5629     } else {
5630         csearch::is_impl(&cx.sess.cstore, id)
5631     }
5632 }
5633
5634 pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId {
5635     tcx.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
5636 }
5637
5638 pub fn try_add_builtin_trait(
5639     tcx: &ctxt,
5640     trait_def_id: ast::DefId,
5641     builtin_bounds: &mut EnumSet<BuiltinBound>)
5642     -> bool
5643 {
5644     //! Checks whether `trait_ref` refers to one of the builtin
5645     //! traits, like `Send`, and adds the corresponding
5646     //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
5647     //! is a builtin trait.
5648
5649     match tcx.lang_items.to_builtin_kind(trait_def_id) {
5650         Some(bound) => { builtin_bounds.insert(bound); true }
5651         None => false
5652     }
5653 }
5654
5655 pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
5656     match ty.sty {
5657         TyTrait(ref tt) =>
5658             Some(tt.principal_def_id()),
5659         TyStruct(id, _) |
5660         TyEnum(id, _) |
5661         TyClosure(id, _) =>
5662             Some(id),
5663         _ =>
5664             None
5665     }
5666 }
5667
5668 // Enum information
5669 #[derive(Clone)]
5670 pub struct VariantInfo<'tcx> {
5671     pub args: Vec<Ty<'tcx>>,
5672     pub arg_names: Option<Vec<ast::Name>>,
5673     pub ctor_ty: Option<Ty<'tcx>>,
5674     pub name: ast::Name,
5675     pub id: ast::DefId,
5676     pub disr_val: Disr,
5677     pub vis: Visibility
5678 }
5679
5680 impl<'tcx> VariantInfo<'tcx> {
5681
5682     /// Creates a new VariantInfo from the corresponding ast representation.
5683     ///
5684     /// Does not do any caching of the value in the type context.
5685     pub fn from_ast_variant(cx: &ctxt<'tcx>,
5686                             ast_variant: &ast::Variant,
5687                             discriminant: Disr) -> VariantInfo<'tcx> {
5688         let ctor_ty = node_id_to_type(cx, ast_variant.node.id);
5689
5690         match ast_variant.node.kind {
5691             ast::TupleVariantKind(ref args) => {
5692                 let arg_tys = if !args.is_empty() {
5693                     // the regions in the argument types come from the
5694                     // enum def'n, and hence will all be early bound
5695                     ty::no_late_bound_regions(cx, &ty_fn_args(ctor_ty)).unwrap()
5696                 } else {
5697                     Vec::new()
5698                 };
5699
5700                 return VariantInfo {
5701                     args: arg_tys,
5702                     arg_names: None,
5703                     ctor_ty: Some(ctor_ty),
5704                     name: ast_variant.node.name.name,
5705                     id: ast_util::local_def(ast_variant.node.id),
5706                     disr_val: discriminant,
5707                     vis: ast_variant.node.vis
5708                 };
5709             },
5710             ast::StructVariantKind(ref struct_def) => {
5711                 let fields: &[StructField] = &struct_def.fields;
5712
5713                 assert!(!fields.is_empty());
5714
5715                 let arg_tys = struct_def.fields.iter()
5716                     .map(|field| node_id_to_type(cx, field.node.id)).collect();
5717                 let arg_names = fields.iter().map(|field| {
5718                     match field.node.kind {
5719                         NamedField(ident, _) => ident.name,
5720                         UnnamedField(..) => cx.sess.bug(
5721                             "enum_variants: all fields in struct must have a name")
5722                     }
5723                 }).collect();
5724
5725                 return VariantInfo {
5726                     args: arg_tys,
5727                     arg_names: Some(arg_names),
5728                     ctor_ty: None,
5729                     name: ast_variant.node.name.name,
5730                     id: ast_util::local_def(ast_variant.node.id),
5731                     disr_val: discriminant,
5732                     vis: ast_variant.node.vis
5733                 };
5734             }
5735         }
5736     }
5737 }
5738
5739 pub fn substd_enum_variants<'tcx>(cx: &ctxt<'tcx>,
5740                                   id: ast::DefId,
5741                                   substs: &Substs<'tcx>)
5742                                   -> Vec<Rc<VariantInfo<'tcx>>> {
5743     enum_variants(cx, id).iter().map(|variant_info| {
5744         let substd_args = variant_info.args.iter()
5745             .map(|aty| aty.subst(cx, substs)).collect::<Vec<_>>();
5746
5747         let substd_ctor_ty = variant_info.ctor_ty.subst(cx, substs);
5748
5749         Rc::new(VariantInfo {
5750             args: substd_args,
5751             ctor_ty: substd_ctor_ty,
5752             ..(**variant_info).clone()
5753         })
5754     }).collect()
5755 }
5756
5757 pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> String {
5758     with_path(cx, id, |path| ast_map::path_to_string(path)).to_string()
5759 }
5760
5761 #[derive(Copy, Clone)]
5762 pub enum DtorKind {
5763     NoDtor,
5764     TraitDtor(DefId, bool)
5765 }
5766
5767 impl DtorKind {
5768     pub fn is_present(&self) -> bool {
5769         match *self {
5770             TraitDtor(..) => true,
5771             _ => false
5772         }
5773     }
5774
5775     pub fn has_drop_flag(&self) -> bool {
5776         match self {
5777             &NoDtor => false,
5778             &TraitDtor(_, flag) => flag
5779         }
5780     }
5781 }
5782
5783 /* If struct_id names a struct with a dtor. */
5784 pub fn ty_dtor(cx: &ctxt, struct_id: DefId) -> DtorKind {
5785     match cx.destructor_for_type.borrow().get(&struct_id) {
5786         Some(&method_def_id) => {
5787             let flag = !has_attr(cx, struct_id, "unsafe_no_drop_flag");
5788
5789             TraitDtor(method_def_id, flag)
5790         }
5791         None => NoDtor,
5792     }
5793 }
5794
5795 pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool {
5796     cx.destructor_for_type.borrow().contains_key(&struct_id)
5797 }
5798
5799 pub fn with_path<T, F>(cx: &ctxt, id: ast::DefId, f: F) -> T where
5800     F: FnOnce(ast_map::PathElems) -> T,
5801 {
5802     if id.krate == ast::LOCAL_CRATE {
5803         cx.map.with_path(id.node, f)
5804     } else {
5805         f(csearch::get_item_path(cx, id).iter().cloned().chain(LinkedPath::empty()))
5806     }
5807 }
5808
5809 pub fn enum_is_univariant(cx: &ctxt, id: ast::DefId) -> bool {
5810     enum_variants(cx, id).len() == 1
5811 }
5812
5813 pub fn type_is_empty(cx: &ctxt, ty: Ty) -> bool {
5814     match ty.sty {
5815        TyEnum(did, _) => (*enum_variants(cx, did)).is_empty(),
5816        _ => false
5817      }
5818 }
5819
5820 trait IntTypeExt {
5821     fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx>;
5822     fn i64_to_disr(&self, val: i64) -> Option<Disr>;
5823     fn u64_to_disr(&self, val: u64) -> Option<Disr>;
5824     fn disr_incr(&self, val: Disr) -> Option<Disr>;
5825     fn disr_string(&self, val: Disr) -> String;
5826     fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr;
5827 }
5828
5829 impl IntTypeExt for attr::IntType {
5830     fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> {
5831         match *self {
5832             SignedInt(ast::TyI8)      => cx.types.i8,
5833             SignedInt(ast::TyI16)     => cx.types.i16,
5834             SignedInt(ast::TyI32)     => cx.types.i32,
5835             SignedInt(ast::TyI64)     => cx.types.i64,
5836             SignedInt(ast::TyIs)   => cx.types.isize,
5837             UnsignedInt(ast::TyU8)    => cx.types.u8,
5838             UnsignedInt(ast::TyU16)   => cx.types.u16,
5839             UnsignedInt(ast::TyU32)   => cx.types.u32,
5840             UnsignedInt(ast::TyU64)   => cx.types.u64,
5841             UnsignedInt(ast::TyUs) => cx.types.usize,
5842         }
5843     }
5844
5845     fn i64_to_disr(&self, val: i64) -> Option<Disr> {
5846         match *self {
5847             SignedInt(ast::TyI8)    => val.to_i8()  .map(|v| v as Disr),
5848             SignedInt(ast::TyI16)   => val.to_i16() .map(|v| v as Disr),
5849             SignedInt(ast::TyI32)   => val.to_i32() .map(|v| v as Disr),
5850             SignedInt(ast::TyI64)   => val.to_i64() .map(|v| v as Disr),
5851             UnsignedInt(ast::TyU8)  => val.to_u8()  .map(|v| v as Disr),
5852             UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
5853             UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
5854             UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
5855
5856             UnsignedInt(ast::TyUs) |
5857             SignedInt(ast::TyIs) => unreachable!(),
5858         }
5859     }
5860
5861     fn u64_to_disr(&self, val: u64) -> Option<Disr> {
5862         match *self {
5863             SignedInt(ast::TyI8)    => val.to_i8()  .map(|v| v as Disr),
5864             SignedInt(ast::TyI16)   => val.to_i16() .map(|v| v as Disr),
5865             SignedInt(ast::TyI32)   => val.to_i32() .map(|v| v as Disr),
5866             SignedInt(ast::TyI64)   => val.to_i64() .map(|v| v as Disr),
5867             UnsignedInt(ast::TyU8)  => val.to_u8()  .map(|v| v as Disr),
5868             UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
5869             UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
5870             UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
5871
5872             UnsignedInt(ast::TyUs) |
5873             SignedInt(ast::TyIs) => unreachable!(),
5874         }
5875     }
5876
5877     fn disr_incr(&self, val: Disr) -> Option<Disr> {
5878         macro_rules! add1 {
5879             ($e:expr) => { $e.and_then(|v|v.checked_add(1)).map(|v| v as Disr) }
5880         }
5881         match *self {
5882             // SignedInt repr means we *want* to reinterpret the bits
5883             // treating the highest bit of Disr as a sign-bit, so
5884             // cast to i64 before range-checking.
5885             SignedInt(ast::TyI8)    => add1!((val as i64).to_i8()),
5886             SignedInt(ast::TyI16)   => add1!((val as i64).to_i16()),
5887             SignedInt(ast::TyI32)   => add1!((val as i64).to_i32()),
5888             SignedInt(ast::TyI64)   => add1!(Some(val as i64)),
5889
5890             UnsignedInt(ast::TyU8)  => add1!(val.to_u8()),
5891             UnsignedInt(ast::TyU16) => add1!(val.to_u16()),
5892             UnsignedInt(ast::TyU32) => add1!(val.to_u32()),
5893             UnsignedInt(ast::TyU64) => add1!(Some(val)),
5894
5895             UnsignedInt(ast::TyUs) |
5896             SignedInt(ast::TyIs) => unreachable!(),
5897         }
5898     }
5899
5900     // This returns a String because (1.) it is only used for
5901     // rendering an error message and (2.) a string can represent the
5902     // full range from `i64::MIN` through `u64::MAX`.
5903     fn disr_string(&self, val: Disr) -> String {
5904         match *self {
5905             SignedInt(ast::TyI8)    => format!("{}", val as i8 ),
5906             SignedInt(ast::TyI16)   => format!("{}", val as i16),
5907             SignedInt(ast::TyI32)   => format!("{}", val as i32),
5908             SignedInt(ast::TyI64)   => format!("{}", val as i64),
5909             UnsignedInt(ast::TyU8)  => format!("{}", val as u8 ),
5910             UnsignedInt(ast::TyU16) => format!("{}", val as u16),
5911             UnsignedInt(ast::TyU32) => format!("{}", val as u32),
5912             UnsignedInt(ast::TyU64) => format!("{}", val as u64),
5913
5914             UnsignedInt(ast::TyUs) |
5915             SignedInt(ast::TyIs) => unreachable!(),
5916         }
5917     }
5918
5919     fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr {
5920         macro_rules! add1 {
5921             ($e:expr) => { ($e).wrapping_add(1) as Disr }
5922         }
5923         let val = val.unwrap_or(ty::INITIAL_DISCRIMINANT_VALUE);
5924         match *self {
5925             SignedInt(ast::TyI8)    => add1!(val as i8 ),
5926             SignedInt(ast::TyI16)   => add1!(val as i16),
5927             SignedInt(ast::TyI32)   => add1!(val as i32),
5928             SignedInt(ast::TyI64)   => add1!(val as i64),
5929             UnsignedInt(ast::TyU8)  => add1!(val as u8 ),
5930             UnsignedInt(ast::TyU16) => add1!(val as u16),
5931             UnsignedInt(ast::TyU32) => add1!(val as u32),
5932             UnsignedInt(ast::TyU64) => add1!(val as u64),
5933
5934             UnsignedInt(ast::TyUs) |
5935             SignedInt(ast::TyIs) => unreachable!(),
5936         }
5937     }
5938 }
5939
5940 /// Returns `(normalized_type, ty)`, where `normalized_type` is the
5941 /// IntType representation of one of {i64,i32,i16,i8,u64,u32,u16,u8},
5942 /// and `ty` is the original type (i.e. may include `isize` or
5943 /// `usize`).
5944 pub fn enum_repr_type<'tcx>(cx: &ctxt<'tcx>,
5945                             opt_hint: Option<&attr::ReprAttr>)
5946                             -> (attr::IntType, Ty<'tcx>)
5947 {
5948     let repr_type = match opt_hint {
5949         // Feed in the given type
5950         Some(&attr::ReprInt(_, int_t)) => int_t,
5951         // ... but provide sensible default if none provided
5952         //
5953         // NB. Historically `fn enum_variants` generate i64 here, while
5954         // rustc_typeck::check would generate isize.
5955         _ => SignedInt(ast::TyIs),
5956     };
5957
5958     let repr_type_ty = repr_type.to_ty(cx);
5959     let repr_type = match repr_type {
5960         SignedInt(ast::TyIs) =>
5961             SignedInt(cx.sess.target.int_type),
5962         UnsignedInt(ast::TyUs) =>
5963             UnsignedInt(cx.sess.target.uint_type),
5964         other => other
5965     };
5966
5967     (repr_type, repr_type_ty)
5968 }
5969
5970 fn report_discrim_overflow(cx: &ctxt,
5971                            variant_span: Span,
5972                            variant_name: &str,
5973                            repr_type: attr::IntType,
5974                            prev_val: Disr) {
5975     let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
5976     let computed_value = repr_type.disr_string(computed_value);
5977     let prev_val = repr_type.disr_string(prev_val);
5978     let repr_type = repr_type.to_ty(cx);
5979     span_err!(cx.sess, variant_span, E0370,
5980               "enum discriminant overflowed on value after {}: {}; \
5981                set explicitly via {} = {} if that is desired outcome",
5982               prev_val, repr_type, variant_name, computed_value);
5983 }
5984
5985 // This computes the discriminant values for the sequence of Variants
5986 // attached to a particular enum, taking into account the #[repr] (if
5987 // any) provided via the `opt_hint`.
5988 fn compute_enum_variants<'tcx>(cx: &ctxt<'tcx>,
5989                                vs: &'tcx [P<ast::Variant>],
5990                                opt_hint: Option<&attr::ReprAttr>)
5991                                -> Vec<Rc<ty::VariantInfo<'tcx>>> {
5992     let mut variants: Vec<Rc<ty::VariantInfo>> = Vec::new();
5993     let mut prev_disr_val: Option<ty::Disr> = None;
5994
5995     let (repr_type, repr_type_ty) = ty::enum_repr_type(cx, opt_hint);
5996
5997     for v in vs {
5998         // If the discriminant value is specified explicitly in the
5999         // enum, check whether the initialization expression is valid,
6000         // otherwise use the last value plus one.
6001         let current_disr_val;
6002
6003         // This closure marks cases where, when an error occurs during
6004         // the computation, attempt to assign a (hopefully) fresh
6005         // value to avoid spurious error reports downstream.
6006         let attempt_fresh_value = move || -> Disr {
6007             repr_type.disr_wrap_incr(prev_disr_val)
6008         };
6009
6010         match v.node.disr_expr {
6011             Some(ref e) => {
6012                 debug!("disr expr, checking {}", pprust::expr_to_string(&**e));
6013
6014                 // check_expr (from check_const pass) doesn't guarantee
6015                 // that the expression is in a form that eval_const_expr can
6016                 // handle, so we may still get an internal compiler error
6017                 //
6018                 // pnkfelix: The above comment was transcribed from
6019                 // the version of this code taken from rustc_typeck.
6020                 // Presumably the implication is that we need to deal
6021                 // with such ICE's as they arise.
6022                 //
6023                 // Since this can be called from `ty::enum_variants`
6024                 // anyway, best thing is to make `eval_const_expr`
6025                 // more robust (on case-by-case basis).
6026
6027                 match const_eval::eval_const_expr_partial(cx, &**e, Some(repr_type_ty)) {
6028                     Ok(const_eval::const_int(val)) => current_disr_val = val as Disr,
6029                     Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr,
6030                     Ok(_) => {
6031                         let sign_desc = if repr_type.is_signed() { "signed" } else { "unsigned" };
6032                         span_err!(cx.sess, e.span, E0079,
6033                                   "expected {} integer constant",
6034                                   sign_desc);
6035                         current_disr_val = attempt_fresh_value();
6036                     }
6037                     Err(ref err) => {
6038                         span_err!(cx.sess, err.span, E0080,
6039                                   "constant evaluation error: {}",
6040                                   err.description());
6041                         current_disr_val = attempt_fresh_value();
6042                     }
6043                 }
6044             },
6045             None => {
6046                 current_disr_val = match prev_disr_val {
6047                     Some(prev_disr_val) => {
6048                         if let Some(v) = repr_type.disr_incr(prev_disr_val) {
6049                             v
6050                         } else {
6051                             report_discrim_overflow(cx, v.span, v.node.name.as_str(),
6052                                                     repr_type, prev_disr_val);
6053                             attempt_fresh_value()
6054                         }
6055                     }
6056                     None => ty::INITIAL_DISCRIMINANT_VALUE
6057                 }
6058             }
6059         }
6060
6061         let variant_info = Rc::new(VariantInfo::from_ast_variant(cx, &**v, current_disr_val));
6062         prev_disr_val = Some(current_disr_val);
6063
6064         variants.push(variant_info);
6065     }
6066
6067     return variants;
6068 }
6069
6070 pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
6071                            -> Rc<Vec<Rc<VariantInfo<'tcx>>>> {
6072     memoized(&cx.enum_var_cache, id, |id: ast::DefId| {
6073         if ast::LOCAL_CRATE != id.krate {
6074             Rc::new(csearch::get_enum_variants(cx, id))
6075         } else {
6076             match cx.map.get(id.node) {
6077                 ast_map::NodeItem(ref item) => {
6078                     match item.node {
6079                         ast::ItemEnum(ref enum_definition, _) => {
6080                             Rc::new(compute_enum_variants(
6081                                 cx,
6082                                 &enum_definition.variants,
6083                                 lookup_repr_hints(cx, id).get(0)))
6084                         }
6085                         _ => {
6086                             cx.sess.bug("enum_variants: id not bound to an enum")
6087                         }
6088                     }
6089                 }
6090                 _ => cx.sess.bug("enum_variants: id not bound to an enum")
6091             }
6092         }
6093     })
6094 }
6095
6096 // Returns information about the enum variant with the given ID:
6097 pub fn enum_variant_with_id<'tcx>(cx: &ctxt<'tcx>,
6098                                   enum_id: ast::DefId,
6099                                   variant_id: ast::DefId)
6100                                   -> Rc<VariantInfo<'tcx>> {
6101     enum_variants(cx, enum_id).iter()
6102                               .find(|variant| variant.id == variant_id)
6103                               .expect("enum_variant_with_id(): no variant exists with that ID")
6104                               .clone()
6105 }
6106
6107
6108 // If the given item is in an external crate, looks up its type and adds it to
6109 // the type cache. Returns the type parameters and type.
6110 pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>,
6111                               did: ast::DefId)
6112                               -> TypeScheme<'tcx> {
6113     lookup_locally_or_in_crate_store(
6114         "tcache", did, &cx.tcache,
6115         || csearch::get_type(cx, did))
6116 }
6117
6118 /// Given the did of a trait, returns its canonical trait ref.
6119 pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
6120                               -> &'tcx TraitDef<'tcx> {
6121     lookup_locally_or_in_crate_store(
6122         "trait_defs", did, &cx.trait_defs,
6123         || cx.arenas.trait_defs.alloc(csearch::get_trait_def(cx, did))
6124     )
6125 }
6126
6127 /// Given the did of an item, returns its full set of predicates.
6128 pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
6129                                 -> GenericPredicates<'tcx>
6130 {
6131     lookup_locally_or_in_crate_store(
6132         "predicates", did, &cx.predicates,
6133         || csearch::get_predicates(cx, did))
6134 }
6135
6136 /// Given the did of a trait, returns its superpredicates.
6137 pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
6138                                      -> GenericPredicates<'tcx>
6139 {
6140     lookup_locally_or_in_crate_store(
6141         "super_predicates", did, &cx.super_predicates,
6142         || csearch::get_super_predicates(cx, did))
6143 }
6144
6145 pub fn predicates<'tcx>(
6146     tcx: &ctxt<'tcx>,
6147     param_ty: Ty<'tcx>,
6148     bounds: &ParamBounds<'tcx>)
6149     -> Vec<Predicate<'tcx>>
6150 {
6151     let mut vec = Vec::new();
6152
6153     for builtin_bound in &bounds.builtin_bounds {
6154         match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) {
6155             Ok(trait_ref) => { vec.push(trait_ref.as_predicate()); }
6156             Err(ErrorReported) => { }
6157         }
6158     }
6159
6160     for &region_bound in &bounds.region_bounds {
6161         // account for the binder being introduced below; no need to shift `param_ty`
6162         // because, at present at least, it can only refer to early-bound regions
6163         let region_bound = ty_fold::shift_region(region_bound, 1);
6164         vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).as_predicate());
6165     }
6166
6167     for bound_trait_ref in &bounds.trait_bounds {
6168         vec.push(bound_trait_ref.as_predicate());
6169     }
6170
6171     for projection in &bounds.projection_bounds {
6172         vec.push(projection.as_predicate());
6173     }
6174
6175     vec
6176 }
6177
6178 /// Get the attributes of a definition.
6179 pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId)
6180                        -> Cow<'tcx, [ast::Attribute]> {
6181     if is_local(did) {
6182         Cow::Borrowed(tcx.map.attrs(did.node))
6183     } else {
6184         Cow::Owned(csearch::get_item_attrs(&tcx.sess.cstore, did))
6185     }
6186 }
6187
6188 /// Determine whether an item is annotated with an attribute
6189 pub fn has_attr(tcx: &ctxt, did: DefId, attr: &str) -> bool {
6190     get_attrs(tcx, did).iter().any(|item| item.check_name(attr))
6191 }
6192
6193 /// Determine whether an item is annotated with `#[repr(packed)]`
6194 pub fn lookup_packed(tcx: &ctxt, did: DefId) -> bool {
6195     lookup_repr_hints(tcx, did).contains(&attr::ReprPacked)
6196 }
6197
6198 /// Determine whether an item is annotated with `#[simd]`
6199 pub fn lookup_simd(tcx: &ctxt, did: DefId) -> bool {
6200     has_attr(tcx, did, "simd")
6201 }
6202
6203 /// Obtain the representation annotation for a struct definition.
6204 pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
6205     memoized(&tcx.repr_hint_cache, did, |did: DefId| {
6206         Rc::new(if did.krate == LOCAL_CRATE {
6207             get_attrs(tcx, did).iter().flat_map(|meta| {
6208                 attr::find_repr_attrs(tcx.sess.diagnostic(), meta).into_iter()
6209             }).collect()
6210         } else {
6211             csearch::get_repr_attrs(&tcx.sess.cstore, did)
6212         })
6213     })
6214 }
6215
6216 // Look up a field ID, whether or not it's local
6217 pub fn lookup_field_type_unsubstituted<'tcx>(tcx: &ctxt<'tcx>,
6218                                              struct_id: DefId,
6219                                              id: DefId)
6220                                              -> Ty<'tcx> {
6221     if id.krate == ast::LOCAL_CRATE {
6222         node_id_to_type(tcx, id.node)
6223     } else {
6224         let mut tcache = tcx.tcache.borrow_mut();
6225         tcache.entry(id).or_insert_with(|| csearch::get_field_type(tcx, struct_id, id)).ty
6226     }
6227 }
6228
6229
6230 // Look up a field ID, whether or not it's local
6231 // Takes a list of type substs in case the struct is generic
6232 pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
6233                                struct_id: DefId,
6234                                id: DefId,
6235                                substs: &Substs<'tcx>)
6236                                -> Ty<'tcx> {
6237     lookup_field_type_unsubstituted(tcx, struct_id, id).subst(tcx, substs)
6238 }
6239
6240 // Look up the list of field names and IDs for a given struct.
6241 // Panics if the id is not bound to a struct.
6242 pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
6243     if did.krate == ast::LOCAL_CRATE {
6244         let struct_fields = cx.struct_fields.borrow();
6245         match struct_fields.get(&did) {
6246             Some(fields) => (**fields).clone(),
6247             _ => {
6248                 cx.sess.bug(
6249                     &format!("ID not mapped to struct fields: {}",
6250                             cx.map.node_to_string(did.node)));
6251             }
6252         }
6253     } else {
6254         csearch::get_struct_fields(&cx.sess.cstore, did)
6255     }
6256 }
6257
6258 pub fn is_tuple_struct(cx: &ctxt, did: ast::DefId) -> bool {
6259     let fields = lookup_struct_fields(cx, did);
6260     !fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field)
6261 }
6262
6263 // Returns a list of fields corresponding to the struct's items. trans uses
6264 // this. Takes a list of substs with which to instantiate field types.
6265 pub fn struct_fields<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: &Substs<'tcx>)
6266                            -> Vec<field<'tcx>> {
6267     lookup_struct_fields(cx, did).iter().map(|f| {
6268        field {
6269             name: f.name,
6270             mt: mt {
6271                 ty: lookup_field_type(cx, did, f.id, substs),
6272                 mutbl: MutImmutable
6273             }
6274         }
6275     }).collect()
6276 }
6277
6278 // Returns a list of fields corresponding to the tuple's items. trans uses
6279 // this.
6280 pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec<field<'tcx>> {
6281     v.iter().enumerate().map(|(i, &f)| {
6282        field {
6283             name: token::intern(&i.to_string()),
6284             mt: mt {
6285                 ty: f,
6286                 mutbl: MutImmutable
6287             }
6288         }
6289     }).collect()
6290 }
6291
6292 /// Returns the deeply last field of nested structures, or the same type,
6293 /// if not a structure at all. Corresponds to the only possible unsized
6294 /// field, and its type can be used to determine unsizing strategy.
6295 pub fn struct_tail<'tcx>(cx: &ctxt<'tcx>, mut ty: Ty<'tcx>) -> Ty<'tcx> {
6296     while let TyStruct(def_id, substs) = ty.sty {
6297         match struct_fields(cx, def_id, substs).last() {
6298             Some(f) => ty = f.mt.ty,
6299             None => break
6300         }
6301     }
6302     ty
6303 }
6304
6305 /// Same as applying struct_tail on `source` and `target`, but only
6306 /// keeps going as long as the two types are instances of the same
6307 /// structure definitions.
6308 /// For `(Foo<Foo<T>>, Foo<Trait>)`, the result will be `(Foo<T>, Trait)`,
6309 /// whereas struct_tail produces `T`, and `Trait`, respectively.
6310 pub fn struct_lockstep_tails<'tcx>(cx: &ctxt<'tcx>,
6311                                    source: Ty<'tcx>,
6312                                    target: Ty<'tcx>)
6313                                    -> (Ty<'tcx>, Ty<'tcx>) {
6314     let (mut a, mut b) = (source, target);
6315     while let (&TyStruct(a_did, a_substs), &TyStruct(b_did, b_substs)) = (&a.sty, &b.sty) {
6316         if a_did != b_did {
6317             continue;
6318         }
6319         if let Some(a_f) = struct_fields(cx, a_did, a_substs).last() {
6320             if let Some(b_f) = struct_fields(cx, b_did, b_substs).last() {
6321                 a = a_f.mt.ty;
6322                 b = b_f.mt.ty;
6323             } else {
6324                 break;
6325             }
6326         } else {
6327             break;
6328         }
6329     }
6330     (a, b)
6331 }
6332
6333 #[derive(Copy, Clone)]
6334 pub struct ClosureUpvar<'tcx> {
6335     pub def: def::Def,
6336     pub span: Span,
6337     pub ty: Ty<'tcx>,
6338 }
6339
6340 // Returns a list of `ClosureUpvar`s for each upvar.
6341 pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
6342                             closure_id: ast::DefId,
6343                             substs: &Substs<'tcx>)
6344                             -> Option<Vec<ClosureUpvar<'tcx>>>
6345 {
6346     // Presently an unboxed closure type cannot "escape" out of a
6347     // function, so we will only encounter ones that originated in the
6348     // local crate or were inlined into it along with some function.
6349     // This may change if abstract return types of some sort are
6350     // implemented.
6351     assert!(closure_id.krate == ast::LOCAL_CRATE);
6352     let tcx = typer.tcx();
6353     match tcx.freevars.borrow().get(&closure_id.node) {
6354         None => Some(vec![]),
6355         Some(ref freevars) => {
6356             freevars.iter()
6357                     .map(|freevar| {
6358                         let freevar_def_id = freevar.def.def_id();
6359                         let freevar_ty = match typer.node_ty(freevar_def_id.node) {
6360                             Ok(t) => { t }
6361                             Err(()) => { return None; }
6362                         };
6363                         let freevar_ty = freevar_ty.subst(tcx, substs);
6364
6365                         let upvar_id = ty::UpvarId {
6366                             var_id: freevar_def_id.node,
6367                             closure_expr_id: closure_id.node
6368                         };
6369
6370                         typer.upvar_capture(upvar_id).map(|capture| {
6371                             let freevar_ref_ty = match capture {
6372                                 UpvarCapture::ByValue => {
6373                                     freevar_ty
6374                                 }
6375                                 UpvarCapture::ByRef(borrow) => {
6376                                     mk_rptr(tcx,
6377                                             tcx.mk_region(borrow.region),
6378                                             ty::mt {
6379                                                 ty: freevar_ty,
6380                                                 mutbl: borrow.kind.to_mutbl_lossy(),
6381                                             })
6382                                 }
6383                             };
6384
6385                             ClosureUpvar {
6386                                 def: freevar.def,
6387                                 span: freevar.span,
6388                                 ty: freevar_ref_ty,
6389                             }
6390                         })
6391                     })
6392                     .collect()
6393         }
6394     }
6395 }
6396
6397 // Returns the repeat count for a repeating vector expression.
6398 pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> usize {
6399     match const_eval::eval_const_expr_partial(tcx, count_expr, Some(tcx.types.usize)) {
6400         Ok(val) => {
6401             let found = match val {
6402                 const_eval::const_uint(count) => return count as usize,
6403                 const_eval::const_int(count) if count >= 0 => return count as usize,
6404                 const_eval::const_int(_) => "negative integer",
6405                 const_eval::const_float(_) => "float",
6406                 const_eval::const_str(_) => "string",
6407                 const_eval::const_bool(_) => "boolean",
6408                 const_eval::const_binary(_) => "binary array",
6409                 const_eval::Struct(..) => "struct",
6410                 const_eval::Tuple(_) => "tuple"
6411             };
6412             span_err!(tcx.sess, count_expr.span, E0306,
6413                 "expected positive integer for repeat count, found {}",
6414                 found);
6415         }
6416         Err(err) => {
6417             let err_description = err.description();
6418             let found = match count_expr.node {
6419                 ast::ExprPath(None, ast::Path {
6420                     global: false,
6421                     ref segments,
6422                     ..
6423                 }) if segments.len() == 1 =>
6424                     format!("{}", "found variable"),
6425                 _ =>
6426                     format!("but {}", err_description),
6427             };
6428             span_err!(tcx.sess, count_expr.span, E0307,
6429                 "expected constant integer for repeat count, {}",
6430                 found);
6431         }
6432     }
6433     0
6434 }
6435
6436 // Iterate over a type parameter's bounded traits and any supertraits
6437 // of those traits, ignoring kinds.
6438 // Here, the supertraits are the transitive closure of the supertrait
6439 // relation on the supertraits from each bounded trait's constraint
6440 // list.
6441 pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
6442                                                  bounds: &[PolyTraitRef<'tcx>],
6443                                                  mut f: F)
6444                                                  -> bool where
6445     F: FnMut(PolyTraitRef<'tcx>) -> bool,
6446 {
6447     for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
6448         if !f(bound_trait_ref) {
6449             return false;
6450         }
6451     }
6452     return true;
6453 }
6454
6455 /// Given a set of predicates that apply to an object type, returns
6456 /// the region bounds that the (erased) `Self` type must
6457 /// outlive. Precisely *because* the `Self` type is erased, the
6458 /// parameter `erased_self_ty` must be supplied to indicate what type
6459 /// has been used to represent `Self` in the predicates
6460 /// themselves. This should really be a unique type; `FreshTy(0)` is a
6461 /// popular choice.
6462 ///
6463 /// Requires that trait definitions have been processed so that we can
6464 /// elaborate predicates and walk supertraits.
6465 pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
6466                                     erased_self_ty: Ty<'tcx>,
6467                                     predicates: Vec<ty::Predicate<'tcx>>)
6468                                     -> Vec<ty::Region>
6469 {
6470     debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
6471            erased_self_ty,
6472            predicates);
6473
6474     assert!(!erased_self_ty.has_escaping_regions());
6475
6476     traits::elaborate_predicates(tcx, predicates)
6477         .filter_map(|predicate| {
6478             match predicate {
6479                 ty::Predicate::Projection(..) |
6480                 ty::Predicate::Trait(..) |
6481                 ty::Predicate::Equate(..) |
6482                 ty::Predicate::RegionOutlives(..) => {
6483                     None
6484                 }
6485                 ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t, r))) => {
6486                     // Search for a bound of the form `erased_self_ty
6487                     // : 'a`, but be wary of something like `for<'a>
6488                     // erased_self_ty : 'a` (we interpret a
6489                     // higher-ranked bound like that as 'static,
6490                     // though at present the code in `fulfill.rs`
6491                     // considers such bounds to be unsatisfiable, so
6492                     // it's kind of a moot point since you could never
6493                     // construct such an object, but this seems
6494                     // correct even if that code changes).
6495                     if t == erased_self_ty && !r.has_escaping_regions() {
6496                         if r.has_escaping_regions() {
6497                             Some(ty::ReStatic)
6498                         } else {
6499                             Some(r)
6500                         }
6501                     } else {
6502                         None
6503                     }
6504                 }
6505             }
6506         })
6507         .collect()
6508 }
6509
6510 pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
6511     lookup_locally_or_in_crate_store(
6512         "item_variance_map", item_id, &tcx.item_variance_map,
6513         || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id)))
6514 }
6515
6516 pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool {
6517     populate_implementations_for_trait_if_necessary(tcx, trait_def_id);
6518
6519     let def = lookup_trait_def(tcx, trait_def_id);
6520     def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
6521 }
6522
6523 /// Records a trait-to-implementation mapping.
6524 pub fn record_trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) {
6525     let def = lookup_trait_def(tcx, trait_def_id);
6526     def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
6527 }
6528
6529 /// Load primitive inherent implementations if necessary
6530 pub fn populate_implementations_for_primitive_if_necessary(tcx: &ctxt,
6531                                                            primitive_def_id: ast::DefId) {
6532     if primitive_def_id.krate == LOCAL_CRATE {
6533         return
6534     }
6535
6536     if tcx.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
6537         return
6538     }
6539
6540     debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
6541            primitive_def_id);
6542
6543     let impl_items = csearch::get_impl_items(&tcx.sess.cstore, primitive_def_id);
6544
6545     // Store the implementation info.
6546     tcx.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
6547     tcx.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
6548 }
6549
6550 /// Populates the type context with all the inherent implementations for
6551 /// the given type if necessary.
6552 pub fn populate_inherent_implementations_for_type_if_necessary(tcx: &ctxt,
6553                                                                type_id: ast::DefId) {
6554     if type_id.krate == LOCAL_CRATE {
6555         return
6556     }
6557
6558     if tcx.populated_external_types.borrow().contains(&type_id) {
6559         return
6560     }
6561
6562     debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}", type_id);
6563
6564     let mut inherent_impls = Vec::new();
6565     csearch::each_inherent_implementation_for_type(&tcx.sess.cstore, type_id, |impl_def_id| {
6566         // Record the implementation.
6567         inherent_impls.push(impl_def_id);
6568
6569         // Store the implementation info.
6570         let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id);
6571         tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
6572     });
6573
6574     tcx.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls));
6575     tcx.populated_external_types.borrow_mut().insert(type_id);
6576 }
6577
6578 /// Populates the type context with all the implementations for the given
6579 /// trait if necessary.
6580 pub fn populate_implementations_for_trait_if_necessary(tcx: &ctxt, trait_id: ast::DefId) {
6581     if trait_id.krate == LOCAL_CRATE {
6582         return
6583     }
6584
6585     let def = lookup_trait_def(tcx, trait_id);
6586     if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
6587         return;
6588     }
6589
6590     debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
6591
6592     if csearch::is_defaulted_trait(&tcx.sess.cstore, trait_id) {
6593         record_trait_has_default_impl(tcx, trait_id);
6594     }
6595
6596     csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id, |implementation_def_id| {
6597         let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id);
6598         let trait_ref = impl_trait_ref(tcx, implementation_def_id).unwrap();
6599         // Record the trait->implementation mapping.
6600         def.record_impl(tcx, implementation_def_id, trait_ref);
6601
6602         // For any methods that use a default implementation, add them to
6603         // the map. This is a bit unfortunate.
6604         for impl_item_def_id in &impl_items {
6605             let method_def_id = impl_item_def_id.def_id();
6606             match impl_or_trait_item(tcx, method_def_id) {
6607                 MethodTraitItem(method) => {
6608                     if let Some(source) = method.provided_source {
6609                         tcx.provided_method_sources
6610                             .borrow_mut()
6611                             .insert(method_def_id, source);
6612                     }
6613                 }
6614                 _ => {}
6615             }
6616         }
6617
6618         // Store the implementation info.
6619         tcx.impl_items.borrow_mut().insert(implementation_def_id, impl_items);
6620     });
6621
6622     def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
6623 }
6624
6625 /// Given the def_id of an impl, return the def_id of the trait it implements.
6626 /// If it implements no trait, return `None`.
6627 pub fn trait_id_of_impl(tcx: &ctxt,
6628                         def_id: ast::DefId)
6629                         -> Option<ast::DefId> {
6630     ty::impl_trait_ref(tcx, def_id).map(|tr| tr.def_id)
6631 }
6632
6633 /// If the given def ID describes a method belonging to an impl, return the
6634 /// ID of the impl that the method belongs to. Otherwise, return `None`.
6635 pub fn impl_of_method(tcx: &ctxt, def_id: ast::DefId)
6636                        -> Option<ast::DefId> {
6637     if def_id.krate != LOCAL_CRATE {
6638         return match csearch::get_impl_or_trait_item(tcx,
6639                                                      def_id).container() {
6640             TraitContainer(_) => None,
6641             ImplContainer(def_id) => Some(def_id),
6642         };
6643     }
6644     match tcx.impl_or_trait_items.borrow().get(&def_id).cloned() {
6645         Some(trait_item) => {
6646             match trait_item.container() {
6647                 TraitContainer(_) => None,
6648                 ImplContainer(def_id) => Some(def_id),
6649             }
6650         }
6651         None => None
6652     }
6653 }
6654
6655 /// If the given def ID describes an item belonging to a trait (either a
6656 /// default method or an implementation of a trait method), return the ID of
6657 /// the trait that the method belongs to. Otherwise, return `None`.
6658 pub fn trait_of_item(tcx: &ctxt, def_id: ast::DefId) -> Option<ast::DefId> {
6659     if def_id.krate != LOCAL_CRATE {
6660         return csearch::get_trait_of_item(&tcx.sess.cstore, def_id, tcx);
6661     }
6662     match tcx.impl_or_trait_items.borrow().get(&def_id).cloned() {
6663         Some(impl_or_trait_item) => {
6664             match impl_or_trait_item.container() {
6665                 TraitContainer(def_id) => Some(def_id),
6666                 ImplContainer(def_id) => trait_id_of_impl(tcx, def_id),
6667             }
6668         }
6669         None => None
6670     }
6671 }
6672
6673 /// If the given def ID describes an item belonging to a trait, (either a
6674 /// default method or an implementation of a trait method), return the ID of
6675 /// the method inside trait definition (this means that if the given def ID
6676 /// is already that of the original trait method, then the return value is
6677 /// the same).
6678 /// Otherwise, return `None`.
6679 pub fn trait_item_of_item(tcx: &ctxt, def_id: ast::DefId)
6680                           -> Option<ImplOrTraitItemId> {
6681     let impl_item = match tcx.impl_or_trait_items.borrow().get(&def_id) {
6682         Some(m) => m.clone(),
6683         None => return None,
6684     };
6685     let name = impl_item.name();
6686     match trait_of_item(tcx, def_id) {
6687         Some(trait_did) => {
6688             let trait_items = ty::trait_items(tcx, trait_did);
6689             trait_items.iter()
6690                 .position(|m| m.name() == name)
6691                 .map(|idx| ty::trait_item(tcx, trait_did, idx).id())
6692         }
6693         None => None
6694     }
6695 }
6696
6697 /// Creates a hash of the type `Ty` which will be the same no matter what crate
6698 /// context it's calculated within. This is used by the `type_id` intrinsic.
6699 pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -> u64 {
6700     let mut state = SipHasher::new();
6701     helper(tcx, ty, svh, &mut state);
6702     return state.finish();
6703
6704     fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh,
6705                     state: &mut SipHasher) {
6706         macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } }
6707         macro_rules! hash { ($e:expr) => { $e.hash(state) }  }
6708
6709         let region = |state: &mut SipHasher, r: Region| {
6710             match r {
6711                 ReStatic => {}
6712                 ReLateBound(db, BrAnon(i)) => {
6713                     db.hash(state);
6714                     i.hash(state);
6715                 }
6716                 ReEmpty |
6717                 ReEarlyBound(..) |
6718                 ReLateBound(..) |
6719                 ReFree(..) |
6720                 ReScope(..) |
6721                 ReInfer(..) => {
6722                     tcx.sess.bug("unexpected region found when hashing a type")
6723                 }
6724             }
6725         };
6726         let did = |state: &mut SipHasher, did: DefId| {
6727             let h = if ast_util::is_local(did) {
6728                 svh.clone()
6729             } else {
6730                 tcx.sess.cstore.get_crate_hash(did.krate)
6731             };
6732             h.as_str().hash(state);
6733             did.node.hash(state);
6734         };
6735         let mt = |state: &mut SipHasher, mt: mt| {
6736             mt.mutbl.hash(state);
6737         };
6738         let fn_sig = |state: &mut SipHasher, sig: &Binder<FnSig<'tcx>>| {
6739             let sig = anonymize_late_bound_regions(tcx, sig).0;
6740             for a in &sig.inputs { helper(tcx, *a, svh, state); }
6741             if let ty::FnConverging(output) = sig.output {
6742                 helper(tcx, output, svh, state);
6743             }
6744         };
6745         maybe_walk_ty(ty, |ty| {
6746             match ty.sty {
6747                 TyBool => byte!(2),
6748                 TyChar => byte!(3),
6749                 TyInt(i) => {
6750                     byte!(4);
6751                     hash!(i);
6752                 }
6753                 TyUint(u) => {
6754                     byte!(5);
6755                     hash!(u);
6756                 }
6757                 TyFloat(f) => {
6758                     byte!(6);
6759                     hash!(f);
6760                 }
6761                 TyStr => {
6762                     byte!(7);
6763                 }
6764                 TyEnum(d, _) => {
6765                     byte!(8);
6766                     did(state, d);
6767                 }
6768                 TyBox(_) => {
6769                     byte!(9);
6770                 }
6771                 TyArray(_, n) => {
6772                     byte!(10);
6773                     n.hash(state);
6774                 }
6775                 TySlice(_) => {
6776                     byte!(11);
6777                 }
6778                 TyRawPtr(m) => {
6779                     byte!(12);
6780                     mt(state, m);
6781                 }
6782                 TyRef(r, m) => {
6783                     byte!(13);
6784                     region(state, *r);
6785                     mt(state, m);
6786                 }
6787                 TyBareFn(opt_def_id, ref b) => {
6788                     byte!(14);
6789                     hash!(opt_def_id);
6790                     hash!(b.unsafety);
6791                     hash!(b.abi);
6792                     fn_sig(state, &b.sig);
6793                     return false;
6794                 }
6795                 TyTrait(ref data) => {
6796                     byte!(17);
6797                     did(state, data.principal_def_id());
6798                     hash!(data.bounds);
6799
6800                     let principal = anonymize_late_bound_regions(tcx, &data.principal).0;
6801                     for subty in &principal.substs.types {
6802                         helper(tcx, subty, svh, state);
6803                     }
6804
6805                     return false;
6806                 }
6807                 TyStruct(d, _) => {
6808                     byte!(18);
6809                     did(state, d);
6810                 }
6811                 TyTuple(ref inner) => {
6812                     byte!(19);
6813                     hash!(inner.len());
6814                 }
6815                 TyParam(p) => {
6816                     byte!(20);
6817                     hash!(p.space);
6818                     hash!(p.idx);
6819                     hash!(token::get_name(p.name));
6820                 }
6821                 TyInfer(_) => unreachable!(),
6822                 TyError => byte!(21),
6823                 TyClosure(d, _) => {
6824                     byte!(22);
6825                     did(state, d);
6826                 }
6827                 TyProjection(ref data) => {
6828                     byte!(23);
6829                     did(state, data.trait_ref.def_id);
6830                     hash!(token::get_name(data.item_name));
6831                 }
6832             }
6833             true
6834         });
6835     }
6836 }
6837
6838 impl fmt::Debug for Variance {
6839     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6840         f.write_str(match *self {
6841             Covariant => "+",
6842             Contravariant => "-",
6843             Invariant => "o",
6844             Bivariant => "*",
6845         })
6846     }
6847 }
6848
6849 /// Construct a parameter environment suitable for static contexts or other contexts where there
6850 /// are no free type/lifetime parameters in scope.
6851 pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvironment<'a,'tcx> {
6852     ty::ParameterEnvironment { tcx: cx,
6853                                free_substs: Substs::empty(),
6854                                caller_bounds: Vec::new(),
6855                                implicit_region_bound: ty::ReEmpty,
6856                                selection_cache: traits::SelectionCache::new(), }
6857 }
6858
6859 /// Constructs and returns a substitution that can be applied to move from
6860 /// the "outer" view of a type or method to the "inner" view.
6861 /// In general, this means converting from bound parameters to
6862 /// free parameters. Since we currently represent bound/free type
6863 /// parameters in the same way, this only has an effect on regions.
6864 pub fn construct_free_substs<'a,'tcx>(
6865     tcx: &'a ctxt<'tcx>,
6866     generics: &Generics<'tcx>,
6867     free_id: ast::NodeId)
6868     -> Substs<'tcx>
6869 {
6870     // map T => T
6871     let mut types = VecPerParamSpace::empty();
6872     push_types_from_defs(tcx, &mut types, generics.types.as_slice());
6873
6874     let free_id_outlive = region::DestructionScopeData::new(free_id);
6875
6876     // map bound 'a => free 'a
6877     let mut regions = VecPerParamSpace::empty();
6878     push_region_params(&mut regions, free_id_outlive, generics.regions.as_slice());
6879
6880     return Substs {
6881         types: types,
6882         regions: subst::NonerasedRegions(regions)
6883     };
6884
6885     fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,
6886                           all_outlive_extent: region::DestructionScopeData,
6887                           region_params: &[RegionParameterDef])
6888     {
6889         for r in region_params {
6890             regions.push(r.space, ty::free_region_from_def(all_outlive_extent, r));
6891         }
6892     }
6893
6894     fn push_types_from_defs<'tcx>(tcx: &ty::ctxt<'tcx>,
6895                                   types: &mut VecPerParamSpace<Ty<'tcx>>,
6896                                   defs: &[TypeParameterDef<'tcx>]) {
6897         for def in defs {
6898             debug!("construct_parameter_environment(): push_types_from_defs: def={:?}",
6899                    def);
6900             let ty = ty::mk_param_from_def(tcx, def);
6901             types.push(def.space, ty);
6902        }
6903     }
6904 }
6905
6906 /// See `ParameterEnvironment` struct def'n for details
6907 pub fn construct_parameter_environment<'a,'tcx>(
6908     tcx: &'a ctxt<'tcx>,
6909     span: Span,
6910     generics: &ty::Generics<'tcx>,
6911     generic_predicates: &ty::GenericPredicates<'tcx>,
6912     free_id: ast::NodeId)
6913     -> ParameterEnvironment<'a, 'tcx>
6914 {
6915     //
6916     // Construct the free substs.
6917     //
6918
6919     let free_substs = construct_free_substs(tcx, generics, free_id);
6920     let free_id_outlive = region::DestructionScopeData::new(free_id);
6921
6922     //
6923     // Compute the bounds on Self and the type parameters.
6924     //
6925
6926     let bounds = generic_predicates.instantiate(tcx, &free_substs);
6927     let bounds = liberate_late_bound_regions(tcx, free_id_outlive, &ty::Binder(bounds));
6928     let predicates = bounds.predicates.into_vec();
6929
6930     debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
6931            free_id,
6932            free_substs,
6933            predicates);
6934
6935     //
6936     // Finally, we have to normalize the bounds in the environment, in
6937     // case they contain any associated type projections. This process
6938     // can yield errors if the put in illegal associated types, like
6939     // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
6940     // report these errors right here; this doesn't actually feel
6941     // right to me, because constructing the environment feels like a
6942     // kind of a "idempotent" action, but I'm not sure where would be
6943     // a better place. In practice, we construct environments for
6944     // every fn once during type checking, and we'll abort if there
6945     // are any errors at that point, so after type checking you can be
6946     // sure that this will succeed without errors anyway.
6947     //
6948
6949     let unnormalized_env = ty::ParameterEnvironment {
6950         tcx: tcx,
6951         free_substs: free_substs,
6952         implicit_region_bound: ty::ReScope(free_id_outlive.to_code_extent()),
6953         caller_bounds: predicates,
6954         selection_cache: traits::SelectionCache::new(),
6955     };
6956
6957     let cause = traits::ObligationCause::misc(span, free_id);
6958     traits::normalize_param_env_or_error(unnormalized_env, cause)
6959 }
6960
6961 impl BorrowKind {
6962     pub fn from_mutbl(m: ast::Mutability) -> BorrowKind {
6963         match m {
6964             ast::MutMutable => MutBorrow,
6965             ast::MutImmutable => ImmBorrow,
6966         }
6967     }
6968
6969     /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
6970     /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
6971     /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
6972     /// question.
6973     pub fn to_mutbl_lossy(self) -> ast::Mutability {
6974         match self {
6975             MutBorrow => ast::MutMutable,
6976             ImmBorrow => ast::MutImmutable,
6977
6978             // We have no type corresponding to a unique imm borrow, so
6979             // use `&mut`. It gives all the capabilities of an `&uniq`
6980             // and hence is a safe "over approximation".
6981             UniqueImmBorrow => ast::MutMutable,
6982         }
6983     }
6984
6985     pub fn to_user_str(&self) -> &'static str {
6986         match *self {
6987             MutBorrow => "mutable",
6988             ImmBorrow => "immutable",
6989             UniqueImmBorrow => "uniquely immutable",
6990         }
6991     }
6992 }
6993
6994 impl<'tcx> ctxt<'tcx> {
6995     pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
6996         self.method_map.borrow().contains_key(&MethodCall::expr(expr_id))
6997     }
6998
6999     pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
7000         Some(self.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
7001     }
7002 }
7003
7004 impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
7005     fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
7006         Ok(ty::node_id_to_type(self.tcx, id))
7007     }
7008
7009     fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
7010         Ok(ty::expr_ty_adjusted(self.tcx, expr))
7011     }
7012
7013     fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
7014         self.tcx.method_map.borrow().get(&method_call).map(|method| method.ty)
7015     }
7016
7017     fn node_method_origin(&self, method_call: ty::MethodCall)
7018                           -> Option<ty::MethodOrigin<'tcx>>
7019     {
7020         self.tcx.method_map.borrow().get(&method_call).map(|method| method.origin.clone())
7021     }
7022
7023     fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
7024         &self.tcx.adjustments
7025     }
7026
7027     fn is_method_call(&self, id: ast::NodeId) -> bool {
7028         self.tcx.is_method_call(id)
7029     }
7030
7031     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
7032         self.tcx.region_maps.temporary_scope(rvalue_id)
7033     }
7034
7035     fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
7036         self.tcx.upvar_capture(upvar_id)
7037     }
7038
7039     fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool {
7040         type_moves_by_default(self, span, ty)
7041     }
7042 }
7043
7044 impl<'a,'tcx> ClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> {
7045     fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
7046         self
7047     }
7048
7049     fn closure_kind(&self,
7050                     def_id: ast::DefId)
7051                     -> Option<ty::ClosureKind>
7052     {
7053         Some(self.tcx.closure_kind(def_id))
7054     }
7055
7056     fn closure_type(&self,
7057                     def_id: ast::DefId,
7058                     substs: &subst::Substs<'tcx>)
7059                     -> ty::ClosureTy<'tcx>
7060     {
7061         self.tcx.closure_type(def_id, substs)
7062     }
7063
7064     fn closure_upvars(&self,
7065                       def_id: ast::DefId,
7066                       substs: &Substs<'tcx>)
7067                       -> Option<Vec<ClosureUpvar<'tcx>>>
7068     {
7069         closure_upvars(self, def_id, substs)
7070     }
7071 }
7072
7073
7074 /// The category of explicit self.
7075 #[derive(Clone, Copy, Eq, PartialEq, Debug)]
7076 pub enum ExplicitSelfCategory {
7077     StaticExplicitSelfCategory,
7078     ByValueExplicitSelfCategory,
7079     ByReferenceExplicitSelfCategory(Region, ast::Mutability),
7080     ByBoxExplicitSelfCategory,
7081 }
7082
7083 /// Pushes all the lifetimes in the given type onto the given list. A
7084 /// "lifetime in a type" is a lifetime specified by a reference or a lifetime
7085 /// in a list of type substitutions. This does *not* traverse into nominal
7086 /// types, nor does it resolve fictitious types.
7087 pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
7088                                     ty: Ty) {
7089     walk_ty(ty, |ty| {
7090         match ty.sty {
7091             TyRef(region, _) => {
7092                 accumulator.push(*region)
7093             }
7094             TyTrait(ref t) => {
7095                 accumulator.push_all(t.principal.0.substs.regions().as_slice());
7096             }
7097             TyEnum(_, substs) |
7098             TyStruct(_, substs) => {
7099                 accum_substs(accumulator, substs);
7100             }
7101             TyClosure(_, substs) => {
7102                 accum_substs(accumulator, substs);
7103             }
7104             TyBool |
7105             TyChar |
7106             TyInt(_) |
7107             TyUint(_) |
7108             TyFloat(_) |
7109             TyBox(_) |
7110             TyStr |
7111             TyArray(_, _) |
7112             TySlice(_) |
7113             TyRawPtr(_) |
7114             TyBareFn(..) |
7115             TyTuple(_) |
7116             TyProjection(_) |
7117             TyParam(_) |
7118             TyInfer(_) |
7119             TyError => {
7120             }
7121         }
7122     });
7123
7124     fn accum_substs(accumulator: &mut Vec<Region>, substs: &Substs) {
7125         match substs.regions {
7126             subst::ErasedRegions => {}
7127             subst::NonerasedRegions(ref regions) => {
7128                 for region in regions {
7129                     accumulator.push(*region)
7130                 }
7131             }
7132         }
7133     }
7134 }
7135
7136 /// A free variable referred to in a function.
7137 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
7138 pub struct Freevar {
7139     /// The variable being accessed free.
7140     pub def: def::Def,
7141
7142     // First span where it is accessed (there can be multiple).
7143     pub span: Span
7144 }
7145
7146 pub type FreevarMap = NodeMap<Vec<Freevar>>;
7147
7148 pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
7149
7150 // Trait method resolution
7151 pub type TraitMap = NodeMap<Vec<DefId>>;
7152
7153 // Map from the NodeId of a glob import to a list of items which are actually
7154 // imported.
7155 pub type GlobMap = HashMap<NodeId, HashSet<Name>>;
7156
7157 pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
7158     F: FnOnce(&[Freevar]) -> T,
7159 {
7160     match tcx.freevars.borrow().get(&fid) {
7161         None => f(&[]),
7162         Some(d) => f(&d[..])
7163     }
7164 }
7165
7166 impl<'tcx> AutoAdjustment<'tcx> {
7167     pub fn is_identity(&self) -> bool {
7168         match *self {
7169             AdjustReifyFnPointer |
7170             AdjustUnsafeFnPointer => false,
7171             AdjustDerefRef(ref r) => r.is_identity(),
7172         }
7173     }
7174 }
7175
7176 impl<'tcx> AutoDerefRef<'tcx> {
7177     pub fn is_identity(&self) -> bool {
7178         self.autoderefs == 0 && self.unsize.is_none() && self.autoref.is_none()
7179     }
7180 }
7181
7182 /// Replace any late-bound regions bound in `value` with free variants attached to scope-id
7183 /// `scope_id`.
7184 pub fn liberate_late_bound_regions<'tcx, T>(
7185     tcx: &ty::ctxt<'tcx>,
7186     all_outlive_scope: region::DestructionScopeData,
7187     value: &Binder<T>)
7188     -> T
7189     where T : TypeFoldable<'tcx>
7190 {
7191     ty_fold::replace_late_bound_regions(
7192         tcx, value,
7193         |br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).0
7194 }
7195
7196 pub fn count_late_bound_regions<'tcx, T>(
7197     tcx: &ty::ctxt<'tcx>,
7198     value: &Binder<T>)
7199     -> usize
7200     where T : TypeFoldable<'tcx>
7201 {
7202     let (_, skol_map) = ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic);
7203     skol_map.len()
7204 }
7205
7206 pub fn binds_late_bound_regions<'tcx, T>(
7207     tcx: &ty::ctxt<'tcx>,
7208     value: &Binder<T>)
7209     -> bool
7210     where T : TypeFoldable<'tcx>
7211 {
7212     count_late_bound_regions(tcx, value) > 0
7213 }
7214
7215 /// Flattens two binding levels into one. So `for<'a> for<'b> Foo`
7216 /// becomes `for<'a,'b> Foo`.
7217 pub fn flatten_late_bound_regions<'tcx, T>(
7218     tcx: &ty::ctxt<'tcx>,
7219     bound2_value: &Binder<Binder<T>>)
7220     -> Binder<T>
7221     where T: TypeFoldable<'tcx>
7222 {
7223     let bound0_value = bound2_value.skip_binder().skip_binder();
7224     let value = ty_fold::fold_regions(tcx, bound0_value, |region, current_depth| {
7225         match region {
7226             ty::ReLateBound(debruijn, br) if debruijn.depth >= current_depth => {
7227                 // should be true if no escaping regions from bound2_value
7228                 assert!(debruijn.depth - current_depth <= 1);
7229                 ty::ReLateBound(DebruijnIndex::new(current_depth), br)
7230             }
7231             _ => {
7232                 region
7233             }
7234         }
7235     });
7236     Binder(value)
7237 }
7238
7239 pub fn no_late_bound_regions<'tcx, T>(
7240     tcx: &ty::ctxt<'tcx>,
7241     value: &Binder<T>)
7242     -> Option<T>
7243     where T : TypeFoldable<'tcx>
7244 {
7245     if binds_late_bound_regions(tcx, value) {
7246         None
7247     } else {
7248         Some(value.0.clone())
7249     }
7250 }
7251
7252 /// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
7253 /// method lookup and a few other places where precise region relationships are not required.
7254 pub fn erase_late_bound_regions<'tcx, T>(
7255     tcx: &ty::ctxt<'tcx>,
7256     value: &Binder<T>)
7257     -> T
7258     where T : TypeFoldable<'tcx>
7259 {
7260     ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic).0
7261 }
7262
7263 /// Rewrite any late-bound regions so that they are anonymous.  Region numbers are
7264 /// assigned starting at 1 and increasing monotonically in the order traversed
7265 /// by the fold operation.
7266 ///
7267 /// The chief purpose of this function is to canonicalize regions so that two
7268 /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
7269 /// structurally identical.  For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and
7270 /// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization.
7271 pub fn anonymize_late_bound_regions<'tcx, T>(
7272     tcx: &ctxt<'tcx>,
7273     sig: &Binder<T>)
7274     -> Binder<T>
7275     where T : TypeFoldable<'tcx>,
7276 {
7277     let mut counter = 0;
7278     ty::Binder(ty_fold::replace_late_bound_regions(tcx, sig, |_| {
7279         counter += 1;
7280         ReLateBound(ty::DebruijnIndex::new(1), BrAnon(counter))
7281     }).0)
7282 }
7283
7284 impl DebruijnIndex {
7285     pub fn new(depth: u32) -> DebruijnIndex {
7286         assert!(depth > 0);
7287         DebruijnIndex { depth: depth }
7288     }
7289
7290     pub fn shifted(&self, amount: u32) -> DebruijnIndex {
7291         DebruijnIndex { depth: self.depth + amount }
7292     }
7293 }
7294
7295 impl<'tcx> fmt::Debug for AutoAdjustment<'tcx> {
7296     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7297         match *self {
7298             AdjustReifyFnPointer => {
7299                 write!(f, "AdjustReifyFnPointer")
7300             }
7301             AdjustUnsafeFnPointer => {
7302                 write!(f, "AdjustUnsafeFnPointer")
7303             }
7304             AdjustDerefRef(ref data) => {
7305                 write!(f, "{:?}", data)
7306             }
7307         }
7308     }
7309 }
7310
7311 impl<'tcx> fmt::Debug for AutoDerefRef<'tcx> {
7312     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7313         write!(f, "AutoDerefRef({}, unsize={:?}, {:?})",
7314                self.autoderefs, self.unsize, self.autoref)
7315     }
7316 }
7317
7318 impl<'tcx> fmt::Debug for TraitTy<'tcx> {
7319     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7320         write!(f, "TraitTy({:?},{:?})",
7321                self.principal,
7322                self.bounds)
7323     }
7324 }
7325
7326 impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
7327     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7328         match *self {
7329             Predicate::Trait(ref a) => write!(f, "{:?}", a),
7330             Predicate::Equate(ref pair) => write!(f, "{:?}", pair),
7331             Predicate::RegionOutlives(ref pair) => write!(f, "{:?}", pair),
7332             Predicate::TypeOutlives(ref pair) => write!(f, "{:?}", pair),
7333             Predicate::Projection(ref pair) => write!(f, "{:?}", pair),
7334         }
7335     }
7336 }
7337
7338 pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
7339                                             trait_ref: &ty::TraitRef<'tcx>,
7340                                             method: &ty::Method<'tcx>)
7341                                             -> subst::Substs<'tcx>
7342 {
7343     /*!
7344      * Substitutes the values for the receiver's type parameters
7345      * that are found in method, leaving the method's type parameters
7346      * intact.
7347      */
7348
7349     let meth_tps: Vec<Ty> =
7350         method.generics.types.get_slice(subst::FnSpace)
7351               .iter()
7352               .map(|def| ty::mk_param_from_def(tcx, def))
7353               .collect();
7354     let meth_regions: Vec<ty::Region> =
7355         method.generics.regions.get_slice(subst::FnSpace)
7356               .iter()
7357               .map(|def| def.to_early_bound_region())
7358               .collect();
7359     trait_ref.substs.clone().with_method(meth_tps, meth_regions)
7360 }
7361
7362 #[derive(Copy, Clone)]
7363 pub enum CopyImplementationError {
7364     FieldDoesNotImplementCopy(ast::Name),
7365     VariantDoesNotImplementCopy(ast::Name),
7366     TypeIsStructural,
7367     TypeHasDestructor,
7368 }
7369
7370 pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>,
7371                                         span: Span,
7372                                         self_type: Ty<'tcx>)
7373                                         -> Result<(),CopyImplementationError>
7374 {
7375     let tcx = param_env.tcx;
7376
7377     let did = match self_type.sty {
7378         ty::TyStruct(struct_did, substs) => {
7379             let fields = ty::struct_fields(tcx, struct_did, substs);
7380             for field in &fields {
7381                 if type_moves_by_default(param_env, span, field.mt.ty) {
7382                     return Err(FieldDoesNotImplementCopy(field.name))
7383                 }
7384             }
7385             struct_did
7386         }
7387         ty::TyEnum(enum_did, substs) => {
7388             let enum_variants = ty::enum_variants(tcx, enum_did);
7389             for variant in enum_variants.iter() {
7390                 for variant_arg_type in &variant.args {
7391                     let substd_arg_type =
7392                         variant_arg_type.subst(tcx, substs);
7393                     if type_moves_by_default(param_env, span, substd_arg_type) {
7394                         return Err(VariantDoesNotImplementCopy(variant.name))
7395                     }
7396                 }
7397             }
7398             enum_did
7399         }
7400         _ => return Err(TypeIsStructural),
7401     };
7402
7403     if ty::has_dtor(tcx, did) {
7404         return Err(TypeHasDestructor)
7405     }
7406
7407     Ok(())
7408 }
7409
7410 // FIXME(#20298) -- all of these types basically walk various
7411 // structures to test whether types/regions are reachable with various
7412 // properties. It should be possible to express them in terms of one
7413 // common "walker" trait or something.
7414
7415 pub trait RegionEscape {
7416     fn has_escaping_regions(&self) -> bool {
7417         self.has_regions_escaping_depth(0)
7418     }
7419
7420     fn has_regions_escaping_depth(&self, depth: u32) -> bool;
7421 }
7422
7423 impl<'tcx> RegionEscape for Ty<'tcx> {
7424     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7425         ty::type_escapes_depth(*self, depth)
7426     }
7427 }
7428
7429 impl<'tcx> RegionEscape for Substs<'tcx> {
7430     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7431         self.types.has_regions_escaping_depth(depth) ||
7432             self.regions.has_regions_escaping_depth(depth)
7433     }
7434 }
7435
7436 impl<'tcx,T:RegionEscape> RegionEscape for VecPerParamSpace<T> {
7437     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7438         self.iter_enumerated().any(|(space, _, t)| {
7439             if space == subst::FnSpace {
7440                 t.has_regions_escaping_depth(depth+1)
7441             } else {
7442                 t.has_regions_escaping_depth(depth)
7443             }
7444         })
7445     }
7446 }
7447
7448 impl<'tcx> RegionEscape for TypeScheme<'tcx> {
7449     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7450         self.ty.has_regions_escaping_depth(depth)
7451     }
7452 }
7453
7454 impl RegionEscape for Region {
7455     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7456         self.escapes_depth(depth)
7457     }
7458 }
7459
7460 impl<'tcx> RegionEscape for GenericPredicates<'tcx> {
7461     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7462         self.predicates.has_regions_escaping_depth(depth)
7463     }
7464 }
7465
7466 impl<'tcx> RegionEscape for Predicate<'tcx> {
7467     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7468         match *self {
7469             Predicate::Trait(ref data) => data.has_regions_escaping_depth(depth),
7470             Predicate::Equate(ref data) => data.has_regions_escaping_depth(depth),
7471             Predicate::RegionOutlives(ref data) => data.has_regions_escaping_depth(depth),
7472             Predicate::TypeOutlives(ref data) => data.has_regions_escaping_depth(depth),
7473             Predicate::Projection(ref data) => data.has_regions_escaping_depth(depth),
7474         }
7475     }
7476 }
7477
7478 impl<'tcx,P:RegionEscape> RegionEscape for traits::Obligation<'tcx,P> {
7479     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7480         self.predicate.has_regions_escaping_depth(depth)
7481     }
7482 }
7483
7484 impl<'tcx> RegionEscape for TraitRef<'tcx> {
7485     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7486         self.substs.types.iter().any(|t| t.has_regions_escaping_depth(depth)) ||
7487             self.substs.regions.has_regions_escaping_depth(depth)
7488     }
7489 }
7490
7491 impl<'tcx> RegionEscape for subst::RegionSubsts {
7492     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7493         match *self {
7494             subst::ErasedRegions => false,
7495             subst::NonerasedRegions(ref r) => {
7496                 r.iter().any(|t| t.has_regions_escaping_depth(depth))
7497             }
7498         }
7499     }
7500 }
7501
7502 impl<'tcx,T:RegionEscape> RegionEscape for Binder<T> {
7503     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7504         self.0.has_regions_escaping_depth(depth + 1)
7505     }
7506 }
7507
7508 impl<'tcx> RegionEscape for EquatePredicate<'tcx> {
7509     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7510         self.0.has_regions_escaping_depth(depth) || self.1.has_regions_escaping_depth(depth)
7511     }
7512 }
7513
7514 impl<'tcx> RegionEscape for TraitPredicate<'tcx> {
7515     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7516         self.trait_ref.has_regions_escaping_depth(depth)
7517     }
7518 }
7519
7520 impl<T:RegionEscape,U:RegionEscape> RegionEscape for OutlivesPredicate<T,U> {
7521     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7522         self.0.has_regions_escaping_depth(depth) || self.1.has_regions_escaping_depth(depth)
7523     }
7524 }
7525
7526 impl<'tcx> RegionEscape for ProjectionPredicate<'tcx> {
7527     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7528         self.projection_ty.has_regions_escaping_depth(depth) ||
7529             self.ty.has_regions_escaping_depth(depth)
7530     }
7531 }
7532
7533 impl<'tcx> RegionEscape for ProjectionTy<'tcx> {
7534     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7535         self.trait_ref.has_regions_escaping_depth(depth)
7536     }
7537 }
7538
7539 pub trait HasProjectionTypes {
7540     fn has_projection_types(&self) -> bool;
7541 }
7542
7543 impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for Vec<T> {
7544     fn has_projection_types(&self) -> bool {
7545         self.iter().any(|p| p.has_projection_types())
7546     }
7547 }
7548
7549 impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for VecPerParamSpace<T> {
7550     fn has_projection_types(&self) -> bool {
7551         self.iter().any(|p| p.has_projection_types())
7552     }
7553 }
7554
7555 impl<'tcx> HasProjectionTypes for ClosureTy<'tcx> {
7556     fn has_projection_types(&self) -> bool {
7557         self.sig.has_projection_types()
7558     }
7559 }
7560
7561 impl<'tcx> HasProjectionTypes for ClosureUpvar<'tcx> {
7562     fn has_projection_types(&self) -> bool {
7563         self.ty.has_projection_types()
7564     }
7565 }
7566
7567 impl<'tcx> HasProjectionTypes for ty::InstantiatedPredicates<'tcx> {
7568     fn has_projection_types(&self) -> bool {
7569         self.predicates.has_projection_types()
7570     }
7571 }
7572
7573 impl<'tcx> HasProjectionTypes for Predicate<'tcx> {
7574     fn has_projection_types(&self) -> bool {
7575         match *self {
7576             Predicate::Trait(ref data) => data.has_projection_types(),
7577             Predicate::Equate(ref data) => data.has_projection_types(),
7578             Predicate::RegionOutlives(ref data) => data.has_projection_types(),
7579             Predicate::TypeOutlives(ref data) => data.has_projection_types(),
7580             Predicate::Projection(ref data) => data.has_projection_types(),
7581         }
7582     }
7583 }
7584
7585 impl<'tcx> HasProjectionTypes for TraitPredicate<'tcx> {
7586     fn has_projection_types(&self) -> bool {
7587         self.trait_ref.has_projection_types()
7588     }
7589 }
7590
7591 impl<'tcx> HasProjectionTypes for EquatePredicate<'tcx> {
7592     fn has_projection_types(&self) -> bool {
7593         self.0.has_projection_types() || self.1.has_projection_types()
7594     }
7595 }
7596
7597 impl HasProjectionTypes for Region {
7598     fn has_projection_types(&self) -> bool {
7599         false
7600     }
7601 }
7602
7603 impl<T:HasProjectionTypes,U:HasProjectionTypes> HasProjectionTypes for OutlivesPredicate<T,U> {
7604     fn has_projection_types(&self) -> bool {
7605         self.0.has_projection_types() || self.1.has_projection_types()
7606     }
7607 }
7608
7609 impl<'tcx> HasProjectionTypes for ProjectionPredicate<'tcx> {
7610     fn has_projection_types(&self) -> bool {
7611         self.projection_ty.has_projection_types() || self.ty.has_projection_types()
7612     }
7613 }
7614
7615 impl<'tcx> HasProjectionTypes for ProjectionTy<'tcx> {
7616     fn has_projection_types(&self) -> bool {
7617         self.trait_ref.has_projection_types()
7618     }
7619 }
7620
7621 impl<'tcx> HasProjectionTypes for Ty<'tcx> {
7622     fn has_projection_types(&self) -> bool {
7623         ty::type_has_projection(*self)
7624     }
7625 }
7626
7627 impl<'tcx> HasProjectionTypes for TraitRef<'tcx> {
7628     fn has_projection_types(&self) -> bool {
7629         self.substs.has_projection_types()
7630     }
7631 }
7632
7633 impl<'tcx> HasProjectionTypes for subst::Substs<'tcx> {
7634     fn has_projection_types(&self) -> bool {
7635         self.types.iter().any(|t| t.has_projection_types())
7636     }
7637 }
7638
7639 impl<'tcx,T> HasProjectionTypes for Option<T>
7640     where T : HasProjectionTypes
7641 {
7642     fn has_projection_types(&self) -> bool {
7643         self.iter().any(|t| t.has_projection_types())
7644     }
7645 }
7646
7647 impl<'tcx,T> HasProjectionTypes for Rc<T>
7648     where T : HasProjectionTypes
7649 {
7650     fn has_projection_types(&self) -> bool {
7651         (**self).has_projection_types()
7652     }
7653 }
7654
7655 impl<'tcx,T> HasProjectionTypes for Box<T>
7656     where T : HasProjectionTypes
7657 {
7658     fn has_projection_types(&self) -> bool {
7659         (**self).has_projection_types()
7660     }
7661 }
7662
7663 impl<T> HasProjectionTypes for Binder<T>
7664     where T : HasProjectionTypes
7665 {
7666     fn has_projection_types(&self) -> bool {
7667         self.0.has_projection_types()
7668     }
7669 }
7670
7671 impl<'tcx> HasProjectionTypes for FnOutput<'tcx> {
7672     fn has_projection_types(&self) -> bool {
7673         match *self {
7674             FnConverging(t) => t.has_projection_types(),
7675             FnDiverging => false,
7676         }
7677     }
7678 }
7679
7680 impl<'tcx> HasProjectionTypes for FnSig<'tcx> {
7681     fn has_projection_types(&self) -> bool {
7682         self.inputs.iter().any(|t| t.has_projection_types()) ||
7683             self.output.has_projection_types()
7684     }
7685 }
7686
7687 impl<'tcx> HasProjectionTypes for field<'tcx> {
7688     fn has_projection_types(&self) -> bool {
7689         self.mt.ty.has_projection_types()
7690     }
7691 }
7692
7693 impl<'tcx> HasProjectionTypes for BareFnTy<'tcx> {
7694     fn has_projection_types(&self) -> bool {
7695         self.sig.has_projection_types()
7696     }
7697 }
7698
7699 pub trait ReferencesError {
7700     fn references_error(&self) -> bool;
7701 }
7702
7703 impl<T:ReferencesError> ReferencesError for Binder<T> {
7704     fn references_error(&self) -> bool {
7705         self.0.references_error()
7706     }
7707 }
7708
7709 impl<T:ReferencesError> ReferencesError for Rc<T> {
7710     fn references_error(&self) -> bool {
7711         (&**self).references_error()
7712     }
7713 }
7714
7715 impl<'tcx> ReferencesError for TraitPredicate<'tcx> {
7716     fn references_error(&self) -> bool {
7717         self.trait_ref.references_error()
7718     }
7719 }
7720
7721 impl<'tcx> ReferencesError for ProjectionPredicate<'tcx> {
7722     fn references_error(&self) -> bool {
7723         self.projection_ty.trait_ref.references_error() || self.ty.references_error()
7724     }
7725 }
7726
7727 impl<'tcx> ReferencesError for TraitRef<'tcx> {
7728     fn references_error(&self) -> bool {
7729         self.input_types().iter().any(|t| t.references_error())
7730     }
7731 }
7732
7733 impl<'tcx> ReferencesError for Ty<'tcx> {
7734     fn references_error(&self) -> bool {
7735         type_is_error(*self)
7736     }
7737 }
7738
7739 impl<'tcx> ReferencesError for Predicate<'tcx> {
7740     fn references_error(&self) -> bool {
7741         match *self {
7742             Predicate::Trait(ref data) => data.references_error(),
7743             Predicate::Equate(ref data) => data.references_error(),
7744             Predicate::RegionOutlives(ref data) => data.references_error(),
7745             Predicate::TypeOutlives(ref data) => data.references_error(),
7746             Predicate::Projection(ref data) => data.references_error(),
7747         }
7748     }
7749 }
7750
7751 impl<A,B> ReferencesError for OutlivesPredicate<A,B>
7752     where A : ReferencesError, B : ReferencesError
7753 {
7754     fn references_error(&self) -> bool {
7755         self.0.references_error() || self.1.references_error()
7756     }
7757 }
7758
7759 impl<'tcx> ReferencesError for EquatePredicate<'tcx>
7760 {
7761     fn references_error(&self) -> bool {
7762         self.0.references_error() || self.1.references_error()
7763     }
7764 }
7765
7766 impl ReferencesError for Region
7767 {
7768     fn references_error(&self) -> bool {
7769         false
7770     }
7771 }
7772
7773 impl<'tcx> fmt::Debug for ClosureTy<'tcx> {
7774     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7775         write!(f, "ClosureTy({},{:?},{})",
7776                self.unsafety,
7777                self.sig,
7778                self.abi)
7779     }
7780 }
7781
7782 impl<'tcx> fmt::Debug for ClosureUpvar<'tcx> {
7783     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7784         write!(f, "ClosureUpvar({:?},{:?})",
7785                self.def,
7786                self.ty)
7787     }
7788 }
7789
7790 impl<'tcx> fmt::Debug for field<'tcx> {
7791     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7792         write!(f, "field({},{})", self.name, self.mt)
7793     }
7794 }
7795
7796 impl<'a, 'tcx> fmt::Debug for ParameterEnvironment<'a, 'tcx> {
7797     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7798         write!(f, "ParameterEnvironment(\
7799             free_substs={:?}, \
7800             implicit_region_bound={:?}, \
7801             caller_bounds={:?})",
7802             self.free_substs,
7803             self.implicit_region_bound,
7804             self.caller_bounds)
7805     }
7806 }
7807
7808 impl<'tcx> fmt::Debug for ObjectLifetimeDefault {
7809     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7810         match *self {
7811             ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
7812             ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r),
7813         }
7814     }
7815 }