]> git.proxmox.com Git - rustc.git/blame - src/librustc/ty/context.rs
New upstream version 1.29.0+dfsg1
[rustc.git] / src / librustc / ty / context.rs
CommitLineData
e9174d1e
SL
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
8bb4bdeb 13use dep_graph::DepGraph;
ea8adc8c 14use dep_graph::{DepNode, DepConstructor};
3b2f2976 15use errors::DiagnosticBuilder;
e9174d1e 16use session::Session;
83c7162d
XL
17use session::config::{BorrowckMode, OutputFilenames, OptLevel};
18use session::config::CrateType::*;
e9174d1e 19use middle;
ea8adc8c
XL
20use hir::{TraitCandidate, HirId, ItemLocalId};
21use hir::def::{Def, Export};
22use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
32a655c1 23use hir::map as hir_map;
3b2f2976
XL
24use hir::map::DefPathHash;
25use lint::{self, Lint};
ea8adc8c 26use ich::{StableHashingContext, NodeIdHashingMode};
0531ce1d 27use infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
ff7c6d11 28use infer::outlives::free_region_map::FreeRegionMap;
94b46f34 29use middle::cstore::{CrateStoreDyn, LinkMeta};
ea8adc8c 30use middle::cstore::EncodedMetadata;
32a655c1 31use middle::lang_items;
ea8adc8c 32use middle::resolve_lifetime::{self, ObjectLifetimeDefault};
e9174d1e 33use middle::stability;
0531ce1d 34use mir::{self, Mir, interpret};
94b46f34 35use mir::interpret::Allocation;
83c7162d 36use ty::subst::{Kind, Substs, Subst};
8bb4bdeb 37use ty::ReprOptions;
54a0048b 38use traits;
83c7162d 39use traits::{Clause, Clauses, Goal, Goals};
041b39d2 40use ty::{self, Ty, TypeAndMut};
9e0c209e 41use ty::{TyS, TypeVariants, Slice};
94b46f34 42use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const};
7cac9316
XL
43use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
44use ty::RegionKind;
54a0048b
SL
45use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
46use ty::TypeVariants::*;
94b46f34 47use ty::GenericParamDefKind;
ff7c6d11 48use ty::layout::{LayoutDetails, TargetDataLayout};
94b46f34 49use ty::query;
7cac9316 50use ty::steal::Steal;
3b2f2976 51use ty::BindingMode;
0531ce1d 52use ty::CanonicalTy;
83c7162d 53use util::nodemap::{DefIdSet, ItemLocalMap};
476ff2be 54use util::nodemap::{FxHashMap, FxHashSet};
c30ab7b3 55use rustc_data_structures::accumulate_vec::AccumulateVec;
ea8adc8c
XL
56use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
57 StableHasher, StableHasherResult,
58 StableVec};
83c7162d 59use arena::{TypedArena, SyncDroplessArena};
8bb4bdeb 60use rustc_data_structures::indexed_vec::IndexVec;
94b46f34 61use rustc_data_structures::sync::{self, Lrc, Lock, WorkerLocal};
ea8adc8c 62use std::any::Any;
e9174d1e 63use std::borrow::Borrow;
7cac9316 64use std::cmp::Ordering;
3b2f2976 65use std::collections::hash_map::{self, Entry};
e9174d1e 66use std::hash::{Hash, Hasher};
8faf50e0 67use std::fmt;
a7813a04
XL
68use std::mem;
69use std::ops::Deref;
c30ab7b3 70use std::iter;
ea8adc8c
XL
71use std::sync::mpsc;
72use std::sync::Arc;
83c7162d 73use rustc_target::spec::abi;
0531ce1d 74use syntax::ast::{self, NodeId};
b039eaaf 75use syntax::attr;
3b2f2976 76use syntax::codemap::MultiSpan;
8faf50e0 77use syntax::edition::Edition;
0531ce1d
XL
78use syntax::feature_gate;
79use syntax::symbol::{Symbol, keywords, InternedString};
7cac9316 80use syntax_pos::Span;
e9174d1e 81
54a0048b 82use hir;
e9174d1e 83
ff7c6d11 84pub struct AllArenas<'tcx> {
94b46f34 85 pub global: WorkerLocal<GlobalArenas<'tcx>>,
83c7162d 86 pub interner: SyncDroplessArena,
ff7c6d11
XL
87}
88
89impl<'tcx> AllArenas<'tcx> {
90 pub fn new() -> Self {
91 AllArenas {
94b46f34 92 global: WorkerLocal::new(|_| GlobalArenas::new()),
83c7162d 93 interner: SyncDroplessArena::new(),
ff7c6d11
XL
94 }
95 }
96}
97
e9174d1e 98/// Internal storage
32a655c1 99pub struct GlobalArenas<'tcx> {
e9174d1e 100 // internings
ff7c6d11 101 layout: TypedArena<LayoutDetails>,
e9174d1e
SL
102
103 // references
8bb4bdeb 104 generics: TypedArena<ty::Generics>,
476ff2be
SL
105 trait_def: TypedArena<ty::TraitDef>,
106 adt_def: TypedArena<ty::AdtDef>,
7cac9316
XL
107 steal_mir: TypedArena<Steal<Mir<'tcx>>>,
108 mir: TypedArena<Mir<'tcx>>,
32a655c1 109 tables: TypedArena<ty::TypeckTables<'tcx>>,
ff7c6d11
XL
110 /// miri allocations
111 const_allocs: TypedArena<interpret::Allocation>,
e9174d1e
SL
112}
113
32a655c1
SL
114impl<'tcx> GlobalArenas<'tcx> {
115 pub fn new() -> GlobalArenas<'tcx> {
116 GlobalArenas {
54a0048b 117 layout: TypedArena::new(),
9e0c209e 118 generics: TypedArena::new(),
c30ab7b3
SL
119 trait_def: TypedArena::new(),
120 adt_def: TypedArena::new(),
7cac9316 121 steal_mir: TypedArena::new(),
32a655c1
SL
122 mir: TypedArena::new(),
123 tables: TypedArena::new(),
ff7c6d11 124 const_allocs: TypedArena::new(),
e9174d1e
SL
125 }
126 }
127}
128
83c7162d
XL
129type InternedSet<'tcx, T> = Lock<FxHashSet<Interned<'tcx, T>>>;
130
a7813a04 131pub struct CtxtInterners<'tcx> {
32a655c1 132 /// The arena that types, regions, etc are allocated from
83c7162d 133 arena: &'tcx SyncDroplessArena,
a7813a04
XL
134
135 /// Specifically use a speedy hash algorithm for these hash sets,
136 /// they're accessed quite often.
83c7162d
XL
137 type_: InternedSet<'tcx, TyS<'tcx>>,
138 type_list: InternedSet<'tcx, Slice<Ty<'tcx>>>,
139 substs: InternedSet<'tcx, Substs<'tcx>>,
140 canonical_var_infos: InternedSet<'tcx, Slice<CanonicalVarInfo>>,
141 region: InternedSet<'tcx, RegionKind>,
142 existential_predicates: InternedSet<'tcx, Slice<ExistentialPredicate<'tcx>>>,
143 predicates: InternedSet<'tcx, Slice<Predicate<'tcx>>>,
144 const_: InternedSet<'tcx, Const<'tcx>>,
145 clauses: InternedSet<'tcx, Slice<Clause<'tcx>>>,
146 goals: InternedSet<'tcx, Slice<Goal<'tcx>>>,
a7813a04
XL
147}
148
149impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
83c7162d 150 fn new(arena: &'tcx SyncDroplessArena) -> CtxtInterners<'tcx> {
a7813a04 151 CtxtInterners {
041b39d2 152 arena,
83c7162d
XL
153 type_: Default::default(),
154 type_list: Default::default(),
155 substs: Default::default(),
156 region: Default::default(),
157 existential_predicates: Default::default(),
158 canonical_var_infos: Default::default(),
159 predicates: Default::default(),
160 const_: Default::default(),
161 clauses: Default::default(),
162 goals: Default::default(),
a7813a04
XL
163 }
164 }
165
94b46f34
XL
166 /// Intern a type
167 fn intern_ty(
168 local: &CtxtInterners<'tcx>,
169 global: &CtxtInterners<'gcx>,
170 st: TypeVariants<'tcx>
171 ) -> Ty<'tcx> {
172 let flags = super::flags::FlagComputation::for_sty(&st);
173
174 // HACK(eddyb) Depend on flags being accurate to
175 // determine that all contents are in the global tcx.
176 // See comments on Lift for why we can't use that.
177 if flags.flags.intersects(ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
178 let mut interner = local.type_.borrow_mut();
a7813a04
XL
179 if let Some(&Interned(ty)) = interner.get(&st) {
180 return ty;
181 }
a7813a04 182
a7813a04
XL
183 let ty_struct = TyS {
184 sty: st,
7cac9316 185 flags: flags.flags,
94b46f34 186 outer_exclusive_binder: flags.outer_exclusive_binder,
a7813a04
XL
187 };
188
94b46f34
XL
189 // Make sure we don't end up with inference
190 // types/regions in the global interner
191 if local as *const _ as usize == global as *const _ as usize {
192 bug!("Attempted to intern `{:?}` which contains \
193 inference types/regions in the global type context",
194 &ty_struct);
a7813a04
XL
195 }
196
197 // Don't be &mut TyS.
94b46f34 198 let ty: Ty<'tcx> = local.arena.alloc(ty_struct);
a7813a04
XL
199 interner.insert(Interned(ty));
200 ty
94b46f34
XL
201 } else {
202 let mut interner = global.type_.borrow_mut();
203 if let Some(&Interned(ty)) = interner.get(&st) {
204 return ty;
205 }
a7813a04 206
94b46f34
XL
207 let ty_struct = TyS {
208 sty: st,
209 flags: flags.flags,
210 outer_exclusive_binder: flags.outer_exclusive_binder,
211 };
212
213 // This is safe because all the types the ty_struct can point to
214 // already is in the global arena
215 let ty_struct: TyS<'gcx> = unsafe {
216 mem::transmute(ty_struct)
217 };
a7813a04 218
94b46f34
XL
219 // Don't be &mut TyS.
220 let ty: Ty<'gcx> = global.arena.alloc(ty_struct);
221 interner.insert(Interned(ty));
222 ty
223 }
224 }
a7813a04
XL
225}
226
e9174d1e
SL
227pub struct CommonTypes<'tcx> {
228 pub bool: Ty<'tcx>,
229 pub char: Ty<'tcx>,
230 pub isize: Ty<'tcx>,
231 pub i8: Ty<'tcx>,
232 pub i16: Ty<'tcx>,
233 pub i32: Ty<'tcx>,
234 pub i64: Ty<'tcx>,
32a655c1 235 pub i128: Ty<'tcx>,
e9174d1e
SL
236 pub usize: Ty<'tcx>,
237 pub u8: Ty<'tcx>,
238 pub u16: Ty<'tcx>,
239 pub u32: Ty<'tcx>,
240 pub u64: Ty<'tcx>,
32a655c1 241 pub u128: Ty<'tcx>,
e9174d1e
SL
242 pub f32: Ty<'tcx>,
243 pub f64: Ty<'tcx>,
5bcae85e 244 pub never: Ty<'tcx>,
e9174d1e 245 pub err: Ty<'tcx>,
cc61c64b 246
7cac9316
XL
247 pub re_empty: Region<'tcx>,
248 pub re_static: Region<'tcx>,
249 pub re_erased: Region<'tcx>,
e9174d1e
SL
250}
251
3b2f2976
XL
252pub struct LocalTableInContext<'a, V: 'a> {
253 local_id_root: Option<DefId>,
254 data: &'a ItemLocalMap<V>
255}
256
257/// Validate that the given HirId (respectively its `local_id` part) can be
258/// safely used as a key in the tables of a TypeckTable. For that to be
259/// the case, the HirId must have the same `owner` as all the other IDs in
260/// this table (signified by `local_id_root`). Otherwise the HirId
261/// would be in a different frame of reference and using its `local_id`
262/// would result in lookup errors, or worse, in silently wrong data being
263/// stored/returned.
264fn validate_hir_id_for_typeck_tables(local_id_root: Option<DefId>,
265 hir_id: hir::HirId,
266 mut_access: bool) {
267 if cfg!(debug_assertions) {
268 if let Some(local_id_root) = local_id_root {
269 if hir_id.owner != local_id_root.index {
270 ty::tls::with(|tcx| {
94b46f34 271 let node_id = tcx.hir.hir_to_node_id(hir_id);
3b2f2976
XL
272
273 bug!("node {} with HirId::owner {:?} cannot be placed in \
274 TypeckTables with local_id_root {:?}",
275 tcx.hir.node_to_string(node_id),
276 DefId::local(hir_id.owner),
277 local_id_root)
278 });
279 }
280 } else {
281 // We use "Null Object" TypeckTables in some of the analysis passes.
282 // These are just expected to be empty and their `local_id_root` is
283 // `None`. Therefore we cannot verify whether a given `HirId` would
284 // be a valid key for the given table. Instead we make sure that
285 // nobody tries to write to such a Null Object table.
286 if mut_access {
287 bug!("access to invalid TypeckTables")
288 }
289 }
290 }
291}
292
293impl<'a, V> LocalTableInContext<'a, V> {
294 pub fn contains_key(&self, id: hir::HirId) -> bool {
295 validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
296 self.data.contains_key(&id.local_id)
297 }
298
299 pub fn get(&self, id: hir::HirId) -> Option<&V> {
300 validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
301 self.data.get(&id.local_id)
302 }
303
304 pub fn iter(&self) -> hash_map::Iter<hir::ItemLocalId, V> {
305 self.data.iter()
306 }
307}
308
309impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> {
310 type Output = V;
311
312 fn index(&self, key: hir::HirId) -> &V {
313 self.get(key).expect("LocalTableInContext: key not found")
314 }
315}
316
317pub struct LocalTableInContextMut<'a, V: 'a> {
318 local_id_root: Option<DefId>,
319 data: &'a mut ItemLocalMap<V>
320}
321
322impl<'a, V> LocalTableInContextMut<'a, V> {
323 pub fn get_mut(&mut self, id: hir::HirId) -> Option<&mut V> {
324 validate_hir_id_for_typeck_tables(self.local_id_root, id, true);
325 self.data.get_mut(&id.local_id)
326 }
327
328 pub fn entry(&mut self, id: hir::HirId) -> Entry<hir::ItemLocalId, V> {
329 validate_hir_id_for_typeck_tables(self.local_id_root, id, true);
330 self.data.entry(id.local_id)
331 }
332
333 pub fn insert(&mut self, id: hir::HirId, val: V) -> Option<V> {
334 validate_hir_id_for_typeck_tables(self.local_id_root, id, true);
335 self.data.insert(id.local_id, val)
336 }
337
338 pub fn remove(&mut self, id: hir::HirId) -> Option<V> {
339 validate_hir_id_for_typeck_tables(self.local_id_root, id, true);
340 self.data.remove(&id.local_id)
341 }
342}
343
ea8adc8c 344#[derive(RustcEncodable, RustcDecodable, Debug)]
32a655c1 345pub struct TypeckTables<'tcx> {
3b2f2976
XL
346 /// The HirId::owner all ItemLocalIds in this table are relative to.
347 pub local_id_root: Option<DefId>,
348
7cac9316
XL
349 /// Resolved definitions for `<T>::X` associated paths and
350 /// method calls, including those of overloaded operators.
3b2f2976 351 type_dependent_defs: ItemLocalMap<Def>,
476ff2be 352
83c7162d
XL
353 /// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
354 /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
355 /// about the field you also need definition of the variant to which the field
356 /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
357 field_indices: ItemLocalMap<usize>,
358
0531ce1d
XL
359 /// Stores the canonicalized types provided by the user. See also `UserAssertTy` statement in
360 /// MIR.
361 user_provided_tys: ItemLocalMap<CanonicalTy<'tcx>>,
362
e9174d1e
SL
363 /// Stores the types for various nodes in the AST. Note that this table
364 /// is not guaranteed to be populated until after typeck. See
365 /// typeck::check::fn_ctxt for details.
3b2f2976 366 node_types: ItemLocalMap<Ty<'tcx>>,
e9174d1e
SL
367
368 /// Stores the type parameters which were substituted to obtain the type
369 /// of this node. This only applies to nodes that refer to entities
370 /// parameterized by type parameters, such as generic fns, types, or
371 /// other items.
3b2f2976 372 node_substs: ItemLocalMap<&'tcx Substs<'tcx>>,
e9174d1e 373
3b2f2976
XL
374 adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
375
ea8adc8c 376 /// Stores the actual binding mode for all instances of hir::BindingAnnotation.
3b2f2976 377 pat_binding_modes: ItemLocalMap<BindingMode>,
e9174d1e 378
ea8adc8c
XL
379 /// Stores the types which were implicitly dereferenced in pattern binding modes
380 /// for later usage in HAIR lowering. For example,
381 ///
382 /// ```
383 /// match &&Some(5i32) {
384 /// Some(n) => {},
385 /// _ => {},
386 /// }
387 /// ```
388 /// leads to a `vec![&&Option<i32>, &Option<i32>]`. Empty vectors are not stored.
389 ///
390 /// See:
391 /// https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions
392 pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>,
393
e9174d1e 394 /// Borrows
9e0c209e 395 pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>,
e9174d1e 396
ff7c6d11
XL
397 /// Records the reasons that we picked the kind of each closure;
398 /// not all closures are present in the map.
399 closure_kind_origins: ItemLocalMap<(Span, ast::Name)>,
ea8adc8c 400
92a42be0
SL
401 /// For each fn, records the "liberated" types of its arguments
402 /// and return type. Liberated means that all bound regions
403 /// (including late-bound regions) are replaced with free
94b46f34 404 /// equivalents. This table is not used in codegen (since regions
92a42be0 405 /// are erased there) and hence is not serialized to metadata.
3b2f2976 406 liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
7453a54e
SL
407
408 /// For each FRU expression, record the normalized types of the fields
409 /// of the struct - this is needed because it is non-trivial to
410 /// normalize while preserving regions. This table is used only in
411 /// MIR construction and hence is not serialized to metadata.
3b2f2976 412 fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
32a655c1
SL
413
414 /// Maps a cast expression to its kind. This is keyed on the
415 /// *from* expression of the cast, not the cast itself.
3b2f2976 416 cast_kinds: ItemLocalMap<ty::cast::CastKind>,
8bb4bdeb
XL
417
418 /// Set of trait imports actually used in the method resolution.
abe05a73 419 /// This is used for warning unused imports. During type
0531ce1d 420 /// checking, this `Lrc` should not be cloned: it must have a ref-count
abe05a73 421 /// of 1 so that we can insert things into the set mutably.
0531ce1d 422 pub used_trait_imports: Lrc<DefIdSet>,
8bb4bdeb
XL
423
424 /// If any errors occurred while type-checking this body,
425 /// this field will be set to `true`.
426 pub tainted_by_errors: bool,
427
428 /// Stores the free-region relationships that were deduced from
429 /// its where clauses and parameter types. These are then
430 /// read-again by borrowck.
7cac9316 431 pub free_region_map: FreeRegionMap<'tcx>,
94b46f34
XL
432
433 /// All the existential types that are restricted to concrete types
434 /// by this function
435 pub concrete_existential_types: FxHashMap<DefId, Ty<'tcx>>,
e9174d1e
SL
436}
437
32a655c1 438impl<'tcx> TypeckTables<'tcx> {
3b2f2976 439 pub fn empty(local_id_root: Option<DefId>) -> TypeckTables<'tcx> {
32a655c1 440 TypeckTables {
3b2f2976
XL
441 local_id_root,
442 type_dependent_defs: ItemLocalMap(),
83c7162d 443 field_indices: ItemLocalMap(),
0531ce1d 444 user_provided_tys: ItemLocalMap(),
3b2f2976
XL
445 node_types: ItemLocalMap(),
446 node_substs: ItemLocalMap(),
447 adjustments: ItemLocalMap(),
448 pat_binding_modes: ItemLocalMap(),
ea8adc8c 449 pat_adjustments: ItemLocalMap(),
476ff2be 450 upvar_capture_map: FxHashMap(),
ff7c6d11 451 closure_kind_origins: ItemLocalMap(),
3b2f2976
XL
452 liberated_fn_sigs: ItemLocalMap(),
453 fru_field_types: ItemLocalMap(),
454 cast_kinds: ItemLocalMap(),
0531ce1d 455 used_trait_imports: Lrc::new(DefIdSet()),
8bb4bdeb
XL
456 tainted_by_errors: false,
457 free_region_map: FreeRegionMap::new(),
94b46f34 458 concrete_existential_types: FxHashMap(),
e9174d1e
SL
459 }
460 }
c30ab7b3 461
476ff2be 462 /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
3b2f2976 463 pub fn qpath_def(&self, qpath: &hir::QPath, id: hir::HirId) -> Def {
476ff2be
SL
464 match *qpath {
465 hir::QPath::Resolved(_, ref path) => path.def,
466 hir::QPath::TypeRelative(..) => {
3b2f2976
XL
467 validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
468 self.type_dependent_defs.get(&id.local_id).cloned().unwrap_or(Def::Err)
476ff2be
SL
469 }
470 }
471 }
472
3b2f2976
XL
473 pub fn type_dependent_defs(&self) -> LocalTableInContext<Def> {
474 LocalTableInContext {
475 local_id_root: self.local_id_root,
476 data: &self.type_dependent_defs
477 }
478 }
479
480 pub fn type_dependent_defs_mut(&mut self) -> LocalTableInContextMut<Def> {
481 LocalTableInContextMut {
482 local_id_root: self.local_id_root,
483 data: &mut self.type_dependent_defs
484 }
485 }
486
83c7162d
XL
487 pub fn field_indices(&self) -> LocalTableInContext<usize> {
488 LocalTableInContext {
489 local_id_root: self.local_id_root,
490 data: &self.field_indices
491 }
492 }
493
494 pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<usize> {
495 LocalTableInContextMut {
496 local_id_root: self.local_id_root,
497 data: &mut self.field_indices
498 }
499 }
500
0531ce1d
XL
501 pub fn user_provided_tys(&self) -> LocalTableInContext<CanonicalTy<'tcx>> {
502 LocalTableInContext {
503 local_id_root: self.local_id_root,
504 data: &self.user_provided_tys
505 }
506 }
507
508 pub fn user_provided_tys_mut(&mut self) -> LocalTableInContextMut<CanonicalTy<'tcx>> {
509 LocalTableInContextMut {
510 local_id_root: self.local_id_root,
511 data: &mut self.user_provided_tys
512 }
513 }
514
3b2f2976
XL
515 pub fn node_types(&self) -> LocalTableInContext<Ty<'tcx>> {
516 LocalTableInContext {
517 local_id_root: self.local_id_root,
518 data: &self.node_types
519 }
520 }
521
522 pub fn node_types_mut(&mut self) -> LocalTableInContextMut<Ty<'tcx>> {
523 LocalTableInContextMut {
524 local_id_root: self.local_id_root,
525 data: &mut self.node_types
526 }
527 }
528
529 pub fn node_id_to_type(&self, id: hir::HirId) -> Ty<'tcx> {
c30ab7b3
SL
530 match self.node_id_to_type_opt(id) {
531 Some(ty) => ty,
532 None => {
533 bug!("node_id_to_type: no type for node `{}`",
3b2f2976 534 tls::with(|tcx| {
94b46f34 535 let id = tcx.hir.hir_to_node_id(id);
3b2f2976
XL
536 tcx.hir.node_to_string(id)
537 }))
c30ab7b3
SL
538 }
539 }
540 }
541
3b2f2976
XL
542 pub fn node_id_to_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
543 validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
544 self.node_types.get(&id.local_id).cloned()
545 }
546
547 pub fn node_substs_mut(&mut self) -> LocalTableInContextMut<&'tcx Substs<'tcx>> {
548 LocalTableInContextMut {
549 local_id_root: self.local_id_root,
550 data: &mut self.node_substs
551 }
552 }
553
554 pub fn node_substs(&self, id: hir::HirId) -> &'tcx Substs<'tcx> {
555 validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
556 self.node_substs.get(&id.local_id).cloned().unwrap_or(Substs::empty())
c30ab7b3
SL
557 }
558
3b2f2976
XL
559 pub fn node_substs_opt(&self, id: hir::HirId) -> Option<&'tcx Substs<'tcx>> {
560 validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
561 self.node_substs.get(&id.local_id).cloned()
c30ab7b3
SL
562 }
563
564 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
565 // doesn't provide type parameter substitutions.
566 pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
3b2f2976 567 self.node_id_to_type(pat.hir_id)
c30ab7b3
SL
568 }
569
570 pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
3b2f2976 571 self.node_id_to_type_opt(pat.hir_id)
c30ab7b3
SL
572 }
573
574 // Returns the type of an expression as a monotype.
575 //
576 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
577 // some cases, we insert `Adjustment` annotations such as auto-deref or
578 // auto-ref. The type returned by this function does not consider such
579 // adjustments. See `expr_ty_adjusted()` instead.
580 //
581 // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
582 // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
583 // instead of "fn(ty) -> T with T = isize".
584 pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
3b2f2976 585 self.node_id_to_type(expr.hir_id)
c30ab7b3
SL
586 }
587
588 pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
3b2f2976
XL
589 self.node_id_to_type_opt(expr.hir_id)
590 }
591
592 pub fn adjustments(&self) -> LocalTableInContext<Vec<ty::adjustment::Adjustment<'tcx>>> {
593 LocalTableInContext {
594 local_id_root: self.local_id_root,
595 data: &self.adjustments
596 }
597 }
598
599 pub fn adjustments_mut(&mut self)
600 -> LocalTableInContextMut<Vec<ty::adjustment::Adjustment<'tcx>>> {
601 LocalTableInContextMut {
602 local_id_root: self.local_id_root,
603 data: &mut self.adjustments
604 }
c30ab7b3
SL
605 }
606
7cac9316
XL
607 pub fn expr_adjustments(&self, expr: &hir::Expr)
608 -> &[ty::adjustment::Adjustment<'tcx>] {
3b2f2976
XL
609 validate_hir_id_for_typeck_tables(self.local_id_root, expr.hir_id, false);
610 self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
7cac9316
XL
611 }
612
c30ab7b3
SL
613 /// Returns the type of `expr`, considering any `Adjustment`
614 /// entry recorded for that expression.
615 pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> Ty<'tcx> {
7cac9316
XL
616 self.expr_adjustments(expr)
617 .last()
c30ab7b3
SL
618 .map_or_else(|| self.expr_ty(expr), |adj| adj.target)
619 }
620
621 pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
7cac9316
XL
622 self.expr_adjustments(expr)
623 .last()
624 .map(|adj| adj.target)
625 .or_else(|| self.expr_ty_opt(expr))
c30ab7b3
SL
626 }
627
7cac9316
XL
628 pub fn is_method_call(&self, expr: &hir::Expr) -> bool {
629 // Only paths and method calls/overloaded operators have
630 // entries in type_dependent_defs, ignore the former here.
8faf50e0 631 if let hir::ExprKind::Path(_) = expr.node {
7cac9316
XL
632 return false;
633 }
c30ab7b3 634
3b2f2976 635 match self.type_dependent_defs().get(expr.hir_id) {
7cac9316
XL
636 Some(&Def::Method(_)) => true,
637 _ => false
638 }
c30ab7b3
SL
639 }
640
3b2f2976
XL
641 pub fn pat_binding_modes(&self) -> LocalTableInContext<BindingMode> {
642 LocalTableInContext {
643 local_id_root: self.local_id_root,
644 data: &self.pat_binding_modes
645 }
646 }
647
648 pub fn pat_binding_modes_mut(&mut self)
649 -> LocalTableInContextMut<BindingMode> {
650 LocalTableInContextMut {
651 local_id_root: self.local_id_root,
652 data: &mut self.pat_binding_modes
653 }
654 }
655
ea8adc8c
XL
656 pub fn pat_adjustments(&self) -> LocalTableInContext<Vec<Ty<'tcx>>> {
657 LocalTableInContext {
658 local_id_root: self.local_id_root,
659 data: &self.pat_adjustments,
660 }
661 }
662
663 pub fn pat_adjustments_mut(&mut self)
664 -> LocalTableInContextMut<Vec<Ty<'tcx>>> {
665 LocalTableInContextMut {
666 local_id_root: self.local_id_root,
667 data: &mut self.pat_adjustments,
668 }
669 }
670
041b39d2
XL
671 pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> ty::UpvarCapture<'tcx> {
672 self.upvar_capture_map[&upvar_id]
c30ab7b3 673 }
3b2f2976 674
ff7c6d11 675 pub fn closure_kind_origins(&self) -> LocalTableInContext<(Span, ast::Name)> {
3b2f2976
XL
676 LocalTableInContext {
677 local_id_root: self.local_id_root,
ff7c6d11 678 data: &self.closure_kind_origins
3b2f2976
XL
679 }
680 }
681
ff7c6d11 682 pub fn closure_kind_origins_mut(&mut self) -> LocalTableInContextMut<(Span, ast::Name)> {
3b2f2976
XL
683 LocalTableInContextMut {
684 local_id_root: self.local_id_root,
ff7c6d11 685 data: &mut self.closure_kind_origins
3b2f2976
XL
686 }
687 }
688
689 pub fn liberated_fn_sigs(&self) -> LocalTableInContext<ty::FnSig<'tcx>> {
690 LocalTableInContext {
691 local_id_root: self.local_id_root,
692 data: &self.liberated_fn_sigs
693 }
694 }
695
696 pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut<ty::FnSig<'tcx>> {
697 LocalTableInContextMut {
698 local_id_root: self.local_id_root,
699 data: &mut self.liberated_fn_sigs
700 }
701 }
702
703 pub fn fru_field_types(&self) -> LocalTableInContext<Vec<Ty<'tcx>>> {
704 LocalTableInContext {
705 local_id_root: self.local_id_root,
706 data: &self.fru_field_types
707 }
708 }
709
710 pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut<Vec<Ty<'tcx>>> {
711 LocalTableInContextMut {
712 local_id_root: self.local_id_root,
713 data: &mut self.fru_field_types
714 }
715 }
716
717 pub fn cast_kinds(&self) -> LocalTableInContext<ty::cast::CastKind> {
718 LocalTableInContext {
719 local_id_root: self.local_id_root,
720 data: &self.cast_kinds
721 }
722 }
723
724 pub fn cast_kinds_mut(&mut self) -> LocalTableInContextMut<ty::cast::CastKind> {
725 LocalTableInContextMut {
726 local_id_root: self.local_id_root,
727 data: &mut self.cast_kinds
728 }
729 }
730}
731
0531ce1d 732impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
3b2f2976 733 fn hash_stable<W: StableHasherResult>(&self,
0531ce1d 734 hcx: &mut StableHashingContext<'a>,
3b2f2976
XL
735 hasher: &mut StableHasher<W>) {
736 let ty::TypeckTables {
737 local_id_root,
738 ref type_dependent_defs,
83c7162d 739 ref field_indices,
0531ce1d 740 ref user_provided_tys,
3b2f2976
XL
741 ref node_types,
742 ref node_substs,
743 ref adjustments,
744 ref pat_binding_modes,
ea8adc8c 745 ref pat_adjustments,
3b2f2976 746 ref upvar_capture_map,
ff7c6d11 747 ref closure_kind_origins,
3b2f2976
XL
748 ref liberated_fn_sigs,
749 ref fru_field_types,
750
751 ref cast_kinds,
752
753 ref used_trait_imports,
754 tainted_by_errors,
755 ref free_region_map,
94b46f34 756 ref concrete_existential_types,
3b2f2976
XL
757 } = *self;
758
759 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
ea8adc8c 760 type_dependent_defs.hash_stable(hcx, hasher);
83c7162d 761 field_indices.hash_stable(hcx, hasher);
0531ce1d 762 user_provided_tys.hash_stable(hcx, hasher);
ea8adc8c
XL
763 node_types.hash_stable(hcx, hasher);
764 node_substs.hash_stable(hcx, hasher);
765 adjustments.hash_stable(hcx, hasher);
766 pat_binding_modes.hash_stable(hcx, hasher);
767 pat_adjustments.hash_stable(hcx, hasher);
768 hash_stable_hashmap(hcx, hasher, upvar_capture_map, |up_var_id, hcx| {
3b2f2976
XL
769 let ty::UpvarId {
770 var_id,
771 closure_expr_id
772 } = *up_var_id;
773
774 let local_id_root =
775 local_id_root.expect("trying to hash invalid TypeckTables");
776
ea8adc8c 777 let var_owner_def_id = DefId {
3b2f2976 778 krate: local_id_root.krate,
ea8adc8c 779 index: var_id.owner,
3b2f2976
XL
780 };
781 let closure_def_id = DefId {
782 krate: local_id_root.krate,
abe05a73 783 index: closure_expr_id.to_def_id().index,
3b2f2976 784 };
ea8adc8c
XL
785 (hcx.def_path_hash(var_owner_def_id),
786 var_id.local_id,
787 hcx.def_path_hash(closure_def_id))
3b2f2976
XL
788 });
789
ff7c6d11 790 closure_kind_origins.hash_stable(hcx, hasher);
ea8adc8c
XL
791 liberated_fn_sigs.hash_stable(hcx, hasher);
792 fru_field_types.hash_stable(hcx, hasher);
793 cast_kinds.hash_stable(hcx, hasher);
ea8adc8c 794 used_trait_imports.hash_stable(hcx, hasher);
3b2f2976
XL
795 tainted_by_errors.hash_stable(hcx, hasher);
796 free_region_map.hash_stable(hcx, hasher);
94b46f34 797 concrete_existential_types.hash_stable(hcx, hasher);
3b2f2976
XL
798 })
799 }
e9174d1e
SL
800}
801
802impl<'tcx> CommonTypes<'tcx> {
a7813a04 803 fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
94b46f34
XL
804 // Ensure our type representation does not grow
805 #[cfg(target_pointer_width = "64")]
806 assert!(mem::size_of::<ty::TypeVariants>() <= 24);
807 #[cfg(target_pointer_width = "64")]
808 assert!(mem::size_of::<ty::TyS>() <= 32);
809
810 let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
cc61c64b
XL
811 let mk_region = |r| {
812 if let Some(r) = interners.region.borrow().get(&r) {
813 return r.0;
814 }
815 let r = interners.arena.alloc(r);
816 interners.region.borrow_mut().insert(Interned(r));
817 &*r
818 };
e9174d1e
SL
819 CommonTypes {
820 bool: mk(TyBool),
821 char: mk(TyChar),
5bcae85e 822 never: mk(TyNever),
e9174d1e 823 err: mk(TyError),
2c00a5a8 824 isize: mk(TyInt(ast::IntTy::Isize)),
7453a54e
SL
825 i8: mk(TyInt(ast::IntTy::I8)),
826 i16: mk(TyInt(ast::IntTy::I16)),
827 i32: mk(TyInt(ast::IntTy::I32)),
828 i64: mk(TyInt(ast::IntTy::I64)),
32a655c1 829 i128: mk(TyInt(ast::IntTy::I128)),
2c00a5a8 830 usize: mk(TyUint(ast::UintTy::Usize)),
7453a54e
SL
831 u8: mk(TyUint(ast::UintTy::U8)),
832 u16: mk(TyUint(ast::UintTy::U16)),
833 u32: mk(TyUint(ast::UintTy::U32)),
834 u64: mk(TyUint(ast::UintTy::U64)),
32a655c1 835 u128: mk(TyUint(ast::UintTy::U128)),
7453a54e
SL
836 f32: mk(TyFloat(ast::FloatTy::F32)),
837 f64: mk(TyFloat(ast::FloatTy::F64)),
cc61c64b 838
7cac9316
XL
839 re_empty: mk_region(RegionKind::ReEmpty),
840 re_static: mk_region(RegionKind::ReStatic),
841 re_erased: mk_region(RegionKind::ReErased),
e9174d1e
SL
842 }
843 }
844}
845
ea8adc8c
XL
846/// The central data structure of the compiler. It stores references
847/// to the various **arenas** and also houses the results of the
ff7c6d11 848/// various **compiler queries** that have been performed. See the
0531ce1d 849/// [rustc guide] for more details.
ff7c6d11 850///
0531ce1d 851/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ty.html
a7813a04 852#[derive(Copy, Clone)]
8faf50e0 853pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> {
a7813a04
XL
854 gcx: &'a GlobalCtxt<'gcx>,
855 interners: &'a CtxtInterners<'tcx>
856}
e9174d1e 857
a7813a04
XL
858impl<'a, 'gcx, 'tcx> Deref for TyCtxt<'a, 'gcx, 'tcx> {
859 type Target = &'a GlobalCtxt<'gcx>;
860 fn deref(&self) -> &Self::Target {
861 &self.gcx
862 }
863}
864
865pub struct GlobalCtxt<'tcx> {
94b46f34 866 global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
a7813a04 867 global_interners: CtxtInterners<'tcx>,
e9174d1e 868
94b46f34 869 cstore: &'tcx CrateStoreDyn,
ea8adc8c 870
8bb4bdeb
XL
871 pub sess: &'tcx Session,
872
9cc50fc6
SL
873 pub dep_graph: DepGraph,
874
e9174d1e
SL
875 /// Common types, pre-interned for your convenience.
876 pub types: CommonTypes<'tcx>,
877
5bcae85e
SL
878 /// Map indicating what traits are in scope for places where this
879 /// is relevant; generated by resolve.
ea8adc8c 880 trait_map: FxHashMap<DefIndex,
0531ce1d
XL
881 Lrc<FxHashMap<ItemLocalId,
882 Lrc<StableVec<TraitCandidate>>>>>,
5bcae85e 883
cc61c64b 884 /// Export map produced by name resolution.
0531ce1d 885 export_map: FxHashMap<DefId, Lrc<Vec<Export>>>,
cc61c64b 886
32a655c1 887 pub hir: hir_map::Map<'tcx>,
7cac9316
XL
888
889 /// A map from DefPathHash -> DefId. Includes DefIds from the local crate
890 /// as well as all upstream crates. Only populated in incremental mode.
891 pub def_path_hash_to_def_id: Option<FxHashMap<DefPathHash, DefId>>,
892
94b46f34 893 pub(crate) queries: query::Queries<'tcx>,
c30ab7b3 894
9cc50fc6
SL
895 // Records the free variables refrenced by every closure
896 // expression. Do not track deps for this, just recompute it from
897 // scratch every time.
0531ce1d 898 freevars: FxHashMap<DefId, Lrc<Vec<hir::Freevar>>>,
9cc50fc6 899
ea8adc8c 900 maybe_unused_trait_imports: FxHashSet<DefId>,
a7813a04 901
ea8adc8c 902 maybe_unused_extern_crates: Vec<(DefId, Span)>,
3b2f2976 903
9cc50fc6 904 // Internal cache for metadata decoding. No need to track deps on this.
83c7162d 905 pub rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
9cc50fc6 906
e9174d1e
SL
907 /// Caches the results of trait selection. This cache is used
908 /// for things that do not have to do with the parameters in scope.
909 pub selection_cache: traits::SelectionCache<'tcx>,
910
92a42be0
SL
911 /// Caches the results of trait evaluation. This cache is used
912 /// for things that do not have to do with the parameters in scope.
913 /// Merge this with `selection_cache`?
914 pub evaluation_cache: traits::EvaluationCache<'tcx>,
915
54a0048b
SL
916 /// The definite name of the current crate after taking into account
917 /// attributes, commandline parameters, etc.
476ff2be 918 pub crate_name: Symbol,
54a0048b
SL
919
920 /// Data layout specification for the current target.
921 pub data_layout: TargetDataLayout,
922
83c7162d 923 stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>,
32a655c1 924
94b46f34
XL
925 /// Stores the value of constants (and deduplicates the actual memory)
926 allocation_interner: Lock<FxHashSet<&'tcx Allocation>>,
927
928 pub alloc_map: Lock<interpret::AllocMap<'tcx, &'tcx Allocation>>,
ff7c6d11 929
83c7162d 930 layout_interner: Lock<FxHashSet<&'tcx LayoutDetails>>,
ea8adc8c
XL
931
932 /// A general purpose channel to throw data out the back towards LLVM worker
933 /// threads.
934 ///
94b46f34 935 /// This is intended to only get used during the codegen phase of the compiler
ea8adc8c
XL
936 /// when satisfying the query for a particular codegen unit. Internally in
937 /// the query it'll send data along this channel to get processed later.
83c7162d 938 pub tx_to_llvm_workers: Lock<mpsc::Sender<Box<dyn Any + Send>>>,
ea8adc8c
XL
939
940 output_filenames: Arc<OutputFilenames>,
e9174d1e 941}
e9174d1e 942
0531ce1d 943impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
a7813a04 944 /// Get the global TyCtxt.
0531ce1d
XL
945 #[inline]
946 pub fn global_tcx(self) -> TyCtxt<'a, 'gcx, 'gcx> {
a7813a04 947 TyCtxt {
0531ce1d
XL
948 gcx: self.gcx,
949 interners: &self.gcx.global_interners,
a7813a04
XL
950 }
951 }
a7813a04 952
8bb4bdeb 953 pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics {
32a655c1 954 self.global_arenas.generics.alloc(generics)
9e0c209e
SL
955 }
956
7cac9316
XL
957 pub fn alloc_steal_mir(self, mir: Mir<'gcx>) -> &'gcx Steal<Mir<'gcx>> {
958 self.global_arenas.steal_mir.alloc(Steal::new(mir))
959 }
960
961 pub fn alloc_mir(self, mir: Mir<'gcx>) -> &'gcx Mir<'gcx> {
962 self.global_arenas.mir.alloc(mir)
32a655c1
SL
963 }
964
965 pub fn alloc_tables(self, tables: ty::TypeckTables<'gcx>) -> &'gcx ty::TypeckTables<'gcx> {
966 self.global_arenas.tables.alloc(tables)
c30ab7b3
SL
967 }
968
476ff2be 969 pub fn alloc_trait_def(self, def: ty::TraitDef) -> &'gcx ty::TraitDef {
32a655c1 970 self.global_arenas.trait_def.alloc(def)
e9174d1e
SL
971 }
972
476ff2be
SL
973 pub fn alloc_adt_def(self,
974 did: DefId,
975 kind: AdtKind,
8bb4bdeb
XL
976 variants: Vec<ty::VariantDef>,
977 repr: ReprOptions)
476ff2be 978 -> &'gcx ty::AdtDef {
8bb4bdeb 979 let def = ty::AdtDef::new(self, did, kind, variants, repr);
32a655c1 980 self.global_arenas.adt_def.alloc(def)
e9174d1e
SL
981 }
982
ea8adc8c
XL
983 pub fn alloc_byte_array(self, bytes: &[u8]) -> &'gcx [u8] {
984 if bytes.is_empty() {
985 &[]
986 } else {
987 self.global_interners.arena.alloc_slice(bytes)
988 }
989 }
990
991 pub fn alloc_const_slice(self, values: &[&'tcx ty::Const<'tcx>])
992 -> &'tcx [&'tcx ty::Const<'tcx>] {
993 if values.is_empty() {
994 &[]
995 } else {
996 self.interners.arena.alloc_slice(values)
997 }
998 }
999
1000 pub fn alloc_name_const_slice(self, values: &[(ast::Name, &'tcx ty::Const<'tcx>)])
1001 -> &'tcx [(ast::Name, &'tcx ty::Const<'tcx>)] {
1002 if values.is_empty() {
1003 &[]
1004 } else {
1005 self.interners.arena.alloc_slice(values)
1006 }
1007 }
1008
ff7c6d11
XL
1009 pub fn intern_const_alloc(
1010 self,
94b46f34
XL
1011 alloc: Allocation,
1012 ) -> &'gcx Allocation {
1013 let allocs = &mut self.allocation_interner.borrow_mut();
0531ce1d 1014 if let Some(alloc) = allocs.get(&alloc) {
ff7c6d11
XL
1015 return alloc;
1016 }
1017
1018 let interned = self.global_arenas.const_allocs.alloc(alloc);
0531ce1d 1019 if let Some(prev) = allocs.replace(interned) {
ff7c6d11
XL
1020 bug!("Tried to overwrite interned Allocation: {:#?}", prev)
1021 }
1022 interned
1023 }
1024
1025 /// Allocates a byte or string literal for `mir::interpret`
94b46f34 1026 pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
ff7c6d11 1027 // create an allocation that just contains these bytes
94b46f34 1028 let alloc = interpret::Allocation::from_byte_aligned_bytes(bytes);
ff7c6d11 1029 let alloc = self.intern_const_alloc(alloc);
94b46f34 1030 self.alloc_map.lock().allocate(alloc)
ff7c6d11
XL
1031 }
1032
a7813a04 1033 pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
0531ce1d
XL
1034 let mut stability_interner = self.stability_interner.borrow_mut();
1035 if let Some(st) = stability_interner.get(&stab) {
e9174d1e
SL
1036 return st;
1037 }
1038
32a655c1 1039 let interned = self.global_interners.arena.alloc(stab);
0531ce1d 1040 if let Some(prev) = stability_interner.replace(interned) {
54a0048b
SL
1041 bug!("Tried to overwrite interned Stability: {:?}", prev)
1042 }
1043 interned
1044 }
1045
ff7c6d11 1046 pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails {
0531ce1d
XL
1047 let mut layout_interner = self.layout_interner.borrow_mut();
1048 if let Some(layout) = layout_interner.get(&layout) {
54a0048b
SL
1049 return layout;
1050 }
1051
32a655c1 1052 let interned = self.global_arenas.layout.alloc(layout);
0531ce1d 1053 if let Some(prev) = layout_interner.replace(interned) {
54a0048b 1054 bug!("Tried to overwrite interned Layout: {:?}", prev)
92a42be0 1055 }
e9174d1e
SL
1056 interned
1057 }
1058
a7813a04 1059 pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
e9174d1e
SL
1060 value.lift_to_tcx(self)
1061 }
1062
a7813a04
XL
1063 /// Like lift, but only tries in the global tcx.
1064 pub fn lift_to_global<T: ?Sized + Lift<'gcx>>(self, value: &T) -> Option<T::Lifted> {
1065 value.lift_to_tcx(self.global_tcx())
1066 }
1067
1068 /// Returns true if self is the same as self.global_tcx().
1069 fn is_global(self) -> bool {
1070 let local = self.interners as *const _;
1071 let global = &self.global_interners as *const _;
1072 local as usize == global as usize
1073 }
1074
1075 /// Create a type context and call the closure with a `TyCtxt` reference
e9174d1e
SL
1076 /// to the context. The closure enforces that the type context and any interned
1077 /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
1078 /// reference to the context, to allow formatting values that need it.
b039eaaf 1079 pub fn create_and_enter<F, R>(s: &'tcx Session,
94b46f34
XL
1080 cstore: &'tcx CrateStoreDyn,
1081 local_providers: ty::query::Providers<'tcx>,
1082 extern_providers: ty::query::Providers<'tcx>,
ff7c6d11 1083 arenas: &'tcx AllArenas<'tcx>,
32a655c1 1084 resolutions: ty::Resolutions,
32a655c1 1085 hir: hir_map::Map<'tcx>,
94b46f34 1086 on_disk_query_result_cache: query::OnDiskCache<'tcx>,
32a655c1 1087 crate_name: &str,
0531ce1d 1088 tx: mpsc::Sender<Box<dyn Any + Send>>,
ea8adc8c 1089 output_filenames: &OutputFilenames,
a7813a04
XL
1090 f: F) -> R
1091 where F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'tcx>) -> R
e9174d1e 1092 {
83c7162d
XL
1093 let data_layout = TargetDataLayout::parse(&s.target.target).unwrap_or_else(|err| {
1094 s.fatal(&err);
1095 });
ff7c6d11 1096 let interners = CtxtInterners::new(&arenas.interner);
a7813a04 1097 let common_types = CommonTypes::new(&interners);
32a655c1 1098 let dep_graph = hir.dep_graph.clone();
ea8adc8c 1099 let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
8bb4bdeb
XL
1100 let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
1101 providers[LOCAL_CRATE] = local_providers;
7cac9316
XL
1102
1103 let def_path_hash_to_def_id = if s.opts.build_dep_graph() {
0531ce1d 1104 let upstream_def_path_tables: Vec<(CrateNum, Lrc<_>)> = cstore
ea8adc8c 1105 .crates_untracked()
7cac9316 1106 .iter()
ea8adc8c 1107 .map(|&cnum| (cnum, cstore.def_path_table(cnum)))
7cac9316
XL
1108 .collect();
1109
1110 let def_path_tables = || {
1111 upstream_def_path_tables
1112 .iter()
1113 .map(|&(cnum, ref rc)| (cnum, &**rc))
1114 .chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())))
1115 };
1116
1117 // Precompute the capacity of the hashmap so we don't have to
1118 // re-allocate when populating it.
1119 let capacity = def_path_tables().map(|(_, t)| t.size()).sum::<usize>();
1120
1121 let mut map: FxHashMap<_, _> = FxHashMap::with_capacity_and_hasher(
1122 capacity,
1123 ::std::default::Default::default()
1124 );
1125
1126 for (cnum, def_path_table) in def_path_tables() {
1127 def_path_table.add_def_path_hashes_to(cnum, &mut map);
1128 }
1129
1130 Some(map)
1131 } else {
1132 None
1133 };
1134
ea8adc8c
XL
1135 let mut trait_map = FxHashMap();
1136 for (k, v) in resolutions.trait_map {
1137 let hir_id = hir.node_to_hir_id(k);
1138 let map = trait_map.entry(hir_id.owner)
0531ce1d
XL
1139 .or_insert_with(|| Lrc::new(FxHashMap()));
1140 Lrc::get_mut(map).unwrap()
ea8adc8c 1141 .insert(hir_id.local_id,
0531ce1d 1142 Lrc::new(StableVec::new(v)));
ea8adc8c 1143 }
ea8adc8c 1144
83c7162d 1145 let gcx = &GlobalCtxt {
8bb4bdeb 1146 sess: s,
ea8adc8c 1147 cstore,
ff7c6d11 1148 global_arenas: &arenas.global,
a7813a04 1149 global_interners: interners,
9cc50fc6 1150 dep_graph: dep_graph.clone(),
e9174d1e 1151 types: common_types,
ea8adc8c
XL
1152 trait_map,
1153 export_map: resolutions.export_map.into_iter().map(|(k, v)| {
0531ce1d 1154 (k, Lrc::new(v))
ea8adc8c
XL
1155 }).collect(),
1156 freevars: resolutions.freevars.into_iter().map(|(k, v)| {
0531ce1d 1157 (hir.local_def_id(k), Lrc::new(v))
ea8adc8c
XL
1158 }).collect(),
1159 maybe_unused_trait_imports:
1160 resolutions.maybe_unused_trait_imports
1161 .into_iter()
1162 .map(|id| hir.local_def_id(id))
1163 .collect(),
1164 maybe_unused_extern_crates:
1165 resolutions.maybe_unused_extern_crates
1166 .into_iter()
1167 .map(|(id, sp)| (hir.local_def_id(id), sp))
1168 .collect(),
041b39d2
XL
1169 hir,
1170 def_path_hash_to_def_id,
94b46f34 1171 queries: query::Queries::new(providers, on_disk_query_result_cache),
83c7162d 1172 rcache: Lock::new(FxHashMap()),
e9174d1e 1173 selection_cache: traits::SelectionCache::new(),
92a42be0 1174 evaluation_cache: traits::EvaluationCache::new(),
476ff2be 1175 crate_name: Symbol::intern(crate_name),
041b39d2 1176 data_layout,
83c7162d
XL
1177 layout_interner: Lock::new(FxHashSet()),
1178 stability_interner: Lock::new(FxHashSet()),
94b46f34
XL
1179 allocation_interner: Lock::new(FxHashSet()),
1180 alloc_map: Lock::new(interpret::AllocMap::new()),
83c7162d 1181 tx_to_llvm_workers: Lock::new(tx),
ea8adc8c 1182 output_filenames: Arc::new(output_filenames.clone()),
83c7162d
XL
1183 };
1184
94b46f34
XL
1185 sync::assert_send_val(&gcx);
1186
83c7162d 1187 tls::enter_global(gcx, f)
e9174d1e 1188 }
cc61c64b
XL
1189
1190 pub fn consider_optimizing<T: Fn() -> String>(&self, msg: T) -> bool {
1191 let cname = self.crate_name(LOCAL_CRATE).as_str();
1192 self.sess.consider_optimizing(&cname, msg)
1193 }
ea8adc8c 1194
0531ce1d 1195 pub fn lang_items(self) -> Lrc<middle::lang_items::LanguageItems> {
ea8adc8c
XL
1196 self.get_lang_items(LOCAL_CRATE)
1197 }
1198
0531ce1d
XL
1199 /// Due to missing llvm support for lowering 128 bit math to software emulation
1200 /// (on some targets), the lowering can be done in MIR.
1201 ///
1202 /// This function only exists until said support is implemented.
1203 pub fn is_binop_lang_item(&self, def_id: DefId) -> Option<(mir::BinOp, bool)> {
1204 let items = self.lang_items();
1205 let def_id = Some(def_id);
1206 if items.i128_add_fn() == def_id { Some((mir::BinOp::Add, false)) }
1207 else if items.u128_add_fn() == def_id { Some((mir::BinOp::Add, false)) }
1208 else if items.i128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) }
1209 else if items.u128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) }
1210 else if items.i128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) }
1211 else if items.u128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) }
1212 else if items.i128_div_fn() == def_id { Some((mir::BinOp::Div, false)) }
1213 else if items.u128_div_fn() == def_id { Some((mir::BinOp::Div, false)) }
1214 else if items.i128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) }
1215 else if items.u128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) }
1216 else if items.i128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) }
1217 else if items.u128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) }
1218 else if items.i128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) }
1219 else if items.u128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) }
1220 else if items.i128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) }
1221 else if items.u128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) }
1222 else if items.i128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) }
1223 else if items.u128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) }
1224 else if items.i128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) }
1225 else if items.u128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) }
1226 else if items.i128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) }
1227 else if items.u128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) }
1228 else if items.i128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) }
1229 else if items.u128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) }
1230 else { None }
1231 }
1232
1233 pub fn stability(self) -> Lrc<stability::Index<'tcx>> {
ff7c6d11 1234 self.stability_index(LOCAL_CRATE)
ea8adc8c
XL
1235 }
1236
0531ce1d 1237 pub fn crates(self) -> Lrc<Vec<CrateNum>> {
ea8adc8c
XL
1238 self.all_crate_nums(LOCAL_CRATE)
1239 }
1240
0531ce1d
XL
1241 pub fn features(self) -> Lrc<feature_gate::Features> {
1242 self.features_query(LOCAL_CRATE)
1243 }
1244
ea8adc8c
XL
1245 pub fn def_key(self, id: DefId) -> hir_map::DefKey {
1246 if id.is_local() {
1247 self.hir.def_key(id)
1248 } else {
1249 self.cstore.def_key(id)
1250 }
1251 }
1252
1253 /// Convert a `DefId` into its fully expanded `DefPath` (every
1254 /// `DefId` is really just an interned def-path).
1255 ///
1256 /// Note that if `id` is not local to this crate, the result will
1257 /// be a non-local `DefPath`.
1258 pub fn def_path(self, id: DefId) -> hir_map::DefPath {
1259 if id.is_local() {
1260 self.hir.def_path(id)
1261 } else {
1262 self.cstore.def_path(id)
1263 }
1264 }
1265
1266 #[inline]
1267 pub fn def_path_hash(self, def_id: DefId) -> hir_map::DefPathHash {
1268 if def_id.is_local() {
1269 self.hir.definitions().def_path_hash(def_id.index)
1270 } else {
1271 self.cstore.def_path_hash(def_id)
1272 }
1273 }
1274
1275 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1276 // We are explicitly not going through queries here in order to get
1277 // crate name and disambiguator since this code is called from debug!()
1278 // statements within the query system and we'd run into endless
1279 // recursion otherwise.
1280 let (crate_name, crate_disambiguator) = if def_id.is_local() {
1281 (self.crate_name.clone(),
1282 self.sess.local_crate_disambiguator())
1283 } else {
1284 (self.cstore.crate_name_untracked(def_id.krate),
1285 self.cstore.crate_disambiguator_untracked(def_id.krate))
1286 };
1287
1288 format!("{}[{}]{}",
1289 crate_name,
1290 // Don't print the whole crate disambiguator. That's just
1291 // annoying in debug output.
abe05a73 1292 &(crate_disambiguator.to_fingerprint().to_hex())[..4],
ea8adc8c
XL
1293 self.def_path(def_id).to_string_no_crate())
1294 }
1295
1296 pub fn metadata_encoding_version(self) -> Vec<u8> {
1297 self.cstore.metadata_encoding_version().to_vec()
1298 }
1299
1300 // Note that this is *untracked* and should only be used within the query
1301 // system if the result is otherwise tracked through queries
0531ce1d 1302 pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Lrc<dyn Any> {
ea8adc8c
XL
1303 self.cstore.crate_data_as_rc_any(cnum)
1304 }
1305
0531ce1d 1306 pub fn create_stable_hashing_context(self) -> StableHashingContext<'a> {
ea8adc8c
XL
1307 let krate = self.dep_graph.with_ignore(|| self.gcx.hir.krate());
1308
1309 StableHashingContext::new(self.sess,
1310 krate,
1311 self.hir.definitions(),
1312 self.cstore)
1313 }
1314
1315 // This method makes sure that we have a DepNode and a Fingerprint for
1316 // every upstream crate. It needs to be called once right after the tcx is
1317 // created.
1318 // With full-fledged red/green, the method will probably become unnecessary
1319 // as this will be done on-demand.
1320 pub fn allocate_metadata_dep_nodes(self) {
1321 // We cannot use the query versions of crates() and crate_hash(), since
1322 // those would need the DepNodes that we are allocating here.
1323 for cnum in self.cstore.crates_untracked() {
1324 let dep_node = DepNode::new(self, DepConstructor::CrateMetadata(cnum));
1325 let crate_hash = self.cstore.crate_hash_untracked(cnum);
1326 self.dep_graph.with_task(dep_node,
1327 self,
1328 crate_hash,
1329 |_, x| x // No transformation needed
1330 );
1331 }
1332 }
1333
1334 // This method exercises the `in_scope_traits_map` query for all possible
1335 // values so that we have their fingerprints available in the DepGraph.
1336 // This is only required as long as we still use the old dependency tracking
1337 // which needs to have the fingerprints of all input nodes beforehand.
1338 pub fn precompute_in_scope_traits_hashes(self) {
1339 for &def_index in self.trait_map.keys() {
1340 self.in_scope_traits_map(def_index);
1341 }
1342 }
abe05a73
XL
1343
1344 pub fn serialize_query_result_cache<E>(self,
1345 encoder: &mut E)
1346 -> Result<(), E::Error>
1347 where E: ty::codec::TyEncoder
1348 {
94b46f34
XL
1349 self.queries.on_disk_cache.serialize(self.global_tcx(), encoder)
1350 }
1351
1352 /// If true, we should use a naive AST walk to determine if match
1353 /// guard could perform bad mutations (or mutable-borrows).
1354 pub fn check_for_mutation_in_guard_via_ast_walk(self) -> bool {
1355 !self.sess.opts.debugging_opts.disable_ast_check_for_mutation_in_guard
abe05a73
XL
1356 }
1357
8faf50e0
XL
1358 /// If true, we should use the AST-based borrowck (we may *also* use
1359 /// the MIR-based borrowck).
1360 pub fn use_ast_borrowck(self) -> bool {
1361 self.borrowck_mode().use_ast()
1362 }
1363
0531ce1d
XL
1364 /// If true, we should use the MIR-based borrowck (we may *also* use
1365 /// the AST-based borrowck).
83c7162d
XL
1366 pub fn use_mir_borrowck(self) -> bool {
1367 self.borrowck_mode().use_mir()
1368 }
1369
8faf50e0
XL
1370 /// If true, we should use the MIR-based borrow check, but also
1371 /// fall back on the AST borrow check if the MIR-based one errors.
1372 pub fn migrate_borrowck(self) -> bool {
1373 self.borrowck_mode().migrate()
1374 }
1375
94b46f34
XL
1376 /// If true, make MIR codegen for `match` emit a temp that holds a
1377 /// borrow of the input to the match expression.
1378 pub fn generate_borrow_of_any_match_input(&self) -> bool {
1379 self.emit_read_for_match()
1380 }
1381
1382 /// If true, make MIR codegen for `match` emit ReadForMatch
1383 /// statements (which simulate the maximal effect of executing the
1384 /// patterns in a match arm).
1385 pub fn emit_read_for_match(&self) -> bool {
1386 self.use_mir_borrowck() && !self.sess.opts.debugging_opts.nll_dont_emit_read_for_match
1387 }
1388
83c7162d
XL
1389 /// If true, pattern variables for use in guards on match arms
1390 /// will be bound as references to the data, and occurrences of
1391 /// those variables in the guard expression will implicitly
1392 /// dereference those bindings. (See rust-lang/rust#27282.)
1393 pub fn all_pat_vars_are_implicit_refs_within_guards(self) -> bool {
0531ce1d
XL
1394 self.borrowck_mode().use_mir()
1395 }
1396
1397 /// If true, we should enable two-phase borrows checks. This is
1398 /// done with either `-Ztwo-phase-borrows` or with
1399 /// `#![feature(nll)]`.
1400 pub fn two_phase_borrows(self) -> bool {
1401 self.features().nll || self.sess.opts.debugging_opts.two_phase_borrows
1402 }
1403
1404 /// What mode(s) of borrowck should we run? AST? MIR? both?
1405 /// (Also considers the `#![feature(nll)]` setting.)
1406 pub fn borrowck_mode(&self) -> BorrowckMode {
8faf50e0
XL
1407 // Here are the main constraints we need to deal with:
1408 //
1409 // 1. An opts.borrowck_mode of `BorrowckMode::Ast` is
1410 // synonymous with no `-Z borrowck=...` flag at all.
1411 // (This is arguably a historical accident.)
1412 //
1413 // 2. `BorrowckMode::Migrate` is the limited migration to
1414 // NLL that we are deploying with the 2018 edition.
1415 //
1416 // 3. We want to allow developers on the Nightly channel
1417 // to opt back into the "hard error" mode for NLL,
1418 // (which they can do via specifying `#![feature(nll)]`
1419 // explicitly in their crate).
1420 //
1421 // So, this precedence list is how pnkfelix chose to work with
1422 // the above constraints:
1423 //
1424 // * `#![feature(nll)]` *always* means use NLL with hard
1425 // errors. (To simplify the code here, it now even overrides
1426 // a user's attempt to specify `-Z borrowck=compare`, which
1427 // we arguably do not need anymore and should remove.)
1428 //
1429 // * Otherwise, if no `-Z borrowck=...` flag was given (or
1430 // if `borrowck=ast` was specified), then use the default
1431 // as required by the edition.
1432 //
1433 // * Otherwise, use the behavior requested via `-Z borrowck=...`
1434
1435 if self.features().nll { return BorrowckMode::Mir; }
1436
0531ce1d
XL
1437 match self.sess.opts.borrowck_mode {
1438 mode @ BorrowckMode::Mir |
8faf50e0
XL
1439 mode @ BorrowckMode::Compare |
1440 mode @ BorrowckMode::Migrate => mode,
1441
1442 BorrowckMode::Ast => match self.sess.edition() {
1443 Edition::Edition2015 => BorrowckMode::Ast,
1444 Edition::Edition2018 => BorrowckMode::Migrate,
1445
1446 // For now, future editions mean Migrate. (But it
1447 // would make a lot of sense for it to be changed to
1448 // `BorrowckMode::Mir`, depending on how we plan to
1449 // time the forcing of full migration to NLL.)
1450 _ => BorrowckMode::Migrate,
1451 },
0531ce1d
XL
1452 }
1453 }
1454
1455 /// Should we emit EndRegion MIR statements? These are consumed by
1456 /// MIR borrowck, but not when NLL is used. They are also consumed
1457 /// by the validation stuff.
1458 pub fn emit_end_regions(self) -> bool {
0531ce1d
XL
1459 self.sess.opts.debugging_opts.emit_end_regions ||
1460 self.sess.opts.debugging_opts.mir_emit_validate > 0 ||
83c7162d
XL
1461 self.use_mir_borrowck()
1462 }
1463
1464 #[inline]
1465 pub fn share_generics(self) -> bool {
1466 match self.sess.opts.debugging_opts.share_generics {
1467 Some(setting) => setting,
1468 None => {
1469 self.sess.opts.incremental.is_some() ||
1470 match self.sess.opts.optimize {
1471 OptLevel::No |
1472 OptLevel::Less |
1473 OptLevel::Size |
1474 OptLevel::SizeMin => true,
1475 OptLevel::Default |
1476 OptLevel::Aggressive => false,
1477 }
1478 }
1479 }
1480 }
1481
1482 #[inline]
1483 pub fn local_crate_exports_generics(self) -> bool {
1484 debug_assert!(self.share_generics());
1485
1486 self.sess.crate_types.borrow().iter().any(|crate_type| {
1487 match crate_type {
1488 CrateTypeExecutable |
1489 CrateTypeStaticlib |
1490 CrateTypeProcMacro |
1491 CrateTypeCdylib => false,
1492 CrateTypeRlib |
1493 CrateTypeDylib => true,
1494 }
1495 })
0531ce1d 1496 }
ea8adc8c
XL
1497}
1498
1499impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
0531ce1d 1500 pub fn encode_metadata(self, link_meta: &LinkMeta)
ff7c6d11 1501 -> EncodedMetadata
ea8adc8c 1502 {
0531ce1d 1503 self.cstore.encode_metadata(self, link_meta)
ea8adc8c 1504 }
e9174d1e
SL
1505}
1506
a7813a04 1507impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> {
32a655c1 1508 /// Call the closure with a local `TyCtxt` using the given arena.
83c7162d
XL
1509 pub fn enter_local<F, R>(
1510 &self,
1511 arena: &'tcx SyncDroplessArena,
1512 f: F
1513 ) -> R
1514 where
1515 F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R
a7813a04 1516 {
32a655c1 1517 let interners = CtxtInterners::new(arena);
83c7162d
XL
1518 let tcx = TyCtxt {
1519 gcx: self,
1520 interners: &interners,
1521 };
1522 ty::tls::with_related_context(tcx.global_tcx(), |icx| {
1523 let new_icx = ty::tls::ImplicitCtxt {
1524 tcx,
1525 query: icx.query.clone(),
1526 layout_depth: icx.layout_depth,
1527 task: icx.task,
1528 };
1529 ty::tls::enter_context(&new_icx, |new_icx| {
1530 f(new_icx.tcx)
1531 })
1532 })
a7813a04
XL
1533 }
1534}
1535
e9174d1e
SL
1536/// A trait implemented for all X<'a> types which can be safely and
1537/// efficiently converted to X<'tcx> as long as they are part of the
54a0048b 1538/// provided TyCtxt<'tcx>.
e9174d1e
SL
1539/// This can be done, for example, for Ty<'tcx> or &'tcx Substs<'tcx>
1540/// by looking them up in their respective interners.
a7813a04
XL
1541///
1542/// However, this is still not the best implementation as it does
1543/// need to compare the components, even for interned values.
1544/// It would be more efficient if TypedArena provided a way to
1545/// determine whether the address is in the allocated range.
1546///
e9174d1e
SL
1547/// None is returned if the value or one of the components is not part
1548/// of the provided context.
1549/// For Ty, None can be returned if either the type interner doesn't
1550/// contain the TypeVariants key or if the address of the interned
1551/// pointer differs. The latter case is possible if a primitive type,
1552/// e.g. `()` or `u8`, was interned in a different context.
8faf50e0
XL
1553pub trait Lift<'tcx>: fmt::Debug {
1554 type Lifted: fmt::Debug + 'tcx;
a7813a04 1555 fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted>;
e9174d1e
SL
1556}
1557
1558impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
1559 type Lifted = Ty<'tcx>;
a7813a04 1560 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
32a655c1
SL
1561 if tcx.interners.arena.in_arena(*self as *const _) {
1562 return Some(unsafe { mem::transmute(*self) });
e9174d1e 1563 }
a7813a04
XL
1564 // Also try in the global tcx if we're not that.
1565 if !tcx.is_global() {
1566 self.lift_to_tcx(tcx.global_tcx())
1567 } else {
1568 None
1569 }
e9174d1e
SL
1570 }
1571}
1572
ea8adc8c
XL
1573impl<'a, 'tcx> Lift<'tcx> for Region<'a> {
1574 type Lifted = Region<'tcx>;
1575 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Region<'tcx>> {
1576 if tcx.interners.arena.in_arena(*self as *const _) {
32a655c1 1577 return Some(unsafe { mem::transmute(*self) });
e9174d1e 1578 }
a7813a04
XL
1579 // Also try in the global tcx if we're not that.
1580 if !tcx.is_global() {
1581 self.lift_to_tcx(tcx.global_tcx())
1582 } else {
1583 None
1584 }
1585 }
1586}
1587
94b46f34
XL
1588impl<'a, 'tcx> Lift<'tcx> for &'a Goal<'a> {
1589 type Lifted = &'tcx Goal<'tcx>;
1590 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Goal<'tcx>> {
1591 if tcx.interners.arena.in_arena(*self as *const _) {
1592 return Some(unsafe { mem::transmute(*self) });
1593 }
1594 // Also try in the global tcx if we're not that.
1595 if !tcx.is_global() {
1596 self.lift_to_tcx(tcx.global_tcx())
1597 } else {
1598 None
1599 }
1600 }
1601}
1602
1603impl<'a, 'tcx> Lift<'tcx> for &'a Slice<Goal<'a>> {
1604 type Lifted = &'tcx Slice<Goal<'tcx>>;
1605 fn lift_to_tcx<'b, 'gcx>(
1606 &self,
1607 tcx: TyCtxt<'b, 'gcx, 'tcx>,
1608 ) -> Option<&'tcx Slice<Goal<'tcx>>> {
1609 if tcx.interners.arena.in_arena(*self as *const _) {
1610 return Some(unsafe { mem::transmute(*self) });
1611 }
1612 // Also try in the global tcx if we're not that.
1613 if !tcx.is_global() {
1614 self.lift_to_tcx(tcx.global_tcx())
1615 } else {
1616 None
1617 }
1618 }
1619}
1620
1621impl<'a, 'tcx> Lift<'tcx> for &'a Slice<Clause<'a>> {
1622 type Lifted = &'tcx Slice<Clause<'tcx>>;
1623 fn lift_to_tcx<'b, 'gcx>(
1624 &self,
1625 tcx: TyCtxt<'b, 'gcx, 'tcx>,
1626 ) -> Option<&'tcx Slice<Clause<'tcx>>> {
1627 if tcx.interners.arena.in_arena(*self as *const _) {
1628 return Some(unsafe { mem::transmute(*self) });
1629 }
1630 // Also try in the global tcx if we're not that.
1631 if !tcx.is_global() {
1632 self.lift_to_tcx(tcx.global_tcx())
1633 } else {
1634 None
1635 }
1636 }
1637}
1638
ea8adc8c
XL
1639impl<'a, 'tcx> Lift<'tcx> for &'a Const<'a> {
1640 type Lifted = &'tcx Const<'tcx>;
1641 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Const<'tcx>> {
32a655c1
SL
1642 if tcx.interners.arena.in_arena(*self as *const _) {
1643 return Some(unsafe { mem::transmute(*self) });
a7813a04
XL
1644 }
1645 // Also try in the global tcx if we're not that.
1646 if !tcx.is_global() {
1647 self.lift_to_tcx(tcx.global_tcx())
1648 } else {
1649 None
1650 }
1651 }
1652}
1653
ea8adc8c
XL
1654impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
1655 type Lifted = &'tcx Substs<'tcx>;
1656 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Substs<'tcx>> {
1657 if self.len() == 0 {
1658 return Some(Slice::empty());
1659 }
1660 if tcx.interners.arena.in_arena(&self[..] as *const _) {
1661 return Some(unsafe { mem::transmute(*self) });
1662 }
1663 // Also try in the global tcx if we're not that.
1664 if !tcx.is_global() {
1665 self.lift_to_tcx(tcx.global_tcx())
1666 } else {
1667 None
1668 }
1669 }
1670}
1671
9e0c209e
SL
1672impl<'a, 'tcx> Lift<'tcx> for &'a Slice<Ty<'a>> {
1673 type Lifted = &'tcx Slice<Ty<'tcx>>;
1674 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
1675 -> Option<&'tcx Slice<Ty<'tcx>>> {
c30ab7b3
SL
1676 if self.len() == 0 {
1677 return Some(Slice::empty());
1678 }
32a655c1
SL
1679 if tcx.interners.arena.in_arena(*self as *const _) {
1680 return Some(unsafe { mem::transmute(*self) });
a7813a04
XL
1681 }
1682 // Also try in the global tcx if we're not that.
1683 if !tcx.is_global() {
1684 self.lift_to_tcx(tcx.global_tcx())
1685 } else {
1686 None
1687 }
1688 }
1689}
1690
476ff2be
SL
1691impl<'a, 'tcx> Lift<'tcx> for &'a Slice<ExistentialPredicate<'a>> {
1692 type Lifted = &'tcx Slice<ExistentialPredicate<'tcx>>;
1693 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
1694 -> Option<&'tcx Slice<ExistentialPredicate<'tcx>>> {
1695 if self.is_empty() {
1696 return Some(Slice::empty());
1697 }
32a655c1
SL
1698 if tcx.interners.arena.in_arena(*self as *const _) {
1699 return Some(unsafe { mem::transmute(*self) });
476ff2be
SL
1700 }
1701 // Also try in the global tcx if we're not that.
1702 if !tcx.is_global() {
1703 self.lift_to_tcx(tcx.global_tcx())
1704 } else {
1705 None
1706 }
1707 }
1708}
1709
7cac9316
XL
1710impl<'a, 'tcx> Lift<'tcx> for &'a Slice<Predicate<'a>> {
1711 type Lifted = &'tcx Slice<Predicate<'tcx>>;
1712 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
1713 -> Option<&'tcx Slice<Predicate<'tcx>>> {
1714 if self.is_empty() {
1715 return Some(Slice::empty());
1716 }
1717 if tcx.interners.arena.in_arena(*self as *const _) {
1718 return Some(unsafe { mem::transmute(*self) });
1719 }
1720 // Also try in the global tcx if we're not that.
1721 if !tcx.is_global() {
1722 self.lift_to_tcx(tcx.global_tcx())
1723 } else {
1724 None
1725 }
1726 }
1727}
1728
0531ce1d
XL
1729impl<'a, 'tcx> Lift<'tcx> for &'a Slice<CanonicalVarInfo> {
1730 type Lifted = &'tcx Slice<CanonicalVarInfo>;
1731 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
1732 if self.len() == 0 {
1733 return Some(Slice::empty());
1734 }
1735 if tcx.interners.arena.in_arena(*self as *const _) {
1736 return Some(unsafe { mem::transmute(*self) });
1737 }
1738 // Also try in the global tcx if we're not that.
1739 if !tcx.is_global() {
1740 self.lift_to_tcx(tcx.global_tcx())
1741 } else {
1742 None
1743 }
1744 }
1745}
1746
e9174d1e 1747pub mod tls {
83c7162d 1748 use super::{GlobalCtxt, TyCtxt};
e9174d1e
SL
1749
1750 use std::fmt;
83c7162d 1751 use std::mem;
3157f602 1752 use syntax_pos;
94b46f34 1753 use ty::query;
83c7162d
XL
1754 use errors::{Diagnostic, TRACK_DIAGNOSTICS};
1755 use rustc_data_structures::OnDrop;
94b46f34 1756 use rustc_data_structures::sync::{self, Lrc, Lock};
83c7162d
XL
1757 use dep_graph::OpenTask;
1758
94b46f34
XL
1759 #[cfg(not(parallel_queries))]
1760 use std::cell::Cell;
1761
1762 #[cfg(parallel_queries)]
1763 use rayon_core;
1764
83c7162d
XL
1765 /// This is the implicit state of rustc. It contains the current
1766 /// TyCtxt and query. It is updated when creating a local interner or
1767 /// executing a new query. Whenever there's a TyCtxt value available
1768 /// you should also have access to an ImplicitCtxt through the functions
1769 /// in this module.
1770 #[derive(Clone)]
1771 pub struct ImplicitCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
1772 /// The current TyCtxt. Initially created by `enter_global` and updated
1773 /// by `enter_local` with a new local interner
1774 pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
1775
1776 /// The current query job, if any. This is updated by start_job in
94b46f34
XL
1777 /// ty::query::plumbing when executing a query
1778 pub query: Option<Lrc<query::QueryJob<'gcx>>>,
83c7162d
XL
1779
1780 /// Used to prevent layout from recursing too deeply.
1781 pub layout_depth: usize,
1782
1783 /// The current dep graph task. This is used to add dependencies to queries
1784 /// when executing them
1785 pub task: &'a OpenTask,
1786 }
1787
94b46f34
XL
1788 /// Sets Rayon's thread local variable which is preserved for Rayon jobs
1789 /// to `value` during the call to `f`. It is restored to its previous value after.
1790 /// This is used to set the pointer to the new ImplicitCtxt.
1791 #[cfg(parallel_queries)]
1792 fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
1793 rayon_core::tlv::with(value, f)
1794 }
1795
1796 /// Gets Rayon's thread local variable which is preserved for Rayon jobs.
1797 /// This is used to get the pointer to the current ImplicitCtxt.
1798 #[cfg(parallel_queries)]
1799 fn get_tlv() -> usize {
1800 rayon_core::tlv::get()
1801 }
1802
1803 /// A thread local variable which stores a pointer to the current ImplicitCtxt
1804 #[cfg(not(parallel_queries))]
83c7162d 1805 thread_local!(static TLV: Cell<usize> = Cell::new(0));
e9174d1e 1806
94b46f34
XL
1807 /// Sets TLV to `value` during the call to `f`.
1808 /// It is restored to its previous value after.
1809 /// This is used to set the pointer to the new ImplicitCtxt.
1810 #[cfg(not(parallel_queries))]
83c7162d
XL
1811 fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
1812 let old = get_tlv();
1813 let _reset = OnDrop(move || TLV.with(|tlv| tlv.set(old)));
1814 TLV.with(|tlv| tlv.set(value));
1815 f()
1816 }
e9174d1e 1817
94b46f34
XL
1818 /// This is used to get the pointer to the current ImplicitCtxt.
1819 #[cfg(not(parallel_queries))]
83c7162d
XL
1820 fn get_tlv() -> usize {
1821 TLV.with(|tlv| tlv.get())
7453a54e 1822 }
e9174d1e 1823
83c7162d
XL
1824 /// This is a callback from libsyntax as it cannot access the implicit state
1825 /// in librustc otherwise
3157f602 1826 fn span_debug(span: syntax_pos::Span, f: &mut fmt::Formatter) -> fmt::Result {
e9174d1e
SL
1827 with(|tcx| {
1828 write!(f, "{}", tcx.sess.codemap().span_to_string(span))
1829 })
1830 }
1831
83c7162d
XL
1832 /// This is a callback from libsyntax as it cannot access the implicit state
1833 /// in librustc otherwise. It is used to when diagnostic messages are
1834 /// emitted and stores them in the current query, if there is one.
1835 fn track_diagnostic(diagnostic: &Diagnostic) {
94b46f34
XL
1836 with_context_opt(|icx| {
1837 if let Some(icx) = icx {
1838 if let Some(ref query) = icx.query {
1839 query.diagnostics.lock().push(diagnostic.clone());
1840 }
83c7162d
XL
1841 }
1842 })
1843 }
1844
1845 /// Sets up the callbacks from libsyntax on the current thread
1846 pub fn with_thread_locals<F, R>(f: F) -> R
1847 where F: FnOnce() -> R
a7813a04 1848 {
3157f602 1849 syntax_pos::SPAN_DEBUG.with(|span_dbg| {
e9174d1e
SL
1850 let original_span_debug = span_dbg.get();
1851 span_dbg.set(span_debug);
83c7162d
XL
1852
1853 let _on_drop = OnDrop(move || {
1854 span_dbg.set(original_span_debug);
1855 });
1856
1857 TRACK_DIAGNOSTICS.with(|current| {
1858 let original = current.get();
1859 current.set(track_diagnostic);
1860
1861 let _on_drop = OnDrop(move || {
1862 current.set(original);
1863 });
1864
1865 f()
1866 })
b039eaaf 1867 })
e9174d1e
SL
1868 }
1869
83c7162d
XL
1870 /// Sets `context` as the new current ImplicitCtxt for the duration of the function `f`
1871 pub fn enter_context<'a, 'gcx: 'tcx, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'gcx, 'tcx>,
1872 f: F) -> R
1873 where F: FnOnce(&ImplicitCtxt<'a, 'gcx, 'tcx>) -> R
a7813a04 1874 {
83c7162d
XL
1875 set_tlv(context as *const _ as usize, || {
1876 f(&context)
a7813a04
XL
1877 })
1878 }
1879
83c7162d
XL
1880 /// Enters GlobalCtxt by setting up libsyntax callbacks and
1881 /// creating a initial TyCtxt and ImplicitCtxt.
1882 /// This happens once per rustc session and TyCtxts only exists
1883 /// inside the `f` function.
1884 pub fn enter_global<'gcx, F, R>(gcx: &GlobalCtxt<'gcx>, f: F) -> R
1885 where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'gcx>) -> R
a7813a04 1886 {
83c7162d 1887 with_thread_locals(|| {
94b46f34
XL
1888 // Update GCX_PTR to indicate there's a GlobalCtxt available
1889 GCX_PTR.with(|lock| {
1890 *lock.lock() = gcx as *const _ as usize;
1891 });
1892 // Set GCX_PTR back to 0 when we exit
1893 let _on_drop = OnDrop(move || {
1894 GCX_PTR.with(|lock| *lock.lock() = 0);
1895 });
1896
83c7162d 1897 let tcx = TyCtxt {
041b39d2 1898 gcx,
83c7162d
XL
1899 interners: &gcx.global_interners,
1900 };
1901 let icx = ImplicitCtxt {
1902 tcx,
1903 query: None,
1904 layout_depth: 0,
1905 task: &OpenTask::Ignore,
1906 };
1907 enter_context(&icx, |_| {
1908 f(tcx)
a7813a04 1909 })
7453a54e 1910 })
e9174d1e
SL
1911 }
1912
94b46f34
XL
1913 /// Stores a pointer to the GlobalCtxt if one is available.
1914 /// This is used to access the GlobalCtxt in the deadlock handler
1915 /// given to Rayon.
1916 scoped_thread_local!(pub static GCX_PTR: Lock<usize>);
1917
1918 /// Creates a TyCtxt and ImplicitCtxt based on the GCX_PTR thread local.
1919 /// This is used in the deadlock handler.
1920 pub unsafe fn with_global<F, R>(f: F) -> R
1921 where F: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R
1922 {
1923 let gcx = GCX_PTR.with(|lock| *lock.lock());
1924 assert!(gcx != 0);
1925 let gcx = &*(gcx as *const GlobalCtxt<'_>);
1926 let tcx = TyCtxt {
1927 gcx,
1928 interners: &gcx.global_interners,
1929 };
1930 let icx = ImplicitCtxt {
1931 query: None,
1932 tcx,
1933 layout_depth: 0,
1934 task: &OpenTask::Ignore,
1935 };
1936 enter_context(&icx, |_| f(tcx))
1937 }
1938
83c7162d
XL
1939 /// Allows access to the current ImplicitCtxt in a closure if one is available
1940 pub fn with_context_opt<F, R>(f: F) -> R
1941 where F: for<'a, 'gcx, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'gcx, 'tcx>>) -> R
a7813a04 1942 {
83c7162d
XL
1943 let context = get_tlv();
1944 if context == 0 {
e9174d1e 1945 f(None)
83c7162d 1946 } else {
94b46f34
XL
1947 // We could get a ImplicitCtxt pointer from another thread.
1948 // Ensure that ImplicitCtxt is Sync
1949 sync::assert_sync::<ImplicitCtxt>();
1950
83c7162d 1951 unsafe { f(Some(&*(context as *const ImplicitCtxt))) }
e9174d1e
SL
1952 }
1953 }
83c7162d
XL
1954
1955 /// Allows access to the current ImplicitCtxt.
1956 /// Panics if there is no ImplicitCtxt available
1957 pub fn with_context<F, R>(f: F) -> R
1958 where F: for<'a, 'gcx, 'tcx> FnOnce(&ImplicitCtxt<'a, 'gcx, 'tcx>) -> R
1959 {
1960 with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
1961 }
1962
1963 /// Allows access to the current ImplicitCtxt whose tcx field has the same global
1964 /// interner as the tcx argument passed in. This means the closure is given an ImplicitCtxt
1965 /// with the same 'gcx lifetime as the TyCtxt passed in.
1966 /// This will panic if you pass it a TyCtxt which has a different global interner from
1967 /// the current ImplicitCtxt's tcx field.
1968 pub fn with_related_context<'a, 'gcx, 'tcx1, F, R>(tcx: TyCtxt<'a, 'gcx, 'tcx1>, f: F) -> R
1969 where F: for<'b, 'tcx2> FnOnce(&ImplicitCtxt<'b, 'gcx, 'tcx2>) -> R
1970 {
1971 with_context(|context| {
1972 unsafe {
1973 let gcx = tcx.gcx as *const _ as usize;
1974 assert!(context.tcx.gcx as *const _ as usize == gcx);
1975 let context: &ImplicitCtxt = mem::transmute(context);
1976 f(context)
1977 }
1978 })
1979 }
1980
1981 /// Allows access to the current ImplicitCtxt whose tcx field has the same global
1982 /// interner and local interner as the tcx argument passed in. This means the closure
1983 /// is given an ImplicitCtxt with the same 'tcx and 'gcx lifetimes as the TyCtxt passed in.
1984 /// This will panic if you pass it a TyCtxt which has a different global interner or
1985 /// a different local interner from the current ImplicitCtxt's tcx field.
1986 pub fn with_fully_related_context<'a, 'gcx, 'tcx, F, R>(tcx: TyCtxt<'a, 'gcx, 'tcx>, f: F) -> R
1987 where F: for<'b> FnOnce(&ImplicitCtxt<'b, 'gcx, 'tcx>) -> R
1988 {
1989 with_context(|context| {
1990 unsafe {
1991 let gcx = tcx.gcx as *const _ as usize;
1992 let interners = tcx.interners as *const _ as usize;
1993 assert!(context.tcx.gcx as *const _ as usize == gcx);
1994 assert!(context.tcx.interners as *const _ as usize == interners);
1995 let context: &ImplicitCtxt = mem::transmute(context);
1996 f(context)
1997 }
1998 })
1999 }
2000
2001 /// Allows access to the TyCtxt in the current ImplicitCtxt.
2002 /// Panics if there is no ImplicitCtxt available
2003 pub fn with<F, R>(f: F) -> R
2004 where F: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R
2005 {
2006 with_context(|context| f(context.tcx))
2007 }
2008
2009 /// Allows access to the TyCtxt in the current ImplicitCtxt.
2010 /// The closure is passed None if there is no ImplicitCtxt available
2011 pub fn with_opt<F, R>(f: F) -> R
2012 where F: for<'a, 'gcx, 'tcx> FnOnce(Option<TyCtxt<'a, 'gcx, 'tcx>>) -> R
2013 {
2014 with_context_opt(|opt_context| f(opt_context.map(|context| context.tcx)))
2015 }
e9174d1e
SL
2016}
2017
2018macro_rules! sty_debug_print {
2019 ($ctxt: expr, $($variant: ident),*) => {{
2020 // curious inner module to allow variant names to be used as
2021 // variable names.
2022 #[allow(non_snake_case)]
2023 mod inner {
54a0048b 2024 use ty::{self, TyCtxt};
a7813a04
XL
2025 use ty::context::Interned;
2026
e9174d1e
SL
2027 #[derive(Copy, Clone)]
2028 struct DebugStat {
2029 total: usize,
2030 region_infer: usize,
2031 ty_infer: usize,
2032 both_infer: usize,
2033 }
2034
a7813a04 2035 pub fn go(tcx: TyCtxt) {
e9174d1e
SL
2036 let mut total = DebugStat {
2037 total: 0,
2038 region_infer: 0, ty_infer: 0, both_infer: 0,
2039 };
2040 $(let mut $variant = total;)*
2041
2042
a7813a04 2043 for &Interned(t) in tcx.interners.type_.borrow().iter() {
e9174d1e
SL
2044 let variant = match t.sty {
2045 ty::TyBool | ty::TyChar | ty::TyInt(..) | ty::TyUint(..) |
5bcae85e 2046 ty::TyFloat(..) | ty::TyStr | ty::TyNever => continue,
e9174d1e
SL
2047 ty::TyError => /* unimportant */ continue,
2048 $(ty::$variant(..) => &mut $variant,)*
2049 };
7cac9316
XL
2050 let region = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2051 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
e9174d1e
SL
2052
2053 variant.total += 1;
2054 total.total += 1;
2055 if region { total.region_infer += 1; variant.region_infer += 1 }
2056 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2057 if region && ty { total.both_infer += 1; variant.both_infer += 1 }
2058 }
2059 println!("Ty interner total ty region both");
2060 $(println!(" {:18}: {uses:6} {usespc:4.1}%, \
2061{ty:4.1}% {region:5.1}% {both:4.1}%",
2062 stringify!($variant),
2063 uses = $variant.total,
2064 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2065 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2066 region = $variant.region_infer as f64 * 100.0 / total.total as f64,
2067 both = $variant.both_infer as f64 * 100.0 / total.total as f64);
2068 )*
2069 println!(" total {uses:6} \
2070{ty:4.1}% {region:5.1}% {both:4.1}%",
2071 uses = total.total,
2072 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2073 region = total.region_infer as f64 * 100.0 / total.total as f64,
2074 both = total.both_infer as f64 * 100.0 / total.total as f64)
2075 }
2076 }
2077
2078 inner::go($ctxt)
2079 }}
2080}
2081
a7813a04
XL
2082impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
2083 pub fn print_debug_stats(self) {
e9174d1e
SL
2084 sty_debug_print!(
2085 self,
2c00a5a8
XL
2086 TyAdt, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr,
2087 TyGenerator, TyGeneratorWitness, TyDynamic, TyClosure, TyTuple,
2088 TyParam, TyInfer, TyProjection, TyAnon, TyForeign);
e9174d1e 2089
a7813a04 2090 println!("Substs interner: #{}", self.interners.substs.borrow().len());
a7813a04 2091 println!("Region interner: #{}", self.interners.region.borrow().len());
32a655c1 2092 println!("Stability interner: #{}", self.stability_interner.borrow().len());
94b46f34 2093 println!("Allocation interner: #{}", self.allocation_interner.borrow().len());
32a655c1 2094 println!("Layout interner: #{}", self.layout_interner.borrow().len());
e9174d1e
SL
2095 }
2096}
2097
2098
a7813a04
XL
2099/// An entry in an interner.
2100struct Interned<'tcx, T: 'tcx+?Sized>(&'tcx T);
e9174d1e 2101
a7813a04
XL
2102// NB: An Interned<Ty> compares and hashes as a sty.
2103impl<'tcx> PartialEq for Interned<'tcx, TyS<'tcx>> {
2104 fn eq(&self, other: &Interned<'tcx, TyS<'tcx>>) -> bool {
2105 self.0.sty == other.0.sty
e9174d1e
SL
2106 }
2107}
2108
a7813a04 2109impl<'tcx> Eq for Interned<'tcx, TyS<'tcx>> {}
e9174d1e 2110
a7813a04 2111impl<'tcx> Hash for Interned<'tcx, TyS<'tcx>> {
e9174d1e 2112 fn hash<H: Hasher>(&self, s: &mut H) {
a7813a04 2113 self.0.sty.hash(s)
e9174d1e
SL
2114 }
2115}
2116
a7813a04
XL
2117impl<'tcx: 'lcx, 'lcx> Borrow<TypeVariants<'lcx>> for Interned<'tcx, TyS<'tcx>> {
2118 fn borrow<'a>(&'a self) -> &'a TypeVariants<'lcx> {
2119 &self.0.sty
e9174d1e
SL
2120 }
2121}
2122
9e0c209e
SL
2123// NB: An Interned<Slice<T>> compares and hashes as its elements.
2124impl<'tcx, T: PartialEq> PartialEq for Interned<'tcx, Slice<T>> {
2125 fn eq(&self, other: &Interned<'tcx, Slice<T>>) -> bool {
2126 self.0[..] == other.0[..]
2127 }
2128}
2129
2130impl<'tcx, T: Eq> Eq for Interned<'tcx, Slice<T>> {}
2131
2132impl<'tcx, T: Hash> Hash for Interned<'tcx, Slice<T>> {
2133 fn hash<H: Hasher>(&self, s: &mut H) {
2134 self.0[..].hash(s)
2135 }
2136}
2137
2138impl<'tcx: 'lcx, 'lcx> Borrow<[Ty<'lcx>]> for Interned<'tcx, Slice<Ty<'tcx>>> {
a7813a04 2139 fn borrow<'a>(&'a self) -> &'a [Ty<'lcx>] {
9e0c209e 2140 &self.0[..]
a7813a04 2141 }
e9174d1e
SL
2142}
2143
0531ce1d
XL
2144impl<'tcx: 'lcx, 'lcx> Borrow<[CanonicalVarInfo]> for Interned<'tcx, Slice<CanonicalVarInfo>> {
2145 fn borrow<'a>(&'a self) -> &'a [CanonicalVarInfo] {
2146 &self.0[..]
2147 }
2148}
2149
c30ab7b3
SL
2150impl<'tcx: 'lcx, 'lcx> Borrow<[Kind<'lcx>]> for Interned<'tcx, Substs<'tcx>> {
2151 fn borrow<'a>(&'a self) -> &'a [Kind<'lcx>] {
2152 &self.0[..]
a7813a04
XL
2153 }
2154}
e9174d1e 2155
7cac9316
XL
2156impl<'tcx> Borrow<RegionKind> for Interned<'tcx, RegionKind> {
2157 fn borrow<'a>(&'a self) -> &'a RegionKind {
2158 &self.0
e9174d1e 2159 }
a7813a04 2160}
e9174d1e 2161
476ff2be
SL
2162impl<'tcx: 'lcx, 'lcx> Borrow<[ExistentialPredicate<'lcx>]>
2163 for Interned<'tcx, Slice<ExistentialPredicate<'tcx>>> {
2164 fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'lcx>] {
2165 &self.0[..]
2166 }
2167}
2168
7cac9316
XL
2169impl<'tcx: 'lcx, 'lcx> Borrow<[Predicate<'lcx>]>
2170 for Interned<'tcx, Slice<Predicate<'tcx>>> {
2171 fn borrow<'a>(&'a self) -> &'a [Predicate<'lcx>] {
2172 &self.0[..]
2173 }
2174}
2175
ea8adc8c
XL
2176impl<'tcx: 'lcx, 'lcx> Borrow<Const<'lcx>> for Interned<'tcx, Const<'tcx>> {
2177 fn borrow<'a>(&'a self) -> &'a Const<'lcx> {
2178 &self.0
2179 }
2180}
2181
83c7162d
XL
2182impl<'tcx: 'lcx, 'lcx> Borrow<[Clause<'lcx>]>
2183for Interned<'tcx, Slice<Clause<'tcx>>> {
2184 fn borrow<'a>(&'a self) -> &'a [Clause<'lcx>] {
2185 &self.0[..]
2186 }
2187}
2188
2189impl<'tcx: 'lcx, 'lcx> Borrow<[Goal<'lcx>]>
2190for Interned<'tcx, Slice<Goal<'tcx>>> {
2191 fn borrow<'a>(&'a self) -> &'a [Goal<'lcx>] {
2192 &self.0[..]
2193 }
2194}
2195
9e0c209e
SL
2196macro_rules! intern_method {
2197 ($lt_tcx:tt, $name:ident: $method:ident($alloc:ty,
94b46f34 2198 $alloc_method:expr,
9e0c209e 2199 $alloc_to_key:expr,
83c7162d 2200 $keep_in_local_tcx:expr) -> $ty:ty) => {
a7813a04
XL
2201 impl<'a, 'gcx, $lt_tcx> TyCtxt<'a, 'gcx, $lt_tcx> {
2202 pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
94b46f34 2203 let key = ($alloc_to_key)(&v);
e9174d1e 2204
a7813a04
XL
2205 // HACK(eddyb) Depend on flags being accurate to
2206 // determine that all contents are in the global tcx.
2207 // See comments on Lift for why we can't use that.
94b46f34
XL
2208 if ($keep_in_local_tcx)(&v) {
2209 let mut interner = self.interners.$name.borrow_mut();
2210 if let Some(&Interned(v)) = interner.get(key) {
2211 return v;
a7813a04 2212 }
94b46f34 2213
a7813a04
XL
2214 // Make sure we don't end up with inference
2215 // types/regions in the global tcx.
2216 if self.is_global() {
2217 bug!("Attempted to intern `{:?}` which contains \
2218 inference types/regions in the global type context",
2219 v);
2220 }
a7813a04 2221
94b46f34
XL
2222 let i = $alloc_method(&self.interners.arena, v);
2223 interner.insert(Interned(i));
2224 i
2225 } else {
2226 let mut interner = self.global_interners.$name.borrow_mut();
2227 if let Some(&Interned(v)) = interner.get(key) {
2228 return v;
2229 }
2230
2231 // This transmutes $alloc<'tcx> to $alloc<'gcx>
2232 let v = unsafe {
2233 mem::transmute(v)
2234 };
2235 let i: &$lt_tcx $ty = $alloc_method(&self.global_interners.arena, v);
2236 // Cast to 'gcx
2237 let i = unsafe { mem::transmute(i) };
2238 interner.insert(Interned(i));
2239 i
2240 }
e9174d1e 2241 }
9e0c209e
SL
2242 }
2243 }
2244}
2245
2246macro_rules! direct_interners {
83c7162d 2247 ($lt_tcx:tt, $($name:ident: $method:ident($keep_in_local_tcx:expr) -> $ty:ty),+) => {
9e0c209e
SL
2248 $(impl<$lt_tcx> PartialEq for Interned<$lt_tcx, $ty> {
2249 fn eq(&self, other: &Self) -> bool {
2250 self.0 == other.0
2251 }
2252 }
2253
2254 impl<$lt_tcx> Eq for Interned<$lt_tcx, $ty> {}
2255
2256 impl<$lt_tcx> Hash for Interned<$lt_tcx, $ty> {
2257 fn hash<H: Hasher>(&self, s: &mut H) {
2258 self.0.hash(s)
2259 }
2260 }
2261
83c7162d
XL
2262 intern_method!(
2263 $lt_tcx,
94b46f34
XL
2264 $name: $method($ty,
2265 |a: &$lt_tcx SyncDroplessArena, v| -> &$lt_tcx $ty { a.alloc(v) },
2266 |x| x,
2267 $keep_in_local_tcx) -> $ty);)+
a7813a04
XL
2268 }
2269}
e9174d1e 2270
3b2f2976 2271pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
a7813a04
XL
2272 x.has_type_flags(ty::TypeFlags::KEEP_IN_LOCAL_TCX)
2273}
e9174d1e 2274
9e0c209e 2275direct_interners!('tcx,
83c7162d 2276 region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
ea8adc8c 2277 const_: mk_const(|c: &Const| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>
a7813a04 2278);
e9174d1e 2279
c30ab7b3
SL
2280macro_rules! slice_interners {
2281 ($($field:ident: $method:ident($ty:ident)),+) => (
94b46f34
XL
2282 $(intern_method!( 'tcx, $field: $method(
2283 &[$ty<'tcx>],
2284 |a, v| Slice::from_arena(a, v),
2285 Deref::deref,
2286 |xs: &[$ty]| xs.iter().any(keep_local)) -> Slice<$ty<'tcx>>);)+
c30ab7b3
SL
2287 )
2288}
2289
2290slice_interners!(
476ff2be 2291 existential_predicates: _intern_existential_predicates(ExistentialPredicate),
7cac9316 2292 predicates: _intern_predicates(Predicate),
c30ab7b3 2293 type_list: _intern_type_list(Ty),
83c7162d
XL
2294 substs: _intern_substs(Kind),
2295 clauses: _intern_clauses(Clause),
2296 goals: _intern_goals(Goal)
9e0c209e 2297);
e9174d1e 2298
0531ce1d
XL
2299// This isn't a perfect fit: CanonicalVarInfo slices are always
2300// allocated in the global arena, so this `intern_method!` macro is
2301// overly general. But we just return false for the code that checks
2302// whether they belong in the thread-local arena, so no harm done, and
2303// seems better than open-coding the rest.
2304intern_method! {
2305 'tcx,
2306 canonical_var_infos: _intern_canonical_var_infos(
2307 &[CanonicalVarInfo],
94b46f34 2308 |a, v| Slice::from_arena(a, v),
0531ce1d 2309 Deref::deref,
0531ce1d
XL
2310 |_xs: &[CanonicalVarInfo]| -> bool { false }
2311 ) -> Slice<CanonicalVarInfo>
2312}
2313
a7813a04 2314impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
ff7c6d11
XL
2315 /// Given a `fn` type, returns an equivalent `unsafe fn` type;
2316 /// that is, a `fn` type that is equivalent in every way for being
2317 /// unsafe.
8bb4bdeb
XL
2318 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2319 assert_eq!(sig.unsafety(), hir::Unsafety::Normal);
2320 self.mk_fn_ptr(sig.map_bound(|sig| ty::FnSig {
a7813a04 2321 unsafety: hir::Unsafety::Unsafe,
8bb4bdeb 2322 ..sig
a7813a04 2323 }))
e9174d1e
SL
2324 }
2325
ff7c6d11
XL
2326 /// Given a closure signature `sig`, returns an equivalent `fn`
2327 /// type with the same signature. Detuples and so forth -- so
2328 /// e.g. if we have a sig with `Fn<(u32, i32)>` then you would get
2329 /// a `fn(u32, i32)`.
2330 pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2331 let converted_sig = sig.map_bound(|s| {
2332 let params_iter = match s.inputs()[0].sty {
0531ce1d 2333 ty::TyTuple(params) => {
ff7c6d11
XL
2334 params.into_iter().cloned()
2335 }
2336 _ => bug!(),
2337 };
2338 self.mk_fn_sig(
2339 params_iter,
2340 s.output(),
2341 s.variadic,
2342 hir::Unsafety::Normal,
2343 abi::Abi::Rust,
2344 )
2345 });
2346
2347 self.mk_fn_ptr(converted_sig)
2348 }
2349
94b46f34
XL
2350 pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
2351 CtxtInterners::intern_ty(&self.interners, &self.global_interners, st)
e9174d1e
SL
2352 }
2353
a7813a04 2354 pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> {
e9174d1e 2355 match tm {
2c00a5a8 2356 ast::IntTy::Isize => self.types.isize,
7453a54e
SL
2357 ast::IntTy::I8 => self.types.i8,
2358 ast::IntTy::I16 => self.types.i16,
2359 ast::IntTy::I32 => self.types.i32,
2360 ast::IntTy::I64 => self.types.i64,
32a655c1 2361 ast::IntTy::I128 => self.types.i128,
e9174d1e
SL
2362 }
2363 }
2364
a7813a04 2365 pub fn mk_mach_uint(self, tm: ast::UintTy) -> Ty<'tcx> {
e9174d1e 2366 match tm {
2c00a5a8 2367 ast::UintTy::Usize => self.types.usize,
7453a54e
SL
2368 ast::UintTy::U8 => self.types.u8,
2369 ast::UintTy::U16 => self.types.u16,
2370 ast::UintTy::U32 => self.types.u32,
2371 ast::UintTy::U64 => self.types.u64,
32a655c1 2372 ast::UintTy::U128 => self.types.u128,
e9174d1e
SL
2373 }
2374 }
2375
a7813a04 2376 pub fn mk_mach_float(self, tm: ast::FloatTy) -> Ty<'tcx> {
e9174d1e 2377 match tm {
7453a54e
SL
2378 ast::FloatTy::F32 => self.types.f32,
2379 ast::FloatTy::F64 => self.types.f64,
e9174d1e
SL
2380 }
2381 }
2382
a7813a04 2383 pub fn mk_str(self) -> Ty<'tcx> {
e9174d1e
SL
2384 self.mk_ty(TyStr)
2385 }
2386
a7813a04 2387 pub fn mk_static_str(self) -> Ty<'tcx> {
cc61c64b 2388 self.mk_imm_ref(self.types.re_static, self.mk_str())
e9174d1e
SL
2389 }
2390
476ff2be 2391 pub fn mk_adt(self, def: &'tcx AdtDef, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
e9174d1e 2392 // take a copy of substs so that we own the vectors inside
9e0c209e 2393 self.mk_ty(TyAdt(def, substs))
e9174d1e
SL
2394 }
2395
abe05a73
XL
2396 pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
2397 self.mk_ty(TyForeign(def_id))
2398 }
2399
a7813a04 2400 pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
32a655c1 2401 let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem);
7cac9316 2402 let adt_def = self.adt_def(def_id);
94b46f34
XL
2403 let substs = Substs::for_item(self, def_id, |param, substs| {
2404 match param.kind {
2405 GenericParamDefKind::Lifetime => bug!(),
2406 GenericParamDefKind::Type { has_default, .. } => {
2407 if param.index == 0 {
2408 ty.into()
2409 } else {
2410 assert!(has_default);
2411 self.type_of(param.def_id).subst(self, substs).into()
2412 }
2413 }
2414 }
2415 });
32a655c1 2416 self.mk_ty(TyAdt(adt_def, substs))
e9174d1e
SL
2417 }
2418
a7813a04 2419 pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
e9174d1e
SL
2420 self.mk_ty(TyRawPtr(tm))
2421 }
2422
7cac9316 2423 pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
94b46f34 2424 self.mk_ty(TyRef(r, tm.ty, tm.mutbl))
e9174d1e
SL
2425 }
2426
7cac9316 2427 pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
e9174d1e
SL
2428 self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutMutable})
2429 }
2430
7cac9316 2431 pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
e9174d1e
SL
2432 self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
2433 }
2434
a7813a04 2435 pub fn mk_mut_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
e9174d1e
SL
2436 self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutMutable})
2437 }
2438
a7813a04 2439 pub fn mk_imm_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
e9174d1e
SL
2440 self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
2441 }
2442
a7813a04 2443 pub fn mk_nil_ptr(self) -> Ty<'tcx> {
e9174d1e
SL
2444 self.mk_imm_ptr(self.mk_nil())
2445 }
2446
ea8adc8c 2447 pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
94b46f34 2448 self.mk_ty(TyArray(ty, ty::Const::from_usize(self, n)))
e9174d1e
SL
2449 }
2450
a7813a04 2451 pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
e9174d1e
SL
2452 self.mk_ty(TySlice(ty))
2453 }
2454
0531ce1d
XL
2455 pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
2456 self.mk_ty(TyTuple(self.intern_type_list(ts)))
c30ab7b3
SL
2457 }
2458
0531ce1d
XL
2459 pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I) -> I::Output {
2460 iter.intern_with(|ts| self.mk_ty(TyTuple(self.intern_type_list(ts))))
e9174d1e
SL
2461 }
2462
a7813a04 2463 pub fn mk_nil(self) -> Ty<'tcx> {
0531ce1d 2464 self.intern_tup(&[])
e9174d1e
SL
2465 }
2466
5bcae85e 2467 pub fn mk_diverging_default(self) -> Ty<'tcx> {
0531ce1d 2468 if self.features().never_type {
5bcae85e
SL
2469 self.types.never
2470 } else {
0531ce1d 2471 self.intern_tup(&[])
5bcae85e
SL
2472 }
2473 }
2474
a7813a04 2475 pub fn mk_bool(self) -> Ty<'tcx> {
e9174d1e
SL
2476 self.mk_ty(TyBool)
2477 }
2478
a7813a04 2479 pub fn mk_fn_def(self, def_id: DefId,
041b39d2
XL
2480 substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
2481 self.mk_ty(TyFnDef(def_id, substs))
54a0048b
SL
2482 }
2483
8bb4bdeb 2484 pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
a7813a04 2485 self.mk_ty(TyFnPtr(fty))
e9174d1e
SL
2486 }
2487
476ff2be
SL
2488 pub fn mk_dynamic(
2489 self,
2490 obj: ty::Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>,
7cac9316 2491 reg: ty::Region<'tcx>
476ff2be
SL
2492 ) -> Ty<'tcx> {
2493 self.mk_ty(TyDynamic(obj, reg))
e9174d1e
SL
2494 }
2495
a7813a04 2496 pub fn mk_projection(self,
041b39d2
XL
2497 item_def_id: DefId,
2498 substs: &'tcx Substs<'tcx>)
476ff2be 2499 -> Ty<'tcx> {
041b39d2 2500 self.mk_ty(TyProjection(ProjectionTy {
3b2f2976
XL
2501 item_def_id,
2502 substs,
041b39d2 2503 }))
476ff2be 2504 }
e9174d1e 2505
94b46f34 2506 pub fn mk_closure(self, closure_id: DefId, closure_substs: ClosureSubsts<'tcx>)
e9174d1e
SL
2507 -> Ty<'tcx> {
2508 self.mk_ty(TyClosure(closure_id, closure_substs))
2509 }
2510
ea8adc8c
XL
2511 pub fn mk_generator(self,
2512 id: DefId,
94b46f34
XL
2513 generator_substs: GeneratorSubsts<'tcx>,
2514 movability: hir::GeneratorMovability)
ea8adc8c 2515 -> Ty<'tcx> {
94b46f34 2516 self.mk_ty(TyGenerator(id, generator_substs, movability))
ea8adc8c
XL
2517 }
2518
2c00a5a8
XL
2519 pub fn mk_generator_witness(self, types: ty::Binder<&'tcx Slice<Ty<'tcx>>>) -> Ty<'tcx> {
2520 self.mk_ty(TyGeneratorWitness(types))
2521 }
2522
a7813a04 2523 pub fn mk_var(self, v: TyVid) -> Ty<'tcx> {
e9174d1e
SL
2524 self.mk_infer(TyVar(v))
2525 }
2526
a7813a04 2527 pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
e9174d1e
SL
2528 self.mk_infer(IntVar(v))
2529 }
2530
a7813a04 2531 pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
e9174d1e
SL
2532 self.mk_infer(FloatVar(v))
2533 }
2534
a7813a04 2535 pub fn mk_infer(self, it: InferTy) -> Ty<'tcx> {
e9174d1e
SL
2536 self.mk_ty(TyInfer(it))
2537 }
2538
94b46f34 2539 pub fn mk_ty_param(self,
e9174d1e 2540 index: u32,
0531ce1d 2541 name: InternedString) -> Ty<'tcx> {
9e0c209e 2542 self.mk_ty(TyParam(ParamTy { idx: index, name: name }))
e9174d1e
SL
2543 }
2544
a7813a04 2545 pub fn mk_self_type(self) -> Ty<'tcx> {
94b46f34 2546 self.mk_ty_param(0, keywords::SelfType.name().as_interned_str())
e9174d1e
SL
2547 }
2548
94b46f34
XL
2549 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> Kind<'tcx> {
2550 match param.kind {
2551 GenericParamDefKind::Lifetime => {
2552 self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
2553 }
2554 GenericParamDefKind::Type {..} => self.mk_ty_param(param.index, param.name).into(),
2555 }
e9174d1e 2556 }
9cc50fc6 2557
5bcae85e
SL
2558 pub fn mk_anon(self, def_id: DefId, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
2559 self.mk_ty(TyAnon(def_id, substs))
2560 }
2561
476ff2be
SL
2562 pub fn intern_existential_predicates(self, eps: &[ExistentialPredicate<'tcx>])
2563 -> &'tcx Slice<ExistentialPredicate<'tcx>> {
2564 assert!(!eps.is_empty());
94b46f34 2565 assert!(eps.windows(2).all(|w| w[0].stable_cmp(self, &w[1]) != Ordering::Greater));
476ff2be
SL
2566 self._intern_existential_predicates(eps)
2567 }
2568
7cac9316
XL
2569 pub fn intern_predicates(self, preds: &[Predicate<'tcx>])
2570 -> &'tcx Slice<Predicate<'tcx>> {
2571 // FIXME consider asking the input slice to be sorted to avoid
2572 // re-interning permutations, in which case that would be asserted
2573 // here.
2574 if preds.len() == 0 {
2575 // The macro-generated method below asserts we don't intern an empty slice.
2576 Slice::empty()
2577 } else {
2578 self._intern_predicates(preds)
2579 }
2580 }
2581
c30ab7b3
SL
2582 pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx Slice<Ty<'tcx>> {
2583 if ts.len() == 0 {
2584 Slice::empty()
2585 } else {
2586 self._intern_type_list(ts)
2587 }
2588 }
2589
2590 pub fn intern_substs(self, ts: &[Kind<'tcx>]) -> &'tcx Slice<Kind<'tcx>> {
2591 if ts.len() == 0 {
2592 Slice::empty()
2593 } else {
2594 self._intern_substs(ts)
2595 }
2596 }
2597
0531ce1d
XL
2598 pub fn intern_canonical_var_infos(self, ts: &[CanonicalVarInfo]) -> CanonicalVarInfos<'gcx> {
2599 if ts.len() == 0 {
2600 Slice::empty()
2601 } else {
2602 self.global_tcx()._intern_canonical_var_infos(ts)
2603 }
2604 }
2605
83c7162d
XL
2606 pub fn intern_clauses(self, ts: &[Clause<'tcx>]) -> Clauses<'tcx> {
2607 if ts.len() == 0 {
2608 Slice::empty()
2609 } else {
2610 self._intern_clauses(ts)
2611 }
2612 }
2613
2614 pub fn intern_goals(self, ts: &[Goal<'tcx>]) -> Goals<'tcx> {
2615 if ts.len() == 0 {
2616 Slice::empty()
2617 } else {
2618 self._intern_goals(ts)
2619 }
2620 }
2621
8bb4bdeb
XL
2622 pub fn mk_fn_sig<I>(self,
2623 inputs: I,
2624 output: I::Item,
2625 variadic: bool,
2626 unsafety: hir::Unsafety,
2627 abi: abi::Abi)
476ff2be
SL
2628 -> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
2629 where I: Iterator,
2630 I::Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>
2631 {
2632 inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
2633 inputs_and_output: self.intern_type_list(xs),
8bb4bdeb 2634 variadic, unsafety, abi
476ff2be
SL
2635 })
2636 }
2637
2638 pub fn mk_existential_predicates<I: InternAs<[ExistentialPredicate<'tcx>],
2639 &'tcx Slice<ExistentialPredicate<'tcx>>>>(self, iter: I)
2640 -> I::Output {
2641 iter.intern_with(|xs| self.intern_existential_predicates(xs))
2642 }
2643
7cac9316
XL
2644 pub fn mk_predicates<I: InternAs<[Predicate<'tcx>],
2645 &'tcx Slice<Predicate<'tcx>>>>(self, iter: I)
2646 -> I::Output {
2647 iter.intern_with(|xs| self.intern_predicates(xs))
2648 }
2649
c30ab7b3
SL
2650 pub fn mk_type_list<I: InternAs<[Ty<'tcx>],
2651 &'tcx Slice<Ty<'tcx>>>>(self, iter: I) -> I::Output {
2652 iter.intern_with(|xs| self.intern_type_list(xs))
2653 }
2654
2655 pub fn mk_substs<I: InternAs<[Kind<'tcx>],
2656 &'tcx Slice<Kind<'tcx>>>>(self, iter: I) -> I::Output {
2657 iter.intern_with(|xs| self.intern_substs(xs))
2658 }
2659
2660 pub fn mk_substs_trait(self,
94b46f34
XL
2661 self_ty: Ty<'tcx>,
2662 rest: &[Kind<'tcx>])
c30ab7b3
SL
2663 -> &'tcx Substs<'tcx>
2664 {
94b46f34 2665 self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
c30ab7b3 2666 }
3b2f2976 2667
83c7162d
XL
2668 pub fn mk_clauses<I: InternAs<[Clause<'tcx>], Clauses<'tcx>>>(self, iter: I) -> I::Output {
2669 iter.intern_with(|xs| self.intern_clauses(xs))
2670 }
2671
2672 pub fn mk_goals<I: InternAs<[Goal<'tcx>], Goals<'tcx>>>(self, iter: I) -> I::Output {
2673 iter.intern_with(|xs| self.intern_goals(xs))
2674 }
2675
2676 pub fn mk_goal(self, goal: Goal<'tcx>) -> &'tcx Goal {
94b46f34
XL
2677 &self.intern_goals(&[goal])[0]
2678 }
2679
2680 pub fn lint_hir<S: Into<MultiSpan>>(self,
2681 lint: &'static Lint,
2682 hir_id: HirId,
2683 span: S,
2684 msg: &str) {
2685 self.struct_span_lint_hir(lint, hir_id, span.into(), msg).emit()
83c7162d
XL
2686 }
2687
3b2f2976
XL
2688 pub fn lint_node<S: Into<MultiSpan>>(self,
2689 lint: &'static Lint,
2690 id: NodeId,
2691 span: S,
2692 msg: &str) {
2693 self.struct_span_lint_node(lint, id, span.into(), msg).emit()
2694 }
2695
94b46f34
XL
2696 pub fn lint_hir_note<S: Into<MultiSpan>>(self,
2697 lint: &'static Lint,
2698 hir_id: HirId,
2699 span: S,
2700 msg: &str,
2701 note: &str) {
2702 let mut err = self.struct_span_lint_hir(lint, hir_id, span.into(), msg);
2703 err.note(note);
2704 err.emit()
2705 }
2706
3b2f2976
XL
2707 pub fn lint_node_note<S: Into<MultiSpan>>(self,
2708 lint: &'static Lint,
2709 id: NodeId,
2710 span: S,
2711 msg: &str,
2712 note: &str) {
2713 let mut err = self.struct_span_lint_node(lint, id, span.into(), msg);
2714 err.note(note);
2715 err.emit()
2716 }
2717
2718 pub fn lint_level_at_node(self, lint: &'static Lint, mut id: NodeId)
2719 -> (lint::Level, lint::LintSource)
2720 {
2721 // Right now we insert a `with_ignore` node in the dep graph here to
2722 // ignore the fact that `lint_levels` below depends on the entire crate.
2723 // For now this'll prevent false positives of recompiling too much when
2724 // anything changes.
2725 //
2726 // Once red/green incremental compilation lands we should be able to
2727 // remove this because while the crate changes often the lint level map
2728 // will change rarely.
2729 self.dep_graph.with_ignore(|| {
2730 let sets = self.lint_levels(LOCAL_CRATE);
2731 loop {
2732 let hir_id = self.hir.definitions().node_to_hir_id(id);
0531ce1d 2733 if let Some(pair) = sets.level_and_source(lint, hir_id, self.sess) {
3b2f2976
XL
2734 return pair
2735 }
2736 let next = self.hir.get_parent_node(id);
2737 if next == id {
2738 bug!("lint traversal reached the root of the crate");
2739 }
2740 id = next;
2741 }
2742 })
2743 }
2744
94b46f34
XL
2745 pub fn struct_span_lint_hir<S: Into<MultiSpan>>(self,
2746 lint: &'static Lint,
2747 hir_id: HirId,
2748 span: S,
2749 msg: &str)
2750 -> DiagnosticBuilder<'tcx>
2751 {
2752 let node_id = self.hir.hir_to_node_id(hir_id);
2753 let (level, src) = self.lint_level_at_node(lint, node_id);
2754 lint::struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg)
2755 }
2756
3b2f2976
XL
2757 pub fn struct_span_lint_node<S: Into<MultiSpan>>(self,
2758 lint: &'static Lint,
2759 id: NodeId,
2760 span: S,
2761 msg: &str)
2762 -> DiagnosticBuilder<'tcx>
2763 {
2764 let (level, src) = self.lint_level_at_node(lint, id);
2765 lint::struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg)
2766 }
2767
2768 pub fn struct_lint_node(self, lint: &'static Lint, id: NodeId, msg: &str)
2769 -> DiagnosticBuilder<'tcx>
2770 {
2771 let (level, src) = self.lint_level_at_node(lint, id);
2772 lint::struct_lint_level(self.sess, lint, level, src, None, msg)
2773 }
ea8adc8c 2774
0531ce1d 2775 pub fn in_scope_traits(self, id: HirId) -> Option<Lrc<StableVec<TraitCandidate>>> {
ea8adc8c
XL
2776 self.in_scope_traits_map(id.owner)
2777 .and_then(|map| map.get(&id.local_id).cloned())
2778 }
2779
2780 pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
2781 self.named_region_map(id.owner)
2782 .and_then(|map| map.get(&id.local_id).cloned())
2783 }
2784
2785 pub fn is_late_bound(self, id: HirId) -> bool {
2786 self.is_late_bound_map(id.owner)
2787 .map(|set| set.contains(&id.local_id))
2788 .unwrap_or(false)
2789 }
2790
2791 pub fn object_lifetime_defaults(self, id: HirId)
0531ce1d 2792 -> Option<Lrc<Vec<ObjectLifetimeDefault>>>
ea8adc8c
XL
2793 {
2794 self.object_lifetime_defaults_map(id.owner)
2795 .and_then(|map| map.get(&id.local_id).cloned())
2796 }
e9174d1e 2797}
c30ab7b3
SL
2798
2799pub trait InternAs<T: ?Sized, R> {
2800 type Output;
7cac9316 2801 fn intern_with<F>(self, f: F) -> Self::Output
c30ab7b3
SL
2802 where F: FnOnce(&T) -> R;
2803}
2804
2805impl<I, T, R, E> InternAs<[T], R> for I
2806 where E: InternIteratorElement<T, R>,
2807 I: Iterator<Item=E> {
2808 type Output = E::Output;
2809 fn intern_with<F>(self, f: F) -> Self::Output
2810 where F: FnOnce(&[T]) -> R {
2811 E::intern_with(self, f)
2812 }
2813}
2814
2815pub trait InternIteratorElement<T, R>: Sized {
2816 type Output;
2817 fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output;
2818}
2819
2820impl<T, R> InternIteratorElement<T, R> for T {
2821 type Output = R;
2822 fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
2823 f(&iter.collect::<AccumulateVec<[_; 8]>>())
2824 }
2825}
2826
cc61c64b
XL
2827impl<'a, T, R> InternIteratorElement<T, R> for &'a T
2828 where T: Clone + 'a
2829{
2830 type Output = R;
2831 fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
2832 f(&iter.cloned().collect::<AccumulateVec<[_; 8]>>())
2833 }
2834}
2835
c30ab7b3
SL
2836impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
2837 type Output = Result<R, E>;
2838 fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
2839 Ok(f(&iter.collect::<Result<AccumulateVec<[_; 8]>, _>>()?))
2840 }
2841}
ea8adc8c 2842
94b46f34 2843pub fn provide(providers: &mut ty::query::Providers) {
ea8adc8c
XL
2844 // FIXME(#44234) - almost all of these queries have no sub-queries and
2845 // therefore no actual inputs, they're just reading tables calculated in
2846 // resolve! Does this work? Unsure! That's what the issue is about
2847 providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id).cloned();
2848 providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).cloned();
ea8adc8c
XL
2849 providers.crate_name = |tcx, id| {
2850 assert_eq!(id, LOCAL_CRATE);
2851 tcx.crate_name
2852 };
2853 providers.get_lang_items = |tcx, id| {
2854 assert_eq!(id, LOCAL_CRATE);
2855 // FIXME(#42293) Right now we insert a `with_ignore` node in the dep
2856 // graph here to ignore the fact that `get_lang_items` below depends on
2857 // the entire crate. For now this'll prevent false positives of
2858 // recompiling too much when anything changes.
2859 //
2860 // Once red/green incremental compilation lands we should be able to
2861 // remove this because while the crate changes often the lint level map
2862 // will change rarely.
0531ce1d 2863 tcx.dep_graph.with_ignore(|| Lrc::new(middle::lang_items::collect(tcx)))
ea8adc8c
XL
2864 };
2865 providers.freevars = |tcx, id| tcx.gcx.freevars.get(&id).cloned();
2866 providers.maybe_unused_trait_import = |tcx, id| {
2867 tcx.maybe_unused_trait_imports.contains(&id)
2868 };
2869 providers.maybe_unused_extern_crates = |tcx, cnum| {
2870 assert_eq!(cnum, LOCAL_CRATE);
0531ce1d 2871 Lrc::new(tcx.maybe_unused_extern_crates.clone())
ea8adc8c
XL
2872 };
2873
2874 providers.stability_index = |tcx, cnum| {
2875 assert_eq!(cnum, LOCAL_CRATE);
0531ce1d 2876 Lrc::new(stability::Index::new(tcx))
ea8adc8c
XL
2877 };
2878 providers.lookup_stability = |tcx, id| {
2879 assert_eq!(id.krate, LOCAL_CRATE);
2880 let id = tcx.hir.definitions().def_index_to_hir_id(id.index);
2881 tcx.stability().local_stability(id)
2882 };
2883 providers.lookup_deprecation_entry = |tcx, id| {
2884 assert_eq!(id.krate, LOCAL_CRATE);
2885 let id = tcx.hir.definitions().def_index_to_hir_id(id.index);
2886 tcx.stability().local_deprecation_entry(id)
2887 };
2888 providers.extern_mod_stmt_cnum = |tcx, id| {
2889 let id = tcx.hir.as_local_node_id(id).unwrap();
2890 tcx.cstore.extern_mod_stmt_cnum_untracked(id)
2891 };
2892 providers.all_crate_nums = |tcx, cnum| {
2893 assert_eq!(cnum, LOCAL_CRATE);
0531ce1d 2894 Lrc::new(tcx.cstore.crates_untracked())
ea8adc8c
XL
2895 };
2896 providers.postorder_cnums = |tcx, cnum| {
2897 assert_eq!(cnum, LOCAL_CRATE);
0531ce1d 2898 Lrc::new(tcx.cstore.postorder_cnums_untracked())
ea8adc8c
XL
2899 };
2900 providers.output_filenames = |tcx, cnum| {
2901 assert_eq!(cnum, LOCAL_CRATE);
2902 tcx.output_filenames.clone()
2903 };
0531ce1d 2904 providers.features_query = |tcx, cnum| {
ea8adc8c 2905 assert_eq!(cnum, LOCAL_CRATE);
0531ce1d 2906 Lrc::new(tcx.sess.features_untracked().clone())
ea8adc8c 2907 };
0531ce1d 2908 providers.is_panic_runtime = |tcx, cnum| {
ea8adc8c 2909 assert_eq!(cnum, LOCAL_CRATE);
0531ce1d 2910 attr::contains_name(tcx.hir.krate_attrs(), "panic_runtime")
ea8adc8c 2911 };
0531ce1d
XL
2912 providers.is_compiler_builtins = |tcx, cnum| {
2913 assert_eq!(cnum, LOCAL_CRATE);
2914 attr::contains_name(tcx.hir.krate_attrs(), "compiler_builtins")
abe05a73 2915 };
ea8adc8c 2916}