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