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