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