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