]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/ty/context.rs
split ty::util and ty::adjustment
[rust.git] / src / librustc / middle / ty / context.rs
1 // Copyright 2012-2015 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 //! type context book-keeping
12
13 // FIXME: (@jroesch) @eddyb should remove this when he renames ctxt
14 #![allow(non_camel_case_types)]
15
16 use front::map as ast_map;
17 use session::Session;
18 use lint;
19 use middle;
20 use middle::def::DefMap;
21 use middle::def_id::DefId;
22 use middle::free_region::FreeRegionMap;
23 use middle::region::RegionMaps;
24 use middle::resolve_lifetime;
25 use middle::stability;
26 use middle::subst::{self, Subst, Substs};
27 use middle::traits;
28 use middle::ty::{self, TraitRef, Ty, TypeAndMut};
29 use middle::ty::{TyS, TypeVariants};
30 use middle::ty::{AdtDef, ClosureSubsts, ExistentialBounds, Region};
31 use middle::ty::{FreevarMap, GenericPredicates};
32 use middle::ty::{BareFnTy, InferTy, ParamTy, ProjectionTy, TraitTy};
33 use middle::ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
34 use middle::ty::TypeVariants::*;
35 use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
36 use util::nodemap::FnvHashMap;
37
38 use arena::TypedArena;
39 use std::borrow::Borrow;
40 use std::cell::{Cell, RefCell, Ref};
41 use std::hash::{Hash, Hasher};
42 use std::rc::Rc;
43 use syntax::abi;
44 use syntax::ast::{Name, NodeId};
45 use syntax::parse::token::special_idents;
46
47 use rustc_front::hir;
48 use rustc_front::attr;
49
50 /// Internal storage
51 pub struct CtxtArenas<'tcx> {
52     // internings
53     type_: TypedArena<TyS<'tcx>>,
54     substs: TypedArena<Substs<'tcx>>,
55     bare_fn: TypedArena<BareFnTy<'tcx>>,
56     region: TypedArena<Region>,
57     stability: TypedArena<attr::Stability>,
58
59     // references
60     trait_defs: TypedArena<ty::TraitDef<'tcx>>,
61     adt_defs: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
62 }
63
64 impl<'tcx> CtxtArenas<'tcx> {
65     pub fn new() -> CtxtArenas<'tcx> {
66         CtxtArenas {
67             type_: TypedArena::new(),
68             substs: TypedArena::new(),
69             bare_fn: TypedArena::new(),
70             region: TypedArena::new(),
71             stability: TypedArena::new(),
72
73             trait_defs: TypedArena::new(),
74             adt_defs: TypedArena::new()
75         }
76     }
77 }
78
79 pub struct CommonTypes<'tcx> {
80     pub bool: Ty<'tcx>,
81     pub char: Ty<'tcx>,
82     pub isize: Ty<'tcx>,
83     pub i8: Ty<'tcx>,
84     pub i16: Ty<'tcx>,
85     pub i32: Ty<'tcx>,
86     pub i64: Ty<'tcx>,
87     pub usize: Ty<'tcx>,
88     pub u8: Ty<'tcx>,
89     pub u16: Ty<'tcx>,
90     pub u32: Ty<'tcx>,
91     pub u64: Ty<'tcx>,
92     pub f32: Ty<'tcx>,
93     pub f64: Ty<'tcx>,
94     pub err: Ty<'tcx>,
95 }
96
97 pub struct Tables<'tcx> {
98     /// Stores the types for various nodes in the AST.  Note that this table
99     /// is not guaranteed to be populated until after typeck.  See
100     /// typeck::check::fn_ctxt for details.
101     pub node_types: NodeMap<Ty<'tcx>>,
102
103     /// Stores the type parameters which were substituted to obtain the type
104     /// of this node.  This only applies to nodes that refer to entities
105     /// parameterized by type parameters, such as generic fns, types, or
106     /// other items.
107     pub item_substs: NodeMap<ty::ItemSubsts<'tcx>>,
108
109     pub adjustments: NodeMap<ty::adjustment::AutoAdjustment<'tcx>>,
110
111     pub method_map: ty::MethodMap<'tcx>,
112
113     /// Borrows
114     pub upvar_capture_map: ty::UpvarCaptureMap,
115
116     /// Records the type of each closure. The def ID is the ID of the
117     /// expression defining the closure.
118     pub closure_tys: DefIdMap<ty::ClosureTy<'tcx>>,
119
120     /// Records the type of each closure. The def ID is the ID of the
121     /// expression defining the closure.
122     pub closure_kinds: DefIdMap<ty::ClosureKind>,
123 }
124
125 impl<'tcx> Tables<'tcx> {
126     pub fn empty() -> Tables<'tcx> {
127         Tables {
128             node_types: FnvHashMap(),
129             item_substs: NodeMap(),
130             adjustments: NodeMap(),
131             method_map: FnvHashMap(),
132             upvar_capture_map: FnvHashMap(),
133             closure_tys: DefIdMap(),
134             closure_kinds: DefIdMap(),
135         }
136     }
137 }
138
139 impl<'tcx> CommonTypes<'tcx> {
140     fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
141            interner: &RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>)
142            -> CommonTypes<'tcx>
143     {
144         let mk = |sty| ctxt::intern_ty(arena, interner, sty);
145         CommonTypes {
146             bool: mk(TyBool),
147             char: mk(TyChar),
148             err: mk(TyError),
149             isize: mk(TyInt(hir::TyIs)),
150             i8: mk(TyInt(hir::TyI8)),
151             i16: mk(TyInt(hir::TyI16)),
152             i32: mk(TyInt(hir::TyI32)),
153             i64: mk(TyInt(hir::TyI64)),
154             usize: mk(TyUint(hir::TyUs)),
155             u8: mk(TyUint(hir::TyU8)),
156             u16: mk(TyUint(hir::TyU16)),
157             u32: mk(TyUint(hir::TyU32)),
158             u64: mk(TyUint(hir::TyU64)),
159             f32: mk(TyFloat(hir::TyF32)),
160             f64: mk(TyFloat(hir::TyF64)),
161         }
162     }
163 }
164
165 /// The data structure to keep track of all the information that typechecker
166 /// generates so that so that it can be reused and doesn't have to be redone
167 /// later on.
168 pub struct ctxt<'tcx> {
169     /// The arenas that types etc are allocated from.
170     arenas: &'tcx CtxtArenas<'tcx>,
171
172     /// Specifically use a speedy hash algorithm for this hash map, it's used
173     /// quite often.
174     // FIXME(eddyb) use a FnvHashSet<InternedTy<'tcx>> when equivalent keys can
175     // queried from a HashSet.
176     interner: RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>,
177
178     // FIXME as above, use a hashset if equivalent elements can be queried.
179     substs_interner: RefCell<FnvHashMap<&'tcx Substs<'tcx>, &'tcx Substs<'tcx>>>,
180     bare_fn_interner: RefCell<FnvHashMap<&'tcx BareFnTy<'tcx>, &'tcx BareFnTy<'tcx>>>,
181     region_interner: RefCell<FnvHashMap<&'tcx Region, &'tcx Region>>,
182     stability_interner: RefCell<FnvHashMap<&'tcx attr::Stability, &'tcx attr::Stability>>,
183
184     /// Common types, pre-interned for your convenience.
185     pub types: CommonTypes<'tcx>,
186
187     pub sess: Session,
188     pub def_map: DefMap,
189
190     pub named_region_map: resolve_lifetime::NamedRegionMap,
191
192     pub region_maps: RegionMaps,
193
194     // For each fn declared in the local crate, type check stores the
195     // free-region relationships that were deduced from its where
196     // clauses and parameter types. These are then read-again by
197     // borrowck. (They are not used during trans, and hence are not
198     // serialized or needed for cross-crate fns.)
199     free_region_maps: RefCell<NodeMap<FreeRegionMap>>,
200     // FIXME: jroesch make this a refcell
201
202     pub tables: RefCell<Tables<'tcx>>,
203
204     /// Maps from a trait item to the trait item "descriptor"
205     pub impl_or_trait_items: RefCell<DefIdMap<ty::ImplOrTraitItem<'tcx>>>,
206
207     /// Maps from a trait def-id to a list of the def-ids of its trait items
208     pub trait_item_def_ids: RefCell<DefIdMap<Rc<Vec<ty::ImplOrTraitItemId>>>>,
209
210     /// A cache for the trait_items() routine
211     pub trait_items_cache: RefCell<DefIdMap<Rc<Vec<ty::ImplOrTraitItem<'tcx>>>>>,
212
213     pub impl_trait_refs: RefCell<DefIdMap<Option<TraitRef<'tcx>>>>,
214     pub trait_defs: RefCell<DefIdMap<&'tcx ty::TraitDef<'tcx>>>,
215     pub adt_defs: RefCell<DefIdMap<ty::AdtDefMaster<'tcx>>>,
216
217     /// Maps from the def-id of an item (trait/struct/enum/fn) to its
218     /// associated predicates.
219     pub predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
220
221     /// Maps from the def-id of a trait to the list of
222     /// super-predicates. This is a subset of the full list of
223     /// predicates. We store these in a separate map because we must
224     /// evaluate them even during type conversion, often before the
225     /// full predicates are available (note that supertraits have
226     /// additional acyclicity requirements).
227     pub super_predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
228
229     pub map: ast_map::Map<'tcx>,
230     pub freevars: RefCell<FreevarMap>,
231     pub tcache: RefCell<DefIdMap<ty::TypeScheme<'tcx>>>,
232     pub rcache: RefCell<FnvHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
233     pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, ty::contents::TypeContents>>,
234     pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
235     pub ty_param_defs: RefCell<NodeMap<ty::TypeParameterDef<'tcx>>>,
236     pub normalized_cache: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
237     pub lang_items: middle::lang_items::LanguageItems,
238     /// A mapping of fake provided method def_ids to the default implementation
239     pub provided_method_sources: RefCell<DefIdMap<DefId>>,
240
241     /// Maps from def-id of a type or region parameter to its
242     /// (inferred) variance.
243     pub item_variance_map: RefCell<DefIdMap<Rc<ty::ItemVariances>>>,
244
245     /// True if the variance has been computed yet; false otherwise.
246     pub variance_computed: Cell<bool>,
247
248     /// A method will be in this list if and only if it is a destructor.
249     pub destructors: RefCell<DefIdSet>,
250
251     /// Maps a DefId of a type to a list of its inherent impls.
252     /// Contains implementations of methods that are inherent to a type.
253     /// Methods in these implementations don't need to be exported.
254     pub inherent_impls: RefCell<DefIdMap<Rc<Vec<DefId>>>>,
255
256     /// Maps a DefId of an impl to a list of its items.
257     /// Note that this contains all of the impls that we know about,
258     /// including ones in other crates. It's not clear that this is the best
259     /// way to do it.
260     pub impl_items: RefCell<DefIdMap<Vec<ty::ImplOrTraitItemId>>>,
261
262     /// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
263     /// present in this set can be warned about.
264     pub used_unsafe: RefCell<NodeSet>,
265
266     /// Set of nodes which mark locals as mutable which end up getting used at
267     /// some point. Local variable definitions not in this set can be warned
268     /// about.
269     pub used_mut_nodes: RefCell<NodeSet>,
270
271     /// The set of external nominal types whose implementations have been read.
272     /// This is used for lazy resolution of methods.
273     pub populated_external_types: RefCell<DefIdSet>,
274     /// The set of external primitive types whose implementations have been read.
275     /// FIXME(arielb1): why is this separate from populated_external_types?
276     pub populated_external_primitive_impls: RefCell<DefIdSet>,
277
278     /// These caches are used by const_eval when decoding external constants.
279     pub extern_const_statics: RefCell<DefIdMap<NodeId>>,
280     pub extern_const_variants: RefCell<DefIdMap<NodeId>>,
281     pub extern_const_fns: RefCell<DefIdMap<NodeId>>,
282
283     pub node_lint_levels: RefCell<FnvHashMap<(NodeId, lint::LintId),
284                                               lint::LevelSource>>,
285
286     /// The types that must be asserted to be the same size for `transmute`
287     /// to be valid. We gather up these restrictions in the intrinsicck pass
288     /// and check them in trans.
289     pub transmute_restrictions: RefCell<Vec<ty::TransmuteRestriction<'tcx>>>,
290
291     /// Maps any item's def-id to its stability index.
292     pub stability: RefCell<stability::Index<'tcx>>,
293
294     /// Caches the results of trait selection. This cache is used
295     /// for things that do not have to do with the parameters in scope.
296     pub selection_cache: traits::SelectionCache<'tcx>,
297
298     /// A set of predicates that have been fulfilled *somewhere*.
299     /// This is used to avoid duplicate work. Predicates are only
300     /// added to this set when they mention only "global" names
301     /// (i.e., no type or lifetime parameters).
302     pub fulfilled_predicates: RefCell<traits::FulfilledPredicates<'tcx>>,
303
304     /// Caches the representation hints for struct definitions.
305     pub repr_hint_cache: RefCell<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
306
307     /// Maps Expr NodeId's to their constant qualification.
308     pub const_qualif_map: RefCell<NodeMap<middle::check_const::ConstQualif>>,
309
310     /// Caches CoerceUnsized kinds for impls on custom types.
311     pub custom_coerce_unsized_kinds: RefCell<DefIdMap<ty::adjustment::CustomCoerceUnsized>>,
312
313     /// Maps a cast expression to its kind. This is keyed on the
314     /// *from* expression of the cast, not the cast itself.
315     pub cast_kinds: RefCell<NodeMap<ty::cast::CastKind>>,
316
317     /// Maps Fn items to a collection of fragment infos.
318     ///
319     /// The main goal is to identify data (each of which may be moved
320     /// or assigned) whose subparts are not moved nor assigned
321     /// (i.e. their state is *unfragmented*) and corresponding ast
322     /// nodes where the path to that data is moved or assigned.
323     ///
324     /// In the long term, unfragmented values will have their
325     /// destructor entirely driven by a single stack-local drop-flag,
326     /// and their parents, the collections of the unfragmented values
327     /// (or more simply, "fragmented values"), are mapped to the
328     /// corresponding collections of stack-local drop-flags.
329     ///
330     /// (However, in the short term that is not the case; e.g. some
331     /// unfragmented paths still need to be zeroed, namely when they
332     /// reference parent data from an outer scope that was not
333     /// entirely moved, and therefore that needs to be zeroed so that
334     /// we do not get double-drop when we hit the end of the parent
335     /// scope.)
336     ///
337     /// Also: currently the table solely holds keys for node-ids of
338     /// unfragmented values (see `FragmentInfo` enum definition), but
339     /// longer-term we will need to also store mappings from
340     /// fragmented data to the set of unfragmented pieces that
341     /// constitute it.
342     pub fragment_infos: RefCell<DefIdMap<Vec<ty::FragmentInfo>>>,
343 }
344 impl<'tcx> ctxt<'tcx> {
345     pub fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind {
346         *self.tables.borrow().closure_kinds.get(&def_id).unwrap()
347     }
348
349     pub fn closure_type(&self,
350                         def_id: DefId,
351                         substs: &ClosureSubsts<'tcx>)
352                         -> ty::ClosureTy<'tcx>
353     {
354         self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self, &substs.func_substs)
355     }
356
357     pub fn type_parameter_def(&self,
358                               node_id: NodeId)
359                               -> ty::TypeParameterDef<'tcx>
360     {
361         self.ty_param_defs.borrow().get(&node_id).unwrap().clone()
362     }
363
364     pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> {
365         fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap<Ty<'tcx>> {
366             &tables.node_types
367         }
368
369         Ref::map(self.tables.borrow(), projection)
370     }
371
372     pub fn node_type_insert(&self, id: NodeId, ty: Ty<'tcx>) {
373         self.tables.borrow_mut().node_types.insert(id, ty);
374     }
375
376     pub fn intern_trait_def(&self, def: ty::TraitDef<'tcx>)
377                             -> &'tcx ty::TraitDef<'tcx> {
378         let did = def.trait_ref.def_id;
379         let interned = self.arenas.trait_defs.alloc(def);
380         self.trait_defs.borrow_mut().insert(did, interned);
381         interned
382     }
383
384     pub fn alloc_trait_def(&self, def: ty::TraitDef<'tcx>)
385                            -> &'tcx ty::TraitDef<'tcx> {
386         self.arenas.trait_defs.alloc(def)
387     }
388
389     pub fn intern_adt_def(&self,
390                           did: DefId,
391                           kind: ty::AdtKind,
392                           variants: Vec<ty::VariantDefData<'tcx, 'tcx>>)
393                           -> ty::AdtDefMaster<'tcx> {
394         let def = ty::AdtDefData::new(self, did, kind, variants);
395         let interned = self.arenas.adt_defs.alloc(def);
396         // this will need a transmute when reverse-variance is removed
397         self.adt_defs.borrow_mut().insert(did, interned);
398         interned
399     }
400
401     pub fn intern_stability(&self, stab: attr::Stability) -> &'tcx attr::Stability {
402         if let Some(st) = self.stability_interner.borrow().get(&stab) {
403             return st;
404         }
405
406         let interned = self.arenas.stability.alloc(stab);
407         self.stability_interner.borrow_mut().insert(interned, interned);
408         interned
409     }
410
411     pub fn store_free_region_map(&self, id: NodeId, map: FreeRegionMap) {
412         self.free_region_maps.borrow_mut()
413                              .insert(id, map);
414     }
415
416     pub fn free_region_map(&self, id: NodeId) -> FreeRegionMap {
417         self.free_region_maps.borrow()[&id].clone()
418     }
419
420     pub fn lift<T: ?Sized + Lift<'tcx>>(&self, value: &T) -> Option<T::Lifted> {
421         value.lift_to_tcx(self)
422     }
423
424     /// Create a type context and call the closure with a `&ty::ctxt` reference
425     /// to the context. The closure enforces that the type context and any interned
426     /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
427     /// reference to the context, to allow formatting values that need it.
428     pub fn create_and_enter<F, R>(s: Session,
429                                  arenas: &'tcx CtxtArenas<'tcx>,
430                                  def_map: DefMap,
431                                  named_region_map: resolve_lifetime::NamedRegionMap,
432                                  map: ast_map::Map<'tcx>,
433                                  freevars: RefCell<FreevarMap>,
434                                  region_maps: RegionMaps,
435                                  lang_items: middle::lang_items::LanguageItems,
436                                  stability: stability::Index<'tcx>,
437                                  f: F) -> (Session, R)
438                                  where F: FnOnce(&ctxt<'tcx>) -> R
439     {
440         let interner = RefCell::new(FnvHashMap());
441         let common_types = CommonTypes::new(&arenas.type_, &interner);
442
443         tls::enter(ctxt {
444             arenas: arenas,
445             interner: interner,
446             substs_interner: RefCell::new(FnvHashMap()),
447             bare_fn_interner: RefCell::new(FnvHashMap()),
448             region_interner: RefCell::new(FnvHashMap()),
449             stability_interner: RefCell::new(FnvHashMap()),
450             types: common_types,
451             named_region_map: named_region_map,
452             region_maps: region_maps,
453             free_region_maps: RefCell::new(FnvHashMap()),
454             item_variance_map: RefCell::new(DefIdMap()),
455             variance_computed: Cell::new(false),
456             sess: s,
457             def_map: def_map,
458             tables: RefCell::new(Tables::empty()),
459             impl_trait_refs: RefCell::new(DefIdMap()),
460             trait_defs: RefCell::new(DefIdMap()),
461             adt_defs: RefCell::new(DefIdMap()),
462             predicates: RefCell::new(DefIdMap()),
463             super_predicates: RefCell::new(DefIdMap()),
464             fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()),
465             map: map,
466             freevars: freevars,
467             tcache: RefCell::new(DefIdMap()),
468             rcache: RefCell::new(FnvHashMap()),
469             tc_cache: RefCell::new(FnvHashMap()),
470             ast_ty_to_ty_cache: RefCell::new(NodeMap()),
471             impl_or_trait_items: RefCell::new(DefIdMap()),
472             trait_item_def_ids: RefCell::new(DefIdMap()),
473             trait_items_cache: RefCell::new(DefIdMap()),
474             ty_param_defs: RefCell::new(NodeMap()),
475             normalized_cache: RefCell::new(FnvHashMap()),
476             lang_items: lang_items,
477             provided_method_sources: RefCell::new(DefIdMap()),
478             destructors: RefCell::new(DefIdSet()),
479             inherent_impls: RefCell::new(DefIdMap()),
480             impl_items: RefCell::new(DefIdMap()),
481             used_unsafe: RefCell::new(NodeSet()),
482             used_mut_nodes: RefCell::new(NodeSet()),
483             populated_external_types: RefCell::new(DefIdSet()),
484             populated_external_primitive_impls: RefCell::new(DefIdSet()),
485             extern_const_statics: RefCell::new(DefIdMap()),
486             extern_const_variants: RefCell::new(DefIdMap()),
487             extern_const_fns: RefCell::new(DefIdMap()),
488             node_lint_levels: RefCell::new(FnvHashMap()),
489             transmute_restrictions: RefCell::new(Vec::new()),
490             stability: RefCell::new(stability),
491             selection_cache: traits::SelectionCache::new(),
492             repr_hint_cache: RefCell::new(DefIdMap()),
493             const_qualif_map: RefCell::new(NodeMap()),
494             custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
495             cast_kinds: RefCell::new(NodeMap()),
496             fragment_infos: RefCell::new(DefIdMap()),
497        }, f)
498     }
499 }
500
501 /// A trait implemented for all X<'a> types which can be safely and
502 /// efficiently converted to X<'tcx> as long as they are part of the
503 /// provided ty::ctxt<'tcx>.
504 /// This can be done, for example, for Ty<'tcx> or &'tcx Substs<'tcx>
505 /// by looking them up in their respective interners.
506 /// None is returned if the value or one of the components is not part
507 /// of the provided context.
508 /// For Ty, None can be returned if either the type interner doesn't
509 /// contain the TypeVariants key or if the address of the interned
510 /// pointer differs. The latter case is possible if a primitive type,
511 /// e.g. `()` or `u8`, was interned in a different context.
512 pub trait Lift<'tcx> {
513     type Lifted;
514     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Self::Lifted>;
515 }
516
517 impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
518     type Lifted = Ty<'tcx>;
519     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<Ty<'tcx>> {
520         if let Some(&ty) = tcx.interner.borrow().get(&self.sty) {
521             if *self as *const _ == ty as *const _ {
522                 return Some(ty);
523             }
524         }
525         None
526     }
527 }
528
529 impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
530     type Lifted = &'tcx Substs<'tcx>;
531     fn lift_to_tcx(&self, tcx: &ctxt<'tcx>) -> Option<&'tcx Substs<'tcx>> {
532         if let Some(&substs) = tcx.substs_interner.borrow().get(*self) {
533             if *self as *const _ == substs as *const _ {
534                 return Some(substs);
535             }
536         }
537         None
538     }
539 }
540
541
542 pub mod tls {
543     use middle::ty;
544     use session::Session;
545
546     use std::fmt;
547     use syntax::codemap;
548
549     /// Marker type used for the scoped TLS slot.
550     /// The type context cannot be used directly because the scoped TLS
551     /// in libstd doesn't allow types generic over lifetimes.
552     struct ThreadLocalTyCx;
553
554     scoped_thread_local!(static TLS_TCX: ThreadLocalTyCx);
555
556     fn span_debug(span: codemap::Span, f: &mut fmt::Formatter) -> fmt::Result {
557         with(|tcx| {
558             write!(f, "{}", tcx.sess.codemap().span_to_string(span))
559         })
560     }
561
562     pub fn enter<'tcx, F: FnOnce(&ty::ctxt<'tcx>) -> R, R>(tcx: ty::ctxt<'tcx>, f: F)
563                                                            -> (Session, R) {
564         let result = codemap::SPAN_DEBUG.with(|span_dbg| {
565             let original_span_debug = span_dbg.get();
566             span_dbg.set(span_debug);
567             let tls_ptr = &tcx as *const _ as *const ThreadLocalTyCx;
568             let result = TLS_TCX.set(unsafe { &*tls_ptr }, || f(&tcx));
569             span_dbg.set(original_span_debug);
570             result
571         });
572         (tcx.sess, result)
573     }
574
575     pub fn with<F: FnOnce(&ty::ctxt) -> R, R>(f: F) -> R {
576         TLS_TCX.with(|tcx| f(unsafe { &*(tcx as *const _ as *const ty::ctxt) }))
577     }
578
579     pub fn with_opt<F: FnOnce(Option<&ty::ctxt>) -> R, R>(f: F) -> R {
580         if TLS_TCX.is_set() {
581             with(|v| f(Some(v)))
582         } else {
583             f(None)
584         }
585     }
586 }
587
588 macro_rules! sty_debug_print {
589     ($ctxt: expr, $($variant: ident),*) => {{
590         // curious inner module to allow variant names to be used as
591         // variable names.
592         #[allow(non_snake_case)]
593         mod inner {
594             use middle::ty;
595             #[derive(Copy, Clone)]
596             struct DebugStat {
597                 total: usize,
598                 region_infer: usize,
599                 ty_infer: usize,
600                 both_infer: usize,
601             }
602
603             pub fn go(tcx: &ty::ctxt) {
604                 let mut total = DebugStat {
605                     total: 0,
606                     region_infer: 0, ty_infer: 0, both_infer: 0,
607                 };
608                 $(let mut $variant = total;)*
609
610
611                 for (_, t) in tcx.interner.borrow().iter() {
612                     let variant = match t.sty {
613                         ty::TyBool | ty::TyChar | ty::TyInt(..) | ty::TyUint(..) |
614                             ty::TyFloat(..) | ty::TyStr => continue,
615                         ty::TyError => /* unimportant */ continue,
616                         $(ty::$variant(..) => &mut $variant,)*
617                     };
618                     let region = t.flags.get().intersects(ty::TypeFlags::HAS_RE_INFER);
619                     let ty = t.flags.get().intersects(ty::TypeFlags::HAS_TY_INFER);
620
621                     variant.total += 1;
622                     total.total += 1;
623                     if region { total.region_infer += 1; variant.region_infer += 1 }
624                     if ty { total.ty_infer += 1; variant.ty_infer += 1 }
625                     if region && ty { total.both_infer += 1; variant.both_infer += 1 }
626                 }
627                 println!("Ty interner             total           ty region  both");
628                 $(println!("    {:18}: {uses:6} {usespc:4.1}%, \
629 {ty:4.1}% {region:5.1}% {both:4.1}%",
630                            stringify!($variant),
631                            uses = $variant.total,
632                            usespc = $variant.total as f64 * 100.0 / total.total as f64,
633                            ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
634                            region = $variant.region_infer as f64 * 100.0  / total.total as f64,
635                            both = $variant.both_infer as f64 * 100.0  / total.total as f64);
636                   )*
637                 println!("                  total {uses:6}        \
638 {ty:4.1}% {region:5.1}% {both:4.1}%",
639                          uses = total.total,
640                          ty = total.ty_infer as f64 * 100.0  / total.total as f64,
641                          region = total.region_infer as f64 * 100.0  / total.total as f64,
642                          both = total.both_infer as f64 * 100.0  / total.total as f64)
643             }
644         }
645
646         inner::go($ctxt)
647     }}
648 }
649
650 impl<'tcx> ctxt<'tcx> {
651     pub fn print_debug_stats(&self) {
652         sty_debug_print!(
653             self,
654             TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyBareFn, TyTrait,
655             TyStruct, TyClosure, TyTuple, TyParam, TyInfer, TyProjection);
656
657         println!("Substs interner: #{}", self.substs_interner.borrow().len());
658         println!("BareFnTy interner: #{}", self.bare_fn_interner.borrow().len());
659         println!("Region interner: #{}", self.region_interner.borrow().len());
660         println!("Stability interner: #{}", self.stability_interner.borrow().len());
661     }
662 }
663
664
665 /// An entry in the type interner.
666 pub struct InternedTy<'tcx> {
667     ty: Ty<'tcx>
668 }
669
670 // NB: An InternedTy compares and hashes as a sty.
671 impl<'tcx> PartialEq for InternedTy<'tcx> {
672     fn eq(&self, other: &InternedTy<'tcx>) -> bool {
673         self.ty.sty == other.ty.sty
674     }
675 }
676
677 impl<'tcx> Eq for InternedTy<'tcx> {}
678
679 impl<'tcx> Hash for InternedTy<'tcx> {
680     fn hash<H: Hasher>(&self, s: &mut H) {
681         self.ty.sty.hash(s)
682     }
683 }
684
685 impl<'tcx> Borrow<TypeVariants<'tcx>> for InternedTy<'tcx> {
686     fn borrow<'a>(&'a self) -> &'a TypeVariants<'tcx> {
687         &self.ty.sty
688     }
689 }
690
691 fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool {
692     bounds.is_empty() ||
693         bounds[1..].iter().enumerate().all(
694             |(index, bound)| bounds[index].sort_key() <= bound.sort_key())
695 }
696
697 impl<'tcx> ctxt<'tcx> {
698     // Type constructors
699     pub fn mk_substs(&self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> {
700         if let Some(substs) = self.substs_interner.borrow().get(&substs) {
701             return *substs;
702         }
703
704         let substs = self.arenas.substs.alloc(substs);
705         self.substs_interner.borrow_mut().insert(substs, substs);
706         substs
707     }
708
709     /// Create an unsafe fn ty based on a safe fn ty.
710     pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
711         assert_eq!(bare_fn.unsafety, hir::Unsafety::Normal);
712         let unsafe_fn_ty_a = self.mk_bare_fn(ty::BareFnTy {
713             unsafety: hir::Unsafety::Unsafe,
714             abi: bare_fn.abi,
715             sig: bare_fn.sig.clone()
716         });
717         self.mk_fn(None, unsafe_fn_ty_a)
718     }
719
720     pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
721         if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) {
722             return *bare_fn;
723         }
724
725         let bare_fn = self.arenas.bare_fn.alloc(bare_fn);
726         self.bare_fn_interner.borrow_mut().insert(bare_fn, bare_fn);
727         bare_fn
728     }
729
730     pub fn mk_region(&self, region: Region) -> &'tcx Region {
731         if let Some(region) = self.region_interner.borrow().get(&region) {
732             return *region;
733         }
734
735         let region = self.arenas.region.alloc(region);
736         self.region_interner.borrow_mut().insert(region, region);
737         region
738     }
739
740     fn intern_ty(type_arena: &'tcx TypedArena<TyS<'tcx>>,
741                  interner: &RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>,
742                  st: TypeVariants<'tcx>)
743                  -> Ty<'tcx> {
744         let ty: Ty /* don't be &mut TyS */ = {
745             let mut interner = interner.borrow_mut();
746             match interner.get(&st) {
747                 Some(ty) => return *ty,
748                 _ => ()
749             }
750
751             let flags = super::flags::FlagComputation::for_sty(&st);
752
753             let ty = match () {
754                 () => type_arena.alloc(TyS { sty: st,
755                                              flags: Cell::new(flags.flags),
756                                              region_depth: flags.depth, }),
757             };
758
759             interner.insert(InternedTy { ty: ty }, ty);
760             ty
761         };
762
763         debug!("Interned type: {:?} Pointer: {:?}",
764             ty, ty as *const TyS);
765         ty
766     }
767
768     // Interns a type/name combination, stores the resulting box in cx.interner,
769     // and returns the box as cast to an unsafe ptr (see comments for Ty above).
770     pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
771         ctxt::intern_ty(&self.arenas.type_, &self.interner, st)
772     }
773
774     pub fn mk_mach_int(&self, tm: hir::IntTy) -> Ty<'tcx> {
775         match tm {
776             hir::TyIs   => self.types.isize,
777             hir::TyI8   => self.types.i8,
778             hir::TyI16  => self.types.i16,
779             hir::TyI32  => self.types.i32,
780             hir::TyI64  => self.types.i64,
781         }
782     }
783
784     pub fn mk_mach_uint(&self, tm: hir::UintTy) -> Ty<'tcx> {
785         match tm {
786             hir::TyUs   => self.types.usize,
787             hir::TyU8   => self.types.u8,
788             hir::TyU16  => self.types.u16,
789             hir::TyU32  => self.types.u32,
790             hir::TyU64  => self.types.u64,
791         }
792     }
793
794     pub fn mk_mach_float(&self, tm: hir::FloatTy) -> Ty<'tcx> {
795         match tm {
796             hir::TyF32  => self.types.f32,
797             hir::TyF64  => self.types.f64,
798         }
799     }
800
801     pub fn mk_str(&self) -> Ty<'tcx> {
802         self.mk_ty(TyStr)
803     }
804
805     pub fn mk_static_str(&self) -> Ty<'tcx> {
806         self.mk_imm_ref(self.mk_region(ty::ReStatic), self.mk_str())
807     }
808
809     pub fn mk_enum(&self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
810         // take a copy of substs so that we own the vectors inside
811         self.mk_ty(TyEnum(def, substs))
812     }
813
814     pub fn mk_box(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
815         self.mk_ty(TyBox(ty))
816     }
817
818     pub fn mk_ptr(&self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
819         self.mk_ty(TyRawPtr(tm))
820     }
821
822     pub fn mk_ref(&self, r: &'tcx Region, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
823         self.mk_ty(TyRef(r, tm))
824     }
825
826     pub fn mk_mut_ref(&self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
827         self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutMutable})
828     }
829
830     pub fn mk_imm_ref(&self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
831         self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
832     }
833
834     pub fn mk_mut_ptr(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
835         self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutMutable})
836     }
837
838     pub fn mk_imm_ptr(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
839         self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
840     }
841
842     pub fn mk_nil_ptr(&self) -> Ty<'tcx> {
843         self.mk_imm_ptr(self.mk_nil())
844     }
845
846     pub fn mk_array(&self, ty: Ty<'tcx>, n: usize) -> Ty<'tcx> {
847         self.mk_ty(TyArray(ty, n))
848     }
849
850     pub fn mk_slice(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
851         self.mk_ty(TySlice(ty))
852     }
853
854     pub fn mk_tup(&self, ts: Vec<Ty<'tcx>>) -> Ty<'tcx> {
855         self.mk_ty(TyTuple(ts))
856     }
857
858     pub fn mk_nil(&self) -> Ty<'tcx> {
859         self.mk_tup(Vec::new())
860     }
861
862     pub fn mk_bool(&self) -> Ty<'tcx> {
863         self.mk_ty(TyBool)
864     }
865
866     pub fn mk_fn(&self,
867                  opt_def_id: Option<DefId>,
868                  fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
869         self.mk_ty(TyBareFn(opt_def_id, fty))
870     }
871
872     pub fn mk_ctor_fn(&self,
873                       def_id: DefId,
874                       input_tys: &[Ty<'tcx>],
875                       output: Ty<'tcx>) -> Ty<'tcx> {
876         let input_args = input_tys.iter().cloned().collect();
877         self.mk_fn(Some(def_id), self.mk_bare_fn(BareFnTy {
878             unsafety: hir::Unsafety::Normal,
879             abi: abi::Rust,
880             sig: ty::Binder(ty::FnSig {
881                 inputs: input_args,
882                 output: ty::FnConverging(output),
883                 variadic: false
884             })
885         }))
886     }
887
888     pub fn mk_trait(&self,
889                     principal: ty::PolyTraitRef<'tcx>,
890                     bounds: ExistentialBounds<'tcx>)
891                     -> Ty<'tcx>
892     {
893         assert!(bound_list_is_sorted(&bounds.projection_bounds));
894
895         let inner = box TraitTy {
896             principal: principal,
897             bounds: bounds
898         };
899         self.mk_ty(TyTrait(inner))
900     }
901
902     pub fn mk_projection(&self,
903                          trait_ref: TraitRef<'tcx>,
904                          item_name: Name)
905                          -> Ty<'tcx> {
906         // take a copy of substs so that we own the vectors inside
907         let inner = ProjectionTy { trait_ref: trait_ref, item_name: item_name };
908         self.mk_ty(TyProjection(inner))
909     }
910
911     pub fn mk_struct(&self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
912         // take a copy of substs so that we own the vectors inside
913         self.mk_ty(TyStruct(def, substs))
914     }
915
916     pub fn mk_closure(&self,
917                       closure_id: DefId,
918                       substs: &'tcx Substs<'tcx>,
919                       tys: Vec<Ty<'tcx>>)
920                       -> Ty<'tcx> {
921         self.mk_closure_from_closure_substs(closure_id, Box::new(ClosureSubsts {
922             func_substs: substs,
923             upvar_tys: tys
924         }))
925     }
926
927     pub fn mk_closure_from_closure_substs(&self,
928                                           closure_id: DefId,
929                                           closure_substs: Box<ClosureSubsts<'tcx>>)
930                                           -> Ty<'tcx> {
931         self.mk_ty(TyClosure(closure_id, closure_substs))
932     }
933
934     pub fn mk_var(&self, v: TyVid) -> Ty<'tcx> {
935         self.mk_infer(TyVar(v))
936     }
937
938     pub fn mk_int_var(&self, v: IntVid) -> Ty<'tcx> {
939         self.mk_infer(IntVar(v))
940     }
941
942     pub fn mk_float_var(&self, v: FloatVid) -> Ty<'tcx> {
943         self.mk_infer(FloatVar(v))
944     }
945
946     pub fn mk_infer(&self, it: InferTy) -> Ty<'tcx> {
947         self.mk_ty(TyInfer(it))
948     }
949
950     pub fn mk_param(&self,
951                     space: subst::ParamSpace,
952                     index: u32,
953                     name: Name) -> Ty<'tcx> {
954         self.mk_ty(TyParam(ParamTy { space: space, idx: index, name: name }))
955     }
956
957     pub fn mk_self_type(&self) -> Ty<'tcx> {
958         self.mk_param(subst::SelfSpace, 0, special_idents::type_self.name)
959     }
960
961     pub fn mk_param_from_def(&self, def: &ty::TypeParameterDef) -> Ty<'tcx> {
962         self.mk_param(def.space, def.index, def.name)
963     }
964 }