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