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