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