]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/ty.rs
rustc: remove dead code
[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 varidic 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 to_bounds(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>)
1780                      -> GenericBounds<'tcx> {
1781         GenericBounds {
1782             predicates: self.predicates.subst(tcx, substs),
1783         }
1784     }
1785 }
1786
1787 #[derive(Clone, PartialEq, Eq, Hash, Show)]
1788 pub enum Predicate<'tcx> {
1789     /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
1790     /// the `Self` type of the trait reference and `A`, `B`, and `C`
1791     /// would be the parameters in the `TypeSpace`.
1792     Trait(PolyTraitPredicate<'tcx>),
1793
1794     /// where `T1 == T2`.
1795     Equate(PolyEquatePredicate<'tcx>),
1796
1797     /// where 'a : 'b
1798     RegionOutlives(PolyRegionOutlivesPredicate),
1799
1800     /// where T : 'a
1801     TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
1802
1803     /// where <T as TraitRef>::Name == X, approximately.
1804     /// See `ProjectionPredicate` struct for details.
1805     Projection(PolyProjectionPredicate<'tcx>),
1806 }
1807
1808 #[derive(Clone, PartialEq, Eq, Hash, Show)]
1809 pub struct TraitPredicate<'tcx> {
1810     pub trait_ref: Rc<TraitRef<'tcx>>
1811 }
1812 pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
1813
1814 impl<'tcx> TraitPredicate<'tcx> {
1815     pub fn def_id(&self) -> ast::DefId {
1816         self.trait_ref.def_id
1817     }
1818
1819     pub fn input_types(&self) -> &[Ty<'tcx>] {
1820         self.trait_ref.substs.types.as_slice()
1821     }
1822
1823     pub fn self_ty(&self) -> Ty<'tcx> {
1824         self.trait_ref.self_ty()
1825     }
1826 }
1827
1828 impl<'tcx> PolyTraitPredicate<'tcx> {
1829     pub fn def_id(&self) -> ast::DefId {
1830         self.0.def_id()
1831     }
1832 }
1833
1834 #[derive(Clone, PartialEq, Eq, Hash, Show)]
1835 pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
1836 pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
1837
1838 #[derive(Clone, PartialEq, Eq, Hash, Show)]
1839 pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
1840 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
1841 pub type PolyRegionOutlivesPredicate = PolyOutlivesPredicate<ty::Region, ty::Region>;
1842 pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region>;
1843
1844 /// This kind of predicate has no *direct* correspondent in the
1845 /// syntax, but it roughly corresponds to the syntactic forms:
1846 ///
1847 /// 1. `T : TraitRef<..., Item=Type>`
1848 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
1849 ///
1850 /// In particular, form #1 is "desugared" to the combination of a
1851 /// normal trait predicate (`T : TraitRef<...>`) and one of these
1852 /// predicates. Form #2 is a broader form in that it also permits
1853 /// equality between arbitrary types. Processing an instance of Form
1854 /// #2 eventually yields one of these `ProjectionPredicate`
1855 /// instances to normalize the LHS.
1856 #[derive(Clone, PartialEq, Eq, Hash, Show)]
1857 pub struct ProjectionPredicate<'tcx> {
1858     pub projection_ty: ProjectionTy<'tcx>,
1859     pub ty: Ty<'tcx>,
1860 }
1861
1862 pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
1863
1864 impl<'tcx> PolyProjectionPredicate<'tcx> {
1865     pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
1866         self.0.projection_ty.sort_key()
1867     }
1868 }
1869
1870 /// Represents the projection of an associated type. In explicit UFCS
1871 /// form this would be written `<T as Trait<..>>::N`.
1872 #[derive(Clone, PartialEq, Eq, Hash, Show)]
1873 pub struct ProjectionTy<'tcx> {
1874     /// The trait reference `T as Trait<..>`.
1875     pub trait_ref: Rc<ty::TraitRef<'tcx>>,
1876
1877     /// The name `N` of the associated type.
1878     pub item_name: ast::Name,
1879 }
1880
1881 impl<'tcx> ProjectionTy<'tcx> {
1882     pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
1883         (self.trait_ref.def_id, self.item_name)
1884     }
1885 }
1886
1887 pub trait ToPolyTraitRef<'tcx> {
1888     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
1889 }
1890
1891 impl<'tcx> ToPolyTraitRef<'tcx> for Rc<TraitRef<'tcx>> {
1892     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1893         assert!(!self.has_escaping_regions());
1894         ty::Binder(self.clone())
1895     }
1896 }
1897
1898 impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
1899     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1900         // We are just preserving the binder levels here
1901         ty::Binder(self.0.trait_ref.clone())
1902     }
1903 }
1904
1905 impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
1906     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1907         // Note: unlike with TraitRef::to_poly_trait_ref(),
1908         // self.0.trait_ref is permitted to have escaping regions.
1909         // This is because here `self` has a `Binder` and so does our
1910         // return value, so we are preserving the number of binding
1911         // levels.
1912         ty::Binder(self.0.projection_ty.trait_ref.clone())
1913     }
1914 }
1915
1916 pub trait AsPredicate<'tcx> {
1917     fn as_predicate(&self) -> Predicate<'tcx>;
1918 }
1919
1920 impl<'tcx> AsPredicate<'tcx> for Rc<TraitRef<'tcx>> {
1921     fn as_predicate(&self) -> Predicate<'tcx> {
1922         // we're about to add a binder, so let's check that we don't
1923         // accidentally capture anything, or else that might be some
1924         // weird debruijn accounting.
1925         assert!(!self.has_escaping_regions());
1926
1927         ty::Predicate::Trait(ty::Binder(ty::TraitPredicate {
1928             trait_ref: self.clone()
1929         }))
1930     }
1931 }
1932
1933 impl<'tcx> AsPredicate<'tcx> for PolyTraitRef<'tcx> {
1934     fn as_predicate(&self) -> Predicate<'tcx> {
1935         ty::Predicate::Trait(self.to_poly_trait_predicate())
1936     }
1937 }
1938
1939 impl<'tcx> AsPredicate<'tcx> for PolyEquatePredicate<'tcx> {
1940     fn as_predicate(&self) -> Predicate<'tcx> {
1941         Predicate::Equate(self.clone())
1942     }
1943 }
1944
1945 impl<'tcx> AsPredicate<'tcx> for PolyRegionOutlivesPredicate {
1946     fn as_predicate(&self) -> Predicate<'tcx> {
1947         Predicate::RegionOutlives(self.clone())
1948     }
1949 }
1950
1951 impl<'tcx> AsPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
1952     fn as_predicate(&self) -> Predicate<'tcx> {
1953         Predicate::TypeOutlives(self.clone())
1954     }
1955 }
1956
1957 impl<'tcx> AsPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
1958     fn as_predicate(&self) -> Predicate<'tcx> {
1959         Predicate::Projection(self.clone())
1960     }
1961 }
1962
1963 impl<'tcx> Predicate<'tcx> {
1964     pub fn has_escaping_regions(&self) -> bool {
1965         match *self {
1966             Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(),
1967             Predicate::Equate(ref p) => p.has_escaping_regions(),
1968             Predicate::RegionOutlives(ref p) => p.has_escaping_regions(),
1969             Predicate::TypeOutlives(ref p) => p.has_escaping_regions(),
1970             Predicate::Projection(ref p) => p.has_escaping_regions(),
1971         }
1972     }
1973
1974     pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
1975         match *self {
1976             Predicate::Trait(ref t) => {
1977                 Some(t.to_poly_trait_ref())
1978             }
1979             Predicate::Projection(..) |
1980             Predicate::Equate(..) |
1981             Predicate::RegionOutlives(..) |
1982             Predicate::TypeOutlives(..) => {
1983                 None
1984             }
1985         }
1986     }
1987 }
1988
1989 /// Represents the bounds declared on a particular set of type
1990 /// parameters.  Should eventually be generalized into a flag list of
1991 /// where clauses.  You can obtain a `GenericBounds` list from a
1992 /// `Generics` by using the `to_bounds` method. Note that this method
1993 /// reflects an important semantic invariant of `GenericBounds`: while
1994 /// the bounds in a `Generics` are expressed in terms of the bound type
1995 /// parameters of the impl/trait/whatever, a `GenericBounds` instance
1996 /// represented a set of bounds for some particular instantiation,
1997 /// meaning that the generic parameters have been substituted with
1998 /// their values.
1999 ///
2000 /// Example:
2001 ///
2002 ///     struct Foo<T,U:Bar<T>> { ... }
2003 ///
2004 /// Here, the `Generics` for `Foo` would contain a list of bounds like
2005 /// `[[], [U:Bar<T>]]`.  Now if there were some particular reference
2006 /// like `Foo<int,uint>`, then the `GenericBounds` would be `[[],
2007 /// [uint:Bar<int>]]`.
2008 #[derive(Clone, Show)]
2009 pub struct GenericBounds<'tcx> {
2010     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
2011 }
2012
2013 impl<'tcx> GenericBounds<'tcx> {
2014     pub fn empty() -> GenericBounds<'tcx> {
2015         GenericBounds { predicates: VecPerParamSpace::empty() }
2016     }
2017
2018     pub fn has_escaping_regions(&self) -> bool {
2019         self.predicates.any(|p| p.has_escaping_regions())
2020     }
2021
2022     pub fn is_empty(&self) -> bool {
2023         self.predicates.is_empty()
2024     }
2025 }
2026
2027 impl<'tcx> TraitRef<'tcx> {
2028     pub fn new(def_id: ast::DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
2029         TraitRef { def_id: def_id, substs: substs }
2030     }
2031
2032     pub fn self_ty(&self) -> Ty<'tcx> {
2033         self.substs.self_ty().unwrap()
2034     }
2035
2036     pub fn input_types(&self) -> &[Ty<'tcx>] {
2037         // Select only the "input types" from a trait-reference. For
2038         // now this is all the types that appear in the
2039         // trait-reference, but it should eventually exclude
2040         // associated types.
2041         self.substs.types.as_slice()
2042     }
2043 }
2044
2045 /// When type checking, we use the `ParameterEnvironment` to track
2046 /// details about the type/lifetime parameters that are in scope.
2047 /// It primarily stores the bounds information.
2048 ///
2049 /// Note: This information might seem to be redundant with the data in
2050 /// `tcx.ty_param_defs`, but it is not. That table contains the
2051 /// parameter definitions from an "outside" perspective, but this
2052 /// struct will contain the bounds for a parameter as seen from inside
2053 /// the function body. Currently the only real distinction is that
2054 /// bound lifetime parameters are replaced with free ones, but in the
2055 /// future I hope to refine the representation of types so as to make
2056 /// more distinctions clearer.
2057 #[derive(Clone)]
2058 pub struct ParameterEnvironment<'a, 'tcx:'a> {
2059     pub tcx: &'a ctxt<'tcx>,
2060
2061     /// A substitution that can be applied to move from
2062     /// the "outer" view of a type or method to the "inner" view.
2063     /// In general, this means converting from bound parameters to
2064     /// free parameters. Since we currently represent bound/free type
2065     /// parameters in the same way, this only has an effect on regions.
2066     pub free_substs: Substs<'tcx>,
2067
2068     /// Each type parameter has an implicit region bound that
2069     /// indicates it must outlive at least the function body (the user
2070     /// may specify stronger requirements). This field indicates the
2071     /// region of the callee.
2072     pub implicit_region_bound: ty::Region,
2073
2074     /// Obligations that the caller must satisfy. This is basically
2075     /// the set of bounds on the in-scope type parameters, translated
2076     /// into Obligations.
2077     pub caller_bounds: ty::GenericBounds<'tcx>,
2078
2079     /// Caches the results of trait selection. This cache is used
2080     /// for things that have to do with the parameters in scope.
2081     pub selection_cache: traits::SelectionCache<'tcx>,
2082 }
2083
2084 impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2085     pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
2086         match cx.map.find(id) {
2087             Some(ast_map::NodeImplItem(ref impl_item)) => {
2088                 match **impl_item {
2089                     ast::MethodImplItem(ref method) => {
2090                         let method_def_id = ast_util::local_def(id);
2091                         match ty::impl_or_trait_item(cx, method_def_id) {
2092                             MethodTraitItem(ref method_ty) => {
2093                                 let method_generics = &method_ty.generics;
2094                                 construct_parameter_environment(
2095                                     cx,
2096                                     method_generics,
2097                                     method.pe_body().id)
2098                             }
2099                             TypeTraitItem(_) => {
2100                                 cx.sess
2101                                   .bug("ParameterEnvironment::for_item(): \
2102                                         can't create a parameter environment \
2103                                         for type trait items")
2104                             }
2105                         }
2106                     }
2107                     ast::TypeImplItem(_) => {
2108                         cx.sess.bug("ParameterEnvironment::for_item(): \
2109                                      can't create a parameter environment \
2110                                      for type impl items")
2111                     }
2112                 }
2113             }
2114             Some(ast_map::NodeTraitItem(trait_method)) => {
2115                 match *trait_method {
2116                     ast::RequiredMethod(ref required) => {
2117                         cx.sess.span_bug(required.span,
2118                                          "ParameterEnvironment::for_item():
2119                                           can't create a parameter \
2120                                           environment for required trait \
2121                                           methods")
2122                     }
2123                     ast::ProvidedMethod(ref method) => {
2124                         let method_def_id = ast_util::local_def(id);
2125                         match ty::impl_or_trait_item(cx, method_def_id) {
2126                             MethodTraitItem(ref method_ty) => {
2127                                 let method_generics = &method_ty.generics;
2128                                 construct_parameter_environment(
2129                                     cx,
2130                                     method_generics,
2131                                     method.pe_body().id)
2132                             }
2133                             TypeTraitItem(_) => {
2134                                 cx.sess
2135                                   .bug("ParameterEnvironment::for_item(): \
2136                                         can't create a parameter environment \
2137                                         for type trait items")
2138                             }
2139                         }
2140                     }
2141                     ast::TypeTraitItem(_) => {
2142                         cx.sess.bug("ParameterEnvironment::from_item(): \
2143                                      can't create a parameter environment \
2144                                      for type trait items")
2145                     }
2146                 }
2147             }
2148             Some(ast_map::NodeItem(item)) => {
2149                 match item.node {
2150                     ast::ItemFn(_, _, _, _, ref body) => {
2151                         // We assume this is a function.
2152                         let fn_def_id = ast_util::local_def(id);
2153                         let fn_pty = ty::lookup_item_type(cx, fn_def_id);
2154
2155                         construct_parameter_environment(cx,
2156                                                         &fn_pty.generics,
2157                                                         body.id)
2158                     }
2159                     ast::ItemEnum(..) |
2160                     ast::ItemStruct(..) |
2161                     ast::ItemImpl(..) |
2162                     ast::ItemConst(..) |
2163                     ast::ItemStatic(..) => {
2164                         let def_id = ast_util::local_def(id);
2165                         let pty = ty::lookup_item_type(cx, def_id);
2166                         construct_parameter_environment(cx, &pty.generics, id)
2167                     }
2168                     _ => {
2169                         cx.sess.span_bug(item.span,
2170                                          "ParameterEnvironment::from_item():
2171                                           can't create a parameter \
2172                                           environment for this kind of item")
2173                     }
2174                 }
2175             }
2176             Some(ast_map::NodeExpr(..)) => {
2177                 // This is a convenience to allow closures to work.
2178                 ParameterEnvironment::for_item(cx, cx.map.get_parent(id))
2179             }
2180             _ => {
2181                 cx.sess.bug(format!("ParameterEnvironment::from_item(): \
2182                                      `{}` is not an item",
2183                                     cx.map.node_to_string(id))[])
2184             }
2185         }
2186     }
2187 }
2188
2189 /// A "type scheme", in ML terminology, is a type combined with some
2190 /// set of generic types that the type is, well, generic over. In Rust
2191 /// terms, it is the "type" of a fn item or struct -- this type will
2192 /// include various generic parameters that must be substituted when
2193 /// the item/struct is referenced. That is called converting the type
2194 /// scheme to a monotype.
2195 ///
2196 /// - `generics`: the set of type parameters and their bounds
2197 /// - `ty`: the base types, which may reference the parameters defined
2198 ///   in `generics`
2199 ///
2200 /// Note that TypeSchemes are also sometimes called "polytypes" (and
2201 /// in fact this struct used to carry that name, so you may find some
2202 /// stray references in a comment or something). We try to reserve the
2203 /// "poly" prefix to refer to higher-ranked things, as in
2204 /// `PolyTraitRef`.
2205 #[derive(Clone, Show)]
2206 pub struct TypeScheme<'tcx> {
2207     pub generics: Generics<'tcx>,
2208     pub ty: Ty<'tcx>
2209 }
2210
2211 /// As `TypeScheme` but for a trait ref.
2212 pub struct TraitDef<'tcx> {
2213     pub unsafety: ast::Unsafety,
2214
2215     /// Generic type definitions. Note that `Self` is listed in here
2216     /// as having a single bound, the trait itself (e.g., in the trait
2217     /// `Eq`, there is a single bound `Self : Eq`). This is so that
2218     /// default methods get to assume that the `Self` parameters
2219     /// implements the trait.
2220     pub generics: Generics<'tcx>,
2221
2222     /// The "supertrait" bounds.
2223     pub bounds: ParamBounds<'tcx>,
2224
2225     pub trait_ref: Rc<ty::TraitRef<'tcx>>,
2226
2227     /// A list of the associated types defined in this trait. Useful
2228     /// for resolving `X::Foo` type markers.
2229     pub associated_type_names: Vec<ast::Name>,
2230 }
2231
2232 /// Records the substitutions used to translate the polytype for an
2233 /// item into the monotype of an item reference.
2234 #[derive(Clone)]
2235 pub struct ItemSubsts<'tcx> {
2236     pub substs: Substs<'tcx>,
2237 }
2238
2239 /// Records information about each unboxed closure.
2240 #[derive(Clone)]
2241 pub struct UnboxedClosure<'tcx> {
2242     /// The type of the unboxed closure.
2243     pub closure_type: ClosureTy<'tcx>,
2244     /// The kind of unboxed closure this is.
2245     pub kind: UnboxedClosureKind,
2246 }
2247
2248 #[derive(Clone, Copy, PartialEq, Eq, Show)]
2249 pub enum UnboxedClosureKind {
2250     FnUnboxedClosureKind,
2251     FnMutUnboxedClosureKind,
2252     FnOnceUnboxedClosureKind,
2253 }
2254
2255 impl UnboxedClosureKind {
2256     pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
2257         let result = match *self {
2258             FnUnboxedClosureKind => cx.lang_items.require(FnTraitLangItem),
2259             FnMutUnboxedClosureKind => {
2260                 cx.lang_items.require(FnMutTraitLangItem)
2261             }
2262             FnOnceUnboxedClosureKind => {
2263                 cx.lang_items.require(FnOnceTraitLangItem)
2264             }
2265         };
2266         match result {
2267             Ok(trait_did) => trait_did,
2268             Err(err) => cx.sess.fatal(err[]),
2269         }
2270     }
2271 }
2272
2273 pub trait UnboxedClosureTyper<'tcx> {
2274     fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
2275
2276     fn unboxed_closure_kind(&self,
2277                             def_id: ast::DefId)
2278                             -> ty::UnboxedClosureKind;
2279
2280     fn unboxed_closure_type(&self,
2281                             def_id: ast::DefId,
2282                             substs: &subst::Substs<'tcx>)
2283                             -> ty::ClosureTy<'tcx>;
2284
2285     // Returns `None` if the upvar types cannot yet be definitively determined.
2286     fn unboxed_closure_upvars(&self,
2287                               def_id: ast::DefId,
2288                               substs: &Substs<'tcx>)
2289                               -> Option<Vec<UnboxedClosureUpvar<'tcx>>>;
2290 }
2291
2292 impl<'tcx> CommonTypes<'tcx> {
2293     fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
2294            interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>)
2295            -> CommonTypes<'tcx>
2296     {
2297         CommonTypes {
2298             bool: intern_ty(arena, interner, ty_bool),
2299             char: intern_ty(arena, interner, ty_char),
2300             err: intern_ty(arena, interner, ty_err),
2301             int: intern_ty(arena, interner, ty_int(ast::TyI)),
2302             i8: intern_ty(arena, interner, ty_int(ast::TyI8)),
2303             i16: intern_ty(arena, interner, ty_int(ast::TyI16)),
2304             i32: intern_ty(arena, interner, ty_int(ast::TyI32)),
2305             i64: intern_ty(arena, interner, ty_int(ast::TyI64)),
2306             uint: intern_ty(arena, interner, ty_uint(ast::TyU)),
2307             u8: intern_ty(arena, interner, ty_uint(ast::TyU8)),
2308             u16: intern_ty(arena, interner, ty_uint(ast::TyU16)),
2309             u32: intern_ty(arena, interner, ty_uint(ast::TyU32)),
2310             u64: intern_ty(arena, interner, ty_uint(ast::TyU64)),
2311             f32: intern_ty(arena, interner, ty_float(ast::TyF32)),
2312             f64: intern_ty(arena, interner, ty_float(ast::TyF64)),
2313         }
2314     }
2315 }
2316
2317 pub fn mk_ctxt<'tcx>(s: Session,
2318                      arenas: &'tcx CtxtArenas<'tcx>,
2319                      dm: DefMap,
2320                      named_region_map: resolve_lifetime::NamedRegionMap,
2321                      map: ast_map::Map<'tcx>,
2322                      freevars: RefCell<FreevarMap>,
2323                      capture_modes: RefCell<CaptureModeMap>,
2324                      region_maps: middle::region::RegionMaps,
2325                      lang_items: middle::lang_items::LanguageItems,
2326                      stability: stability::Index) -> ctxt<'tcx>
2327 {
2328     let mut interner = FnvHashMap::new();
2329     let common_types = CommonTypes::new(&arenas.type_, &mut interner);
2330
2331     ctxt {
2332         arenas: arenas,
2333         interner: RefCell::new(interner),
2334         substs_interner: RefCell::new(FnvHashMap::new()),
2335         bare_fn_interner: RefCell::new(FnvHashMap::new()),
2336         region_interner: RefCell::new(FnvHashMap::new()),
2337         types: common_types,
2338         named_region_map: named_region_map,
2339         item_variance_map: RefCell::new(DefIdMap::new()),
2340         variance_computed: Cell::new(false),
2341         sess: s,
2342         def_map: dm,
2343         region_maps: region_maps,
2344         node_types: RefCell::new(FnvHashMap::new()),
2345         item_substs: RefCell::new(NodeMap::new()),
2346         trait_refs: RefCell::new(NodeMap::new()),
2347         trait_defs: RefCell::new(DefIdMap::new()),
2348         object_cast_map: RefCell::new(NodeMap::new()),
2349         map: map,
2350         intrinsic_defs: RefCell::new(DefIdMap::new()),
2351         freevars: freevars,
2352         tcache: RefCell::new(DefIdMap::new()),
2353         rcache: RefCell::new(FnvHashMap::new()),
2354         short_names_cache: RefCell::new(FnvHashMap::new()),
2355         tc_cache: RefCell::new(FnvHashMap::new()),
2356         ast_ty_to_ty_cache: RefCell::new(NodeMap::new()),
2357         enum_var_cache: RefCell::new(DefIdMap::new()),
2358         impl_or_trait_items: RefCell::new(DefIdMap::new()),
2359         trait_item_def_ids: RefCell::new(DefIdMap::new()),
2360         trait_items_cache: RefCell::new(DefIdMap::new()),
2361         impl_trait_cache: RefCell::new(DefIdMap::new()),
2362         ty_param_defs: RefCell::new(NodeMap::new()),
2363         adjustments: RefCell::new(NodeMap::new()),
2364         normalized_cache: RefCell::new(FnvHashMap::new()),
2365         lang_items: lang_items,
2366         provided_method_sources: RefCell::new(DefIdMap::new()),
2367         struct_fields: RefCell::new(DefIdMap::new()),
2368         destructor_for_type: RefCell::new(DefIdMap::new()),
2369         destructors: RefCell::new(DefIdSet::new()),
2370         trait_impls: RefCell::new(DefIdMap::new()),
2371         inherent_impls: RefCell::new(DefIdMap::new()),
2372         impl_items: RefCell::new(DefIdMap::new()),
2373         used_unsafe: RefCell::new(NodeSet::new()),
2374         used_mut_nodes: RefCell::new(NodeSet::new()),
2375         populated_external_types: RefCell::new(DefIdSet::new()),
2376         populated_external_traits: RefCell::new(DefIdSet::new()),
2377         upvar_borrow_map: RefCell::new(FnvHashMap::new()),
2378         extern_const_statics: RefCell::new(DefIdMap::new()),
2379         extern_const_variants: RefCell::new(DefIdMap::new()),
2380         method_map: RefCell::new(FnvHashMap::new()),
2381         dependency_formats: RefCell::new(FnvHashMap::new()),
2382         unboxed_closures: RefCell::new(DefIdMap::new()),
2383         node_lint_levels: RefCell::new(FnvHashMap::new()),
2384         transmute_restrictions: RefCell::new(Vec::new()),
2385         stability: RefCell::new(stability),
2386         capture_modes: capture_modes,
2387         associated_types: RefCell::new(DefIdMap::new()),
2388         selection_cache: traits::SelectionCache::new(),
2389         repr_hint_cache: RefCell::new(DefIdMap::new()),
2390         type_impls_copy_cache: RefCell::new(HashMap::new()),
2391         type_impls_sized_cache: RefCell::new(HashMap::new()),
2392         object_safety_cache: RefCell::new(DefIdMap::new()),
2393    }
2394 }
2395
2396 // Type constructors
2397
2398 impl<'tcx> ctxt<'tcx> {
2399     pub fn mk_substs(&self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> {
2400         if let Some(substs) = self.substs_interner.borrow().get(&substs) {
2401             return *substs;
2402         }
2403
2404         let substs = self.arenas.substs.alloc(substs);
2405         self.substs_interner.borrow_mut().insert(substs, substs);
2406         substs
2407     }
2408
2409     pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
2410         if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) {
2411             return *bare_fn;
2412         }
2413
2414         let bare_fn = self.arenas.bare_fn.alloc(bare_fn);
2415         self.bare_fn_interner.borrow_mut().insert(bare_fn, bare_fn);
2416         bare_fn
2417     }
2418
2419     pub fn mk_region(&self, region: Region) -> &'tcx Region {
2420         if let Some(region) = self.region_interner.borrow().get(&region) {
2421             return *region;
2422         }
2423
2424         let region = self.arenas.region.alloc(region);
2425         self.region_interner.borrow_mut().insert(region, region);
2426         region
2427     }
2428
2429     pub fn unboxed_closure_kind(&self,
2430                             def_id: ast::DefId)
2431                             -> ty::UnboxedClosureKind
2432     {
2433         self.unboxed_closures.borrow()[def_id].kind
2434     }
2435
2436     pub fn unboxed_closure_type(&self,
2437                             def_id: ast::DefId,
2438                             substs: &subst::Substs<'tcx>)
2439                             -> ty::ClosureTy<'tcx>
2440     {
2441         self.unboxed_closures.borrow()[def_id].closure_type.subst(self, substs)
2442     }
2443 }
2444
2445 // Interns a type/name combination, stores the resulting box in cx.interner,
2446 // and returns the box as cast to an unsafe ptr (see comments for Ty above).
2447 pub fn mk_t<'tcx>(cx: &ctxt<'tcx>, st: sty<'tcx>) -> Ty<'tcx> {
2448     let mut interner = cx.interner.borrow_mut();
2449     intern_ty(&cx.arenas.type_, &mut *interner, st)
2450 }
2451
2452 fn intern_ty<'tcx>(type_arena: &'tcx TypedArena<TyS<'tcx>>,
2453                    interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>,
2454                    st: sty<'tcx>)
2455                    -> Ty<'tcx>
2456 {
2457     match interner.get(&st) {
2458         Some(ty) => return *ty,
2459         _ => ()
2460     }
2461
2462     let flags = FlagComputation::for_sty(&st);
2463
2464     let ty = type_arena.alloc(TyS {
2465         sty: st,
2466         flags: flags.flags,
2467         region_depth: flags.depth,
2468     });
2469
2470     debug!("Interned type: {} Pointer: {}",
2471            ty, ty as *const _);
2472
2473     interner.insert(InternedTy { ty: ty }, ty);
2474
2475     ty
2476 }
2477
2478 struct FlagComputation {
2479     flags: TypeFlags,
2480
2481     // maximum depth of any bound region that we have seen thus far
2482     depth: u32,
2483 }
2484
2485 impl FlagComputation {
2486     fn new() -> FlagComputation {
2487         FlagComputation { flags: NO_TYPE_FLAGS, depth: 0 }
2488     }
2489
2490     fn for_sty(st: &sty) -> FlagComputation {
2491         let mut result = FlagComputation::new();
2492         result.add_sty(st);
2493         result
2494     }
2495
2496     fn add_flags(&mut self, flags: TypeFlags) {
2497         self.flags = self.flags | flags;
2498     }
2499
2500     fn add_depth(&mut self, depth: u32) {
2501         if depth > self.depth {
2502             self.depth = depth;
2503         }
2504     }
2505
2506     /// Adds the flags/depth from a set of types that appear within the current type, but within a
2507     /// region binder.
2508     fn add_bound_computation(&mut self, computation: &FlagComputation) {
2509         self.add_flags(computation.flags);
2510
2511         // The types that contributed to `computation` occured within
2512         // a region binder, so subtract one from the region depth
2513         // within when adding the depth to `self`.
2514         let depth = computation.depth;
2515         if depth > 0 {
2516             self.add_depth(depth - 1);
2517         }
2518     }
2519
2520     fn add_sty(&mut self, st: &sty) {
2521         match st {
2522             &ty_bool |
2523             &ty_char |
2524             &ty_int(_) |
2525             &ty_float(_) |
2526             &ty_uint(_) |
2527             &ty_str => {
2528             }
2529
2530             // You might think that we could just return ty_err for
2531             // any type containing ty_err as a component, and get
2532             // rid of the HAS_TY_ERR flag -- likewise for ty_bot (with
2533             // the exception of function types that return bot).
2534             // But doing so caused sporadic memory corruption, and
2535             // neither I (tjc) nor nmatsakis could figure out why,
2536             // so we're doing it this way.
2537             &ty_err => {
2538                 self.add_flags(HAS_TY_ERR)
2539             }
2540
2541             &ty_param(ref p) => {
2542                 if p.space == subst::SelfSpace {
2543                     self.add_flags(HAS_SELF);
2544                 } else {
2545                     self.add_flags(HAS_PARAMS);
2546                 }
2547             }
2548
2549             &ty_unboxed_closure(_, region, substs) => {
2550                 self.add_region(*region);
2551                 self.add_substs(substs);
2552             }
2553
2554             &ty_infer(_) => {
2555                 self.add_flags(HAS_TY_INFER)
2556             }
2557
2558             &ty_enum(_, substs) | &ty_struct(_, substs) => {
2559                 self.add_substs(substs);
2560             }
2561
2562             &ty_projection(ref data) => {
2563                 self.add_flags(HAS_PROJECTION);
2564                 self.add_substs(data.trait_ref.substs);
2565             }
2566
2567             &ty_trait(box TyTrait { ref principal, ref bounds }) => {
2568                 let mut computation = FlagComputation::new();
2569                 computation.add_substs(principal.0.substs);
2570                 self.add_bound_computation(&computation);
2571
2572                 self.add_bounds(bounds);
2573             }
2574
2575             &ty_uniq(tt) | &ty_vec(tt, _) | &ty_open(tt) => {
2576                 self.add_ty(tt)
2577             }
2578
2579             &ty_ptr(ref m) => {
2580                 self.add_ty(m.ty);
2581             }
2582
2583             &ty_rptr(r, ref m) => {
2584                 self.add_region(*r);
2585                 self.add_ty(m.ty);
2586             }
2587
2588             &ty_tup(ref ts) => {
2589                 self.add_tys(ts[]);
2590             }
2591
2592             &ty_bare_fn(_, ref f) => {
2593                 self.add_fn_sig(&f.sig);
2594             }
2595         }
2596     }
2597
2598     fn add_ty(&mut self, ty: Ty) {
2599         self.add_flags(ty.flags);
2600         self.add_depth(ty.region_depth);
2601     }
2602
2603     fn add_tys(&mut self, tys: &[Ty]) {
2604         for &ty in tys.iter() {
2605             self.add_ty(ty);
2606         }
2607     }
2608
2609     fn add_fn_sig(&mut self, fn_sig: &PolyFnSig) {
2610         let mut computation = FlagComputation::new();
2611
2612         computation.add_tys(fn_sig.0.inputs[]);
2613
2614         if let ty::FnConverging(output) = fn_sig.0.output {
2615             computation.add_ty(output);
2616         }
2617
2618         self.add_bound_computation(&computation);
2619     }
2620
2621     fn add_region(&mut self, r: Region) {
2622         self.add_flags(HAS_REGIONS);
2623         match r {
2624             ty::ReInfer(_) => { self.add_flags(HAS_RE_INFER); }
2625             ty::ReLateBound(debruijn, _) => {
2626                 self.add_flags(HAS_RE_LATE_BOUND);
2627                 self.add_depth(debruijn.depth);
2628             }
2629             _ => { }
2630         }
2631     }
2632
2633     fn add_substs(&mut self, substs: &Substs) {
2634         self.add_tys(substs.types.as_slice());
2635         match substs.regions {
2636             subst::ErasedRegions => {}
2637             subst::NonerasedRegions(ref regions) => {
2638                 for &r in regions.iter() {
2639                     self.add_region(r);
2640                 }
2641             }
2642         }
2643     }
2644
2645     fn add_bounds(&mut self, bounds: &ExistentialBounds) {
2646         self.add_region(bounds.region_bound);
2647     }
2648 }
2649
2650 pub fn mk_mach_int<'tcx>(tcx: &ctxt<'tcx>, tm: ast::IntTy) -> Ty<'tcx> {
2651     match tm {
2652         ast::TyI    => tcx.types.int,
2653         ast::TyI8   => tcx.types.i8,
2654         ast::TyI16  => tcx.types.i16,
2655         ast::TyI32  => tcx.types.i32,
2656         ast::TyI64  => tcx.types.i64,
2657     }
2658 }
2659
2660 pub fn mk_mach_uint<'tcx>(tcx: &ctxt<'tcx>, tm: ast::UintTy) -> Ty<'tcx> {
2661     match tm {
2662         ast::TyU    => tcx.types.uint,
2663         ast::TyU8   => tcx.types.u8,
2664         ast::TyU16  => tcx.types.u16,
2665         ast::TyU32  => tcx.types.u32,
2666         ast::TyU64  => tcx.types.u64,
2667     }
2668 }
2669
2670 pub fn mk_mach_float<'tcx>(tcx: &ctxt<'tcx>, tm: ast::FloatTy) -> Ty<'tcx> {
2671     match tm {
2672         ast::TyF32  => tcx.types.f32,
2673         ast::TyF64  => tcx.types.f64,
2674     }
2675 }
2676
2677 pub fn mk_str<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
2678     mk_t(cx, ty_str)
2679 }
2680
2681 pub fn mk_str_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, m: ast::Mutability) -> Ty<'tcx> {
2682     mk_rptr(cx, r,
2683             mt {
2684                 ty: mk_t(cx, ty_str),
2685                 mutbl: m
2686             })
2687 }
2688
2689 pub fn mk_enum<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
2690     // take a copy of substs so that we own the vectors inside
2691     mk_t(cx, ty_enum(did, substs))
2692 }
2693
2694 pub fn mk_uniq<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_uniq(ty)) }
2695
2696 pub fn mk_ptr<'tcx>(cx: &ctxt<'tcx>, tm: mt<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_ptr(tm)) }
2697
2698 pub fn mk_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> {
2699     mk_t(cx, ty_rptr(r, tm))
2700 }
2701
2702 pub fn mk_mut_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
2703     mk_rptr(cx, r, mt {ty: ty, mutbl: ast::MutMutable})
2704 }
2705 pub fn mk_imm_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
2706     mk_rptr(cx, r, mt {ty: ty, mutbl: ast::MutImmutable})
2707 }
2708
2709 pub fn mk_mut_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
2710     mk_ptr(cx, mt {ty: ty, mutbl: ast::MutMutable})
2711 }
2712
2713 pub fn mk_imm_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
2714     mk_ptr(cx, mt {ty: ty, mutbl: ast::MutImmutable})
2715 }
2716
2717 pub fn mk_nil_ptr<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
2718     mk_ptr(cx, mt {ty: mk_nil(cx), mutbl: ast::MutImmutable})
2719 }
2720
2721 pub fn mk_vec<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, sz: Option<uint>) -> Ty<'tcx> {
2722     mk_t(cx, ty_vec(ty, sz))
2723 }
2724
2725 pub fn mk_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> {
2726     mk_rptr(cx, r,
2727             mt {
2728                 ty: mk_vec(cx, tm.ty, None),
2729                 mutbl: tm.mutbl
2730             })
2731 }
2732
2733 pub fn mk_tup<'tcx>(cx: &ctxt<'tcx>, ts: Vec<Ty<'tcx>>) -> Ty<'tcx> {
2734     mk_t(cx, ty_tup(ts))
2735 }
2736
2737 pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
2738     mk_tup(cx, Vec::new())
2739 }
2740
2741 pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
2742                         opt_def_id: Option<ast::DefId>,
2743                         fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
2744     mk_t(cx, ty_bare_fn(opt_def_id, fty))
2745 }
2746
2747 pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
2748                         def_id: ast::DefId,
2749                         input_tys: &[Ty<'tcx>],
2750                         output: Ty<'tcx>) -> Ty<'tcx> {
2751     let input_args = input_tys.iter().map(|ty| *ty).collect();
2752     mk_bare_fn(cx,
2753                Some(def_id),
2754                cx.mk_bare_fn(BareFnTy {
2755                    unsafety: ast::Unsafety::Normal,
2756                    abi: abi::Rust,
2757                    sig: ty::Binder(FnSig {
2758                     inputs: input_args,
2759                     output: ty::FnConverging(output),
2760                     variadic: false
2761                    })
2762                 }))
2763 }
2764
2765 pub fn mk_trait<'tcx>(cx: &ctxt<'tcx>,
2766                       principal: ty::PolyTraitRef<'tcx>,
2767                       bounds: ExistentialBounds<'tcx>)
2768                       -> Ty<'tcx>
2769 {
2770     assert!(bound_list_is_sorted(bounds.projection_bounds.as_slice()));
2771
2772     let inner = box TyTrait {
2773         principal: principal,
2774         bounds: bounds
2775     };
2776     mk_t(cx, ty_trait(inner))
2777 }
2778
2779 fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool {
2780     bounds.len() == 0 ||
2781         bounds[1..].iter().enumerate().all(
2782             |(index, bound)| bounds[index].sort_key() <= bound.sort_key())
2783 }
2784
2785 pub fn sort_bounds_list(bounds: &mut [ty::PolyProjectionPredicate]) {
2786     bounds.sort_by(|a, b| a.sort_key().cmp(&b.sort_key()))
2787 }
2788
2789 pub fn mk_projection<'tcx>(cx: &ctxt<'tcx>,
2790                            trait_ref: Rc<ty::TraitRef<'tcx>>,
2791                            item_name: ast::Name)
2792                            -> Ty<'tcx> {
2793     // take a copy of substs so that we own the vectors inside
2794     let inner = ProjectionTy { trait_ref: trait_ref, item_name: item_name };
2795     mk_t(cx, ty_projection(inner))
2796 }
2797
2798 pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId,
2799                        substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
2800     // take a copy of substs so that we own the vectors inside
2801     mk_t(cx, ty_struct(struct_id, substs))
2802 }
2803
2804 pub fn mk_unboxed_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId,
2805                                 region: &'tcx Region, substs: &'tcx Substs<'tcx>)
2806                                 -> Ty<'tcx> {
2807     mk_t(cx, ty_unboxed_closure(closure_id, region, substs))
2808 }
2809
2810 pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
2811     mk_infer(cx, TyVar(v))
2812 }
2813
2814 pub fn mk_int_var<'tcx>(cx: &ctxt<'tcx>, v: IntVid) -> Ty<'tcx> {
2815     mk_infer(cx, IntVar(v))
2816 }
2817
2818 pub fn mk_float_var<'tcx>(cx: &ctxt<'tcx>, v: FloatVid) -> Ty<'tcx> {
2819     mk_infer(cx, FloatVar(v))
2820 }
2821
2822 pub fn mk_infer<'tcx>(cx: &ctxt<'tcx>, it: InferTy) -> Ty<'tcx> {
2823     mk_t(cx, ty_infer(it))
2824 }
2825
2826 pub fn mk_param<'tcx>(cx: &ctxt<'tcx>,
2827                       space: subst::ParamSpace,
2828                       index: u32,
2829                       name: ast::Name) -> Ty<'tcx> {
2830     mk_t(cx, ty_param(ParamTy { space: space, idx: index, name: name }))
2831 }
2832
2833 pub fn mk_self_type<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
2834     mk_param(cx, subst::SelfSpace, 0, special_idents::type_self.name)
2835 }
2836
2837 pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'tcx> {
2838     mk_param(cx, def.space, def.index, def.name)
2839 }
2840
2841 pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) }
2842
2843 impl<'tcx> TyS<'tcx> {
2844     /// Iterator that walks `self` and any types reachable from
2845     /// `self`, in depth-first order. Note that just walks the types
2846     /// that appear in `self`, it does not descend into the fields of
2847     /// structs or variants. For example:
2848     ///
2849     /// ```notrust
2850     /// int => { int }
2851     /// Foo<Bar<int>> => { Foo<Bar<int>>, Bar<int>, int }
2852     /// [int] => { [int], int }
2853     /// ```
2854     pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
2855         TypeWalker::new(self)
2856     }
2857
2858     /// Iterator that walks types reachable from `self`, in
2859     /// depth-first order. Note that this is a shallow walk. For
2860     /// example:
2861     ///
2862     /// ```notrust
2863     /// int => { }
2864     /// Foo<Bar<int>> => { Bar<int>, int }
2865     /// [int] => { int }
2866     /// ```
2867     pub fn walk_children(&'tcx self) -> TypeWalker<'tcx> {
2868         // Walks type reachable from `self` but not `self
2869         let mut walker = self.walk();
2870         let r = walker.next();
2871         assert_eq!(r, Some(self));
2872         walker
2873     }
2874 }
2875
2876 pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F)
2877     where F: FnMut(Ty<'tcx>),
2878 {
2879     for ty in ty_root.walk() {
2880         f(ty);
2881     }
2882 }
2883
2884 /// Walks `ty` and any types appearing within `ty`, invoking the
2885 /// callback `f` on each type. If the callback returns false, then the
2886 /// children of the current type are ignored.
2887 ///
2888 /// Note: prefer `ty.walk()` where possible.
2889 pub fn maybe_walk_ty<'tcx,F>(ty_root: Ty<'tcx>, mut f: F)
2890     where F : FnMut(Ty<'tcx>) -> bool
2891 {
2892     let mut walker = ty_root.walk();
2893     while let Some(ty) = walker.next() {
2894         if !f(ty) {
2895             walker.skip_current_subtree();
2896         }
2897     }
2898 }
2899
2900 // Folds types from the bottom up.
2901 pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
2902                         fldop: F)
2903                         -> Ty<'tcx> where
2904     F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
2905 {
2906     let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop};
2907     f.fold_ty(t0)
2908 }
2909
2910 impl ParamTy {
2911     pub fn new(space: subst::ParamSpace,
2912                index: u32,
2913                name: ast::Name)
2914                -> ParamTy {
2915         ParamTy { space: space, idx: index, name: name }
2916     }
2917
2918     pub fn for_self() -> ParamTy {
2919         ParamTy::new(subst::SelfSpace, 0, special_idents::type_self.name)
2920     }
2921
2922     pub fn for_def(def: &TypeParameterDef) -> ParamTy {
2923         ParamTy::new(def.space, def.index, def.name)
2924     }
2925
2926     pub fn to_ty<'tcx>(self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
2927         ty::mk_param(tcx, self.space, self.idx, self.name)
2928     }
2929
2930     pub fn is_self(&self) -> bool {
2931         self.space == subst::SelfSpace && self.idx == 0
2932     }
2933 }
2934
2935 impl<'tcx> ItemSubsts<'tcx> {
2936     pub fn empty() -> ItemSubsts<'tcx> {
2937         ItemSubsts { substs: Substs::empty() }
2938     }
2939
2940     pub fn is_noop(&self) -> bool {
2941         self.substs.is_noop()
2942     }
2943 }
2944
2945 impl<'tcx> ParamBounds<'tcx> {
2946     pub fn empty() -> ParamBounds<'tcx> {
2947         ParamBounds {
2948             builtin_bounds: empty_builtin_bounds(),
2949             trait_bounds: Vec::new(),
2950             region_bounds: Vec::new(),
2951             projection_bounds: Vec::new(),
2952         }
2953     }
2954 }
2955
2956 // Type utilities
2957
2958 pub fn type_is_nil(ty: Ty) -> bool {
2959     match ty.sty {
2960         ty_tup(ref tys) => tys.is_empty(),
2961         _ => false
2962     }
2963 }
2964
2965 pub fn type_is_error(ty: Ty) -> bool {
2966     ty.flags.intersects(HAS_TY_ERR)
2967 }
2968
2969 pub fn type_needs_subst(ty: Ty) -> bool {
2970     ty.flags.intersects(NEEDS_SUBST)
2971 }
2972
2973 pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool {
2974     tref.substs.types.any(|&ty| type_is_error(ty))
2975 }
2976
2977 pub fn type_is_ty_var(ty: Ty) -> bool {
2978     match ty.sty {
2979         ty_infer(TyVar(_)) => true,
2980         _ => false
2981     }
2982 }
2983
2984 pub fn type_is_bool(ty: Ty) -> bool { ty.sty == ty_bool }
2985
2986 pub fn type_is_self(ty: Ty) -> bool {
2987     match ty.sty {
2988         ty_param(ref p) => p.space == subst::SelfSpace,
2989         _ => false
2990     }
2991 }
2992
2993 fn type_is_slice(ty: Ty) -> bool {
2994     match ty.sty {
2995         ty_ptr(mt) | ty_rptr(_, mt) => match mt.ty.sty {
2996             ty_vec(_, None) | ty_str => true,
2997             _ => false,
2998         },
2999         _ => false
3000     }
3001 }
3002
3003 pub fn type_is_vec(ty: Ty) -> bool {
3004     match ty.sty {
3005         ty_vec(..) => true,
3006         ty_ptr(mt{ty, ..}) | ty_rptr(_, mt{ty, ..}) |
3007         ty_uniq(ty) => match ty.sty {
3008             ty_vec(_, None) => true,
3009             _ => false
3010         },
3011         _ => false
3012     }
3013 }
3014
3015 pub fn type_is_structural(ty: Ty) -> bool {
3016     match ty.sty {
3017       ty_struct(..) | ty_tup(_) | ty_enum(..) |
3018       ty_vec(_, Some(_)) | ty_unboxed_closure(..) => true,
3019       _ => type_is_slice(ty) | type_is_trait(ty)
3020     }
3021 }
3022
3023 pub fn type_is_simd(cx: &ctxt, ty: Ty) -> bool {
3024     match ty.sty {
3025         ty_struct(did, _) => lookup_simd(cx, did),
3026         _ => false
3027     }
3028 }
3029
3030 pub fn sequence_element_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3031     match ty.sty {
3032         ty_vec(ty, _) => ty,
3033         ty_str => mk_mach_uint(cx, ast::TyU8),
3034         ty_open(ty) => sequence_element_type(cx, ty),
3035         _ => cx.sess.bug(format!("sequence_element_type called on non-sequence value: {}",
3036                                  ty_to_string(cx, ty))[]),
3037     }
3038 }
3039
3040 pub fn simd_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3041     match ty.sty {
3042         ty_struct(did, substs) => {
3043             let fields = lookup_struct_fields(cx, did);
3044             lookup_field_type(cx, did, fields[0].id, substs)
3045         }
3046         _ => panic!("simd_type called on invalid type")
3047     }
3048 }
3049
3050 pub fn simd_size(cx: &ctxt, ty: Ty) -> uint {
3051     match ty.sty {
3052         ty_struct(did, _) => {
3053             let fields = lookup_struct_fields(cx, did);
3054             fields.len()
3055         }
3056         _ => panic!("simd_size called on invalid type")
3057     }
3058 }
3059
3060 pub fn type_is_region_ptr(ty: Ty) -> bool {
3061     match ty.sty {
3062         ty_rptr(..) => true,
3063         _ => false
3064     }
3065 }
3066
3067 pub fn type_is_unsafe_ptr(ty: Ty) -> bool {
3068     match ty.sty {
3069       ty_ptr(_) => return true,
3070       _ => return false
3071     }
3072 }
3073
3074 pub fn type_is_unique(ty: Ty) -> bool {
3075     match ty.sty {
3076         ty_uniq(_) => match ty.sty {
3077             ty_trait(..) => false,
3078             _ => true
3079         },
3080         _ => false
3081     }
3082 }
3083
3084 /*
3085  A scalar type is one that denotes an atomic datum, with no sub-components.
3086  (A ty_ptr is scalar because it represents a non-managed pointer, so its
3087  contents are abstract to rustc.)
3088 */
3089 pub fn type_is_scalar(ty: Ty) -> bool {
3090     match ty.sty {
3091       ty_bool | ty_char | ty_int(_) | ty_float(_) | ty_uint(_) |
3092       ty_infer(IntVar(_)) | ty_infer(FloatVar(_)) |
3093       ty_bare_fn(..) | ty_ptr(_) => true,
3094       ty_tup(ref tys) if tys.is_empty() => true,
3095       _ => false
3096     }
3097 }
3098
3099 /// Returns true if this type is a floating point type and false otherwise.
3100 pub fn type_is_floating_point(ty: Ty) -> bool {
3101     match ty.sty {
3102         ty_float(_) => true,
3103         _ => false,
3104     }
3105 }
3106
3107 /// Type contents is how the type checker reasons about kinds.
3108 /// They track what kinds of things are found within a type.  You can
3109 /// think of them as kind of an "anti-kind".  They track the kinds of values
3110 /// and thinks that are contained in types.  Having a larger contents for
3111 /// a type tends to rule that type *out* from various kinds.  For example,
3112 /// a type that contains a reference is not sendable.
3113 ///
3114 /// The reason we compute type contents and not kinds is that it is
3115 /// easier for me (nmatsakis) to think about what is contained within
3116 /// a type than to think about what is *not* contained within a type.
3117 #[derive(Clone, Copy)]
3118 pub struct TypeContents {
3119     pub bits: u64
3120 }
3121
3122 macro_rules! def_type_content_sets {
3123     (mod $mname:ident { $($name:ident = $bits:expr),+ }) => {
3124         #[allow(non_snake_case)]
3125         mod $mname {
3126             use middle::ty::TypeContents;
3127             $(
3128                 #[allow(non_upper_case_globals)]
3129                 pub const $name: TypeContents = TypeContents { bits: $bits };
3130              )+
3131         }
3132     }
3133 }
3134
3135 def_type_content_sets! {
3136     mod TC {
3137         None                                = 0b0000_0000__0000_0000__0000,
3138
3139         // Things that are interior to the value (first nibble):
3140         InteriorUnsized                     = 0b0000_0000__0000_0000__0001,
3141         InteriorUnsafe                      = 0b0000_0000__0000_0000__0010,
3142         InteriorParam                       = 0b0000_0000__0000_0000__0100,
3143         // InteriorAll                         = 0b00000000__00000000__1111,
3144
3145         // Things that are owned by the value (second and third nibbles):
3146         OwnsOwned                           = 0b0000_0000__0000_0001__0000,
3147         OwnsDtor                            = 0b0000_0000__0000_0010__0000,
3148         OwnsManaged /* see [1] below */     = 0b0000_0000__0000_0100__0000,
3149         OwnsAll                             = 0b0000_0000__1111_1111__0000,
3150
3151         // Things that are reachable by the value in any way (fourth nibble):
3152         ReachesBorrowed                     = 0b0000_0010__0000_0000__0000,
3153         // ReachesManaged /* see [1] below */  = 0b0000_0100__0000_0000__0000,
3154         ReachesMutable                      = 0b0000_1000__0000_0000__0000,
3155         ReachesFfiUnsafe                    = 0b0010_0000__0000_0000__0000,
3156         ReachesAll                          = 0b0011_1111__0000_0000__0000,
3157
3158         // Things that mean drop glue is necessary
3159         NeedsDrop                           = 0b0000_0000__0000_0111__0000,
3160
3161         // Things that prevent values from being considered sized
3162         Nonsized                            = 0b0000_0000__0000_0000__0001,
3163
3164         // Bits to set when a managed value is encountered
3165         //
3166         // [1] Do not set the bits TC::OwnsManaged or
3167         //     TC::ReachesManaged directly, instead reference
3168         //     TC::Managed to set them both at once.
3169         Managed                             = 0b0000_0100__0000_0100__0000,
3170
3171         // All bits
3172         All                                 = 0b1111_1111__1111_1111__1111
3173     }
3174 }
3175
3176 impl TypeContents {
3177     pub fn when(&self, cond: bool) -> TypeContents {
3178         if cond {*self} else {TC::None}
3179     }
3180
3181     pub fn intersects(&self, tc: TypeContents) -> bool {
3182         (self.bits & tc.bits) != 0
3183     }
3184
3185     pub fn owns_managed(&self) -> bool {
3186         self.intersects(TC::OwnsManaged)
3187     }
3188
3189     pub fn owns_owned(&self) -> bool {
3190         self.intersects(TC::OwnsOwned)
3191     }
3192
3193     pub fn is_sized(&self, _: &ctxt) -> bool {
3194         !self.intersects(TC::Nonsized)
3195     }
3196
3197     pub fn interior_param(&self) -> bool {
3198         self.intersects(TC::InteriorParam)
3199     }
3200
3201     pub fn interior_unsafe(&self) -> bool {
3202         self.intersects(TC::InteriorUnsafe)
3203     }
3204
3205     pub fn interior_unsized(&self) -> bool {
3206         self.intersects(TC::InteriorUnsized)
3207     }
3208
3209     pub fn needs_drop(&self, _: &ctxt) -> bool {
3210         self.intersects(TC::NeedsDrop)
3211     }
3212
3213     /// Includes only those bits that still apply when indirected through a `Box` pointer
3214     pub fn owned_pointer(&self) -> TypeContents {
3215         TC::OwnsOwned | (
3216             *self & (TC::OwnsAll | TC::ReachesAll))
3217     }
3218
3219     /// Includes only those bits that still apply when indirected through a reference (`&`)
3220     pub fn reference(&self, bits: TypeContents) -> TypeContents {
3221         bits | (
3222             *self & TC::ReachesAll)
3223     }
3224
3225     /// Includes only those bits that still apply when indirected through a managed pointer (`@`)
3226     pub fn managed_pointer(&self) -> TypeContents {
3227         TC::Managed | (
3228             *self & TC::ReachesAll)
3229     }
3230
3231     /// Includes only those bits that still apply when indirected through an unsafe pointer (`*`)
3232     pub fn unsafe_pointer(&self) -> TypeContents {
3233         *self & TC::ReachesAll
3234     }
3235
3236     pub fn union<T, F>(v: &[T], mut f: F) -> TypeContents where
3237         F: FnMut(&T) -> TypeContents,
3238     {
3239         v.iter().fold(TC::None, |tc, ty| tc | f(ty))
3240     }
3241
3242     pub fn has_dtor(&self) -> bool {
3243         self.intersects(TC::OwnsDtor)
3244     }
3245 }
3246
3247 impl ops::BitOr for TypeContents {
3248     type Output = TypeContents;
3249
3250     fn bitor(self, other: TypeContents) -> TypeContents {
3251         TypeContents {bits: self.bits | other.bits}
3252     }
3253 }
3254
3255 impl ops::BitAnd for TypeContents {
3256     type Output = TypeContents;
3257
3258     fn bitand(self, other: TypeContents) -> TypeContents {
3259         TypeContents {bits: self.bits & other.bits}
3260     }
3261 }
3262
3263 impl ops::Sub for TypeContents {
3264     type Output = TypeContents;
3265
3266     fn sub(self, other: TypeContents) -> TypeContents {
3267         TypeContents {bits: self.bits & !other.bits}
3268     }
3269 }
3270
3271 impl fmt::Show for TypeContents {
3272     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3273         write!(f, "TypeContents({:b})", self.bits)
3274     }
3275 }
3276
3277 pub fn type_interior_is_unsafe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
3278     type_contents(cx, ty).interior_unsafe()
3279 }
3280
3281 pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
3282     return memoized(&cx.tc_cache, ty, |ty| {
3283         tc_ty(cx, ty, &mut FnvHashMap::new())
3284     });
3285
3286     fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
3287                    ty: Ty<'tcx>,
3288                    cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
3289     {
3290         // Subtle: Note that we are *not* using cx.tc_cache here but rather a
3291         // private cache for this walk.  This is needed in the case of cyclic
3292         // types like:
3293         //
3294         //     struct List { next: Box<Option<List>>, ... }
3295         //
3296         // When computing the type contents of such a type, we wind up deeply
3297         // recursing as we go.  So when we encounter the recursive reference
3298         // to List, we temporarily use TC::None as its contents.  Later we'll
3299         // patch up the cache with the correct value, once we've computed it
3300         // (this is basically a co-inductive process, if that helps).  So in
3301         // the end we'll compute TC::OwnsOwned, in this case.
3302         //
3303         // The problem is, as we are doing the computation, we will also
3304         // compute an *intermediate* contents for, e.g., Option<List> of
3305         // TC::None.  This is ok during the computation of List itself, but if
3306         // we stored this intermediate value into cx.tc_cache, then later
3307         // requests for the contents of Option<List> would also yield TC::None
3308         // which is incorrect.  This value was computed based on the crutch
3309         // value for the type contents of list.  The correct value is
3310         // TC::OwnsOwned.  This manifested as issue #4821.
3311         match cache.get(&ty) {
3312             Some(tc) => { return *tc; }
3313             None => {}
3314         }
3315         match cx.tc_cache.borrow().get(&ty) {    // Must check both caches!
3316             Some(tc) => { return *tc; }
3317             None => {}
3318         }
3319         cache.insert(ty, TC::None);
3320
3321         let result = match ty.sty {
3322             // uint and int are ffi-unsafe
3323             ty_uint(ast::TyU) | ty_int(ast::TyI) => {
3324                 TC::ReachesFfiUnsafe
3325             }
3326
3327             // Scalar and unique types are sendable, and durable
3328             ty_infer(ty::FreshIntTy(_)) |
3329             ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
3330             ty_bare_fn(..) | ty::ty_char => {
3331                 TC::None
3332             }
3333
3334             ty_uniq(typ) => {
3335                 TC::ReachesFfiUnsafe | match typ.sty {
3336                     ty_str => TC::OwnsOwned,
3337                     _ => tc_ty(cx, typ, cache).owned_pointer(),
3338                 }
3339             }
3340
3341             ty_trait(box TyTrait { ref bounds, .. }) => {
3342                 object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized
3343             }
3344
3345             ty_ptr(ref mt) => {
3346                 tc_ty(cx, mt.ty, cache).unsafe_pointer()
3347             }
3348
3349             ty_rptr(r, ref mt) => {
3350                 TC::ReachesFfiUnsafe | match mt.ty.sty {
3351                     ty_str => borrowed_contents(*r, ast::MutImmutable),
3352                     ty_vec(..) => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r,
3353                                                                                       mt.mutbl)),
3354                     _ => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r, mt.mutbl)),
3355                 }
3356             }
3357
3358             ty_vec(ty, Some(_)) => {
3359                 tc_ty(cx, ty, cache)
3360             }
3361
3362             ty_vec(ty, None) => {
3363                 tc_ty(cx, ty, cache) | TC::Nonsized
3364             }
3365             ty_str => TC::Nonsized,
3366
3367             ty_struct(did, substs) => {
3368                 let flds = struct_fields(cx, did, substs);
3369                 let mut res =
3370                     TypeContents::union(flds[],
3371                                         |f| tc_mt(cx, f.mt, cache));
3372
3373                 if !lookup_repr_hints(cx, did).contains(&attr::ReprExtern) {
3374                     res = res | TC::ReachesFfiUnsafe;
3375                 }
3376
3377                 if ty::has_dtor(cx, did) {
3378                     res = res | TC::OwnsDtor;
3379                 }
3380                 apply_lang_items(cx, did, res)
3381             }
3382
3383             ty_unboxed_closure(did, r, substs) => {
3384                 // FIXME(#14449): `borrowed_contents` below assumes `&mut`
3385                 // unboxed closure.
3386                 let param_env = ty::empty_parameter_environment(cx);
3387                 let upvars = unboxed_closure_upvars(&param_env, did, substs).unwrap();
3388                 TypeContents::union(upvars.as_slice(),
3389                                     |f| tc_ty(cx, f.ty, cache))
3390                     | borrowed_contents(*r, MutMutable)
3391             }
3392
3393             ty_tup(ref tys) => {
3394                 TypeContents::union(tys[],
3395                                     |ty| tc_ty(cx, *ty, cache))
3396             }
3397
3398             ty_enum(did, substs) => {
3399                 let variants = substd_enum_variants(cx, did, substs);
3400                 let mut res =
3401                     TypeContents::union(variants[], |variant| {
3402                         TypeContents::union(variant.args[],
3403                                             |arg_ty| {
3404                             tc_ty(cx, *arg_ty, cache)
3405                         })
3406                     });
3407
3408                 if ty::has_dtor(cx, did) {
3409                     res = res | TC::OwnsDtor;
3410                 }
3411
3412                 if variants.len() != 0 {
3413                     let repr_hints = lookup_repr_hints(cx, did);
3414                     if repr_hints.len() > 1 {
3415                         // this is an error later on, but this type isn't safe
3416                         res = res | TC::ReachesFfiUnsafe;
3417                     }
3418
3419                     match repr_hints.get(0) {
3420                         Some(h) => if !h.is_ffi_safe() {
3421                             res = res | TC::ReachesFfiUnsafe;
3422                         },
3423                         // ReprAny
3424                         None => {
3425                             res = res | TC::ReachesFfiUnsafe;
3426
3427                             // We allow ReprAny enums if they are eligible for
3428                             // the nullable pointer optimization and the
3429                             // contained type is an `extern fn`
3430
3431                             if variants.len() == 2 {
3432                                 let mut data_idx = 0;
3433
3434                                 if variants[0].args.len() == 0 {
3435                                     data_idx = 1;
3436                                 }
3437
3438                                 if variants[data_idx].args.len() == 1 {
3439                                     match variants[data_idx].args[0].sty {
3440                                         ty_bare_fn(..) => { res = res - TC::ReachesFfiUnsafe; }
3441                                         _ => { }
3442                                     }
3443                                 }
3444                             }
3445                         }
3446                     }
3447                 }
3448
3449
3450                 apply_lang_items(cx, did, res)
3451             }
3452
3453             ty_projection(..) |
3454             ty_param(_) => {
3455                 TC::All
3456             }
3457
3458             ty_open(ty) => {
3459                 let result = tc_ty(cx, ty, cache);
3460                 assert!(!result.is_sized(cx));
3461                 result.unsafe_pointer() | TC::Nonsized
3462             }
3463
3464             ty_infer(_) |
3465             ty_err => {
3466                 cx.sess.bug("asked to compute contents of error type");
3467             }
3468         };
3469
3470         cache.insert(ty, result);
3471         result
3472     }
3473
3474     fn tc_mt<'tcx>(cx: &ctxt<'tcx>,
3475                    mt: mt<'tcx>,
3476                    cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
3477     {
3478         let mc = TC::ReachesMutable.when(mt.mutbl == MutMutable);
3479         mc | tc_ty(cx, mt.ty, cache)
3480     }
3481
3482     fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents)
3483                         -> TypeContents {
3484         if Some(did) == cx.lang_items.managed_bound() {
3485             tc | TC::Managed
3486         } else if Some(did) == cx.lang_items.unsafe_type() {
3487             tc | TC::InteriorUnsafe
3488         } else {
3489             tc
3490         }
3491     }
3492
3493     /// Type contents due to containing a reference with the region `region` and borrow kind `bk`
3494     fn borrowed_contents(region: ty::Region,
3495                          mutbl: ast::Mutability)
3496                          -> TypeContents {
3497         let b = match mutbl {
3498             ast::MutMutable => TC::ReachesMutable,
3499             ast::MutImmutable => TC::None,
3500         };
3501         b | (TC::ReachesBorrowed).when(region != ty::ReStatic)
3502     }
3503
3504     fn object_contents(bounds: &ExistentialBounds) -> TypeContents {
3505         // These are the type contents of the (opaque) interior. We
3506         // make no assumptions (other than that it cannot have an
3507         // in-scope type parameter within, which makes no sense).
3508         let mut tc = TC::All - TC::InteriorParam;
3509         for bound in bounds.builtin_bounds.iter() {
3510             tc = tc - match bound {
3511                 BoundSync | BoundSend | BoundCopy => TC::None,
3512                 BoundSized => TC::Nonsized,
3513             };
3514         }
3515         return tc;
3516     }
3517 }
3518
3519 fn type_impls_bound<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
3520                              cache: &RefCell<HashMap<Ty<'tcx>,bool>>,
3521                              ty: Ty<'tcx>,
3522                              bound: ty::BuiltinBound,
3523                              span: Span)
3524                              -> bool
3525 {
3526     assert!(!ty::type_needs_infer(ty));
3527
3528     if !type_has_params(ty) && !type_has_self(ty) {
3529         match cache.borrow().get(&ty) {
3530             None => {}
3531             Some(&result) => {
3532                 debug!("type_impls_bound({}, {}) = {} (cached)",
3533                        ty.repr(param_env.tcx),
3534                        bound,
3535                        result);
3536                 return result
3537             }
3538         }
3539     }
3540
3541     let infcx = infer::new_infer_ctxt(param_env.tcx);
3542
3543     let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, ty, bound, span);
3544
3545     debug!("type_impls_bound({}, {}) = {}",
3546            ty.repr(param_env.tcx),
3547            bound,
3548            is_impld);
3549
3550     if !type_has_params(ty) && !type_has_self(ty) {
3551         let old_value = cache.borrow_mut().insert(ty, is_impld);
3552         assert!(old_value.is_none());
3553     }
3554
3555     is_impld
3556 }
3557
3558 pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
3559                                       span: Span,
3560                                       ty: Ty<'tcx>)
3561                                       -> bool
3562 {
3563     let tcx = param_env.tcx;
3564     !type_impls_bound(param_env, &tcx.type_impls_copy_cache, ty, ty::BoundCopy, span)
3565 }
3566
3567 pub fn type_is_sized<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
3568                               span: Span,
3569                               ty: Ty<'tcx>)
3570                               -> bool
3571 {
3572     let tcx = param_env.tcx;
3573     type_impls_bound(param_env, &tcx.type_impls_sized_cache, ty, ty::BoundSized, span)
3574 }
3575
3576 pub fn is_ffi_safe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
3577     !type_contents(cx, ty).intersects(TC::ReachesFfiUnsafe)
3578 }
3579
3580 // True if instantiating an instance of `r_ty` requires an instance of `r_ty`.
3581 pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
3582     fn type_requires<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
3583                            r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
3584         debug!("type_requires({}, {})?",
3585                ::util::ppaux::ty_to_string(cx, r_ty),
3586                ::util::ppaux::ty_to_string(cx, ty));
3587
3588         let r = r_ty == ty || subtypes_require(cx, seen, r_ty, ty);
3589
3590         debug!("type_requires({}, {})? {}",
3591                ::util::ppaux::ty_to_string(cx, r_ty),
3592                ::util::ppaux::ty_to_string(cx, ty),
3593                r);
3594         return r;
3595     }
3596
3597     fn subtypes_require<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
3598                               r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
3599         debug!("subtypes_require({}, {})?",
3600                ::util::ppaux::ty_to_string(cx, r_ty),
3601                ::util::ppaux::ty_to_string(cx, ty));
3602
3603         let r = match ty.sty {
3604             // fixed length vectors need special treatment compared to
3605             // normal vectors, since they don't necessarily have the
3606             // possibility to have length zero.
3607             ty_vec(_, Some(0)) => false, // don't need no contents
3608             ty_vec(ty, Some(_)) => type_requires(cx, seen, r_ty, ty),
3609
3610             ty_bool |
3611             ty_char |
3612             ty_int(_) |
3613             ty_uint(_) |
3614             ty_float(_) |
3615             ty_str |
3616             ty_bare_fn(..) |
3617             ty_param(_) |
3618             ty_projection(_) |
3619             ty_vec(_, None) => {
3620                 false
3621             }
3622             ty_uniq(typ) | ty_open(typ) => {
3623                 type_requires(cx, seen, r_ty, typ)
3624             }
3625             ty_rptr(_, ref mt) => {
3626                 type_requires(cx, seen, r_ty, mt.ty)
3627             }
3628
3629             ty_ptr(..) => {
3630                 false           // unsafe ptrs can always be NULL
3631             }
3632
3633             ty_trait(..) => {
3634                 false
3635             }
3636
3637             ty_struct(ref did, _) if seen.contains(did) => {
3638                 false
3639             }
3640
3641             ty_struct(did, substs) => {
3642                 seen.push(did);
3643                 let fields = struct_fields(cx, did, substs);
3644                 let r = fields.iter().any(|f| type_requires(cx, seen, r_ty, f.mt.ty));
3645                 seen.pop().unwrap();
3646                 r
3647             }
3648
3649             ty_err |
3650             ty_infer(_) |
3651             ty_unboxed_closure(..) => {
3652                 // this check is run on type definitions, so we don't expect to see
3653                 // inference by-products or unboxed closure types
3654                 cx.sess.bug(format!("requires check invoked on inapplicable type: {}", ty)[])
3655             }
3656
3657             ty_tup(ref ts) => {
3658                 ts.iter().any(|ty| type_requires(cx, seen, r_ty, *ty))
3659             }
3660
3661             ty_enum(ref did, _) if seen.contains(did) => {
3662                 false
3663             }
3664
3665             ty_enum(did, substs) => {
3666                 seen.push(did);
3667                 let vs = enum_variants(cx, did);
3668                 let r = !vs.is_empty() && vs.iter().all(|variant| {
3669                     variant.args.iter().any(|aty| {
3670                         let sty = aty.subst(cx, substs);
3671                         type_requires(cx, seen, r_ty, sty)
3672                     })
3673                 });
3674                 seen.pop().unwrap();
3675                 r
3676             }
3677         };
3678
3679         debug!("subtypes_require({}, {})? {}",
3680                ::util::ppaux::ty_to_string(cx, r_ty),
3681                ::util::ppaux::ty_to_string(cx, ty),
3682                r);
3683
3684         return r;
3685     }
3686
3687     let mut seen = Vec::new();
3688     !subtypes_require(cx, &mut seen, r_ty, r_ty)
3689 }
3690
3691 /// Describes whether a type is representable. For types that are not
3692 /// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
3693 /// distinguish between types that are recursive with themselves and types that
3694 /// contain a different recursive type. These cases can therefore be treated
3695 /// differently when reporting errors.
3696 ///
3697 /// The ordering of the cases is significant. They are sorted so that cmp::max
3698 /// will keep the "more erroneous" of two values.
3699 #[derive(Copy, PartialOrd, Ord, Eq, PartialEq, Show)]
3700 pub enum Representability {
3701     Representable,
3702     ContainsRecursive,
3703     SelfRecursive,
3704 }
3705
3706 /// Check whether a type is representable. This means it cannot contain unboxed
3707 /// structural recursion. This check is needed for structs and enums.
3708 pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
3709                                    -> Representability {
3710
3711     // Iterate until something non-representable is found
3712     fn find_nonrepresentable<'tcx, It: Iterator<Item=Ty<'tcx>>>(cx: &ctxt<'tcx>, sp: Span,
3713                                                                 seen: &mut Vec<Ty<'tcx>>,
3714                                                                 iter: It)
3715                                                                 -> Representability {
3716         iter.fold(Representable,
3717                   |r, ty| cmp::max(r, is_type_structurally_recursive(cx, sp, seen, ty)))
3718     }
3719
3720     fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
3721                                        seen: &mut Vec<Ty<'tcx>>, ty: Ty<'tcx>)
3722                                        -> Representability {
3723         match ty.sty {
3724             ty_tup(ref ts) => {
3725                 find_nonrepresentable(cx, sp, seen, ts.iter().map(|ty| *ty))
3726             }
3727             // Fixed-length vectors.
3728             // FIXME(#11924) Behavior undecided for zero-length vectors.
3729             ty_vec(ty, Some(_)) => {
3730                 is_type_structurally_recursive(cx, sp, seen, ty)
3731             }
3732             ty_struct(did, substs) => {
3733                 let fields = struct_fields(cx, did, substs);
3734                 find_nonrepresentable(cx, sp, seen, fields.iter().map(|f| f.mt.ty))
3735             }
3736             ty_enum(did, substs) => {
3737                 let vs = enum_variants(cx, did);
3738                 let iter = vs.iter()
3739                     .flat_map(|variant| { variant.args.iter() })
3740                     .map(|aty| { aty.subst_spanned(cx, substs, Some(sp)) });
3741
3742                 find_nonrepresentable(cx, sp, seen, iter)
3743             }
3744             ty_unboxed_closure(..) => {
3745                 // this check is run on type definitions, so we don't expect to see
3746                 // unboxed closure types
3747                 cx.sess.bug(format!("requires check invoked on inapplicable type: {}", ty)[])
3748             }
3749             _ => Representable,
3750         }
3751     }
3752
3753     fn same_struct_or_enum_def_id(ty: Ty, did: DefId) -> bool {
3754         match ty.sty {
3755             ty_struct(ty_did, _) | ty_enum(ty_did, _) => {
3756                  ty_did == did
3757             }
3758             _ => false
3759         }
3760     }
3761
3762     fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
3763         match (&a.sty, &b.sty) {
3764             (&ty_struct(did_a, ref substs_a), &ty_struct(did_b, ref substs_b)) |
3765             (&ty_enum(did_a, ref substs_a), &ty_enum(did_b, ref substs_b)) => {
3766                 if did_a != did_b {
3767                     return false;
3768                 }
3769
3770                 let types_a = substs_a.types.get_slice(subst::TypeSpace);
3771                 let types_b = substs_b.types.get_slice(subst::TypeSpace);
3772
3773                 let pairs = types_a.iter().zip(types_b.iter());
3774
3775                 pairs.all(|(&a, &b)| same_type(a, b))
3776             }
3777             _ => {
3778                 a == b
3779             }
3780         }
3781     }
3782
3783     // Does the type `ty` directly (without indirection through a pointer)
3784     // contain any types on stack `seen`?
3785     fn is_type_structurally_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
3786                                             seen: &mut Vec<Ty<'tcx>>,
3787                                             ty: Ty<'tcx>) -> Representability {
3788         debug!("is_type_structurally_recursive: {}",
3789                ::util::ppaux::ty_to_string(cx, ty));
3790
3791         match ty.sty {
3792             ty_struct(did, _) | ty_enum(did, _) => {
3793                 {
3794                     // Iterate through stack of previously seen types.
3795                     let mut iter = seen.iter();
3796
3797                     // The first item in `seen` is the type we are actually curious about.
3798                     // We want to return SelfRecursive if this type contains itself.
3799                     // It is important that we DON'T take generic parameters into account
3800                     // for this check, so that Bar<T> in this example counts as SelfRecursive:
3801                     //
3802                     // struct Foo;
3803                     // struct Bar<T> { x: Bar<Foo> }
3804
3805                     match iter.next() {
3806                         Some(&seen_type) => {
3807                             if same_struct_or_enum_def_id(seen_type, did) {
3808                                 debug!("SelfRecursive: {} contains {}",
3809                                        ::util::ppaux::ty_to_string(cx, seen_type),
3810                                        ::util::ppaux::ty_to_string(cx, ty));
3811                                 return SelfRecursive;
3812                             }
3813                         }
3814                         None => {}
3815                     }
3816
3817                     // We also need to know whether the first item contains other types that
3818                     // are structurally recursive. If we don't catch this case, we will recurse
3819                     // infinitely for some inputs.
3820                     //
3821                     // It is important that we DO take generic parameters into account here,
3822                     // so that code like this is considered SelfRecursive, not ContainsRecursive:
3823                     //
3824                     // struct Foo { Option<Option<Foo>> }
3825
3826                     for &seen_type in iter {
3827                         if same_type(ty, seen_type) {
3828                             debug!("ContainsRecursive: {} contains {}",
3829                                    ::util::ppaux::ty_to_string(cx, seen_type),
3830                                    ::util::ppaux::ty_to_string(cx, ty));
3831                             return ContainsRecursive;
3832                         }
3833                     }
3834                 }
3835
3836                 // For structs and enums, track all previously seen types by pushing them
3837                 // onto the 'seen' stack.
3838                 seen.push(ty);
3839                 let out = are_inner_types_recursive(cx, sp, seen, ty);
3840                 seen.pop();
3841                 out
3842             }
3843             _ => {
3844                 // No need to push in other cases.
3845                 are_inner_types_recursive(cx, sp, seen, ty)
3846             }
3847         }
3848     }
3849
3850     debug!("is_type_representable: {}",
3851            ::util::ppaux::ty_to_string(cx, ty));
3852
3853     // To avoid a stack overflow when checking an enum variant or struct that
3854     // contains a different, structurally recursive type, maintain a stack
3855     // of seen types and check recursion for each of them (issues #3008, #3779).
3856     let mut seen: Vec<Ty> = Vec::new();
3857     let r = is_type_structurally_recursive(cx, sp, &mut seen, ty);
3858     debug!("is_type_representable: {} is {}",
3859            ::util::ppaux::ty_to_string(cx, ty), r);
3860     r
3861 }
3862
3863 pub fn type_is_trait(ty: Ty) -> bool {
3864     type_trait_info(ty).is_some()
3865 }
3866
3867 pub fn type_trait_info<'tcx>(ty: Ty<'tcx>) -> Option<&'tcx TyTrait<'tcx>> {
3868     match ty.sty {
3869         ty_uniq(ty) | ty_rptr(_, mt { ty, ..}) | ty_ptr(mt { ty, ..}) => match ty.sty {
3870             ty_trait(ref t) => Some(&**t),
3871             _ => None
3872         },
3873         ty_trait(ref t) => Some(&**t),
3874         _ => None
3875     }
3876 }
3877
3878 pub fn type_is_integral(ty: Ty) -> bool {
3879     match ty.sty {
3880       ty_infer(IntVar(_)) | ty_int(_) | ty_uint(_) => true,
3881       _ => false
3882     }
3883 }
3884
3885 pub fn type_is_fresh(ty: Ty) -> bool {
3886     match ty.sty {
3887       ty_infer(FreshTy(_)) => true,
3888       ty_infer(FreshIntTy(_)) => true,
3889       _ => false
3890     }
3891 }
3892
3893 pub fn type_is_uint(ty: Ty) -> bool {
3894     match ty.sty {
3895       ty_infer(IntVar(_)) | ty_uint(ast::TyU) => true,
3896       _ => false
3897     }
3898 }
3899
3900 pub fn type_is_char(ty: Ty) -> bool {
3901     match ty.sty {
3902         ty_char => true,
3903         _ => false
3904     }
3905 }
3906
3907 pub fn type_is_bare_fn(ty: Ty) -> bool {
3908     match ty.sty {
3909         ty_bare_fn(..) => true,
3910         _ => false
3911     }
3912 }
3913
3914 pub fn type_is_bare_fn_item(ty: Ty) -> bool {
3915     match ty.sty {
3916         ty_bare_fn(Some(_), _) => true,
3917         _ => false
3918     }
3919 }
3920
3921 pub fn type_is_fp(ty: Ty) -> bool {
3922     match ty.sty {
3923       ty_infer(FloatVar(_)) | ty_float(_) => true,
3924       _ => false
3925     }
3926 }
3927
3928 pub fn type_is_numeric(ty: Ty) -> bool {
3929     return type_is_integral(ty) || type_is_fp(ty);
3930 }
3931
3932 pub fn type_is_signed(ty: Ty) -> bool {
3933     match ty.sty {
3934       ty_int(_) => true,
3935       _ => false
3936     }
3937 }
3938
3939 pub fn type_is_machine(ty: Ty) -> bool {
3940     match ty.sty {
3941         ty_int(ast::TyI) | ty_uint(ast::TyU) => false,
3942         ty_int(..) | ty_uint(..) | ty_float(..) => true,
3943         _ => false
3944     }
3945 }
3946
3947 // Whether a type is enum like, that is an enum type with only nullary
3948 // constructors
3949 pub fn type_is_c_like_enum(cx: &ctxt, ty: Ty) -> bool {
3950     match ty.sty {
3951         ty_enum(did, _) => {
3952             let variants = enum_variants(cx, did);
3953             if variants.len() == 0 {
3954                 false
3955             } else {
3956                 variants.iter().all(|v| v.args.len() == 0)
3957             }
3958         }
3959         _ => false
3960     }
3961 }
3962
3963 // Returns the type and mutability of *ty.
3964 //
3965 // The parameter `explicit` indicates if this is an *explicit* dereference.
3966 // Some types---notably unsafe ptrs---can only be dereferenced explicitly.
3967 pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
3968     match ty.sty {
3969         ty_uniq(ty) => {
3970             Some(mt {
3971                 ty: ty,
3972                 mutbl: ast::MutImmutable,
3973             })
3974         },
3975         ty_rptr(_, mt) => Some(mt),
3976         ty_ptr(mt) if explicit => Some(mt),
3977         _ => None
3978     }
3979 }
3980
3981 pub fn close_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
3982     match ty.sty {
3983         ty_open(ty) => mk_rptr(cx, cx.mk_region(ReStatic), mt {ty: ty, mutbl:ast::MutImmutable}),
3984         _ => cx.sess.bug(format!("Trying to close a non-open type {}",
3985                                  ty_to_string(cx, ty))[])
3986     }
3987 }
3988
3989 pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
3990     match ty.sty {
3991         ty_uniq(ty) => ty,
3992         ty_rptr(_, mt) |ty_ptr(mt) => mt.ty,
3993         _ => ty
3994     }
3995 }
3996
3997 // Extract the unsized type in an open type (or just return ty if it is not open).
3998 pub fn unopen_type<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
3999     match ty.sty {
4000         ty_open(ty) => ty,
4001         _ => ty
4002     }
4003 }
4004
4005 // Returns the type of ty[i]
4006 pub fn index<'tcx>(ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
4007     match ty.sty {
4008         ty_vec(ty, _) => Some(ty),
4009         _ => None
4010     }
4011 }
4012
4013 // Returns the type of elements contained within an 'array-like' type.
4014 // This is exactly the same as the above, except it supports strings,
4015 // which can't actually be indexed.
4016 pub fn array_element_ty<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
4017     match ty.sty {
4018         ty_vec(ty, _) => Some(ty),
4019         ty_str => Some(tcx.types.u8),
4020         _ => None
4021     }
4022 }
4023
4024 /// Returns the type of element at index `i` in tuple or tuple-like type `t`.
4025 /// For an enum `t`, `variant` is None only if `t` is a univariant enum.
4026 pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>,
4027                                    ty: Ty<'tcx>,
4028                                    i: uint,
4029                                    variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
4030
4031     match (&ty.sty, variant) {
4032         (&ty_tup(ref v), None) => v.get(i).map(|&t| t),
4033
4034
4035         (&ty_struct(def_id, substs), None) => lookup_struct_fields(cx, def_id)
4036             .get(i)
4037             .map(|&t|lookup_item_type(cx, t.id).ty.subst(cx, substs)),
4038
4039         (&ty_enum(def_id, substs), Some(variant_def_id)) => {
4040             let variant_info = enum_variant_with_id(cx, def_id, variant_def_id);
4041             variant_info.args.get(i).map(|t|t.subst(cx, substs))
4042         }
4043
4044         (&ty_enum(def_id, substs), None) => {
4045             assert!(enum_is_univariant(cx, def_id));
4046             let enum_variants = enum_variants(cx, def_id);
4047             let variant_info = &(*enum_variants)[0];
4048             variant_info.args.get(i).map(|t|t.subst(cx, substs))
4049         }
4050
4051         _ => None
4052     }
4053 }
4054
4055 /// Returns the type of element at field `n` in struct or struct-like type `t`.
4056 /// For an enum `t`, `variant` must be some def id.
4057 pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>,
4058                               ty: Ty<'tcx>,
4059                               n: ast::Name,
4060                               variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
4061
4062     match (&ty.sty, variant) {
4063         (&ty_struct(def_id, substs), None) => {
4064             let r = lookup_struct_fields(cx, def_id);
4065             r.iter().find(|f| f.name == n)
4066                 .map(|&f| lookup_field_type(cx, def_id, f.id, substs))
4067         }
4068         (&ty_enum(def_id, substs), Some(variant_def_id)) => {
4069             let variant_info = enum_variant_with_id(cx, def_id, variant_def_id);
4070             variant_info.arg_names.as_ref()
4071                 .expect("must have struct enum variant if accessing a named fields")
4072                 .iter().zip(variant_info.args.iter())
4073                 .find(|&(ident, _)| ident.name == n)
4074                 .map(|(_ident, arg_t)| arg_t.subst(cx, substs))
4075         }
4076         _ => None
4077     }
4078 }
4079
4080 pub fn node_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
4081                                   -> Rc<ty::TraitRef<'tcx>> {
4082     match cx.trait_refs.borrow().get(&id) {
4083         Some(ty) => ty.clone(),
4084         None => cx.sess.bug(
4085             format!("node_id_to_trait_ref: no trait ref for node `{}`",
4086                     cx.map.node_to_string(id))[])
4087     }
4088 }
4089
4090 pub fn try_node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Option<Ty<'tcx>> {
4091     cx.node_types.borrow().get(&id).cloned()
4092 }
4093
4094 pub fn node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Ty<'tcx> {
4095     match try_node_id_to_type(cx, id) {
4096        Some(ty) => ty,
4097        None => cx.sess.bug(
4098            format!("node_id_to_type: no type for node `{}`",
4099                    cx.map.node_to_string(id))[])
4100     }
4101 }
4102
4103 pub fn node_id_to_type_opt<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Option<Ty<'tcx>> {
4104     match cx.node_types.borrow().get(&id) {
4105        Some(&ty) => Some(ty),
4106        None => None
4107     }
4108 }
4109
4110 pub fn node_id_item_substs<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> ItemSubsts<'tcx> {
4111     match cx.item_substs.borrow().get(&id) {
4112       None => ItemSubsts::empty(),
4113       Some(ts) => ts.clone(),
4114     }
4115 }
4116
4117 pub fn fn_is_variadic(fty: Ty) -> bool {
4118     match fty.sty {
4119         ty_bare_fn(_, ref f) => f.sig.0.variadic,
4120         ref s => {
4121             panic!("fn_is_variadic() called on non-fn type: {}", s)
4122         }
4123     }
4124 }
4125
4126 pub fn ty_fn_sig<'tcx>(fty: Ty<'tcx>) -> &'tcx PolyFnSig<'tcx> {
4127     match fty.sty {
4128         ty_bare_fn(_, ref f) => &f.sig,
4129         ref s => {
4130             panic!("ty_fn_sig() called on non-fn type: {}", s)
4131         }
4132     }
4133 }
4134
4135 /// Returns the ABI of the given function.
4136 pub fn ty_fn_abi(fty: Ty) -> abi::Abi {
4137     match fty.sty {
4138         ty_bare_fn(_, ref f) => f.abi,
4139         _ => panic!("ty_fn_abi() called on non-fn type"),
4140     }
4141 }
4142
4143 // Type accessors for substructures of types
4144 pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> &'tcx [Ty<'tcx>] {
4145     ty_fn_sig(fty).0.inputs.as_slice()
4146 }
4147
4148 pub fn ty_closure_store(fty: Ty) -> TraitStore {
4149     match fty.sty {
4150         ty_unboxed_closure(..) => {
4151             // Close enough for the purposes of all the callers of this
4152             // function (which is soon to be deprecated anyhow).
4153             UniqTraitStore
4154         }
4155         ref s => {
4156             panic!("ty_closure_store() called on non-closure type: {}", s)
4157         }
4158     }
4159 }
4160
4161 pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> FnOutput<'tcx> {
4162     match fty.sty {
4163         ty_bare_fn(_, ref f) => f.sig.0.output,
4164         ref s => {
4165             panic!("ty_fn_ret() called on non-fn type: {}", s)
4166         }
4167     }
4168 }
4169
4170 pub fn is_fn_ty(fty: Ty) -> bool {
4171     match fty.sty {
4172         ty_bare_fn(..) => true,
4173         _ => false
4174     }
4175 }
4176
4177 pub fn ty_region(tcx: &ctxt,
4178                  span: Span,
4179                  ty: Ty) -> Region {
4180     match ty.sty {
4181         ty_rptr(r, _) => *r,
4182         ref s => {
4183             tcx.sess.span_bug(
4184                 span,
4185                 format!("ty_region() invoked on an inappropriate ty: {}",
4186                         s)[]);
4187         }
4188     }
4189 }
4190
4191 pub fn free_region_from_def(free_id: ast::NodeId, def: &RegionParameterDef)
4192     -> ty::Region
4193 {
4194     ty::ReFree(ty::FreeRegion { scope: region::CodeExtent::from_node_id(free_id),
4195                                 bound_region: ty::BrNamed(def.def_id,
4196                                                           def.name) })
4197 }
4198
4199 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
4200 // doesn't provide type parameter substitutions.
4201 pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> {
4202     return node_id_to_type(cx, pat.id);
4203 }
4204
4205
4206 // Returns the type of an expression as a monotype.
4207 //
4208 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression.  That is, in
4209 // some cases, we insert `AutoAdjustment` annotations such as auto-deref or
4210 // auto-ref.  The type returned by this function does not consider such
4211 // adjustments.  See `expr_ty_adjusted()` instead.
4212 //
4213 // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
4214 // ask for the type of "id" in "id(3)", it will return "fn(&int) -> int"
4215 // instead of "fn(ty) -> T with T = int".
4216 pub fn expr_ty<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
4217     return node_id_to_type(cx, expr.id);
4218 }
4219
4220 pub fn expr_ty_opt<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Option<Ty<'tcx>> {
4221     return node_id_to_type_opt(cx, expr.id);
4222 }
4223
4224 /// Returns the type of `expr`, considering any `AutoAdjustment`
4225 /// entry recorded for that expression.
4226 ///
4227 /// It would almost certainly be better to store the adjusted ty in with
4228 /// the `AutoAdjustment`, but I opted not to do this because it would
4229 /// require serializing and deserializing the type and, although that's not
4230 /// hard to do, I just hate that code so much I didn't want to touch it
4231 /// unless it was to fix it properly, which seemed a distraction from the
4232 /// task at hand! -nmatsakis
4233 pub fn expr_ty_adjusted<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
4234     adjust_ty(cx, expr.span, expr.id, expr_ty(cx, expr),
4235               cx.adjustments.borrow().get(&expr.id),
4236               |method_call| cx.method_map.borrow().get(&method_call).map(|method| method.ty))
4237 }
4238
4239 pub fn expr_span(cx: &ctxt, id: NodeId) -> Span {
4240     match cx.map.find(id) {
4241         Some(ast_map::NodeExpr(e)) => {
4242             e.span
4243         }
4244         Some(f) => {
4245             cx.sess.bug(format!("Node id {} is not an expr: {}",
4246                                 id,
4247                                 f)[]);
4248         }
4249         None => {
4250             cx.sess.bug(format!("Node id {} is not present \
4251                                 in the node map", id)[]);
4252         }
4253     }
4254 }
4255
4256 pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString {
4257     match cx.map.find(id) {
4258         Some(ast_map::NodeLocal(pat)) => {
4259             match pat.node {
4260                 ast::PatIdent(_, ref path1, _) => {
4261                     token::get_ident(path1.node)
4262                 }
4263                 _ => {
4264                     cx.sess.bug(
4265                         format!("Variable id {} maps to {}, not local",
4266                                 id,
4267                                 pat)[]);
4268                 }
4269             }
4270         }
4271         r => {
4272             cx.sess.bug(format!("Variable id {} maps to {}, not local",
4273                                 id,
4274                                 r)[]);
4275         }
4276     }
4277 }
4278
4279 /// See `expr_ty_adjusted`
4280 pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
4281                           span: Span,
4282                           expr_id: ast::NodeId,
4283                           unadjusted_ty: Ty<'tcx>,
4284                           adjustment: Option<&AutoAdjustment<'tcx>>,
4285                           mut method_type: F)
4286                           -> Ty<'tcx> where
4287     F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
4288 {
4289     if let ty_err = unadjusted_ty.sty {
4290         return unadjusted_ty;
4291     }
4292
4293     return match adjustment {
4294         Some(adjustment) => {
4295             match *adjustment {
4296                 AdjustReifyFnPointer(_) => {
4297                     match unadjusted_ty.sty {
4298                         ty::ty_bare_fn(Some(_), b) => {
4299                             ty::mk_bare_fn(cx, None, b)
4300                         }
4301                         ref b => {
4302                             cx.sess.bug(
4303                                 format!("AdjustReifyFnPointer adjustment on non-fn-item: \
4304                                          {}",
4305                                         b)[]);
4306                         }
4307                     }
4308                 }
4309
4310                 AdjustDerefRef(ref adj) => {
4311                     let mut adjusted_ty = unadjusted_ty;
4312
4313                     if !ty::type_is_error(adjusted_ty) {
4314                         for i in range(0, adj.autoderefs) {
4315                             let method_call = MethodCall::autoderef(expr_id, i);
4316                             match method_type(method_call) {
4317                                 Some(method_ty) => {
4318                                     if let ty::FnConverging(result_type) = ty_fn_ret(method_ty) {
4319                                         adjusted_ty = result_type;
4320                                     }
4321                                 }
4322                                 None => {}
4323                             }
4324                             match deref(adjusted_ty, true) {
4325                                 Some(mt) => { adjusted_ty = mt.ty; }
4326                                 None => {
4327                                     cx.sess.span_bug(
4328                                         span,
4329                                         format!("the {}th autoderef failed: \
4330                                                 {}",
4331                                                 i,
4332                                                 ty_to_string(cx, adjusted_ty))
4333                                                           []);
4334                                 }
4335                             }
4336                         }
4337                     }
4338
4339                     adjust_ty_for_autoref(cx, span, adjusted_ty, adj.autoref.as_ref())
4340                 }
4341             }
4342         }
4343         None => unadjusted_ty
4344     };
4345 }
4346
4347 pub fn adjust_ty_for_autoref<'tcx>(cx: &ctxt<'tcx>,
4348                                    span: Span,
4349                                    ty: Ty<'tcx>,
4350                                    autoref: Option<&AutoRef<'tcx>>)
4351                                    -> Ty<'tcx>
4352 {
4353     match autoref {
4354         None => ty,
4355
4356         Some(&AutoPtr(r, m, ref a)) => {
4357             let adjusted_ty = match a {
4358                 &Some(box ref a) => adjust_ty_for_autoref(cx, span, ty, Some(a)),
4359                 &None => ty
4360             };
4361             mk_rptr(cx, cx.mk_region(r), mt {
4362                 ty: adjusted_ty,
4363                 mutbl: m
4364             })
4365         }
4366
4367         Some(&AutoUnsafe(m, ref a)) => {
4368             let adjusted_ty = match a {
4369                 &Some(box ref a) => adjust_ty_for_autoref(cx, span, ty, Some(a)),
4370                 &None => ty
4371             };
4372             mk_ptr(cx, mt {ty: adjusted_ty, mutbl: m})
4373         }
4374
4375         Some(&AutoUnsize(ref k)) => unsize_ty(cx, ty, k, span),
4376
4377         Some(&AutoUnsizeUniq(ref k)) => ty::mk_uniq(cx, unsize_ty(cx, ty, k, span)),
4378     }
4379 }
4380
4381 // Take a sized type and a sizing adjustment and produce an unsized version of
4382 // the type.
4383 pub fn unsize_ty<'tcx>(cx: &ctxt<'tcx>,
4384                        ty: Ty<'tcx>,
4385                        kind: &UnsizeKind<'tcx>,
4386                        span: Span)
4387                        -> Ty<'tcx> {
4388     match kind {
4389         &UnsizeLength(len) => match ty.sty {
4390             ty_vec(ty, Some(n)) => {
4391                 assert!(len == n);
4392                 mk_vec(cx, ty, None)
4393             }
4394             _ => cx.sess.span_bug(span,
4395                                   format!("UnsizeLength with bad sty: {}",
4396                                           ty_to_string(cx, ty))[])
4397         },
4398         &UnsizeStruct(box ref k, tp_index) => match ty.sty {
4399             ty_struct(did, substs) => {
4400                 let ty_substs = substs.types.get_slice(subst::TypeSpace);
4401                 let new_ty = unsize_ty(cx, ty_substs[tp_index], k, span);
4402                 let mut unsized_substs = substs.clone();
4403                 unsized_substs.types.get_mut_slice(subst::TypeSpace)[tp_index] = new_ty;
4404                 mk_struct(cx, did, cx.mk_substs(unsized_substs))
4405             }
4406             _ => cx.sess.span_bug(span,
4407                                   format!("UnsizeStruct with bad sty: {}",
4408                                           ty_to_string(cx, ty))[])
4409         },
4410         &UnsizeVtable(TyTrait { ref principal, ref bounds }, _) => {
4411             mk_trait(cx, principal.clone(), bounds.clone())
4412         }
4413     }
4414 }
4415
4416 pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
4417     match tcx.def_map.borrow().get(&expr.id) {
4418         Some(&def) => def,
4419         None => {
4420             tcx.sess.span_bug(expr.span, format!(
4421                 "no def-map entry for expr {}", expr.id)[]);
4422         }
4423     }
4424 }
4425
4426 pub fn expr_is_lval(tcx: &ctxt, e: &ast::Expr) -> bool {
4427     match expr_kind(tcx, e) {
4428         LvalueExpr => true,
4429         RvalueDpsExpr | RvalueDatumExpr | RvalueStmtExpr => false
4430     }
4431 }
4432
4433 /// We categorize expressions into three kinds.  The distinction between
4434 /// lvalue/rvalue is fundamental to the language.  The distinction between the
4435 /// two kinds of rvalues is an artifact of trans which reflects how we will
4436 /// generate code for that kind of expression.  See trans/expr.rs for more
4437 /// information.
4438 #[derive(Copy)]
4439 pub enum ExprKind {
4440     LvalueExpr,
4441     RvalueDpsExpr,
4442     RvalueDatumExpr,
4443     RvalueStmtExpr
4444 }
4445
4446 pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
4447     if tcx.method_map.borrow().contains_key(&MethodCall::expr(expr.id)) {
4448         // Overloaded operations are generally calls, and hence they are
4449         // generated via DPS, but there are a few exceptions:
4450         return match expr.node {
4451             // `a += b` has a unit result.
4452             ast::ExprAssignOp(..) => RvalueStmtExpr,
4453
4454             // the deref method invoked for `*a` always yields an `&T`
4455             ast::ExprUnary(ast::UnDeref, _) => LvalueExpr,
4456
4457             // the index method invoked for `a[i]` always yields an `&T`
4458             ast::ExprIndex(..) => LvalueExpr,
4459
4460             // `for` loops are statements
4461             ast::ExprForLoop(..) => RvalueStmtExpr,
4462
4463             // in the general case, result could be any type, use DPS
4464             _ => RvalueDpsExpr
4465         };
4466     }
4467
4468     match expr.node {
4469         ast::ExprPath(..) => {
4470             match resolve_expr(tcx, expr) {
4471                 def::DefVariant(tid, vid, _) => {
4472                     let variant_info = enum_variant_with_id(tcx, tid, vid);
4473                     if variant_info.args.len() > 0u {
4474                         // N-ary variant.
4475                         RvalueDatumExpr
4476                     } else {
4477                         // Nullary variant.
4478                         RvalueDpsExpr
4479                     }
4480                 }
4481
4482                 def::DefStruct(_) => {
4483                     match tcx.node_types.borrow().get(&expr.id) {
4484                         Some(ty) => match ty.sty {
4485                             ty_bare_fn(..) => RvalueDatumExpr,
4486                             _ => RvalueDpsExpr
4487                         },
4488                         // See ExprCast below for why types might be missing.
4489                         None => RvalueDatumExpr
4490                      }
4491                 }
4492
4493                 // Special case: A unit like struct's constructor must be called without () at the
4494                 // end (like `UnitStruct`) which means this is an ExprPath to a DefFn. But in case
4495                 // of unit structs this is should not be interpreted as function pointer but as
4496                 // call to the constructor.
4497                 def::DefFn(_, true) => RvalueDpsExpr,
4498
4499                 // Fn pointers are just scalar values.
4500                 def::DefFn(..) | def::DefStaticMethod(..) | def::DefMethod(..) => RvalueDatumExpr,
4501
4502                 // Note: there is actually a good case to be made that
4503                 // DefArg's, particularly those of immediate type, ought to
4504                 // considered rvalues.
4505                 def::DefStatic(..) |
4506                 def::DefUpvar(..) |
4507                 def::DefLocal(..) => LvalueExpr,
4508
4509                 def::DefConst(..) => RvalueDatumExpr,
4510
4511                 def => {
4512                     tcx.sess.span_bug(
4513                         expr.span,
4514                         format!("uncategorized def for expr {}: {}",
4515                                 expr.id,
4516                                 def)[]);
4517                 }
4518             }
4519         }
4520
4521         ast::ExprUnary(ast::UnDeref, _) |
4522         ast::ExprField(..) |
4523         ast::ExprTupField(..) |
4524         ast::ExprIndex(..) => {
4525             LvalueExpr
4526         }
4527
4528         ast::ExprCall(..) |
4529         ast::ExprMethodCall(..) |
4530         ast::ExprStruct(..) |
4531         ast::ExprRange(..) |
4532         ast::ExprTup(..) |
4533         ast::ExprIf(..) |
4534         ast::ExprMatch(..) |
4535         ast::ExprClosure(..) |
4536         ast::ExprBlock(..) |
4537         ast::ExprRepeat(..) |
4538         ast::ExprVec(..) => {
4539             RvalueDpsExpr
4540         }
4541
4542         ast::ExprIfLet(..) => {
4543             tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
4544         }
4545         ast::ExprWhileLet(..) => {
4546             tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
4547         }
4548
4549         ast::ExprLit(ref lit) if lit_is_str(&**lit) => {
4550             RvalueDpsExpr
4551         }
4552
4553         ast::ExprCast(..) => {
4554             match tcx.node_types.borrow().get(&expr.id) {
4555                 Some(&ty) => {
4556                     if type_is_trait(ty) {
4557                         RvalueDpsExpr
4558                     } else {
4559                         RvalueDatumExpr
4560                     }
4561                 }
4562                 None => {
4563                     // Technically, it should not happen that the expr is not
4564                     // present within the table.  However, it DOES happen
4565                     // during type check, because the final types from the
4566                     // expressions are not yet recorded in the tcx.  At that
4567                     // time, though, we are only interested in knowing lvalue
4568                     // vs rvalue.  It would be better to base this decision on
4569                     // the AST type in cast node---but (at the time of this
4570                     // writing) it's not easy to distinguish casts to traits
4571                     // from other casts based on the AST.  This should be
4572                     // easier in the future, when casts to traits
4573                     // would like @Foo, Box<Foo>, or &Foo.
4574                     RvalueDatumExpr
4575                 }
4576             }
4577         }
4578
4579         ast::ExprBreak(..) |
4580         ast::ExprAgain(..) |
4581         ast::ExprRet(..) |
4582         ast::ExprWhile(..) |
4583         ast::ExprLoop(..) |
4584         ast::ExprAssign(..) |
4585         ast::ExprInlineAsm(..) |
4586         ast::ExprAssignOp(..) |
4587         ast::ExprForLoop(..) => {
4588             RvalueStmtExpr
4589         }
4590
4591         ast::ExprLit(_) | // Note: LitStr is carved out above
4592         ast::ExprUnary(..) |
4593         ast::ExprBox(None, _) |
4594         ast::ExprAddrOf(..) |
4595         ast::ExprBinary(..) => {
4596             RvalueDatumExpr
4597         }
4598
4599         ast::ExprBox(Some(ref place), _) => {
4600             // Special case `Box<T>` for now:
4601             let definition = match tcx.def_map.borrow().get(&place.id) {
4602                 Some(&def) => def,
4603                 None => panic!("no def for place"),
4604             };
4605             let def_id = definition.def_id();
4606             if tcx.lang_items.exchange_heap() == Some(def_id) {
4607                 RvalueDatumExpr
4608             } else {
4609                 RvalueDpsExpr
4610             }
4611         }
4612
4613         ast::ExprParen(ref e) => expr_kind(tcx, &**e),
4614
4615         ast::ExprMac(..) => {
4616             tcx.sess.span_bug(
4617                 expr.span,
4618                 "macro expression remains after expansion");
4619         }
4620     }
4621 }
4622
4623 pub fn stmt_node_id(s: &ast::Stmt) -> ast::NodeId {
4624     match s.node {
4625       ast::StmtDecl(_, id) | StmtExpr(_, id) | StmtSemi(_, id) => {
4626         return id;
4627       }
4628       ast::StmtMac(..) => panic!("unexpanded macro in trans")
4629     }
4630 }
4631
4632 pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
4633                      -> uint {
4634     let mut i = 0u;
4635     for f in fields.iter() { if f.name == name { return i; } i += 1u; }
4636     tcx.sess.bug(format!(
4637         "no field named `{}` found in the list of fields `{}`",
4638         token::get_name(name),
4639         fields.iter()
4640               .map(|f| token::get_name(f.name).get().to_string())
4641               .collect::<Vec<String>>())[]);
4642 }
4643
4644 pub fn impl_or_trait_item_idx(id: ast::Name, trait_items: &[ImplOrTraitItem])
4645                               -> Option<uint> {
4646     trait_items.iter().position(|m| m.name() == id)
4647 }
4648
4649 pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
4650     match ty.sty {
4651         ty_bool | ty_char | ty_int(_) |
4652         ty_uint(_) | ty_float(_) | ty_str => {
4653             ::util::ppaux::ty_to_string(cx, ty)
4654         }
4655         ty_tup(ref tys) if tys.is_empty() => ::util::ppaux::ty_to_string(cx, ty),
4656
4657         ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
4658         ty_uniq(_) => "box".to_string(),
4659         ty_vec(_, Some(n)) => format!("array of {} elements", n),
4660         ty_vec(_, None) => "slice".to_string(),
4661         ty_ptr(_) => "*-ptr".to_string(),
4662         ty_rptr(_, _) => "&-ptr".to_string(),
4663         ty_bare_fn(Some(_), _) => format!("fn item"),
4664         ty_bare_fn(None, _) => "fn pointer".to_string(),
4665         ty_trait(ref inner) => {
4666             format!("trait {}", item_path_str(cx, inner.principal_def_id()))
4667         }
4668         ty_struct(id, _) => {
4669             format!("struct {}", item_path_str(cx, id))
4670         }
4671         ty_unboxed_closure(..) => "closure".to_string(),
4672         ty_tup(_) => "tuple".to_string(),
4673         ty_infer(TyVar(_)) => "inferred type".to_string(),
4674         ty_infer(IntVar(_)) => "integral variable".to_string(),
4675         ty_infer(FloatVar(_)) => "floating-point variable".to_string(),
4676         ty_infer(FreshTy(_)) => "skolemized type".to_string(),
4677         ty_infer(FreshIntTy(_)) => "skolemized integral type".to_string(),
4678         ty_projection(_) => "associated type".to_string(),
4679         ty_param(ref p) => {
4680             if p.space == subst::SelfSpace {
4681                 "Self".to_string()
4682             } else {
4683                 "type parameter".to_string()
4684             }
4685         }
4686         ty_err => "type error".to_string(),
4687         ty_open(_) => "opened DST".to_string(),
4688     }
4689 }
4690
4691 impl<'tcx> Repr<'tcx> for ty::type_err<'tcx> {
4692     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
4693         ty::type_err_to_str(tcx, self)
4694     }
4695 }
4696
4697 /// Explains the source of a type err in a short, human readable way. This is meant to be placed
4698 /// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
4699 /// afterwards to present additional details, particularly when it comes to lifetime-related
4700 /// errors.
4701 pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) -> String {
4702     fn tstore_to_closure(s: &TraitStore) -> String {
4703         match s {
4704             &UniqTraitStore => "proc".to_string(),
4705             &RegionTraitStore(..) => "closure".to_string()
4706         }
4707     }
4708
4709     match *err {
4710         terr_cyclic_ty => "cyclic type of infinite size".to_string(),
4711         terr_mismatch => "types differ".to_string(),
4712         terr_unsafety_mismatch(values) => {
4713             format!("expected {} fn, found {} fn",
4714                     values.expected.to_string(),
4715                     values.found.to_string())
4716         }
4717         terr_abi_mismatch(values) => {
4718             format!("expected {} fn, found {} fn",
4719                     values.expected.to_string(),
4720                     values.found.to_string())
4721         }
4722         terr_onceness_mismatch(values) => {
4723             format!("expected {} fn, found {} fn",
4724                     values.expected.to_string(),
4725                     values.found.to_string())
4726         }
4727         terr_sigil_mismatch(values) => {
4728             format!("expected {}, found {}",
4729                     tstore_to_closure(&values.expected),
4730                     tstore_to_closure(&values.found))
4731         }
4732         terr_mutability => "values differ in mutability".to_string(),
4733         terr_box_mutability => {
4734             "boxed values differ in mutability".to_string()
4735         }
4736         terr_vec_mutability => "vectors differ in mutability".to_string(),
4737         terr_ptr_mutability => "pointers differ in mutability".to_string(),
4738         terr_ref_mutability => "references differ in mutability".to_string(),
4739         terr_ty_param_size(values) => {
4740             format!("expected a type with {} type params, \
4741                      found one with {} type params",
4742                     values.expected,
4743                     values.found)
4744         }
4745         terr_fixed_array_size(values) => {
4746             format!("expected an array with a fixed size of {} elements, \
4747                      found one with {} elements",
4748                     values.expected,
4749                     values.found)
4750         }
4751         terr_tuple_size(values) => {
4752             format!("expected a tuple with {} elements, \
4753                      found one with {} elements",
4754                     values.expected,
4755                     values.found)
4756         }
4757         terr_arg_count => {
4758             "incorrect number of function parameters".to_string()
4759         }
4760         terr_regions_does_not_outlive(..) => {
4761             "lifetime mismatch".to_string()
4762         }
4763         terr_regions_not_same(..) => {
4764             "lifetimes are not the same".to_string()
4765         }
4766         terr_regions_no_overlap(..) => {
4767             "lifetimes do not intersect".to_string()
4768         }
4769         terr_regions_insufficiently_polymorphic(br, _) => {
4770             format!("expected bound lifetime parameter {}, \
4771                      found concrete lifetime",
4772                     bound_region_ptr_to_string(cx, br))
4773         }
4774         terr_regions_overly_polymorphic(br, _) => {
4775             format!("expected concrete lifetime, \
4776                      found bound lifetime parameter {}",
4777                     bound_region_ptr_to_string(cx, br))
4778         }
4779         terr_trait_stores_differ(_, ref values) => {
4780             format!("trait storage differs: expected `{}`, found `{}`",
4781                     trait_store_to_string(cx, (*values).expected),
4782                     trait_store_to_string(cx, (*values).found))
4783         }
4784         terr_sorts(values) => {
4785             // A naive approach to making sure that we're not reporting silly errors such as:
4786             // (expected closure, found closure).
4787             let expected_str = ty_sort_string(cx, values.expected);
4788             let found_str = ty_sort_string(cx, values.found);
4789             if expected_str == found_str {
4790                 format!("expected {}, found a different {}", expected_str, found_str)
4791             } else {
4792                 format!("expected {}, found {}", expected_str, found_str)
4793             }
4794         }
4795         terr_traits(values) => {
4796             format!("expected trait `{}`, found trait `{}`",
4797                     item_path_str(cx, values.expected),
4798                     item_path_str(cx, values.found))
4799         }
4800         terr_builtin_bounds(values) => {
4801             if values.expected.is_empty() {
4802                 format!("expected no bounds, found `{}`",
4803                         values.found.user_string(cx))
4804             } else if values.found.is_empty() {
4805                 format!("expected bounds `{}`, found no bounds",
4806                         values.expected.user_string(cx))
4807             } else {
4808                 format!("expected bounds `{}`, found bounds `{}`",
4809                         values.expected.user_string(cx),
4810                         values.found.user_string(cx))
4811             }
4812         }
4813         terr_integer_as_char => {
4814             "expected an integral type, found `char`".to_string()
4815         }
4816         terr_int_mismatch(ref values) => {
4817             format!("expected `{}`, found `{}`",
4818                     values.expected.to_string(),
4819                     values.found.to_string())
4820         }
4821         terr_float_mismatch(ref values) => {
4822             format!("expected `{}`, found `{}`",
4823                     values.expected.to_string(),
4824                     values.found.to_string())
4825         }
4826         terr_variadic_mismatch(ref values) => {
4827             format!("expected {} fn, found {} function",
4828                     if values.expected { "variadic" } else { "non-variadic" },
4829                     if values.found { "variadic" } else { "non-variadic" })
4830         }
4831         terr_convergence_mismatch(ref values) => {
4832             format!("expected {} fn, found {} function",
4833                     if values.expected { "converging" } else { "diverging" },
4834                     if values.found { "converging" } else { "diverging" })
4835         }
4836         terr_projection_name_mismatched(ref values) => {
4837             format!("expected {}, found {}",
4838                     token::get_name(values.expected),
4839                     token::get_name(values.found))
4840         }
4841         terr_projection_bounds_length(ref values) => {
4842             format!("expected {} associated type bindings, found {}",
4843                     values.expected,
4844                     values.found)
4845         }
4846     }
4847 }
4848
4849 pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) {
4850     match *err {
4851         terr_regions_does_not_outlive(subregion, superregion) => {
4852             note_and_explain_region(cx, "", subregion, "...");
4853             note_and_explain_region(cx, "...does not necessarily outlive ",
4854                                     superregion, "");
4855         }
4856         terr_regions_not_same(region1, region2) => {
4857             note_and_explain_region(cx, "", region1, "...");
4858             note_and_explain_region(cx, "...is not the same lifetime as ",
4859                                     region2, "");
4860         }
4861         terr_regions_no_overlap(region1, region2) => {
4862             note_and_explain_region(cx, "", region1, "...");
4863             note_and_explain_region(cx, "...does not overlap ",
4864                                     region2, "");
4865         }
4866         terr_regions_insufficiently_polymorphic(_, conc_region) => {
4867             note_and_explain_region(cx,
4868                                     "concrete lifetime that was found is ",
4869                                     conc_region, "");
4870         }
4871         terr_regions_overly_polymorphic(_, ty::ReInfer(ty::ReVar(_))) => {
4872             // don't bother to print out the message below for
4873             // inference variables, it's not very illuminating.
4874         }
4875         terr_regions_overly_polymorphic(_, conc_region) => {
4876             note_and_explain_region(cx,
4877                                     "expected concrete lifetime is ",
4878                                     conc_region, "");
4879         }
4880         _ => {}
4881     }
4882 }
4883
4884 pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option<ast::DefId> {
4885     cx.provided_method_sources.borrow().get(&id).map(|x| *x)
4886 }
4887
4888 pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
4889                                     -> Vec<Rc<Method<'tcx>>> {
4890     if is_local(id) {
4891         match cx.map.find(id.node) {
4892             Some(ast_map::NodeItem(item)) => {
4893                 match item.node {
4894                     ItemTrait(_, _, _, ref ms) => {
4895                         let (_, p) =
4896                             ast_util::split_trait_methods(ms[]);
4897                         p.iter()
4898                          .map(|m| {
4899                             match impl_or_trait_item(
4900                                     cx,
4901                                     ast_util::local_def(m.id)) {
4902                                 MethodTraitItem(m) => m,
4903                                 TypeTraitItem(_) => {
4904                                     cx.sess.bug("provided_trait_methods(): \
4905                                                  split_trait_methods() put \
4906                                                  associated types in the \
4907                                                  provided method bucket?!")
4908                                 }
4909                             }
4910                          }).collect()
4911                     }
4912                     _ => {
4913                         cx.sess.bug(format!("provided_trait_methods: `{}` is \
4914                                              not a trait",
4915                                             id)[])
4916                     }
4917                 }
4918             }
4919             _ => {
4920                 cx.sess.bug(format!("provided_trait_methods: `{}` is not a \
4921                                      trait",
4922                                     id)[])
4923             }
4924         }
4925     } else {
4926         csearch::get_provided_trait_methods(cx, id)
4927     }
4928 }
4929
4930 /// Helper for looking things up in the various maps that are populated during
4931 /// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc).  All of
4932 /// these share the pattern that if the id is local, it should have been loaded
4933 /// into the map by the `typeck::collect` phase.  If the def-id is external,
4934 /// then we have to go consult the crate loading code (and cache the result for
4935 /// the future).
4936 fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
4937                                           def_id: ast::DefId,
4938                                           map: &mut DefIdMap<V>,
4939                                           load_external: F) -> V where
4940     V: Clone,
4941     F: FnOnce() -> V,
4942 {
4943     match map.get(&def_id).cloned() {
4944         Some(v) => { return v; }
4945         None => { }
4946     }
4947
4948     if def_id.krate == ast::LOCAL_CRATE {
4949         panic!("No def'n found for {} in tcx.{}", def_id, descr);
4950     }
4951     let v = load_external();
4952     map.insert(def_id, v.clone());
4953     v
4954 }
4955
4956 pub fn trait_item<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId, idx: uint)
4957                         -> ImplOrTraitItem<'tcx> {
4958     let method_def_id = (*ty::trait_item_def_ids(cx, trait_did))[idx].def_id();
4959     impl_or_trait_item(cx, method_def_id)
4960 }
4961
4962 pub fn trait_items<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId)
4963                          -> Rc<Vec<ImplOrTraitItem<'tcx>>> {
4964     let mut trait_items = cx.trait_items_cache.borrow_mut();
4965     match trait_items.get(&trait_did).cloned() {
4966         Some(trait_items) => trait_items,
4967         None => {
4968             let def_ids = ty::trait_item_def_ids(cx, trait_did);
4969             let items: Rc<Vec<ImplOrTraitItem>> =
4970                 Rc::new(def_ids.iter()
4971                                .map(|d| impl_or_trait_item(cx, d.def_id()))
4972                                .collect());
4973             trait_items.insert(trait_did, items.clone());
4974             items
4975         }
4976     }
4977 }
4978
4979 pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
4980                                 -> ImplOrTraitItem<'tcx> {
4981     lookup_locally_or_in_crate_store("impl_or_trait_items",
4982                                      id,
4983                                      &mut *cx.impl_or_trait_items
4984                                              .borrow_mut(),
4985                                      || {
4986         csearch::get_impl_or_trait_item(cx, id)
4987     })
4988 }
4989
4990 /// Returns true if the given ID refers to an associated type and false if it
4991 /// refers to anything else.
4992 pub fn is_associated_type(cx: &ctxt, id: ast::DefId) -> bool {
4993     memoized(&cx.associated_types, id, |id: ast::DefId| {
4994         if id.krate == ast::LOCAL_CRATE {
4995             match cx.impl_or_trait_items.borrow().get(&id) {
4996                 Some(ref item) => {
4997                     match **item {
4998                         TypeTraitItem(_) => true,
4999                         MethodTraitItem(_) => false,
5000                     }
5001                 }
5002                 None => false,
5003             }
5004         } else {
5005             csearch::is_associated_type(&cx.sess.cstore, id)
5006         }
5007     })
5008 }
5009
5010 /// Returns the parameter index that the given associated type corresponds to.
5011 pub fn associated_type_parameter_index(cx: &ctxt,
5012                                        trait_def: &TraitDef,
5013                                        associated_type_id: ast::DefId)
5014                                        -> uint {
5015     for type_parameter_def in trait_def.generics.types.iter() {
5016         if type_parameter_def.def_id == associated_type_id {
5017             return type_parameter_def.index as uint
5018         }
5019     }
5020     cx.sess.bug("couldn't find associated type parameter index")
5021 }
5022
5023 #[derive(Copy, PartialEq, Eq)]
5024 pub struct AssociatedTypeInfo {
5025     pub def_id: ast::DefId,
5026     pub index: uint,
5027     pub name: ast::Name,
5028 }
5029
5030 impl PartialOrd for AssociatedTypeInfo {
5031     fn partial_cmp(&self, other: &AssociatedTypeInfo) -> Option<Ordering> {
5032         Some(self.index.cmp(&other.index))
5033     }
5034 }
5035
5036 impl Ord for AssociatedTypeInfo {
5037     fn cmp(&self, other: &AssociatedTypeInfo) -> Ordering {
5038         self.index.cmp(&other.index)
5039     }
5040 }
5041
5042 pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
5043                           -> Rc<Vec<ImplOrTraitItemId>> {
5044     lookup_locally_or_in_crate_store("trait_item_def_ids",
5045                                      id,
5046                                      &mut *cx.trait_item_def_ids.borrow_mut(),
5047                                      || {
5048         Rc::new(csearch::get_trait_item_def_ids(&cx.sess.cstore, id))
5049     })
5050 }
5051
5052 pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5053                             -> Option<Rc<TraitRef<'tcx>>> {
5054     memoized(&cx.impl_trait_cache, id, |id: ast::DefId| {
5055         if id.krate == ast::LOCAL_CRATE {
5056             debug!("(impl_trait_ref) searching for trait impl {}", id);
5057             match cx.map.find(id.node) {
5058                 Some(ast_map::NodeItem(item)) => {
5059                     match item.node {
5060                         ast::ItemImpl(_, _, _, ref opt_trait, _, _) => {
5061                             match opt_trait {
5062                                 &Some(ref t) => {
5063                                     let trait_ref = ty::node_id_to_trait_ref(cx, t.ref_id);
5064                                     Some(trait_ref)
5065                                 }
5066                                 &None => None
5067                             }
5068                         }
5069                         _ => None
5070                     }
5071                 }
5072                 _ => None
5073             }
5074         } else {
5075             csearch::get_impl_trait(cx, id)
5076         }
5077     })
5078 }
5079
5080 pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId {
5081     let def = *tcx.def_map.borrow()
5082                      .get(&tr.ref_id)
5083                      .expect("no def-map entry for trait");
5084     def.def_id()
5085 }
5086
5087 pub fn try_add_builtin_trait(
5088     tcx: &ctxt,
5089     trait_def_id: ast::DefId,
5090     builtin_bounds: &mut EnumSet<BuiltinBound>)
5091     -> bool
5092 {
5093     //! Checks whether `trait_ref` refers to one of the builtin
5094     //! traits, like `Send`, and adds the corresponding
5095     //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
5096     //! is a builtin trait.
5097
5098     match tcx.lang_items.to_builtin_kind(trait_def_id) {
5099         Some(bound) => { builtin_bounds.insert(bound); true }
5100         None => false
5101     }
5102 }
5103
5104 pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
5105     match ty.sty {
5106         ty_trait(ref tt) =>
5107             Some(tt.principal_def_id()),
5108         ty_struct(id, _) |
5109         ty_enum(id, _) |
5110         ty_unboxed_closure(id, _, _) =>
5111             Some(id),
5112         _ =>
5113             None
5114     }
5115 }
5116
5117 // Enum information
5118 #[derive(Clone)]
5119 pub struct VariantInfo<'tcx> {
5120     pub args: Vec<Ty<'tcx>>,
5121     pub arg_names: Option<Vec<ast::Ident>>,
5122     pub ctor_ty: Option<Ty<'tcx>>,
5123     pub name: ast::Name,
5124     pub id: ast::DefId,
5125     pub disr_val: Disr,
5126     pub vis: Visibility
5127 }
5128
5129 impl<'tcx> VariantInfo<'tcx> {
5130
5131     /// Creates a new VariantInfo from the corresponding ast representation.
5132     ///
5133     /// Does not do any caching of the value in the type context.
5134     pub fn from_ast_variant(cx: &ctxt<'tcx>,
5135                             ast_variant: &ast::Variant,
5136                             discriminant: Disr) -> VariantInfo<'tcx> {
5137         let ctor_ty = node_id_to_type(cx, ast_variant.node.id);
5138
5139         match ast_variant.node.kind {
5140             ast::TupleVariantKind(ref args) => {
5141                 let arg_tys = if args.len() > 0 {
5142                     ty_fn_args(ctor_ty).iter().map(|a| *a).collect()
5143                 } else {
5144                     Vec::new()
5145                 };
5146
5147                 return VariantInfo {
5148                     args: arg_tys,
5149                     arg_names: None,
5150                     ctor_ty: Some(ctor_ty),
5151                     name: ast_variant.node.name.name,
5152                     id: ast_util::local_def(ast_variant.node.id),
5153                     disr_val: discriminant,
5154                     vis: ast_variant.node.vis
5155                 };
5156             },
5157             ast::StructVariantKind(ref struct_def) => {
5158
5159                 let fields: &[StructField] = struct_def.fields[];
5160
5161                 assert!(fields.len() > 0);
5162
5163                 let arg_tys = struct_def.fields.iter()
5164                     .map(|field| node_id_to_type(cx, field.node.id)).collect();
5165                 let arg_names = fields.iter().map(|field| {
5166                     match field.node.kind {
5167                         NamedField(ident, _) => ident,
5168                         UnnamedField(..) => cx.sess.bug(
5169                             "enum_variants: all fields in struct must have a name")
5170                     }
5171                 }).collect();
5172
5173                 return VariantInfo {
5174                     args: arg_tys,
5175                     arg_names: Some(arg_names),
5176                     ctor_ty: None,
5177                     name: ast_variant.node.name.name,
5178                     id: ast_util::local_def(ast_variant.node.id),
5179                     disr_val: discriminant,
5180                     vis: ast_variant.node.vis
5181                 };
5182             }
5183         }
5184     }
5185 }
5186
5187 pub fn substd_enum_variants<'tcx>(cx: &ctxt<'tcx>,
5188                                   id: ast::DefId,
5189                                   substs: &Substs<'tcx>)
5190                                   -> Vec<Rc<VariantInfo<'tcx>>> {
5191     enum_variants(cx, id).iter().map(|variant_info| {
5192         let substd_args = variant_info.args.iter()
5193             .map(|aty| aty.subst(cx, substs)).collect::<Vec<_>>();
5194
5195         let substd_ctor_ty = variant_info.ctor_ty.subst(cx, substs);
5196
5197         Rc::new(VariantInfo {
5198             args: substd_args,
5199             ctor_ty: substd_ctor_ty,
5200             ..(**variant_info).clone()
5201         })
5202     }).collect()
5203 }
5204
5205 pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> String {
5206     with_path(cx, id, |path| ast_map::path_to_string(path)).to_string()
5207 }
5208
5209 #[derive(Copy)]
5210 pub enum DtorKind {
5211     NoDtor,
5212     TraitDtor(DefId, bool)
5213 }
5214
5215 impl DtorKind {
5216     pub fn is_present(&self) -> bool {
5217         match *self {
5218             TraitDtor(..) => true,
5219             _ => false
5220         }
5221     }
5222
5223     pub fn has_drop_flag(&self) -> bool {
5224         match self {
5225             &NoDtor => false,
5226             &TraitDtor(_, flag) => flag
5227         }
5228     }
5229 }
5230
5231 /* If struct_id names a struct with a dtor, return Some(the dtor's id).
5232    Otherwise return none. */
5233 pub fn ty_dtor(cx: &ctxt, struct_id: DefId) -> DtorKind {
5234     match cx.destructor_for_type.borrow().get(&struct_id) {
5235         Some(&method_def_id) => {
5236             let flag = !has_attr(cx, struct_id, "unsafe_no_drop_flag");
5237
5238             TraitDtor(method_def_id, flag)
5239         }
5240         None => NoDtor,
5241     }
5242 }
5243
5244 pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool {
5245     cx.destructor_for_type.borrow().contains_key(&struct_id)
5246 }
5247
5248 pub fn with_path<T, F>(cx: &ctxt, id: ast::DefId, f: F) -> T where
5249     F: FnOnce(ast_map::PathElems) -> T,
5250 {
5251     if id.krate == ast::LOCAL_CRATE {
5252         cx.map.with_path(id.node, f)
5253     } else {
5254         f(ast_map::Values(csearch::get_item_path(cx, id).iter()).chain(None))
5255     }
5256 }
5257
5258 pub fn enum_is_univariant(cx: &ctxt, id: ast::DefId) -> bool {
5259     enum_variants(cx, id).len() == 1
5260 }
5261
5262 pub fn type_is_empty(cx: &ctxt, ty: Ty) -> bool {
5263     match ty.sty {
5264        ty_enum(did, _) => (*enum_variants(cx, did)).is_empty(),
5265        _ => false
5266      }
5267 }
5268
5269 pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
5270                            -> Rc<Vec<Rc<VariantInfo<'tcx>>>> {
5271     memoized(&cx.enum_var_cache, id, |id: ast::DefId| {
5272         if ast::LOCAL_CRATE != id.krate {
5273             Rc::new(csearch::get_enum_variants(cx, id))
5274         } else {
5275             /*
5276               Although both this code and check_enum_variants in typeck/check
5277               call eval_const_expr, it should never get called twice for the same
5278               expr, since check_enum_variants also updates the enum_var_cache
5279              */
5280             match cx.map.get(id.node) {
5281                 ast_map::NodeItem(ref item) => {
5282                     match item.node {
5283                         ast::ItemEnum(ref enum_definition, _) => {
5284                             let mut last_discriminant: Option<Disr> = None;
5285                             Rc::new(enum_definition.variants.iter().map(|variant| {
5286
5287                                 let mut discriminant = match last_discriminant {
5288                                     Some(val) => val + 1,
5289                                     None => INITIAL_DISCRIMINANT_VALUE
5290                                 };
5291
5292                                 match variant.node.disr_expr {
5293                                     Some(ref e) =>
5294                                         match const_eval::eval_const_expr_partial(cx, &**e) {
5295                                             Ok(const_eval::const_int(val)) => {
5296                                                 discriminant = val as Disr
5297                                             }
5298                                             Ok(const_eval::const_uint(val)) => {
5299                                                 discriminant = val as Disr
5300                                             }
5301                                             Ok(_) => {
5302                                                 cx.sess
5303                                                   .span_err(e.span,
5304                                                             "expected signed integer constant");
5305                                             }
5306                                             Err(ref err) => {
5307                                                 cx.sess
5308                                                   .span_err(e.span,
5309                                                             format!("expected constant: {}",
5310                                                                     *err)[]);
5311                                             }
5312                                         },
5313                                     None => {}
5314                                 };
5315
5316                                 last_discriminant = Some(discriminant);
5317                                 Rc::new(VariantInfo::from_ast_variant(cx, &**variant,
5318                                                                       discriminant))
5319                             }).collect())
5320                         }
5321                         _ => {
5322                             cx.sess.bug("enum_variants: id not bound to an enum")
5323                         }
5324                     }
5325                 }
5326                 _ => cx.sess.bug("enum_variants: id not bound to an enum")
5327             }
5328         }
5329     })
5330 }
5331
5332 // Returns information about the enum variant with the given ID:
5333 pub fn enum_variant_with_id<'tcx>(cx: &ctxt<'tcx>,
5334                                   enum_id: ast::DefId,
5335                                   variant_id: ast::DefId)
5336                                   -> Rc<VariantInfo<'tcx>> {
5337     enum_variants(cx, enum_id).iter()
5338                               .find(|variant| variant.id == variant_id)
5339                               .expect("enum_variant_with_id(): no variant exists with that ID")
5340                               .clone()
5341 }
5342
5343
5344 // If the given item is in an external crate, looks up its type and adds it to
5345 // the type cache. Returns the type parameters and type.
5346 pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>,
5347                               did: ast::DefId)
5348                               -> TypeScheme<'tcx> {
5349     lookup_locally_or_in_crate_store(
5350         "tcache", did, &mut *cx.tcache.borrow_mut(),
5351         || csearch::get_type(cx, did))
5352 }
5353
5354 /// Given the did of a trait, returns its canonical trait ref.
5355 pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
5356                               -> Rc<ty::TraitDef<'tcx>> {
5357     memoized(&cx.trait_defs, did, |did: DefId| {
5358         assert!(did.krate != ast::LOCAL_CRATE);
5359         Rc::new(csearch::get_trait_def(cx, did))
5360     })
5361 }
5362
5363 /// Given a reference to a trait, returns the "superbounds" declared
5364 /// on the trait, with appropriate substitutions applied. Basically,
5365 /// this applies a filter to the where clauses on the trait, returning
5366 /// those that have the form:
5367 ///
5368 ///     Self : SuperTrait<...>
5369 ///     Self : 'region
5370 pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
5371                                       trait_ref: &PolyTraitRef<'tcx>)
5372                                       -> Vec<ty::Predicate<'tcx>>
5373 {
5374     let trait_def = lookup_trait_def(tcx, trait_ref.def_id());
5375
5376     debug!("bounds_for_trait_ref(trait_def={}, trait_ref={})",
5377            trait_def.repr(tcx), trait_ref.repr(tcx));
5378
5379     // The interaction between HRTB and supertraits is not entirely
5380     // obvious. Let me walk you (and myself) through an example.
5381     //
5382     // Let's start with an easy case. Consider two traits:
5383     //
5384     //     trait Foo<'a> : Bar<'a,'a> { }
5385     //     trait Bar<'b,'c> { }
5386     //
5387     // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
5388     // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
5389     // knew that `Foo<'x>` (for any 'x) then we also know that
5390     // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
5391     // normal substitution.
5392     //
5393     // In terms of why this is sound, the idea is that whenever there
5394     // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
5395     // holds.  So if there is an impl of `T:Foo<'a>` that applies to
5396     // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
5397     // `'a`.
5398     //
5399     // Another example to be careful of is this:
5400     //
5401     //     trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
5402     //     trait Bar1<'b,'c> { }
5403     //
5404     // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
5405     // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
5406     // reason is similar to the previous example: any impl of
5407     // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`.  So
5408     // basically we would want to collapse the bound lifetimes from
5409     // the input (`trait_ref`) and the supertraits.
5410     //
5411     // To achieve this in practice is fairly straightforward. Let's
5412     // consider the more complicated scenario:
5413     //
5414     // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
5415     //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
5416     //   where both `'x` and `'b` would have a DB index of 1.
5417     //   The substitution from the input trait-ref is therefore going to be
5418     //   `'a => 'x` (where `'x` has a DB index of 1).
5419     // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
5420     //   early-bound parameter and `'b' is a late-bound parameter with a
5421     //   DB index of 1.
5422     // - If we replace `'a` with `'x` from the input, it too will have
5423     //   a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
5424     //   just as we wanted.
5425     //
5426     // There is only one catch. If we just apply the substitution `'a
5427     // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
5428     // adjust the DB index because we substituting into a binder (it
5429     // tries to be so smart...) resulting in `for<'x> for<'b>
5430     // Bar1<'x,'b>` (we have no syntax for this, so use your
5431     // imagination). Basically the 'x will have DB index of 2 and 'b
5432     // will have DB index of 1. Not quite what we want. So we apply
5433     // the substitution to the *contents* of the trait reference,
5434     // rather than the trait reference itself (put another way, the
5435     // substitution code expects equal binding levels in the values
5436     // from the substitution and the value being substituted into, and
5437     // this trick achieves that).
5438
5439     // Carefully avoid the binder introduced by each trait-ref by
5440     // substituting over the substs, not the trait-refs themselves,
5441     // thus achieving the "collapse" described in the big comment
5442     // above.
5443     let trait_bounds: Vec<_> =
5444         trait_def.bounds.trait_bounds
5445         .iter()
5446         .map(|poly_trait_ref| ty::Binder(poly_trait_ref.0.subst(tcx, trait_ref.substs())))
5447         .collect();
5448
5449     let projection_bounds: Vec<_> =
5450         trait_def.bounds.projection_bounds
5451         .iter()
5452         .map(|poly_proj| ty::Binder(poly_proj.0.subst(tcx, trait_ref.substs())))
5453         .collect();
5454
5455     debug!("bounds_for_trait_ref: trait_bounds={} projection_bounds={}",
5456            trait_bounds.repr(tcx),
5457            projection_bounds.repr(tcx));
5458
5459     // The region bounds and builtin bounds do not currently introduce
5460     // binders so we can just substitute in a straightforward way here.
5461     let region_bounds =
5462         trait_def.bounds.region_bounds.subst(tcx, trait_ref.substs());
5463     let builtin_bounds =
5464         trait_def.bounds.builtin_bounds.subst(tcx, trait_ref.substs());
5465
5466     let bounds = ty::ParamBounds {
5467         trait_bounds: trait_bounds,
5468         region_bounds: region_bounds,
5469         builtin_bounds: builtin_bounds,
5470         projection_bounds: projection_bounds,
5471     };
5472
5473     predicates(tcx, trait_ref.self_ty(), &bounds)
5474 }
5475
5476 pub fn predicates<'tcx>(
5477     tcx: &ctxt<'tcx>,
5478     param_ty: Ty<'tcx>,
5479     bounds: &ParamBounds<'tcx>)
5480     -> Vec<Predicate<'tcx>>
5481 {
5482     let mut vec = Vec::new();
5483
5484     for builtin_bound in bounds.builtin_bounds.iter() {
5485         match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) {
5486             Ok(trait_ref) => { vec.push(trait_ref.as_predicate()); }
5487             Err(ErrorReported) => { }
5488         }
5489     }
5490
5491     for &region_bound in bounds.region_bounds.iter() {
5492         // account for the binder being introduced below; no need to shift `param_ty`
5493         // because, at present at least, it can only refer to early-bound regions
5494         let region_bound = ty_fold::shift_region(region_bound, 1);
5495         vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).as_predicate());
5496     }
5497
5498     for bound_trait_ref in bounds.trait_bounds.iter() {
5499         vec.push(bound_trait_ref.as_predicate());
5500     }
5501
5502     for projection in bounds.projection_bounds.iter() {
5503         vec.push(projection.as_predicate());
5504     }
5505
5506     vec
5507 }
5508
5509 /// Iterate over attributes of a definition.
5510 // (This should really be an iterator, but that would require csearch and
5511 // decoder to use iterators instead of higher-order functions.)
5512 pub fn each_attr<F>(tcx: &ctxt, did: DefId, mut f: F) -> bool where
5513     F: FnMut(&ast::Attribute) -> bool,
5514 {
5515     if is_local(did) {
5516         let item = tcx.map.expect_item(did.node);
5517         item.attrs.iter().all(|attr| f(attr))
5518     } else {
5519         info!("getting foreign attrs");
5520         let mut cont = true;
5521         csearch::get_item_attrs(&tcx.sess.cstore, did, |attrs| {
5522             if cont {
5523                 cont = attrs.iter().all(|attr| f(attr));
5524             }
5525         });
5526         info!("done");
5527         cont
5528     }
5529 }
5530
5531 /// Determine whether an item is annotated with an attribute
5532 pub fn has_attr(tcx: &ctxt, did: DefId, attr: &str) -> bool {
5533     let mut found = false;
5534     each_attr(tcx, did, |item| {
5535         if item.check_name(attr) {
5536             found = true;
5537             false
5538         } else {
5539             true
5540         }
5541     });
5542     found
5543 }
5544
5545 /// Determine whether an item is annotated with `#[repr(packed)]`
5546 pub fn lookup_packed(tcx: &ctxt, did: DefId) -> bool {
5547     lookup_repr_hints(tcx, did).contains(&attr::ReprPacked)
5548 }
5549
5550 /// Determine whether an item is annotated with `#[simd]`
5551 pub fn lookup_simd(tcx: &ctxt, did: DefId) -> bool {
5552     has_attr(tcx, did, "simd")
5553 }
5554
5555 /// Obtain the representation annotation for a struct definition.
5556 pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
5557     memoized(&tcx.repr_hint_cache, did, |did: DefId| {
5558         Rc::new(if did.krate == LOCAL_CRATE {
5559             let mut acc = Vec::new();
5560             ty::each_attr(tcx, did, |meta| {
5561                 acc.extend(attr::find_repr_attrs(tcx.sess.diagnostic(),
5562                                                  meta).into_iter());
5563                 true
5564             });
5565             acc
5566         } else {
5567             csearch::get_repr_attrs(&tcx.sess.cstore, did)
5568         })
5569     })
5570 }
5571
5572 // Look up a field ID, whether or not it's local
5573 // Takes a list of type substs in case the struct is generic
5574 pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
5575                                struct_id: DefId,
5576                                id: DefId,
5577                                substs: &Substs<'tcx>)
5578                                -> Ty<'tcx> {
5579     let ty = if id.krate == ast::LOCAL_CRATE {
5580         node_id_to_type(tcx, id.node)
5581     } else {
5582         let mut tcache = tcx.tcache.borrow_mut();
5583         let pty = tcache.entry(&id).get().unwrap_or_else(
5584             |vacant_entry| vacant_entry.insert(csearch::get_field_type(tcx, struct_id, id)));
5585         pty.ty
5586     };
5587     ty.subst(tcx, substs)
5588 }
5589
5590 // Look up the list of field names and IDs for a given struct.
5591 // Panics if the id is not bound to a struct.
5592 pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
5593     if did.krate == ast::LOCAL_CRATE {
5594         let struct_fields = cx.struct_fields.borrow();
5595         match struct_fields.get(&did) {
5596             Some(fields) => (**fields).clone(),
5597             _ => {
5598                 cx.sess.bug(
5599                     format!("ID not mapped to struct fields: {}",
5600                             cx.map.node_to_string(did.node))[]);
5601             }
5602         }
5603     } else {
5604         csearch::get_struct_fields(&cx.sess.cstore, did)
5605     }
5606 }
5607
5608 pub fn is_tuple_struct(cx: &ctxt, did: ast::DefId) -> bool {
5609     let fields = lookup_struct_fields(cx, did);
5610     !fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field)
5611 }
5612
5613 // Returns a list of fields corresponding to the struct's items. trans uses
5614 // this. Takes a list of substs with which to instantiate field types.
5615 pub fn struct_fields<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: &Substs<'tcx>)
5616                            -> Vec<field<'tcx>> {
5617     lookup_struct_fields(cx, did).iter().map(|f| {
5618        field {
5619             name: f.name,
5620             mt: mt {
5621                 ty: lookup_field_type(cx, did, f.id, substs),
5622                 mutbl: MutImmutable
5623             }
5624         }
5625     }).collect()
5626 }
5627
5628 // Returns a list of fields corresponding to the tuple's items. trans uses
5629 // this.
5630 pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec<field<'tcx>> {
5631     v.iter().enumerate().map(|(i, &f)| {
5632        field {
5633             name: token::intern(i.to_string()[]),
5634             mt: mt {
5635                 ty: f,
5636                 mutbl: MutImmutable
5637             }
5638         }
5639     }).collect()
5640 }
5641
5642 #[derive(Copy, Clone)]
5643 pub struct UnboxedClosureUpvar<'tcx> {
5644     pub def: def::Def,
5645     pub span: Span,
5646     pub ty: Ty<'tcx>,
5647 }
5648
5649 // Returns a list of `UnboxedClosureUpvar`s for each upvar.
5650 pub fn unboxed_closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
5651                                     closure_id: ast::DefId,
5652                                     substs: &Substs<'tcx>)
5653                                     -> Option<Vec<UnboxedClosureUpvar<'tcx>>>
5654 {
5655     // Presently an unboxed closure type cannot "escape" out of a
5656     // function, so we will only encounter ones that originated in the
5657     // local crate or were inlined into it along with some function.
5658     // This may change if abstract return types of some sort are
5659     // implemented.
5660     assert!(closure_id.krate == ast::LOCAL_CRATE);
5661     let tcx = typer.tcx();
5662     let capture_mode = tcx.capture_modes.borrow()[closure_id.node].clone();
5663     match tcx.freevars.borrow().get(&closure_id.node) {
5664         None => Some(vec![]),
5665         Some(ref freevars) => {
5666             freevars.iter()
5667                     .map(|freevar| {
5668                         let freevar_def_id = freevar.def.def_id();
5669                         let freevar_ty = match typer.node_ty(freevar_def_id.node) {
5670                             Ok(t) => { t }
5671                             Err(()) => { return None; }
5672                         };
5673                         let freevar_ty = freevar_ty.subst(tcx, substs);
5674
5675                         match capture_mode {
5676                             ast::CaptureByValue => {
5677                                 Some(UnboxedClosureUpvar { def: freevar.def,
5678                                                            span: freevar.span,
5679                                                            ty: freevar_ty })
5680                             }
5681
5682                             ast::CaptureByRef => {
5683                                 let upvar_id = ty::UpvarId {
5684                                     var_id: freevar_def_id.node,
5685                                     closure_expr_id: closure_id.node
5686                                 };
5687
5688                                 // FIXME
5689                                 let freevar_ref_ty = match typer.upvar_borrow(upvar_id) {
5690                                     Some(borrow) => {
5691                                         mk_rptr(tcx,
5692                                                 tcx.mk_region(borrow.region),
5693                                                 ty::mt {
5694                                                     ty: freevar_ty,
5695                                                     mutbl: borrow.kind.to_mutbl_lossy(),
5696                                                 })
5697                                     }
5698                                     None => {
5699                                         // FIXME(#16640) we should really return None here;
5700                                         // but that requires better inference integration,
5701                                         // for now gin up something.
5702                                         freevar_ty
5703                                     }
5704                                 };
5705                                 Some(UnboxedClosureUpvar {
5706                                     def: freevar.def,
5707                                     span: freevar.span,
5708                                     ty: freevar_ref_ty,
5709                                 })
5710                             }
5711                         }
5712                     })
5713                     .collect()
5714         }
5715     }
5716 }
5717
5718 pub fn is_binopable<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, op: ast::BinOp) -> bool {
5719     #![allow(non_upper_case_globals)]
5720     static tycat_other: int = 0;
5721     static tycat_bool: int = 1;
5722     static tycat_char: int = 2;
5723     static tycat_int: int = 3;
5724     static tycat_float: int = 4;
5725     static tycat_raw_ptr: int = 6;
5726
5727     static opcat_add: int = 0;
5728     static opcat_sub: int = 1;
5729     static opcat_mult: int = 2;
5730     static opcat_shift: int = 3;
5731     static opcat_rel: int = 4;
5732     static opcat_eq: int = 5;
5733     static opcat_bit: int = 6;
5734     static opcat_logic: int = 7;
5735     static opcat_mod: int = 8;
5736
5737     fn opcat(op: ast::BinOp) -> int {
5738         match op {
5739           ast::BiAdd => opcat_add,
5740           ast::BiSub => opcat_sub,
5741           ast::BiMul => opcat_mult,
5742           ast::BiDiv => opcat_mult,
5743           ast::BiRem => opcat_mod,
5744           ast::BiAnd => opcat_logic,
5745           ast::BiOr => opcat_logic,
5746           ast::BiBitXor => opcat_bit,
5747           ast::BiBitAnd => opcat_bit,
5748           ast::BiBitOr => opcat_bit,
5749           ast::BiShl => opcat_shift,
5750           ast::BiShr => opcat_shift,
5751           ast::BiEq => opcat_eq,
5752           ast::BiNe => opcat_eq,
5753           ast::BiLt => opcat_rel,
5754           ast::BiLe => opcat_rel,
5755           ast::BiGe => opcat_rel,
5756           ast::BiGt => opcat_rel
5757         }
5758     }
5759
5760     fn tycat<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> int {
5761         if type_is_simd(cx, ty) {
5762             return tycat(cx, simd_type(cx, ty))
5763         }
5764         match ty.sty {
5765           ty_char => tycat_char,
5766           ty_bool => tycat_bool,
5767           ty_int(_) | ty_uint(_) | ty_infer(IntVar(_)) => tycat_int,
5768           ty_float(_) | ty_infer(FloatVar(_)) => tycat_float,
5769           ty_ptr(_) => tycat_raw_ptr,
5770           _ => tycat_other
5771         }
5772     }
5773
5774     static t: bool = true;
5775     static f: bool = false;
5776
5777     let tbl = [
5778     //           +, -, *, shift, rel, ==, bit, logic, mod
5779     /*other*/   [f, f, f, f,     f,   f,  f,   f,     f],
5780     /*bool*/    [f, f, f, f,     t,   t,  t,   t,     f],
5781     /*char*/    [f, f, f, f,     t,   t,  f,   f,     f],
5782     /*int*/     [t, t, t, t,     t,   t,  t,   f,     t],
5783     /*float*/   [t, t, t, f,     t,   t,  f,   f,     f],
5784     /*bot*/     [t, t, t, t,     t,   t,  t,   t,     t],
5785     /*raw ptr*/ [f, f, f, f,     t,   t,  f,   f,     f]];
5786
5787     return tbl[tycat(cx, ty) as uint ][opcat(op) as uint];
5788 }
5789
5790 /// Returns an equivalent type with all the typedefs and self regions removed.
5791 pub fn normalize_ty<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
5792     let u = TypeNormalizer(cx).fold_ty(ty);
5793     return u;
5794
5795     struct TypeNormalizer<'a, 'tcx: 'a>(&'a ctxt<'tcx>);
5796
5797     impl<'a, 'tcx> TypeFolder<'tcx> for TypeNormalizer<'a, 'tcx> {
5798         fn tcx(&self) -> &ctxt<'tcx> { let TypeNormalizer(c) = *self; c }
5799
5800         fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
5801             match self.tcx().normalized_cache.borrow().get(&ty).cloned() {
5802                 None => {}
5803                 Some(u) => return u
5804             }
5805
5806             let t_norm = ty_fold::super_fold_ty(self, ty);
5807             self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm);
5808             return t_norm;
5809         }
5810
5811         fn fold_region(&mut self, _: ty::Region) -> ty::Region {
5812             ty::ReStatic
5813         }
5814
5815         fn fold_substs(&mut self,
5816                        substs: &subst::Substs<'tcx>)
5817                        -> subst::Substs<'tcx> {
5818             subst::Substs { regions: subst::ErasedRegions,
5819                             types: substs.types.fold_with(self) }
5820         }
5821     }
5822 }
5823
5824 // Returns the repeat count for a repeating vector expression.
5825 pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint {
5826     match const_eval::eval_const_expr_partial(tcx, count_expr) {
5827         Ok(val) => {
5828             let found = match val {
5829                 const_eval::const_uint(count) => return count as uint,
5830                 const_eval::const_int(count) if count >= 0 => return count as uint,
5831                 const_eval::const_int(_) =>
5832                     "negative integer",
5833                 const_eval::const_float(_) =>
5834                     "float",
5835                 const_eval::const_str(_) =>
5836                     "string",
5837                 const_eval::const_bool(_) =>
5838                     "boolean",
5839                 const_eval::const_binary(_) =>
5840                     "binary array"
5841             };
5842             tcx.sess.span_err(count_expr.span, format!(
5843                 "expected positive integer for repeat count, found {}",
5844                 found)[]);
5845         }
5846         Err(_) => {
5847             let found = match count_expr.node {
5848                 ast::ExprPath(ast::Path {
5849                     global: false,
5850                     ref segments,
5851                     ..
5852                 }) if segments.len() == 1 =>
5853                     "variable",
5854                 _ =>
5855                     "non-constant expression"
5856             };
5857             tcx.sess.span_err(count_expr.span, format!(
5858                 "expected constant integer for repeat count, found {}",
5859                 found)[]);
5860         }
5861     }
5862     0
5863 }
5864
5865 // Iterate over a type parameter's bounded traits and any supertraits
5866 // of those traits, ignoring kinds.
5867 // Here, the supertraits are the transitive closure of the supertrait
5868 // relation on the supertraits from each bounded trait's constraint
5869 // list.
5870 pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
5871                                                  bounds: &[PolyTraitRef<'tcx>],
5872                                                  mut f: F)
5873                                                  -> bool where
5874     F: FnMut(PolyTraitRef<'tcx>) -> bool,
5875 {
5876     for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
5877         if !f(bound_trait_ref) {
5878             return false;
5879         }
5880     }
5881     return true;
5882 }
5883
5884 pub fn object_region_bounds<'tcx>(
5885     tcx: &ctxt<'tcx>,
5886     opt_principal: Option<&PolyTraitRef<'tcx>>, // None for closures
5887     others: BuiltinBounds)
5888     -> Vec<ty::Region>
5889 {
5890     // Since we don't actually *know* the self type for an object,
5891     // this "open(err)" serves as a kind of dummy standin -- basically
5892     // a skolemized type.
5893     let open_ty = ty::mk_infer(tcx, FreshTy(0));
5894
5895     let opt_trait_ref = opt_principal.map_or(Vec::new(), |principal| {
5896         // Note that we preserve the overall binding levels here.
5897         assert!(!open_ty.has_escaping_regions());
5898         let substs = tcx.mk_substs(principal.0.substs.with_self_ty(open_ty));
5899         vec!(ty::Binder(Rc::new(ty::TraitRef::new(principal.0.def_id, substs))))
5900     });
5901
5902     let param_bounds = ty::ParamBounds {
5903         region_bounds: Vec::new(),
5904         builtin_bounds: others,
5905         trait_bounds: opt_trait_ref,
5906         projection_bounds: Vec::new(), // not relevant to computing region bounds
5907     };
5908
5909     let predicates = ty::predicates(tcx, open_ty, &param_bounds);
5910     ty::required_region_bounds(tcx, open_ty, predicates)
5911 }
5912
5913 /// Given a set of predicates that apply to an object type, returns
5914 /// the region bounds that the (erased) `Self` type must
5915 /// outlive. Precisely *because* the `Self` type is erased, the
5916 /// parameter `erased_self_ty` must be supplied to indicate what type
5917 /// has been used to represent `Self` in the predicates
5918 /// themselves. This should really be a unique type; `FreshTy(0)` is a
5919 /// popular choice (see `object_region_bounds` above).
5920 ///
5921 /// Requires that trait definitions have been processed so that we can
5922 /// elaborate predicates and walk supertraits.
5923 pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
5924                                     erased_self_ty: Ty<'tcx>,
5925                                     predicates: Vec<ty::Predicate<'tcx>>)
5926                                     -> Vec<ty::Region>
5927 {
5928     debug!("required_region_bounds(erased_self_ty={}, predicates={})",
5929            erased_self_ty.repr(tcx),
5930            predicates.repr(tcx));
5931
5932     assert!(!erased_self_ty.has_escaping_regions());
5933
5934     traits::elaborate_predicates(tcx, predicates)
5935         .filter_map(|predicate| {
5936             match predicate {
5937                 ty::Predicate::Projection(..) |
5938                 ty::Predicate::Trait(..) |
5939                 ty::Predicate::Equate(..) |
5940                 ty::Predicate::RegionOutlives(..) => {
5941                     None
5942                 }
5943                 ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t, r))) => {
5944                     // Search for a bound of the form `erased_self_ty
5945                     // : 'a`, but be wary of something like `for<'a>
5946                     // erased_self_ty : 'a` (we interpret a
5947                     // higher-ranked bound like that as 'static,
5948                     // though at present the code in `fulfill.rs`
5949                     // considers such bounds to be unsatisfiable, so
5950                     // it's kind of a moot point since you could never
5951                     // construct such an object, but this seems
5952                     // correct even if that code changes).
5953                     if t == erased_self_ty && !r.has_escaping_regions() {
5954                         if r.has_escaping_regions() {
5955                             Some(ty::ReStatic)
5956                         } else {
5957                             Some(r)
5958                         }
5959                     } else {
5960                         None
5961                     }
5962                 }
5963             }
5964         })
5965         .collect()
5966 }
5967
5968 pub fn get_tydesc_ty<'tcx>(tcx: &ctxt<'tcx>) -> Result<Ty<'tcx>, String> {
5969     tcx.lang_items.require(TyDescStructLangItem).map(|tydesc_lang_item| {
5970         tcx.intrinsic_defs.borrow().get(&tydesc_lang_item).cloned()
5971             .expect("Failed to resolve TyDesc")
5972     })
5973 }
5974
5975 pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
5976     lookup_locally_or_in_crate_store(
5977         "item_variance_map", item_id, &mut *tcx.item_variance_map.borrow_mut(),
5978         || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id)))
5979 }
5980
5981 /// Records a trait-to-implementation mapping.
5982 pub fn record_trait_implementation(tcx: &ctxt,
5983                                    trait_def_id: DefId,
5984                                    impl_def_id: DefId) {
5985     match tcx.trait_impls.borrow().get(&trait_def_id) {
5986         Some(impls_for_trait) => {
5987             impls_for_trait.borrow_mut().push(impl_def_id);
5988             return;
5989         }
5990         None => {}
5991     }
5992     tcx.trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id))));
5993 }
5994
5995 /// Populates the type context with all the implementations for the given type
5996 /// if necessary.
5997 pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
5998                                                       type_id: ast::DefId) {
5999     if type_id.krate == LOCAL_CRATE {
6000         return
6001     }
6002     if tcx.populated_external_types.borrow().contains(&type_id) {
6003         return
6004     }
6005
6006     debug!("populate_implementations_for_type_if_necessary: searching for {}", type_id);
6007
6008     let mut inherent_impls = Vec::new();
6009     csearch::each_implementation_for_type(&tcx.sess.cstore, type_id,
6010             |impl_def_id| {
6011         let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id);
6012
6013         // Record the trait->implementation mappings, if applicable.
6014         let associated_traits = csearch::get_impl_trait(tcx, impl_def_id);
6015         for trait_ref in associated_traits.iter() {
6016             record_trait_implementation(tcx, trait_ref.def_id, impl_def_id);
6017         }
6018
6019         // For any methods that use a default implementation, add them to
6020         // the map. This is a bit unfortunate.
6021         for impl_item_def_id in impl_items.iter() {
6022             let method_def_id = impl_item_def_id.def_id();
6023             match impl_or_trait_item(tcx, method_def_id) {
6024                 MethodTraitItem(method) => {
6025                     for &source in method.provided_source.iter() {
6026                         tcx.provided_method_sources
6027                            .borrow_mut()
6028                            .insert(method_def_id, source);
6029                     }
6030                 }
6031                 TypeTraitItem(_) => {}
6032             }
6033         }
6034
6035         // Store the implementation info.
6036         tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
6037
6038         // If this is an inherent implementation, record it.
6039         if associated_traits.is_none() {
6040             inherent_impls.push(impl_def_id);
6041         }
6042     });
6043
6044     tcx.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls));
6045     tcx.populated_external_types.borrow_mut().insert(type_id);
6046 }
6047
6048 /// Populates the type context with all the implementations for the given
6049 /// trait if necessary.
6050 pub fn populate_implementations_for_trait_if_necessary(
6051         tcx: &ctxt,
6052         trait_id: ast::DefId) {
6053     if trait_id.krate == LOCAL_CRATE {
6054         return
6055     }
6056     if tcx.populated_external_traits.borrow().contains(&trait_id) {
6057         return
6058     }
6059
6060     csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id,
6061             |implementation_def_id| {
6062         let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id);
6063
6064         // Record the trait->implementation mapping.
6065         record_trait_implementation(tcx, trait_id, implementation_def_id);
6066
6067         // For any methods that use a default implementation, add them to
6068         // the map. This is a bit unfortunate.
6069         for impl_item_def_id in impl_items.iter() {
6070             let method_def_id = impl_item_def_id.def_id();
6071             match impl_or_trait_item(tcx, method_def_id) {
6072                 MethodTraitItem(method) => {
6073                     for &source in method.provided_source.iter() {
6074                         tcx.provided_method_sources
6075                            .borrow_mut()
6076                            .insert(method_def_id, source);
6077                     }
6078                 }
6079                 TypeTraitItem(_) => {}
6080             }
6081         }
6082
6083         // Store the implementation info.
6084         tcx.impl_items.borrow_mut().insert(implementation_def_id, impl_items);
6085     });
6086
6087     tcx.populated_external_traits.borrow_mut().insert(trait_id);
6088 }
6089
6090 /// Given the def_id of an impl, return the def_id of the trait it implements.
6091 /// If it implements no trait, return `None`.
6092 pub fn trait_id_of_impl(tcx: &ctxt,
6093                         def_id: ast::DefId)
6094                         -> Option<ast::DefId> {
6095     ty::impl_trait_ref(tcx, def_id).map(|tr| tr.def_id)
6096 }
6097
6098 /// If the given def ID describes a method belonging to an impl, return the
6099 /// ID of the impl that the method belongs to. Otherwise, return `None`.
6100 pub fn impl_of_method(tcx: &ctxt, def_id: ast::DefId)
6101                        -> Option<ast::DefId> {
6102     if def_id.krate != LOCAL_CRATE {
6103         return match csearch::get_impl_or_trait_item(tcx,
6104                                                      def_id).container() {
6105             TraitContainer(_) => None,
6106             ImplContainer(def_id) => Some(def_id),
6107         };
6108     }
6109     match tcx.impl_or_trait_items.borrow().get(&def_id).cloned() {
6110         Some(trait_item) => {
6111             match trait_item.container() {
6112                 TraitContainer(_) => None,
6113                 ImplContainer(def_id) => Some(def_id),
6114             }
6115         }
6116         None => None
6117     }
6118 }
6119
6120 /// If the given def ID describes an item belonging to a trait (either a
6121 /// default method or an implementation of a trait method), return the ID of
6122 /// the trait that the method belongs to. Otherwise, return `None`.
6123 pub fn trait_of_item(tcx: &ctxt, def_id: ast::DefId) -> Option<ast::DefId> {
6124     if def_id.krate != LOCAL_CRATE {
6125         return csearch::get_trait_of_item(&tcx.sess.cstore, def_id, tcx);
6126     }
6127     match tcx.impl_or_trait_items.borrow().get(&def_id).cloned() {
6128         Some(impl_or_trait_item) => {
6129             match impl_or_trait_item.container() {
6130                 TraitContainer(def_id) => Some(def_id),
6131                 ImplContainer(def_id) => trait_id_of_impl(tcx, def_id),
6132             }
6133         }
6134         None => None
6135     }
6136 }
6137
6138 /// If the given def ID describes an item belonging to a trait, (either a
6139 /// default method or an implementation of a trait method), return the ID of
6140 /// the method inside trait definition (this means that if the given def ID
6141 /// is already that of the original trait method, then the return value is
6142 /// the same).
6143 /// Otherwise, return `None`.
6144 pub fn trait_item_of_item(tcx: &ctxt, def_id: ast::DefId)
6145                           -> Option<ImplOrTraitItemId> {
6146     let impl_item = match tcx.impl_or_trait_items.borrow().get(&def_id) {
6147         Some(m) => m.clone(),
6148         None => return None,
6149     };
6150     let name = impl_item.name();
6151     match trait_of_item(tcx, def_id) {
6152         Some(trait_did) => {
6153             let trait_items = ty::trait_items(tcx, trait_did);
6154             trait_items.iter()
6155                 .position(|m| m.name() == name)
6156                 .map(|idx| ty::trait_item(tcx, trait_did, idx).id())
6157         }
6158         None => None
6159     }
6160 }
6161
6162 /// Creates a hash of the type `Ty` which will be the same no matter what crate
6163 /// context it's calculated within. This is used by the `type_id` intrinsic.
6164 pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -> u64 {
6165     let mut state = sip::SipState::new();
6166     helper(tcx, ty, svh, &mut state);
6167     return state.result();
6168
6169     fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh, state: &mut sip::SipState) {
6170         macro_rules! byte( ($b:expr) => { ($b as u8).hash(state) } );
6171         macro_rules! hash( ($e:expr) => { $e.hash(state) } );
6172
6173         let region = |&: state: &mut sip::SipState, r: Region| {
6174             match r {
6175                 ReStatic => {}
6176                 ReLateBound(db, BrAnon(i)) => {
6177                     db.hash(state);
6178                     i.hash(state);
6179                 }
6180                 ReEmpty |
6181                 ReEarlyBound(..) |
6182                 ReLateBound(..) |
6183                 ReFree(..) |
6184                 ReScope(..) |
6185                 ReInfer(..) => {
6186                     tcx.sess.bug("unexpected region found when hashing a type")
6187                 }
6188             }
6189         };
6190         let did = |&: state: &mut sip::SipState, did: DefId| {
6191             let h = if ast_util::is_local(did) {
6192                 svh.clone()
6193             } else {
6194                 tcx.sess.cstore.get_crate_hash(did.krate)
6195             };
6196             h.as_str().hash(state);
6197             did.node.hash(state);
6198         };
6199         let mt = |&: state: &mut sip::SipState, mt: mt| {
6200             mt.mutbl.hash(state);
6201         };
6202         let fn_sig = |&: state: &mut sip::SipState, sig: &Binder<FnSig<'tcx>>| {
6203             let sig = anonymize_late_bound_regions(tcx, sig);
6204             for a in sig.inputs.iter() { helper(tcx, *a, svh, state); }
6205             if let ty::FnConverging(output) = sig.output {
6206                 helper(tcx, output, svh, state);
6207             }
6208         };
6209         maybe_walk_ty(ty, |ty| {
6210             match ty.sty {
6211                 ty_bool => byte!(2),
6212                 ty_char => byte!(3),
6213                 ty_int(i) => {
6214                     byte!(4);
6215                     hash!(i);
6216                 }
6217                 ty_uint(u) => {
6218                     byte!(5);
6219                     hash!(u);
6220                 }
6221                 ty_float(f) => {
6222                     byte!(6);
6223                     hash!(f);
6224                 }
6225                 ty_str => {
6226                     byte!(7);
6227                 }
6228                 ty_enum(d, _) => {
6229                     byte!(8);
6230                     did(state, d);
6231                 }
6232                 ty_uniq(_) => {
6233                     byte!(9);
6234                 }
6235                 ty_vec(_, Some(n)) => {
6236                     byte!(10);
6237                     n.hash(state);
6238                 }
6239                 ty_vec(_, None) => {
6240                     byte!(11);
6241                 }
6242                 ty_ptr(m) => {
6243                     byte!(12);
6244                     mt(state, m);
6245                 }
6246                 ty_rptr(r, m) => {
6247                     byte!(13);
6248                     region(state, *r);
6249                     mt(state, m);
6250                 }
6251                 ty_bare_fn(opt_def_id, ref b) => {
6252                     byte!(14);
6253                     hash!(opt_def_id);
6254                     hash!(b.unsafety);
6255                     hash!(b.abi);
6256                     fn_sig(state, &b.sig);
6257                     return false;
6258                 }
6259                 ty_trait(ref data) => {
6260                     byte!(17);
6261                     did(state, data.principal_def_id());
6262                     hash!(data.bounds);
6263
6264                     let principal = anonymize_late_bound_regions(tcx, &data.principal);
6265                     for subty in principal.substs.types.iter() {
6266                         helper(tcx, *subty, svh, state);
6267                     }
6268
6269                     return false;
6270                 }
6271                 ty_struct(d, _) => {
6272                     byte!(18);
6273                     did(state, d);
6274                 }
6275                 ty_tup(ref inner) => {
6276                     byte!(19);
6277                     hash!(inner.len());
6278                 }
6279                 ty_param(p) => {
6280                     byte!(20);
6281                     hash!(p.space);
6282                     hash!(p.idx);
6283                     hash!(token::get_name(p.name));
6284                 }
6285                 ty_open(_) => byte!(22),
6286                 ty_infer(_) => unreachable!(),
6287                 ty_err => byte!(23),
6288                 ty_unboxed_closure(d, r, _) => {
6289                     byte!(24);
6290                     did(state, d);
6291                     region(state, *r);
6292                 }
6293                 ty_projection(ref data) => {
6294                     byte!(25);
6295                     did(state, data.trait_ref.def_id);
6296                     hash!(token::get_name(data.item_name));
6297                 }
6298             }
6299             true
6300         });
6301     }
6302 }
6303
6304 impl Variance {
6305     pub fn to_string(self) -> &'static str {
6306         match self {
6307             Covariant => "+",
6308             Contravariant => "-",
6309             Invariant => "o",
6310             Bivariant => "*",
6311         }
6312     }
6313 }
6314
6315 /// Construct a parameter environment suitable for static contexts or other contexts where there
6316 /// are no free type/lifetime parameters in scope.
6317 pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvironment<'a,'tcx> {
6318     ty::ParameterEnvironment { tcx: cx,
6319                                free_substs: Substs::empty(),
6320                                caller_bounds: GenericBounds::empty(),
6321                                implicit_region_bound: ty::ReEmpty,
6322                                selection_cache: traits::SelectionCache::new(), }
6323 }
6324
6325 /// See `ParameterEnvironment` struct def'n for details
6326 pub fn construct_parameter_environment<'a,'tcx>(
6327     tcx: &'a ctxt<'tcx>,
6328     generics: &ty::Generics<'tcx>,
6329     free_id: ast::NodeId)
6330     -> ParameterEnvironment<'a, 'tcx>
6331 {
6332
6333     //
6334     // Construct the free substs.
6335     //
6336
6337     // map T => T
6338     let mut types = VecPerParamSpace::empty();
6339     push_types_from_defs(tcx, &mut types, generics.types.as_slice());
6340
6341     // map bound 'a => free 'a
6342     let mut regions = VecPerParamSpace::empty();
6343     push_region_params(&mut regions, free_id, generics.regions.as_slice());
6344
6345     let free_substs = Substs {
6346         types: types,
6347         regions: subst::NonerasedRegions(regions)
6348     };
6349
6350     let free_id_scope = region::CodeExtent::from_node_id(free_id);
6351
6352     //
6353     // Compute the bounds on Self and the type parameters.
6354     //
6355
6356     let bounds = generics.to_bounds(tcx, &free_substs);
6357     let bounds = liberate_late_bound_regions(tcx, free_id_scope, &ty::Binder(bounds));
6358
6359     //
6360     // Compute region bounds. For now, these relations are stored in a
6361     // global table on the tcx, so just enter them there. I'm not
6362     // crazy about this scheme, but it's convenient, at least.
6363     //
6364
6365     record_region_bounds(tcx, &bounds);
6366
6367     debug!("construct_parameter_environment: free_id={} free_subst={} bounds={}",
6368            free_id,
6369            free_substs.repr(tcx),
6370            bounds.repr(tcx));
6371
6372     return ty::ParameterEnvironment {
6373         tcx: tcx,
6374         free_substs: free_substs,
6375         implicit_region_bound: ty::ReScope(free_id_scope),
6376         caller_bounds: bounds,
6377         selection_cache: traits::SelectionCache::new(),
6378     };
6379
6380     fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,
6381                           free_id: ast::NodeId,
6382                           region_params: &[RegionParameterDef])
6383     {
6384         for r in region_params.iter() {
6385             regions.push(r.space, ty::free_region_from_def(free_id, r));
6386         }
6387     }
6388
6389     fn push_types_from_defs<'tcx>(tcx: &ty::ctxt<'tcx>,
6390                                   types: &mut VecPerParamSpace<Ty<'tcx>>,
6391                                   defs: &[TypeParameterDef<'tcx>]) {
6392         for def in defs.iter() {
6393             debug!("construct_parameter_environment(): push_types_from_defs: def={}",
6394                    def.repr(tcx));
6395             let ty = ty::mk_param_from_def(tcx, def);
6396             types.push(def.space, ty);
6397         }
6398     }
6399
6400     fn record_region_bounds<'tcx>(tcx: &ty::ctxt<'tcx>, bounds: &GenericBounds<'tcx>) {
6401         debug!("record_region_bounds(bounds={})", bounds.repr(tcx));
6402
6403         for predicate in bounds.predicates.iter() {
6404             match *predicate {
6405                 Predicate::Projection(..) |
6406                 Predicate::Trait(..) |
6407                 Predicate::Equate(..) |
6408                 Predicate::TypeOutlives(..) => {
6409                     // No region bounds here
6410                 }
6411                 Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
6412                     match (r_a, r_b) {
6413                         (ty::ReFree(fr_a), ty::ReFree(fr_b)) => {
6414                             // Record that `'a:'b`. Or, put another way, `'b <= 'a`.
6415                             tcx.region_maps.relate_free_regions(fr_b, fr_a);
6416                         }
6417                         _ => {
6418                             // All named regions are instantiated with free regions.
6419                             tcx.sess.bug(
6420                                 format!("record_region_bounds: non free region: {} / {}",
6421                                         r_a.repr(tcx),
6422                                         r_b.repr(tcx)).as_slice());
6423                         }
6424                     }
6425                 }
6426             }
6427         }
6428     }
6429 }
6430
6431 impl BorrowKind {
6432     pub fn from_mutbl(m: ast::Mutability) -> BorrowKind {
6433         match m {
6434             ast::MutMutable => MutBorrow,
6435             ast::MutImmutable => ImmBorrow,
6436         }
6437     }
6438
6439     /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
6440     /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
6441     /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
6442     /// question.
6443     pub fn to_mutbl_lossy(self) -> ast::Mutability {
6444         match self {
6445             MutBorrow => ast::MutMutable,
6446             ImmBorrow => ast::MutImmutable,
6447
6448             // We have no type corresponding to a unique imm borrow, so
6449             // use `&mut`. It gives all the capabilities of an `&uniq`
6450             // and hence is a safe "over approximation".
6451             UniqueImmBorrow => ast::MutMutable,
6452         }
6453     }
6454
6455     pub fn to_user_str(&self) -> &'static str {
6456         match *self {
6457             MutBorrow => "mutable",
6458             ImmBorrow => "immutable",
6459             UniqueImmBorrow => "uniquely immutable",
6460         }
6461     }
6462 }
6463
6464 impl<'tcx> ctxt<'tcx> {
6465     pub fn capture_mode(&self, closure_expr_id: ast::NodeId)
6466                     -> ast::CaptureClause {
6467         self.capture_modes.borrow()[closure_expr_id].clone()
6468     }
6469
6470     pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
6471         self.method_map.borrow().contains_key(&MethodCall::expr(expr_id))
6472     }
6473 }
6474
6475 impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
6476     fn tcx(&self) -> &ty::ctxt<'tcx> {
6477         self.tcx
6478     }
6479
6480     fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
6481         Ok(ty::node_id_to_type(self.tcx, id))
6482     }
6483
6484     fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
6485         Ok(ty::expr_ty_adjusted(self.tcx, expr))
6486     }
6487
6488     fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
6489         self.tcx.method_map.borrow().get(&method_call).map(|method| method.ty)
6490     }
6491
6492     fn node_method_origin(&self, method_call: ty::MethodCall)
6493                           -> Option<ty::MethodOrigin<'tcx>>
6494     {
6495         self.tcx.method_map.borrow().get(&method_call).map(|method| method.origin.clone())
6496     }
6497
6498     fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
6499         &self.tcx.adjustments
6500     }
6501
6502     fn is_method_call(&self, id: ast::NodeId) -> bool {
6503         self.tcx.is_method_call(id)
6504     }
6505
6506     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
6507         self.tcx.region_maps.temporary_scope(rvalue_id)
6508     }
6509
6510     fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> {
6511         Some(self.tcx.upvar_borrow_map.borrow()[upvar_id].clone())
6512     }
6513
6514     fn capture_mode(&self, closure_expr_id: ast::NodeId)
6515                     -> ast::CaptureClause {
6516         self.tcx.capture_mode(closure_expr_id)
6517     }
6518
6519     fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool {
6520         type_moves_by_default(self, span, ty)
6521     }
6522 }
6523
6524 impl<'a,'tcx> UnboxedClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> {
6525     fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
6526         self
6527     }
6528
6529     fn unboxed_closure_kind(&self,
6530                             def_id: ast::DefId)
6531                             -> ty::UnboxedClosureKind
6532     {
6533         self.tcx.unboxed_closure_kind(def_id)
6534     }
6535
6536     fn unboxed_closure_type(&self,
6537                             def_id: ast::DefId,
6538                             substs: &subst::Substs<'tcx>)
6539                             -> ty::ClosureTy<'tcx>
6540     {
6541         self.tcx.unboxed_closure_type(def_id, substs)
6542     }
6543
6544     fn unboxed_closure_upvars(&self,
6545                               def_id: ast::DefId,
6546                               substs: &Substs<'tcx>)
6547                               -> Option<Vec<UnboxedClosureUpvar<'tcx>>>
6548     {
6549         unboxed_closure_upvars(self, def_id, substs)
6550     }
6551 }
6552
6553
6554 /// The category of explicit self.
6555 #[derive(Clone, Copy, Eq, PartialEq, Show)]
6556 pub enum ExplicitSelfCategory {
6557     StaticExplicitSelfCategory,
6558     ByValueExplicitSelfCategory,
6559     ByReferenceExplicitSelfCategory(Region, ast::Mutability),
6560     ByBoxExplicitSelfCategory,
6561 }
6562
6563 /// Pushes all the lifetimes in the given type onto the given list. A
6564 /// "lifetime in a type" is a lifetime specified by a reference or a lifetime
6565 /// in a list of type substitutions. This does *not* traverse into nominal
6566 /// types, nor does it resolve fictitious types.
6567 pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
6568                                     ty: Ty) {
6569     walk_ty(ty, |ty| {
6570         match ty.sty {
6571             ty_rptr(region, _) => {
6572                 accumulator.push(*region)
6573             }
6574             ty_trait(ref t) => {
6575                 accumulator.push_all(t.principal.0.substs.regions().as_slice());
6576             }
6577             ty_enum(_, substs) |
6578             ty_struct(_, substs) => {
6579                 accum_substs(accumulator, substs);
6580             }
6581             ty_unboxed_closure(_, region, substs) => {
6582                 accumulator.push(*region);
6583                 accum_substs(accumulator, substs);
6584             }
6585             ty_bool |
6586             ty_char |
6587             ty_int(_) |
6588             ty_uint(_) |
6589             ty_float(_) |
6590             ty_uniq(_) |
6591             ty_str |
6592             ty_vec(_, _) |
6593             ty_ptr(_) |
6594             ty_bare_fn(..) |
6595             ty_tup(_) |
6596             ty_projection(_) |
6597             ty_param(_) |
6598             ty_infer(_) |
6599             ty_open(_) |
6600             ty_err => {
6601             }
6602         }
6603     });
6604
6605     fn accum_substs(accumulator: &mut Vec<Region>, substs: &Substs) {
6606         match substs.regions {
6607             subst::ErasedRegions => {}
6608             subst::NonerasedRegions(ref regions) => {
6609                 for region in regions.iter() {
6610                     accumulator.push(*region)
6611                 }
6612             }
6613         }
6614     }
6615 }
6616
6617 /// A free variable referred to in a function.
6618 #[derive(Copy, RustcEncodable, RustcDecodable)]
6619 pub struct Freevar {
6620     /// The variable being accessed free.
6621     pub def: def::Def,
6622
6623     // First span where it is accessed (there can be multiple).
6624     pub span: Span
6625 }
6626
6627 pub type FreevarMap = NodeMap<Vec<Freevar>>;
6628
6629 pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
6630
6631 // Trait method resolution
6632 pub type TraitMap = NodeMap<Vec<DefId>>;
6633
6634 // Map from the NodeId of a glob import to a list of items which are actually
6635 // imported.
6636 pub type GlobMap = HashMap<NodeId, HashSet<Name>>;
6637
6638 pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
6639     F: FnOnce(&[Freevar]) -> T,
6640 {
6641     match tcx.freevars.borrow().get(&fid) {
6642         None => f(&[]),
6643         Some(d) => f(d[])
6644     }
6645 }
6646
6647 impl<'tcx> AutoAdjustment<'tcx> {
6648     pub fn is_identity(&self) -> bool {
6649         match *self {
6650             AdjustReifyFnPointer(..) => false,
6651             AdjustDerefRef(ref r) => r.is_identity(),
6652         }
6653     }
6654 }
6655
6656 impl<'tcx> AutoDerefRef<'tcx> {
6657     pub fn is_identity(&self) -> bool {
6658         self.autoderefs == 0 && self.autoref.is_none()
6659     }
6660 }
6661
6662 /// Replace any late-bound regions bound in `value` with free variants attached to scope-id
6663 /// `scope_id`.
6664 pub fn liberate_late_bound_regions<'tcx, T>(
6665     tcx: &ty::ctxt<'tcx>,
6666     scope: region::CodeExtent,
6667     value: &Binder<T>)
6668     -> T
6669     where T : TypeFoldable<'tcx> + Repr<'tcx>
6670 {
6671     replace_late_bound_regions(
6672         tcx, value,
6673         |br, _| ty::ReFree(ty::FreeRegion{scope: scope, bound_region: br})).0
6674 }
6675
6676 pub fn count_late_bound_regions<'tcx, T>(
6677     tcx: &ty::ctxt<'tcx>,
6678     value: &Binder<T>)
6679     -> uint
6680     where T : TypeFoldable<'tcx> + Repr<'tcx>
6681 {
6682     let (_, skol_map) = replace_late_bound_regions(tcx, value, |_, _| ty::ReStatic);
6683     skol_map.len()
6684 }
6685
6686 pub fn binds_late_bound_regions<'tcx, T>(
6687     tcx: &ty::ctxt<'tcx>,
6688     value: &Binder<T>)
6689     -> bool
6690     where T : TypeFoldable<'tcx> + Repr<'tcx>
6691 {
6692     count_late_bound_regions(tcx, value) > 0
6693 }
6694
6695 /// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
6696 /// method lookup and a few other places where precise region relationships are not required.
6697 pub fn erase_late_bound_regions<'tcx, T>(
6698     tcx: &ty::ctxt<'tcx>,
6699     value: &Binder<T>)
6700     -> T
6701     where T : TypeFoldable<'tcx> + Repr<'tcx>
6702 {
6703     replace_late_bound_regions(tcx, value, |_, _| ty::ReStatic).0
6704 }
6705
6706 /// Rewrite any late-bound regions so that they are anonymous.  Region numbers are
6707 /// assigned starting at 1 and increasing monotonically in the order traversed
6708 /// by the fold operation.
6709 ///
6710 /// The chief purpose of this function is to canonicalize regions so that two
6711 /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
6712 /// structurally identical.  For example, `for<'a, 'b> fn(&'a int, &'b int)` and
6713 /// `for<'a, 'b> fn(&'b int, &'a int)` will become identical after anonymization.
6714 pub fn anonymize_late_bound_regions<'tcx, T>(
6715     tcx: &ctxt<'tcx>,
6716     sig: &Binder<T>)
6717     -> T
6718     where T : TypeFoldable<'tcx> + Repr<'tcx>,
6719 {
6720     let mut counter = 0;
6721     replace_late_bound_regions(tcx, sig, |_, db| {
6722         counter += 1;
6723         ReLateBound(db, BrAnon(counter))
6724     }).0
6725 }
6726
6727 /// Replaces the late-bound-regions in `value` that are bound by `value`.
6728 pub fn replace_late_bound_regions<'tcx, T, F>(
6729     tcx: &ty::ctxt<'tcx>,
6730     binder: &Binder<T>,
6731     mut mapf: F)
6732     -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
6733     where T : TypeFoldable<'tcx> + Repr<'tcx>,
6734           F : FnMut(BoundRegion, DebruijnIndex) -> ty::Region,
6735 {
6736     debug!("replace_late_bound_regions({})", binder.repr(tcx));
6737
6738     let mut map = FnvHashMap::new();
6739
6740     // Note: fold the field `0`, not the binder, so that late-bound
6741     // regions bound by `binder` are considered free.
6742     let value = ty_fold::fold_regions(tcx, &binder.0, |region, current_depth| {
6743         debug!("region={}", region.repr(tcx));
6744         match region {
6745             ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
6746                 * map.entry(&br).get().unwrap_or_else(
6747                       |vacant_entry| vacant_entry.insert(mapf(br, debruijn)))
6748             }
6749             _ => {
6750                 region
6751             }
6752         }
6753     });
6754
6755     debug!("resulting map: {} value: {}", map, value.repr(tcx));
6756     (value, map)
6757 }
6758
6759 impl DebruijnIndex {
6760     pub fn new(depth: u32) -> DebruijnIndex {
6761         assert!(depth > 0);
6762         DebruijnIndex { depth: depth }
6763     }
6764
6765     pub fn shifted(&self, amount: u32) -> DebruijnIndex {
6766         DebruijnIndex { depth: self.depth + amount }
6767     }
6768 }
6769
6770 impl<'tcx> Repr<'tcx> for AutoAdjustment<'tcx> {
6771     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
6772         match *self {
6773             AdjustReifyFnPointer(def_id) => {
6774                 format!("AdjustReifyFnPointer({})", def_id.repr(tcx))
6775             }
6776             AdjustDerefRef(ref data) => {
6777                 data.repr(tcx)
6778             }
6779         }
6780     }
6781 }
6782
6783 impl<'tcx> Repr<'tcx> for UnsizeKind<'tcx> {
6784     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
6785         match *self {
6786             UnsizeLength(n) => format!("UnsizeLength({})", n),
6787             UnsizeStruct(ref k, n) => format!("UnsizeStruct({},{})", k.repr(tcx), n),
6788             UnsizeVtable(ref a, ref b) => format!("UnsizeVtable({},{})", a.repr(tcx), b.repr(tcx)),
6789         }
6790     }
6791 }
6792
6793 impl<'tcx> Repr<'tcx> for AutoDerefRef<'tcx> {
6794     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
6795         format!("AutoDerefRef({}, {})", self.autoderefs, self.autoref.repr(tcx))
6796     }
6797 }
6798
6799 impl<'tcx> Repr<'tcx> for AutoRef<'tcx> {
6800     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
6801         match *self {
6802             AutoPtr(a, b, ref c) => {
6803                 format!("AutoPtr({},{},{})", a.repr(tcx), b, c.repr(tcx))
6804             }
6805             AutoUnsize(ref a) => {
6806                 format!("AutoUnsize({})", a.repr(tcx))
6807             }
6808             AutoUnsizeUniq(ref a) => {
6809                 format!("AutoUnsizeUniq({})", a.repr(tcx))
6810             }
6811             AutoUnsafe(ref a, ref b) => {
6812                 format!("AutoUnsafe({},{})", a, b.repr(tcx))
6813             }
6814         }
6815     }
6816 }
6817
6818 impl<'tcx> Repr<'tcx> for TyTrait<'tcx> {
6819     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
6820         format!("TyTrait({},{})",
6821                 self.principal.repr(tcx),
6822                 self.bounds.repr(tcx))
6823     }
6824 }
6825
6826 impl<'tcx> Repr<'tcx> for ty::Predicate<'tcx> {
6827     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
6828         match *self {
6829             Predicate::Trait(ref a) => a.repr(tcx),
6830             Predicate::Equate(ref pair) => pair.repr(tcx),
6831             Predicate::RegionOutlives(ref pair) => pair.repr(tcx),
6832             Predicate::TypeOutlives(ref pair) => pair.repr(tcx),
6833             Predicate::Projection(ref pair) => pair.repr(tcx),
6834         }
6835     }
6836 }
6837
6838 impl<'tcx> Repr<'tcx> for vtable_origin<'tcx> {
6839     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
6840         match *self {
6841             vtable_static(def_id, ref tys, ref vtable_res) => {
6842                 format!("vtable_static({}:{}, {}, {})",
6843                         def_id,
6844                         ty::item_path_str(tcx, def_id),
6845                         tys.repr(tcx),
6846                         vtable_res.repr(tcx))
6847             }
6848
6849             vtable_param(x, y) => {
6850                 format!("vtable_param({}, {})", x, y)
6851             }
6852
6853             vtable_unboxed_closure(def_id) => {
6854                 format!("vtable_unboxed_closure({})", def_id)
6855             }
6856
6857             vtable_error => {
6858                 format!("vtable_error")
6859             }
6860         }
6861     }
6862 }
6863
6864 pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
6865                                             trait_ref: &ty::TraitRef<'tcx>,
6866                                             method: &ty::Method<'tcx>)
6867                                             -> subst::Substs<'tcx>
6868 {
6869     /*!
6870      * Substitutes the values for the receiver's type parameters
6871      * that are found in method, leaving the method's type parameters
6872      * intact.
6873      */
6874
6875     let meth_tps: Vec<Ty> =
6876         method.generics.types.get_slice(subst::FnSpace)
6877               .iter()
6878               .map(|def| ty::mk_param_from_def(tcx, def))
6879               .collect();
6880     let meth_regions: Vec<ty::Region> =
6881         method.generics.regions.get_slice(subst::FnSpace)
6882               .iter()
6883               .map(|def| ty::ReEarlyBound(def.def_id.node, def.space,
6884                                           def.index, def.name))
6885               .collect();
6886     trait_ref.substs.clone().with_method(meth_tps, meth_regions)
6887 }
6888
6889 #[derive(Copy)]
6890 pub enum CopyImplementationError {
6891     FieldDoesNotImplementCopy(ast::Name),
6892     VariantDoesNotImplementCopy(ast::Name),
6893     TypeIsStructural,
6894 }
6895
6896 pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>,
6897                                         span: Span,
6898                                         self_type: Ty<'tcx>)
6899                                         -> Result<(),CopyImplementationError>
6900 {
6901     let tcx = param_env.tcx;
6902
6903     match self_type.sty {
6904         ty::ty_struct(struct_did, substs) => {
6905             let fields = ty::struct_fields(tcx, struct_did, substs);
6906             for field in fields.iter() {
6907                 if type_moves_by_default(param_env, span, field.mt.ty) {
6908                     return Err(FieldDoesNotImplementCopy(field.name))
6909                 }
6910             }
6911         }
6912         ty::ty_enum(enum_did, substs) => {
6913             let enum_variants = ty::enum_variants(tcx, enum_did);
6914             for variant in enum_variants.iter() {
6915                 for variant_arg_type in variant.args.iter() {
6916                     let substd_arg_type =
6917                         variant_arg_type.subst(tcx, substs);
6918                     if type_moves_by_default(param_env, span, substd_arg_type) {
6919                         return Err(VariantDoesNotImplementCopy(variant.name))
6920                     }
6921                 }
6922             }
6923         }
6924         _ => return Err(TypeIsStructural),
6925     }
6926
6927     Ok(())
6928 }
6929
6930 // FIXME(#20298) -- all of these types basically walk various
6931 // structures to test whether types/regions are reachable with various
6932 // properties. It should be possible to express them in terms of one
6933 // common "walker" trait or something.
6934
6935 pub trait RegionEscape {
6936     fn has_escaping_regions(&self) -> bool {
6937         self.has_regions_escaping_depth(0)
6938     }
6939
6940     fn has_regions_escaping_depth(&self, depth: u32) -> bool;
6941 }
6942
6943 impl<'tcx> RegionEscape for Ty<'tcx> {
6944     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
6945         ty::type_escapes_depth(*self, depth)
6946     }
6947 }
6948
6949 impl<'tcx,T:RegionEscape> RegionEscape for VecPerParamSpace<T> {
6950     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
6951         self.iter_enumerated().any(|(space, _, t)| {
6952             if space == subst::FnSpace {
6953                 t.has_regions_escaping_depth(depth+1)
6954             } else {
6955                 t.has_regions_escaping_depth(depth)
6956             }
6957         })
6958     }
6959 }
6960
6961 impl<'tcx> RegionEscape for TypeScheme<'tcx> {
6962     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
6963         self.ty.has_regions_escaping_depth(depth) ||
6964             self.generics.has_regions_escaping_depth(depth)
6965     }
6966 }
6967
6968 impl RegionEscape for Region {
6969     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
6970         self.escapes_depth(depth)
6971     }
6972 }
6973
6974 impl<'tcx> RegionEscape for Generics<'tcx> {
6975     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
6976         self.predicates.has_regions_escaping_depth(depth)
6977     }
6978 }
6979
6980 impl<'tcx> RegionEscape for Predicate<'tcx> {
6981     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
6982         match *self {
6983             Predicate::Trait(ref data) => data.has_regions_escaping_depth(depth),
6984             Predicate::Equate(ref data) => data.has_regions_escaping_depth(depth),
6985             Predicate::RegionOutlives(ref data) => data.has_regions_escaping_depth(depth),
6986             Predicate::TypeOutlives(ref data) => data.has_regions_escaping_depth(depth),
6987             Predicate::Projection(ref data) => data.has_regions_escaping_depth(depth),
6988         }
6989     }
6990 }
6991
6992 impl<'tcx> RegionEscape for TraitRef<'tcx> {
6993     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
6994         self.substs.types.iter().any(|t| t.has_regions_escaping_depth(depth)) ||
6995             self.substs.regions.has_regions_escaping_depth(depth)
6996     }
6997 }
6998
6999 impl<'tcx> RegionEscape for subst::RegionSubsts {
7000     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7001         match *self {
7002             subst::ErasedRegions => false,
7003             subst::NonerasedRegions(ref r) => {
7004                 r.iter().any(|t| t.has_regions_escaping_depth(depth))
7005             }
7006         }
7007     }
7008 }
7009
7010 impl<'tcx,T:RegionEscape> RegionEscape for Binder<T> {
7011     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7012         self.0.has_regions_escaping_depth(depth + 1)
7013     }
7014 }
7015
7016 impl<'tcx> RegionEscape for EquatePredicate<'tcx> {
7017     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7018         self.0.has_regions_escaping_depth(depth) || self.1.has_regions_escaping_depth(depth)
7019     }
7020 }
7021
7022 impl<'tcx> RegionEscape for TraitPredicate<'tcx> {
7023     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7024         self.trait_ref.has_regions_escaping_depth(depth)
7025     }
7026 }
7027
7028 impl<T:RegionEscape,U:RegionEscape> RegionEscape for OutlivesPredicate<T,U> {
7029     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7030         self.0.has_regions_escaping_depth(depth) || self.1.has_regions_escaping_depth(depth)
7031     }
7032 }
7033
7034 impl<'tcx> RegionEscape for ProjectionPredicate<'tcx> {
7035     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7036         self.projection_ty.has_regions_escaping_depth(depth) ||
7037             self.ty.has_regions_escaping_depth(depth)
7038     }
7039 }
7040
7041 impl<'tcx> RegionEscape for ProjectionTy<'tcx> {
7042     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
7043         self.trait_ref.has_regions_escaping_depth(depth)
7044     }
7045 }
7046
7047 impl<'tcx> Repr<'tcx> for ty::ProjectionPredicate<'tcx> {
7048     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
7049         format!("ProjectionPredicate({}, {})",
7050                 self.projection_ty.repr(tcx),
7051                 self.ty.repr(tcx))
7052     }
7053 }
7054
7055 pub trait HasProjectionTypes {
7056     fn has_projection_types(&self) -> bool;
7057 }
7058
7059 impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for Vec<T> {
7060     fn has_projection_types(&self) -> bool {
7061         self.iter().any(|p| p.has_projection_types())
7062     }
7063 }
7064
7065 impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for VecPerParamSpace<T> {
7066     fn has_projection_types(&self) -> bool {
7067         self.iter().any(|p| p.has_projection_types())
7068     }
7069 }
7070
7071 impl<'tcx> HasProjectionTypes for ClosureTy<'tcx> {
7072     fn has_projection_types(&self) -> bool {
7073         self.sig.has_projection_types()
7074     }
7075 }
7076
7077 impl<'tcx> HasProjectionTypes for UnboxedClosureUpvar<'tcx> {
7078     fn has_projection_types(&self) -> bool {
7079         self.ty.has_projection_types()
7080     }
7081 }
7082
7083 impl<'tcx> HasProjectionTypes for ty::GenericBounds<'tcx> {
7084     fn has_projection_types(&self) -> bool {
7085         self.predicates.has_projection_types()
7086     }
7087 }
7088
7089 impl<'tcx> HasProjectionTypes for Predicate<'tcx> {
7090     fn has_projection_types(&self) -> bool {
7091         match *self {
7092             Predicate::Trait(ref data) => data.has_projection_types(),
7093             Predicate::Equate(ref data) => data.has_projection_types(),
7094             Predicate::RegionOutlives(ref data) => data.has_projection_types(),
7095             Predicate::TypeOutlives(ref data) => data.has_projection_types(),
7096             Predicate::Projection(ref data) => data.has_projection_types(),
7097         }
7098     }
7099 }
7100
7101 impl<'tcx> HasProjectionTypes for TraitPredicate<'tcx> {
7102     fn has_projection_types(&self) -> bool {
7103         self.trait_ref.has_projection_types()
7104     }
7105 }
7106
7107 impl<'tcx> HasProjectionTypes for EquatePredicate<'tcx> {
7108     fn has_projection_types(&self) -> bool {
7109         self.0.has_projection_types() || self.1.has_projection_types()
7110     }
7111 }
7112
7113 impl HasProjectionTypes for Region {
7114     fn has_projection_types(&self) -> bool {
7115         false
7116     }
7117 }
7118
7119 impl<T:HasProjectionTypes,U:HasProjectionTypes> HasProjectionTypes for OutlivesPredicate<T,U> {
7120     fn has_projection_types(&self) -> bool {
7121         self.0.has_projection_types() || self.1.has_projection_types()
7122     }
7123 }
7124
7125 impl<'tcx> HasProjectionTypes for ProjectionPredicate<'tcx> {
7126     fn has_projection_types(&self) -> bool {
7127         self.projection_ty.has_projection_types() || self.ty.has_projection_types()
7128     }
7129 }
7130
7131 impl<'tcx> HasProjectionTypes for ProjectionTy<'tcx> {
7132     fn has_projection_types(&self) -> bool {
7133         self.trait_ref.has_projection_types()
7134     }
7135 }
7136
7137 impl<'tcx> HasProjectionTypes for Ty<'tcx> {
7138     fn has_projection_types(&self) -> bool {
7139         ty::type_has_projection(*self)
7140     }
7141 }
7142
7143 impl<'tcx> HasProjectionTypes for TraitRef<'tcx> {
7144     fn has_projection_types(&self) -> bool {
7145         self.substs.has_projection_types()
7146     }
7147 }
7148
7149 impl<'tcx> HasProjectionTypes for subst::Substs<'tcx> {
7150     fn has_projection_types(&self) -> bool {
7151         self.types.iter().any(|t| t.has_projection_types())
7152     }
7153 }
7154
7155 impl<'tcx,T> HasProjectionTypes for Option<T>
7156     where T : HasProjectionTypes
7157 {
7158     fn has_projection_types(&self) -> bool {
7159         self.iter().any(|t| t.has_projection_types())
7160     }
7161 }
7162
7163 impl<'tcx,T> HasProjectionTypes for Rc<T>
7164     where T : HasProjectionTypes
7165 {
7166     fn has_projection_types(&self) -> bool {
7167         (**self).has_projection_types()
7168     }
7169 }
7170
7171 impl<'tcx,T> HasProjectionTypes for Box<T>
7172     where T : HasProjectionTypes
7173 {
7174     fn has_projection_types(&self) -> bool {
7175         (**self).has_projection_types()
7176     }
7177 }
7178
7179 impl<T> HasProjectionTypes for Binder<T>
7180     where T : HasProjectionTypes
7181 {
7182     fn has_projection_types(&self) -> bool {
7183         self.0.has_projection_types()
7184     }
7185 }
7186
7187 impl<'tcx> HasProjectionTypes for FnOutput<'tcx> {
7188     fn has_projection_types(&self) -> bool {
7189         match *self {
7190             FnConverging(t) => t.has_projection_types(),
7191             FnDiverging => false,
7192         }
7193     }
7194 }
7195
7196 impl<'tcx> HasProjectionTypes for FnSig<'tcx> {
7197     fn has_projection_types(&self) -> bool {
7198         self.inputs.iter().any(|t| t.has_projection_types()) ||
7199             self.output.has_projection_types()
7200     }
7201 }
7202
7203 impl<'tcx> HasProjectionTypes for BareFnTy<'tcx> {
7204     fn has_projection_types(&self) -> bool {
7205         self.sig.has_projection_types()
7206     }
7207 }
7208
7209 pub trait ReferencesError {
7210     fn references_error(&self) -> bool;
7211 }
7212
7213 impl<T:ReferencesError> ReferencesError for Binder<T> {
7214     fn references_error(&self) -> bool {
7215         self.0.references_error()
7216     }
7217 }
7218
7219 impl<T:ReferencesError> ReferencesError for Rc<T> {
7220     fn references_error(&self) -> bool {
7221         (&**self).references_error()
7222     }
7223 }
7224
7225 impl<'tcx> ReferencesError for TraitPredicate<'tcx> {
7226     fn references_error(&self) -> bool {
7227         self.trait_ref.references_error()
7228     }
7229 }
7230
7231 impl<'tcx> ReferencesError for ProjectionPredicate<'tcx> {
7232     fn references_error(&self) -> bool {
7233         self.projection_ty.trait_ref.references_error() || self.ty.references_error()
7234     }
7235 }
7236
7237 impl<'tcx> ReferencesError for TraitRef<'tcx> {
7238     fn references_error(&self) -> bool {
7239         self.input_types().iter().any(|t| t.references_error())
7240     }
7241 }
7242
7243 impl<'tcx> ReferencesError for Ty<'tcx> {
7244     fn references_error(&self) -> bool {
7245         type_is_error(*self)
7246     }
7247 }
7248
7249 impl<'tcx> ReferencesError for Predicate<'tcx> {
7250     fn references_error(&self) -> bool {
7251         match *self {
7252             Predicate::Trait(ref data) => data.references_error(),
7253             Predicate::Equate(ref data) => data.references_error(),
7254             Predicate::RegionOutlives(ref data) => data.references_error(),
7255             Predicate::TypeOutlives(ref data) => data.references_error(),
7256             Predicate::Projection(ref data) => data.references_error(),
7257         }
7258     }
7259 }
7260
7261 impl<A,B> ReferencesError for OutlivesPredicate<A,B>
7262     where A : ReferencesError, B : ReferencesError
7263 {
7264     fn references_error(&self) -> bool {
7265         self.0.references_error() || self.1.references_error()
7266     }
7267 }
7268
7269 impl<'tcx> ReferencesError for EquatePredicate<'tcx>
7270 {
7271     fn references_error(&self) -> bool {
7272         self.0.references_error() || self.1.references_error()
7273     }
7274 }
7275
7276 impl ReferencesError for Region
7277 {
7278     fn references_error(&self) -> bool {
7279         false
7280     }
7281 }
7282
7283 impl<'tcx> Repr<'tcx> for ClosureTy<'tcx> {
7284     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
7285         format!("ClosureTy({},{},{},{},{},{})",
7286                 self.unsafety,
7287                 self.onceness,
7288                 self.store,
7289                 self.bounds.repr(tcx),
7290                 self.sig.repr(tcx),
7291                 self.abi)
7292     }
7293 }
7294
7295 impl<'tcx> Repr<'tcx> for UnboxedClosureUpvar<'tcx> {
7296     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
7297         format!("UnboxedClosureUpvar({},{})",
7298                 self.def.repr(tcx),
7299                 self.ty.repr(tcx))
7300     }
7301 }