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.
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.
11 //! type context book-keeping
13 use dep_graph
::DepGraph
;
14 use dep_graph
::{DepNode, DepConstructor}
;
15 use errors
::DiagnosticBuilder
;
17 use session
::config
::OutputFilenames
;
19 use hir
::{TraitCandidate, HirId, ItemLocalId}
;
20 use hir
::def
::{Def, Export}
;
21 use hir
::def_id
::{CrateNum, DefId, DefIndex, LOCAL_CRATE}
;
22 use hir
::map
as hir_map
;
23 use hir
::map
::DefPathHash
;
24 use lint
::{self, Lint}
;
25 use ich
::{StableHashingContext, NodeIdHashingMode}
;
26 use middle
::const_val
::ConstVal
;
27 use middle
::cstore
::{CrateStore, LinkMeta, EncodedMetadataHashes}
;
28 use middle
::cstore
::EncodedMetadata
;
29 use middle
::free_region
::FreeRegionMap
;
30 use middle
::lang_items
;
31 use middle
::resolve_lifetime
::{self, ObjectLifetimeDefault}
;
32 use middle
::stability
;
34 use ty
::subst
::{Kind, Substs}
;
37 use ty
::{self, Ty, TypeAndMut}
;
38 use ty
::{TyS, TypeVariants, Slice}
;
39 use ty
::{AdtKind, AdtDef, ClosureSubsts, GeneratorInterior, Region, Const}
;
40 use ty
::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate}
;
42 use ty
::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid}
;
43 use ty
::TypeVariants
::*;
44 use ty
::layout
::{Layout, TargetDataLayout}
;
48 use util
::nodemap
::{NodeMap, NodeSet, DefIdSet, ItemLocalMap}
;
49 use util
::nodemap
::{FxHashMap, FxHashSet}
;
50 use rustc_data_structures
::accumulate_vec
::AccumulateVec
;
51 use rustc_data_structures
::stable_hasher
::{HashStable
, hash_stable_hashmap
,
52 StableHasher
, StableHasherResult
,
54 use arena
::{TypedArena, DroplessArena}
;
55 use rustc_const_math
::{ConstInt, ConstUsize}
;
56 use rustc_data_structures
::indexed_vec
::IndexVec
;
58 use std
::borrow
::Borrow
;
59 use std
::cell
::{Cell, RefCell}
;
60 use std
::cmp
::Ordering
;
61 use std
::collections
::hash_map
::{self, Entry}
;
62 use std
::hash
::{Hash, Hasher}
;
70 use syntax
::ast
::{self, Name, NodeId}
;
72 use syntax
::codemap
::MultiSpan
;
73 use syntax
::symbol
::{Symbol, keywords}
;
79 pub struct GlobalArenas
<'tcx
> {
81 layout
: TypedArena
<Layout
>,
84 generics
: TypedArena
<ty
::Generics
>,
85 trait_def
: TypedArena
<ty
::TraitDef
>,
86 adt_def
: TypedArena
<ty
::AdtDef
>,
87 steal_mir
: TypedArena
<Steal
<Mir
<'tcx
>>>,
88 mir
: TypedArena
<Mir
<'tcx
>>,
89 tables
: TypedArena
<ty
::TypeckTables
<'tcx
>>,
92 impl<'tcx
> GlobalArenas
<'tcx
> {
93 pub fn new() -> GlobalArenas
<'tcx
> {
95 layout
: TypedArena
::new(),
96 generics
: TypedArena
::new(),
97 trait_def
: TypedArena
::new(),
98 adt_def
: TypedArena
::new(),
99 steal_mir
: TypedArena
::new(),
100 mir
: TypedArena
::new(),
101 tables
: TypedArena
::new(),
106 pub struct CtxtInterners
<'tcx
> {
107 /// The arena that types, regions, etc are allocated from
108 arena
: &'tcx DroplessArena
,
110 /// Specifically use a speedy hash algorithm for these hash sets,
111 /// they're accessed quite often.
112 type_
: RefCell
<FxHashSet
<Interned
<'tcx
, TyS
<'tcx
>>>>,
113 type_list
: RefCell
<FxHashSet
<Interned
<'tcx
, Slice
<Ty
<'tcx
>>>>>,
114 substs
: RefCell
<FxHashSet
<Interned
<'tcx
, Substs
<'tcx
>>>>,
115 region
: RefCell
<FxHashSet
<Interned
<'tcx
, RegionKind
>>>,
116 existential_predicates
: RefCell
<FxHashSet
<Interned
<'tcx
, Slice
<ExistentialPredicate
<'tcx
>>>>>,
117 predicates
: RefCell
<FxHashSet
<Interned
<'tcx
, Slice
<Predicate
<'tcx
>>>>>,
118 const_
: RefCell
<FxHashSet
<Interned
<'tcx
, Const
<'tcx
>>>>,
121 impl<'gcx
: 'tcx
, 'tcx
> CtxtInterners
<'tcx
> {
122 fn new(arena
: &'tcx DroplessArena
) -> CtxtInterners
<'tcx
> {
125 type_
: RefCell
::new(FxHashSet()),
126 type_list
: RefCell
::new(FxHashSet()),
127 substs
: RefCell
::new(FxHashSet()),
128 region
: RefCell
::new(FxHashSet()),
129 existential_predicates
: RefCell
::new(FxHashSet()),
130 predicates
: RefCell
::new(FxHashSet()),
131 const_
: RefCell
::new(FxHashSet()),
135 /// Intern a type. global_interners is Some only if this is
136 /// a local interner and global_interners is its counterpart.
137 fn intern_ty(&self, st
: TypeVariants
<'tcx
>,
138 global_interners
: Option
<&CtxtInterners
<'gcx
>>)
141 let mut interner
= self.type_
.borrow_mut();
142 let global_interner
= global_interners
.map(|interners
| {
143 interners
.type_
.borrow_mut()
145 if let Some(&Interned(ty
)) = interner
.get(&st
) {
148 if let Some(ref interner
) = global_interner
{
149 if let Some(&Interned(ty
)) = interner
.get(&st
) {
154 let flags
= super::flags
::FlagComputation
::for_sty(&st
);
155 let ty_struct
= TyS
{
158 region_depth
: flags
.depth
,
161 // HACK(eddyb) Depend on flags being accurate to
162 // determine that all contents are in the global tcx.
163 // See comments on Lift for why we can't use that.
164 if !flags
.flags
.intersects(ty
::TypeFlags
::KEEP_IN_LOCAL_TCX
) {
165 if let Some(interner
) = global_interners
{
166 let ty_struct
: TyS
<'gcx
> = unsafe {
167 mem
::transmute(ty_struct
)
169 let ty
: Ty
<'gcx
> = interner
.arena
.alloc(ty_struct
);
170 global_interner
.unwrap().insert(Interned(ty
));
174 // Make sure we don't end up with inference
175 // types/regions in the global tcx.
176 if global_interners
.is_none() {
178 bug
!("Attempted to intern `{:?}` which contains \
179 inference types/regions in the global type context",
184 // Don't be &mut TyS.
185 let ty
: Ty
<'tcx
> = self.arena
.alloc(ty_struct
);
186 interner
.insert(Interned(ty
));
190 debug
!("Interned type: {:?} Pointer: {:?}",
191 ty
, ty
as *const TyS
);
197 pub struct CommonTypes
<'tcx
> {
217 pub re_empty
: Region
<'tcx
>,
218 pub re_static
: Region
<'tcx
>,
219 pub re_erased
: Region
<'tcx
>,
222 pub struct LocalTableInContext
<'a
, V
: 'a
> {
223 local_id_root
: Option
<DefId
>,
224 data
: &'a ItemLocalMap
<V
>
227 /// Validate that the given HirId (respectively its `local_id` part) can be
228 /// safely used as a key in the tables of a TypeckTable. For that to be
229 /// the case, the HirId must have the same `owner` as all the other IDs in
230 /// this table (signified by `local_id_root`). Otherwise the HirId
231 /// would be in a different frame of reference and using its `local_id`
232 /// would result in lookup errors, or worse, in silently wrong data being
234 fn validate_hir_id_for_typeck_tables(local_id_root
: Option
<DefId
>,
237 if cfg
!(debug_assertions
) {
238 if let Some(local_id_root
) = local_id_root
{
239 if hir_id
.owner
!= local_id_root
.index
{
240 ty
::tls
::with(|tcx
| {
241 let node_id
= tcx
.hir
243 .find_node_for_hir_id(hir_id
);
245 bug
!("node {} with HirId::owner {:?} cannot be placed in \
246 TypeckTables with local_id_root {:?}",
247 tcx
.hir
.node_to_string(node_id
),
248 DefId
::local(hir_id
.owner
),
253 // We use "Null Object" TypeckTables in some of the analysis passes.
254 // These are just expected to be empty and their `local_id_root` is
255 // `None`. Therefore we cannot verify whether a given `HirId` would
256 // be a valid key for the given table. Instead we make sure that
257 // nobody tries to write to such a Null Object table.
259 bug
!("access to invalid TypeckTables")
265 impl<'a
, V
> LocalTableInContext
<'a
, V
> {
266 pub fn contains_key(&self, id
: hir
::HirId
) -> bool
{
267 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
268 self.data
.contains_key(&id
.local_id
)
271 pub fn get(&self, id
: hir
::HirId
) -> Option
<&V
> {
272 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
273 self.data
.get(&id
.local_id
)
276 pub fn iter(&self) -> hash_map
::Iter
<hir
::ItemLocalId
, V
> {
281 impl<'a
, V
> ::std
::ops
::Index
<hir
::HirId
> for LocalTableInContext
<'a
, V
> {
284 fn index(&self, key
: hir
::HirId
) -> &V
{
285 self.get(key
).expect("LocalTableInContext: key not found")
289 pub struct LocalTableInContextMut
<'a
, V
: 'a
> {
290 local_id_root
: Option
<DefId
>,
291 data
: &'a
mut ItemLocalMap
<V
>
294 impl<'a
, V
> LocalTableInContextMut
<'a
, V
> {
295 pub fn get_mut(&mut self, id
: hir
::HirId
) -> Option
<&mut V
> {
296 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
297 self.data
.get_mut(&id
.local_id
)
300 pub fn entry(&mut self, id
: hir
::HirId
) -> Entry
<hir
::ItemLocalId
, V
> {
301 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
302 self.data
.entry(id
.local_id
)
305 pub fn insert(&mut self, id
: hir
::HirId
, val
: V
) -> Option
<V
> {
306 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
307 self.data
.insert(id
.local_id
, val
)
310 pub fn remove(&mut self, id
: hir
::HirId
) -> Option
<V
> {
311 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
312 self.data
.remove(&id
.local_id
)
316 #[derive(RustcEncodable, RustcDecodable, Debug)]
317 pub struct TypeckTables
<'tcx
> {
318 /// The HirId::owner all ItemLocalIds in this table are relative to.
319 pub local_id_root
: Option
<DefId
>,
321 /// Resolved definitions for `<T>::X` associated paths and
322 /// method calls, including those of overloaded operators.
323 type_dependent_defs
: ItemLocalMap
<Def
>,
325 /// Stores the types for various nodes in the AST. Note that this table
326 /// is not guaranteed to be populated until after typeck. See
327 /// typeck::check::fn_ctxt for details.
328 node_types
: ItemLocalMap
<Ty
<'tcx
>>,
330 /// Stores the type parameters which were substituted to obtain the type
331 /// of this node. This only applies to nodes that refer to entities
332 /// parameterized by type parameters, such as generic fns, types, or
334 node_substs
: ItemLocalMap
<&'tcx Substs
<'tcx
>>,
336 adjustments
: ItemLocalMap
<Vec
<ty
::adjustment
::Adjustment
<'tcx
>>>,
338 /// Stores the actual binding mode for all instances of hir::BindingAnnotation.
339 pat_binding_modes
: ItemLocalMap
<BindingMode
>,
341 /// Stores the types which were implicitly dereferenced in pattern binding modes
342 /// for later usage in HAIR lowering. For example,
345 /// match &&Some(5i32) {
350 /// leads to a `vec![&&Option<i32>, &Option<i32>]`. Empty vectors are not stored.
353 /// https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions
354 pat_adjustments
: ItemLocalMap
<Vec
<Ty
<'tcx
>>>,
357 pub upvar_capture_map
: ty
::UpvarCaptureMap
<'tcx
>,
359 /// Records the type of each closure.
360 closure_tys
: ItemLocalMap
<ty
::PolyFnSig
<'tcx
>>,
362 /// Records the kind of each closure and the span and name of the variable
363 /// that caused the closure to be this kind.
364 closure_kinds
: ItemLocalMap
<(ty
::ClosureKind
, Option
<(Span
, ast
::Name
)>)>,
366 generator_sigs
: ItemLocalMap
<Option
<ty
::GenSig
<'tcx
>>>,
368 generator_interiors
: ItemLocalMap
<ty
::GeneratorInterior
<'tcx
>>,
370 /// For each fn, records the "liberated" types of its arguments
371 /// and return type. Liberated means that all bound regions
372 /// (including late-bound regions) are replaced with free
373 /// equivalents. This table is not used in trans (since regions
374 /// are erased there) and hence is not serialized to metadata.
375 liberated_fn_sigs
: ItemLocalMap
<ty
::FnSig
<'tcx
>>,
377 /// For each FRU expression, record the normalized types of the fields
378 /// of the struct - this is needed because it is non-trivial to
379 /// normalize while preserving regions. This table is used only in
380 /// MIR construction and hence is not serialized to metadata.
381 fru_field_types
: ItemLocalMap
<Vec
<Ty
<'tcx
>>>,
383 /// Maps a cast expression to its kind. This is keyed on the
384 /// *from* expression of the cast, not the cast itself.
385 cast_kinds
: ItemLocalMap
<ty
::cast
::CastKind
>,
387 /// Set of trait imports actually used in the method resolution.
388 /// This is used for warning unused imports. During type
389 /// checking, this `Rc` should not be cloned: it must have a ref-count
390 /// of 1 so that we can insert things into the set mutably.
391 pub used_trait_imports
: Rc
<DefIdSet
>,
393 /// If any errors occurred while type-checking this body,
394 /// this field will be set to `true`.
395 pub tainted_by_errors
: bool
,
397 /// Stores the free-region relationships that were deduced from
398 /// its where clauses and parameter types. These are then
399 /// read-again by borrowck.
400 pub free_region_map
: FreeRegionMap
<'tcx
>,
403 impl<'tcx
> TypeckTables
<'tcx
> {
404 pub fn empty(local_id_root
: Option
<DefId
>) -> TypeckTables
<'tcx
> {
407 type_dependent_defs
: ItemLocalMap(),
408 node_types
: ItemLocalMap(),
409 node_substs
: ItemLocalMap(),
410 adjustments
: ItemLocalMap(),
411 pat_binding_modes
: ItemLocalMap(),
412 pat_adjustments
: ItemLocalMap(),
413 upvar_capture_map
: FxHashMap(),
414 generator_sigs
: ItemLocalMap(),
415 generator_interiors
: ItemLocalMap(),
416 closure_tys
: ItemLocalMap(),
417 closure_kinds
: ItemLocalMap(),
418 liberated_fn_sigs
: ItemLocalMap(),
419 fru_field_types
: ItemLocalMap(),
420 cast_kinds
: ItemLocalMap(),
421 used_trait_imports
: Rc
::new(DefIdSet()),
422 tainted_by_errors
: false,
423 free_region_map
: FreeRegionMap
::new(),
427 /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
428 pub fn qpath_def(&self, qpath
: &hir
::QPath
, id
: hir
::HirId
) -> Def
{
430 hir
::QPath
::Resolved(_
, ref path
) => path
.def
,
431 hir
::QPath
::TypeRelative(..) => {
432 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
433 self.type_dependent_defs
.get(&id
.local_id
).cloned().unwrap_or(Def
::Err
)
438 pub fn type_dependent_defs(&self) -> LocalTableInContext
<Def
> {
439 LocalTableInContext
{
440 local_id_root
: self.local_id_root
,
441 data
: &self.type_dependent_defs
445 pub fn type_dependent_defs_mut(&mut self) -> LocalTableInContextMut
<Def
> {
446 LocalTableInContextMut
{
447 local_id_root
: self.local_id_root
,
448 data
: &mut self.type_dependent_defs
452 pub fn node_types(&self) -> LocalTableInContext
<Ty
<'tcx
>> {
453 LocalTableInContext
{
454 local_id_root
: self.local_id_root
,
455 data
: &self.node_types
459 pub fn node_types_mut(&mut self) -> LocalTableInContextMut
<Ty
<'tcx
>> {
460 LocalTableInContextMut
{
461 local_id_root
: self.local_id_root
,
462 data
: &mut self.node_types
466 pub fn node_id_to_type(&self, id
: hir
::HirId
) -> Ty
<'tcx
> {
467 match self.node_id_to_type_opt(id
) {
470 bug
!("node_id_to_type: no type for node `{}`",
472 let id
= tcx
.hir
.definitions().find_node_for_hir_id(id
);
473 tcx
.hir
.node_to_string(id
)
479 pub fn node_id_to_type_opt(&self, id
: hir
::HirId
) -> Option
<Ty
<'tcx
>> {
480 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
481 self.node_types
.get(&id
.local_id
).cloned()
484 pub fn node_substs_mut(&mut self) -> LocalTableInContextMut
<&'tcx Substs
<'tcx
>> {
485 LocalTableInContextMut
{
486 local_id_root
: self.local_id_root
,
487 data
: &mut self.node_substs
491 pub fn node_substs(&self, id
: hir
::HirId
) -> &'tcx Substs
<'tcx
> {
492 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
493 self.node_substs
.get(&id
.local_id
).cloned().unwrap_or(Substs
::empty())
496 pub fn node_substs_opt(&self, id
: hir
::HirId
) -> Option
<&'tcx Substs
<'tcx
>> {
497 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
498 self.node_substs
.get(&id
.local_id
).cloned()
501 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
502 // doesn't provide type parameter substitutions.
503 pub fn pat_ty(&self, pat
: &hir
::Pat
) -> Ty
<'tcx
> {
504 self.node_id_to_type(pat
.hir_id
)
507 pub fn pat_ty_opt(&self, pat
: &hir
::Pat
) -> Option
<Ty
<'tcx
>> {
508 self.node_id_to_type_opt(pat
.hir_id
)
511 // Returns the type of an expression as a monotype.
513 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
514 // some cases, we insert `Adjustment` annotations such as auto-deref or
515 // auto-ref. The type returned by this function does not consider such
516 // adjustments. See `expr_ty_adjusted()` instead.
518 // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
519 // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
520 // instead of "fn(ty) -> T with T = isize".
521 pub fn expr_ty(&self, expr
: &hir
::Expr
) -> Ty
<'tcx
> {
522 self.node_id_to_type(expr
.hir_id
)
525 pub fn expr_ty_opt(&self, expr
: &hir
::Expr
) -> Option
<Ty
<'tcx
>> {
526 self.node_id_to_type_opt(expr
.hir_id
)
529 pub fn adjustments(&self) -> LocalTableInContext
<Vec
<ty
::adjustment
::Adjustment
<'tcx
>>> {
530 LocalTableInContext
{
531 local_id_root
: self.local_id_root
,
532 data
: &self.adjustments
536 pub fn adjustments_mut(&mut self)
537 -> LocalTableInContextMut
<Vec
<ty
::adjustment
::Adjustment
<'tcx
>>> {
538 LocalTableInContextMut
{
539 local_id_root
: self.local_id_root
,
540 data
: &mut self.adjustments
544 pub fn expr_adjustments(&self, expr
: &hir
::Expr
)
545 -> &[ty
::adjustment
::Adjustment
<'tcx
>] {
546 validate_hir_id_for_typeck_tables(self.local_id_root
, expr
.hir_id
, false);
547 self.adjustments
.get(&expr
.hir_id
.local_id
).map_or(&[], |a
| &a
[..])
550 /// Returns the type of `expr`, considering any `Adjustment`
551 /// entry recorded for that expression.
552 pub fn expr_ty_adjusted(&self, expr
: &hir
::Expr
) -> Ty
<'tcx
> {
553 self.expr_adjustments(expr
)
555 .map_or_else(|| self.expr_ty(expr
), |adj
| adj
.target
)
558 pub fn expr_ty_adjusted_opt(&self, expr
: &hir
::Expr
) -> Option
<Ty
<'tcx
>> {
559 self.expr_adjustments(expr
)
561 .map(|adj
| adj
.target
)
562 .or_else(|| self.expr_ty_opt(expr
))
565 pub fn is_method_call(&self, expr
: &hir
::Expr
) -> bool
{
566 // Only paths and method calls/overloaded operators have
567 // entries in type_dependent_defs, ignore the former here.
568 if let hir
::ExprPath(_
) = expr
.node
{
572 match self.type_dependent_defs().get(expr
.hir_id
) {
573 Some(&Def
::Method(_
)) => true,
578 pub fn pat_binding_modes(&self) -> LocalTableInContext
<BindingMode
> {
579 LocalTableInContext
{
580 local_id_root
: self.local_id_root
,
581 data
: &self.pat_binding_modes
585 pub fn pat_binding_modes_mut(&mut self)
586 -> LocalTableInContextMut
<BindingMode
> {
587 LocalTableInContextMut
{
588 local_id_root
: self.local_id_root
,
589 data
: &mut self.pat_binding_modes
593 pub fn pat_adjustments(&self) -> LocalTableInContext
<Vec
<Ty
<'tcx
>>> {
594 LocalTableInContext
{
595 local_id_root
: self.local_id_root
,
596 data
: &self.pat_adjustments
,
600 pub fn pat_adjustments_mut(&mut self)
601 -> LocalTableInContextMut
<Vec
<Ty
<'tcx
>>> {
602 LocalTableInContextMut
{
603 local_id_root
: self.local_id_root
,
604 data
: &mut self.pat_adjustments
,
608 pub fn upvar_capture(&self, upvar_id
: ty
::UpvarId
) -> ty
::UpvarCapture
<'tcx
> {
609 self.upvar_capture_map
[&upvar_id
]
612 pub fn closure_tys(&self) -> LocalTableInContext
<ty
::PolyFnSig
<'tcx
>> {
613 LocalTableInContext
{
614 local_id_root
: self.local_id_root
,
615 data
: &self.closure_tys
619 pub fn closure_tys_mut(&mut self)
620 -> LocalTableInContextMut
<ty
::PolyFnSig
<'tcx
>> {
621 LocalTableInContextMut
{
622 local_id_root
: self.local_id_root
,
623 data
: &mut self.closure_tys
627 pub fn closure_kinds(&self) -> LocalTableInContext
<(ty
::ClosureKind
,
628 Option
<(Span
, ast
::Name
)>)> {
629 LocalTableInContext
{
630 local_id_root
: self.local_id_root
,
631 data
: &self.closure_kinds
635 pub fn closure_kinds_mut(&mut self)
636 -> LocalTableInContextMut
<(ty
::ClosureKind
, Option
<(Span
, ast
::Name
)>)> {
637 LocalTableInContextMut
{
638 local_id_root
: self.local_id_root
,
639 data
: &mut self.closure_kinds
643 pub fn liberated_fn_sigs(&self) -> LocalTableInContext
<ty
::FnSig
<'tcx
>> {
644 LocalTableInContext
{
645 local_id_root
: self.local_id_root
,
646 data
: &self.liberated_fn_sigs
650 pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut
<ty
::FnSig
<'tcx
>> {
651 LocalTableInContextMut
{
652 local_id_root
: self.local_id_root
,
653 data
: &mut self.liberated_fn_sigs
657 pub fn fru_field_types(&self) -> LocalTableInContext
<Vec
<Ty
<'tcx
>>> {
658 LocalTableInContext
{
659 local_id_root
: self.local_id_root
,
660 data
: &self.fru_field_types
664 pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut
<Vec
<Ty
<'tcx
>>> {
665 LocalTableInContextMut
{
666 local_id_root
: self.local_id_root
,
667 data
: &mut self.fru_field_types
671 pub fn cast_kinds(&self) -> LocalTableInContext
<ty
::cast
::CastKind
> {
672 LocalTableInContext
{
673 local_id_root
: self.local_id_root
,
674 data
: &self.cast_kinds
678 pub fn cast_kinds_mut(&mut self) -> LocalTableInContextMut
<ty
::cast
::CastKind
> {
679 LocalTableInContextMut
{
680 local_id_root
: self.local_id_root
,
681 data
: &mut self.cast_kinds
685 pub fn generator_sigs(&self)
686 -> LocalTableInContext
<Option
<ty
::GenSig
<'tcx
>>>
688 LocalTableInContext
{
689 local_id_root
: self.local_id_root
,
690 data
: &self.generator_sigs
,
694 pub fn generator_sigs_mut(&mut self)
695 -> LocalTableInContextMut
<Option
<ty
::GenSig
<'tcx
>>>
697 LocalTableInContextMut
{
698 local_id_root
: self.local_id_root
,
699 data
: &mut self.generator_sigs
,
703 pub fn generator_interiors(&self)
704 -> LocalTableInContext
<ty
::GeneratorInterior
<'tcx
>>
706 LocalTableInContext
{
707 local_id_root
: self.local_id_root
,
708 data
: &self.generator_interiors
,
712 pub fn generator_interiors_mut(&mut self)
713 -> LocalTableInContextMut
<ty
::GeneratorInterior
<'tcx
>>
715 LocalTableInContextMut
{
716 local_id_root
: self.local_id_root
,
717 data
: &mut self.generator_interiors
,
722 impl<'gcx
> HashStable
<StableHashingContext
<'gcx
>> for TypeckTables
<'gcx
> {
723 fn hash_stable
<W
: StableHasherResult
>(&self,
724 hcx
: &mut StableHashingContext
<'gcx
>,
725 hasher
: &mut StableHasher
<W
>) {
726 let ty
::TypeckTables
{
728 ref type_dependent_defs
,
732 ref pat_binding_modes
,
734 ref upvar_capture_map
,
737 ref liberated_fn_sigs
,
742 ref used_trait_imports
,
746 ref generator_interiors
,
749 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
750 type_dependent_defs
.hash_stable(hcx
, hasher
);
751 node_types
.hash_stable(hcx
, hasher
);
752 node_substs
.hash_stable(hcx
, hasher
);
753 adjustments
.hash_stable(hcx
, hasher
);
754 pat_binding_modes
.hash_stable(hcx
, hasher
);
755 pat_adjustments
.hash_stable(hcx
, hasher
);
756 hash_stable_hashmap(hcx
, hasher
, upvar_capture_map
, |up_var_id
, hcx
| {
763 local_id_root
.expect("trying to hash invalid TypeckTables");
765 let var_owner_def_id
= DefId
{
766 krate
: local_id_root
.krate
,
769 let closure_def_id
= DefId
{
770 krate
: local_id_root
.krate
,
771 index
: closure_expr_id
.to_def_id().index
,
773 (hcx
.def_path_hash(var_owner_def_id
),
775 hcx
.def_path_hash(closure_def_id
))
778 closure_tys
.hash_stable(hcx
, hasher
);
779 closure_kinds
.hash_stable(hcx
, hasher
);
780 liberated_fn_sigs
.hash_stable(hcx
, hasher
);
781 fru_field_types
.hash_stable(hcx
, hasher
);
782 cast_kinds
.hash_stable(hcx
, hasher
);
783 generator_sigs
.hash_stable(hcx
, hasher
);
784 generator_interiors
.hash_stable(hcx
, hasher
);
785 used_trait_imports
.hash_stable(hcx
, hasher
);
786 tainted_by_errors
.hash_stable(hcx
, hasher
);
787 free_region_map
.hash_stable(hcx
, hasher
);
792 impl<'tcx
> CommonTypes
<'tcx
> {
793 fn new(interners
: &CtxtInterners
<'tcx
>) -> CommonTypes
<'tcx
> {
794 let mk
= |sty
| interners
.intern_ty(sty
, None
);
795 let mk_region
= |r
| {
796 if let Some(r
) = interners
.region
.borrow().get(&r
) {
799 let r
= interners
.arena
.alloc(r
);
800 interners
.region
.borrow_mut().insert(Interned(r
));
808 isize: mk(TyInt(ast
::IntTy
::Is
)),
809 i8: mk(TyInt(ast
::IntTy
::I8
)),
810 i16: mk(TyInt(ast
::IntTy
::I16
)),
811 i32: mk(TyInt(ast
::IntTy
::I32
)),
812 i64: mk(TyInt(ast
::IntTy
::I64
)),
813 i128
: mk(TyInt(ast
::IntTy
::I128
)),
814 usize: mk(TyUint(ast
::UintTy
::Us
)),
815 u8: mk(TyUint(ast
::UintTy
::U8
)),
816 u16: mk(TyUint(ast
::UintTy
::U16
)),
817 u32: mk(TyUint(ast
::UintTy
::U32
)),
818 u64: mk(TyUint(ast
::UintTy
::U64
)),
819 u128
: mk(TyUint(ast
::UintTy
::U128
)),
820 f32: mk(TyFloat(ast
::FloatTy
::F32
)),
821 f64: mk(TyFloat(ast
::FloatTy
::F64
)),
823 re_empty
: mk_region(RegionKind
::ReEmpty
),
824 re_static
: mk_region(RegionKind
::ReStatic
),
825 re_erased
: mk_region(RegionKind
::ReErased
),
830 /// The central data structure of the compiler. It stores references
831 /// to the various **arenas** and also houses the results of the
832 /// various **compiler queries** that have been performed. See [the
833 /// README](README.md) for more deatils.
834 #[derive(Copy, Clone)]
835 pub struct TyCtxt
<'a
, 'gcx
: 'a
+'tcx
, 'tcx
: 'a
> {
836 gcx
: &'a GlobalCtxt
<'gcx
>,
837 interners
: &'a CtxtInterners
<'tcx
>
840 impl<'a
, 'gcx
, 'tcx
> Deref
for TyCtxt
<'a
, 'gcx
, 'tcx
> {
841 type Target
= &'a GlobalCtxt
<'gcx
>;
842 fn deref(&self) -> &Self::Target
{
847 pub struct GlobalCtxt
<'tcx
> {
848 global_arenas
: &'tcx GlobalArenas
<'tcx
>,
849 global_interners
: CtxtInterners
<'tcx
>,
851 cstore
: &'tcx CrateStore
,
853 pub sess
: &'tcx Session
,
855 pub dep_graph
: DepGraph
,
857 /// This provides access to the incr. comp. on-disk cache for query results.
858 /// Do not access this directly. It is only meant to be used by
859 /// `DepGraph::try_mark_green()` and the query infrastructure in `ty::maps`.
860 pub(crate) on_disk_query_result_cache
: maps
::OnDiskCache
<'tcx
>,
862 /// Common types, pre-interned for your convenience.
863 pub types
: CommonTypes
<'tcx
>,
865 /// Map indicating what traits are in scope for places where this
866 /// is relevant; generated by resolve.
867 trait_map
: FxHashMap
<DefIndex
,
868 Rc
<FxHashMap
<ItemLocalId
,
869 Rc
<StableVec
<TraitCandidate
>>>>>,
871 /// Export map produced by name resolution.
872 export_map
: FxHashMap
<DefId
, Rc
<Vec
<Export
>>>,
874 named_region_map
: NamedRegionMap
,
876 pub hir
: hir_map
::Map
<'tcx
>,
878 /// A map from DefPathHash -> DefId. Includes DefIds from the local crate
879 /// as well as all upstream crates. Only populated in incremental mode.
880 pub def_path_hash_to_def_id
: Option
<FxHashMap
<DefPathHash
, DefId
>>,
882 pub maps
: maps
::Maps
<'tcx
>,
884 // Records the free variables refrenced by every closure
885 // expression. Do not track deps for this, just recompute it from
886 // scratch every time.
887 freevars
: FxHashMap
<DefId
, Rc
<Vec
<hir
::Freevar
>>>,
889 maybe_unused_trait_imports
: FxHashSet
<DefId
>,
891 maybe_unused_extern_crates
: Vec
<(DefId
, Span
)>,
893 // Internal cache for metadata decoding. No need to track deps on this.
894 pub rcache
: RefCell
<FxHashMap
<ty
::CReaderCacheKey
, Ty
<'tcx
>>>,
896 /// Caches the results of trait selection. This cache is used
897 /// for things that do not have to do with the parameters in scope.
898 pub selection_cache
: traits
::SelectionCache
<'tcx
>,
900 /// Caches the results of trait evaluation. This cache is used
901 /// for things that do not have to do with the parameters in scope.
902 /// Merge this with `selection_cache`?
903 pub evaluation_cache
: traits
::EvaluationCache
<'tcx
>,
905 /// The definite name of the current crate after taking into account
906 /// attributes, commandline parameters, etc.
907 pub crate_name
: Symbol
,
909 /// Data layout specification for the current target.
910 pub data_layout
: TargetDataLayout
,
912 /// Used to prevent layout from recursing too deeply.
913 pub layout_depth
: Cell
<usize>,
915 /// Map from function to the `#[derive]` mode that it's defining. Only used
916 /// by `proc-macro` crates.
917 pub derive_macros
: RefCell
<NodeMap
<Symbol
>>,
919 stability_interner
: RefCell
<FxHashSet
<&'tcx attr
::Stability
>>,
921 layout_interner
: RefCell
<FxHashSet
<&'tcx Layout
>>,
923 /// A vector of every trait accessible in the whole crate
924 /// (i.e. including those from subcrates). This is used only for
925 /// error reporting, and so is lazily initialized and generally
926 /// shouldn't taint the common path (hence the RefCell).
927 pub all_traits
: RefCell
<Option
<Vec
<DefId
>>>,
929 /// A general purpose channel to throw data out the back towards LLVM worker
932 /// This is intended to only get used during the trans phase of the compiler
933 /// when satisfying the query for a particular codegen unit. Internally in
934 /// the query it'll send data along this channel to get processed later.
935 pub tx_to_llvm_workers
: mpsc
::Sender
<Box
<Any
+ Send
>>,
937 output_filenames
: Arc
<OutputFilenames
>,
940 impl<'tcx
> GlobalCtxt
<'tcx
> {
941 /// Get the global TyCtxt.
942 pub fn global_tcx
<'a
>(&'a
self) -> TyCtxt
<'a
, 'tcx
, 'tcx
> {
945 interners
: &self.global_interners
950 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
951 pub fn alloc_generics(self, generics
: ty
::Generics
) -> &'gcx ty
::Generics
{
952 self.global_arenas
.generics
.alloc(generics
)
955 pub fn alloc_steal_mir(self, mir
: Mir
<'gcx
>) -> &'gcx Steal
<Mir
<'gcx
>> {
956 self.global_arenas
.steal_mir
.alloc(Steal
::new(mir
))
959 pub fn alloc_mir(self, mir
: Mir
<'gcx
>) -> &'gcx Mir
<'gcx
> {
960 self.global_arenas
.mir
.alloc(mir
)
963 pub fn alloc_tables(self, tables
: ty
::TypeckTables
<'gcx
>) -> &'gcx ty
::TypeckTables
<'gcx
> {
964 self.global_arenas
.tables
.alloc(tables
)
967 pub fn alloc_trait_def(self, def
: ty
::TraitDef
) -> &'gcx ty
::TraitDef
{
968 self.global_arenas
.trait_def
.alloc(def
)
971 pub fn alloc_adt_def(self,
974 variants
: Vec
<ty
::VariantDef
>,
976 -> &'gcx ty
::AdtDef
{
977 let def
= ty
::AdtDef
::new(self, did
, kind
, variants
, repr
);
978 self.global_arenas
.adt_def
.alloc(def
)
981 pub fn alloc_byte_array(self, bytes
: &[u8]) -> &'gcx
[u8] {
982 if bytes
.is_empty() {
985 self.global_interners
.arena
.alloc_slice(bytes
)
989 pub fn alloc_const_slice(self, values
: &[&'tcx ty
::Const
<'tcx
>])
990 -> &'tcx
[&'tcx ty
::Const
<'tcx
>] {
991 if values
.is_empty() {
994 self.interners
.arena
.alloc_slice(values
)
998 pub fn alloc_name_const_slice(self, values
: &[(ast
::Name
, &'tcx ty
::Const
<'tcx
>)])
999 -> &'tcx
[(ast
::Name
, &'tcx ty
::Const
<'tcx
>)] {
1000 if values
.is_empty() {
1003 self.interners
.arena
.alloc_slice(values
)
1007 pub fn intern_stability(self, stab
: attr
::Stability
) -> &'gcx attr
::Stability
{
1008 if let Some(st
) = self.stability_interner
.borrow().get(&stab
) {
1012 let interned
= self.global_interners
.arena
.alloc(stab
);
1013 if let Some(prev
) = self.stability_interner
.borrow_mut().replace(interned
) {
1014 bug
!("Tried to overwrite interned Stability: {:?}", prev
)
1019 pub fn intern_layout(self, layout
: Layout
) -> &'gcx Layout
{
1020 if let Some(layout
) = self.layout_interner
.borrow().get(&layout
) {
1024 let interned
= self.global_arenas
.layout
.alloc(layout
);
1025 if let Some(prev
) = self.layout_interner
.borrow_mut().replace(interned
) {
1026 bug
!("Tried to overwrite interned Layout: {:?}", prev
)
1031 pub fn lift
<T
: ?Sized
+ Lift
<'tcx
>>(self, value
: &T
) -> Option
<T
::Lifted
> {
1032 value
.lift_to_tcx(self)
1035 /// Like lift, but only tries in the global tcx.
1036 pub fn lift_to_global
<T
: ?Sized
+ Lift
<'gcx
>>(self, value
: &T
) -> Option
<T
::Lifted
> {
1037 value
.lift_to_tcx(self.global_tcx())
1040 /// Returns true if self is the same as self.global_tcx().
1041 fn is_global(self) -> bool
{
1042 let local
= self.interners
as *const _
;
1043 let global
= &self.global_interners
as *const _
;
1044 local
as usize == global
as usize
1047 /// Create a type context and call the closure with a `TyCtxt` reference
1048 /// to the context. The closure enforces that the type context and any interned
1049 /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
1050 /// reference to the context, to allow formatting values that need it.
1051 pub fn create_and_enter
<F
, R
>(s
: &'tcx Session
,
1052 cstore
: &'tcx CrateStore
,
1053 local_providers
: ty
::maps
::Providers
<'tcx
>,
1054 extern_providers
: ty
::maps
::Providers
<'tcx
>,
1055 arenas
: &'tcx GlobalArenas
<'tcx
>,
1056 arena
: &'tcx DroplessArena
,
1057 resolutions
: ty
::Resolutions
,
1058 named_region_map
: resolve_lifetime
::NamedRegionMap
,
1059 hir
: hir_map
::Map
<'tcx
>,
1060 on_disk_query_result_cache
: maps
::OnDiskCache
<'tcx
>,
1062 tx
: mpsc
::Sender
<Box
<Any
+ Send
>>,
1063 output_filenames
: &OutputFilenames
,
1065 where F
: for<'b
> FnOnce(TyCtxt
<'b
, 'tcx
, 'tcx
>) -> R
1067 let data_layout
= TargetDataLayout
::parse(s
);
1068 let interners
= CtxtInterners
::new(arena
);
1069 let common_types
= CommonTypes
::new(&interners
);
1070 let dep_graph
= hir
.dep_graph
.clone();
1071 let max_cnum
= cstore
.crates_untracked().iter().map(|c
| c
.as_usize()).max().unwrap_or(0);
1072 let mut providers
= IndexVec
::from_elem_n(extern_providers
, max_cnum
+ 1);
1073 providers
[LOCAL_CRATE
] = local_providers
;
1075 let def_path_hash_to_def_id
= if s
.opts
.build_dep_graph() {
1076 let upstream_def_path_tables
: Vec
<(CrateNum
, Rc
<_
>)> = cstore
1079 .map(|&cnum
| (cnum
, cstore
.def_path_table(cnum
)))
1082 let def_path_tables
= || {
1083 upstream_def_path_tables
1085 .map(|&(cnum
, ref rc
)| (cnum
, &**rc
))
1086 .chain(iter
::once((LOCAL_CRATE
, hir
.definitions().def_path_table())))
1089 // Precompute the capacity of the hashmap so we don't have to
1090 // re-allocate when populating it.
1091 let capacity
= def_path_tables().map(|(_
, t
)| t
.size()).sum
::<usize>();
1093 let mut map
: FxHashMap
<_
, _
> = FxHashMap
::with_capacity_and_hasher(
1095 ::std
::default::Default
::default()
1098 for (cnum
, def_path_table
) in def_path_tables() {
1099 def_path_table
.add_def_path_hashes_to(cnum
, &mut map
);
1107 let mut trait_map
= FxHashMap();
1108 for (k
, v
) in resolutions
.trait_map
{
1109 let hir_id
= hir
.node_to_hir_id(k
);
1110 let map
= trait_map
.entry(hir_id
.owner
)
1111 .or_insert_with(|| Rc
::new(FxHashMap()));
1112 Rc
::get_mut(map
).unwrap()
1113 .insert(hir_id
.local_id
,
1114 Rc
::new(StableVec
::new(v
)));
1116 let mut defs
= FxHashMap();
1117 for (k
, v
) in named_region_map
.defs
{
1118 let hir_id
= hir
.node_to_hir_id(k
);
1119 let map
= defs
.entry(hir_id
.owner
)
1120 .or_insert_with(|| Rc
::new(FxHashMap()));
1121 Rc
::get_mut(map
).unwrap().insert(hir_id
.local_id
, v
);
1123 let mut late_bound
= FxHashMap();
1124 for k
in named_region_map
.late_bound
{
1125 let hir_id
= hir
.node_to_hir_id(k
);
1126 let map
= late_bound
.entry(hir_id
.owner
)
1127 .or_insert_with(|| Rc
::new(FxHashSet()));
1128 Rc
::get_mut(map
).unwrap().insert(hir_id
.local_id
);
1130 let mut object_lifetime_defaults
= FxHashMap();
1131 for (k
, v
) in named_region_map
.object_lifetime_defaults
{
1132 let hir_id
= hir
.node_to_hir_id(k
);
1133 let map
= object_lifetime_defaults
.entry(hir_id
.owner
)
1134 .or_insert_with(|| Rc
::new(FxHashMap()));
1135 Rc
::get_mut(map
).unwrap().insert(hir_id
.local_id
, Rc
::new(v
));
1138 tls
::enter_global(GlobalCtxt
{
1141 global_arenas
: arenas
,
1142 global_interners
: interners
,
1143 dep_graph
: dep_graph
.clone(),
1144 on_disk_query_result_cache
,
1145 types
: common_types
,
1146 named_region_map
: NamedRegionMap
{
1149 object_lifetime_defaults
,
1152 export_map
: resolutions
.export_map
.into_iter().map(|(k
, v
)| {
1155 freevars
: resolutions
.freevars
.into_iter().map(|(k
, v
)| {
1156 (hir
.local_def_id(k
), Rc
::new(v
))
1158 maybe_unused_trait_imports
:
1159 resolutions
.maybe_unused_trait_imports
1161 .map(|id
| hir
.local_def_id(id
))
1163 maybe_unused_extern_crates
:
1164 resolutions
.maybe_unused_extern_crates
1166 .map(|(id
, sp
)| (hir
.local_def_id(id
), sp
))
1169 def_path_hash_to_def_id
,
1170 maps
: maps
::Maps
::new(providers
),
1171 rcache
: RefCell
::new(FxHashMap()),
1172 selection_cache
: traits
::SelectionCache
::new(),
1173 evaluation_cache
: traits
::EvaluationCache
::new(),
1174 crate_name
: Symbol
::intern(crate_name
),
1176 layout_interner
: RefCell
::new(FxHashSet()),
1177 layout_depth
: Cell
::new(0),
1178 derive_macros
: RefCell
::new(NodeMap()),
1179 stability_interner
: RefCell
::new(FxHashSet()),
1180 all_traits
: RefCell
::new(None
),
1181 tx_to_llvm_workers
: tx
,
1182 output_filenames
: Arc
::new(output_filenames
.clone()),
1186 pub fn consider_optimizing
<T
: Fn() -> String
>(&self, msg
: T
) -> bool
{
1187 let cname
= self.crate_name(LOCAL_CRATE
).as_str();
1188 self.sess
.consider_optimizing(&cname
, msg
)
1191 pub fn lang_items(self) -> Rc
<middle
::lang_items
::LanguageItems
> {
1192 self.get_lang_items(LOCAL_CRATE
)
1195 pub fn stability(self) -> Rc
<stability
::Index
<'tcx
>> {
1196 // FIXME(#42293) we should actually track this, but fails too many tests
1198 self.dep_graph
.with_ignore(|| {
1199 self.stability_index(LOCAL_CRATE
)
1203 pub fn crates(self) -> Rc
<Vec
<CrateNum
>> {
1204 self.all_crate_nums(LOCAL_CRATE
)
1207 pub fn def_key(self, id
: DefId
) -> hir_map
::DefKey
{
1209 self.hir
.def_key(id
)
1211 self.cstore
.def_key(id
)
1215 /// Convert a `DefId` into its fully expanded `DefPath` (every
1216 /// `DefId` is really just an interned def-path).
1218 /// Note that if `id` is not local to this crate, the result will
1219 /// be a non-local `DefPath`.
1220 pub fn def_path(self, id
: DefId
) -> hir_map
::DefPath
{
1222 self.hir
.def_path(id
)
1224 self.cstore
.def_path(id
)
1229 pub fn def_path_hash(self, def_id
: DefId
) -> hir_map
::DefPathHash
{
1230 if def_id
.is_local() {
1231 self.hir
.definitions().def_path_hash(def_id
.index
)
1233 self.cstore
.def_path_hash(def_id
)
1237 pub fn def_path_debug_str(self, def_id
: DefId
) -> String
{
1238 // We are explicitly not going through queries here in order to get
1239 // crate name and disambiguator since this code is called from debug!()
1240 // statements within the query system and we'd run into endless
1241 // recursion otherwise.
1242 let (crate_name
, crate_disambiguator
) = if def_id
.is_local() {
1243 (self.crate_name
.clone(),
1244 self.sess
.local_crate_disambiguator())
1246 (self.cstore
.crate_name_untracked(def_id
.krate
),
1247 self.cstore
.crate_disambiguator_untracked(def_id
.krate
))
1252 // Don't print the whole crate disambiguator. That's just
1253 // annoying in debug output.
1254 &(crate_disambiguator
.to_fingerprint().to_hex())[..4],
1255 self.def_path(def_id
).to_string_no_crate())
1258 pub fn metadata_encoding_version(self) -> Vec
<u8> {
1259 self.cstore
.metadata_encoding_version().to_vec()
1262 // Note that this is *untracked* and should only be used within the query
1263 // system if the result is otherwise tracked through queries
1264 pub fn crate_data_as_rc_any(self, cnum
: CrateNum
) -> Rc
<Any
> {
1265 self.cstore
.crate_data_as_rc_any(cnum
)
1268 pub fn create_stable_hashing_context(self) -> StableHashingContext
<'gcx
> {
1269 let krate
= self.dep_graph
.with_ignore(|| self.gcx
.hir
.krate());
1271 StableHashingContext
::new(self.sess
,
1273 self.hir
.definitions(),
1277 // This method makes sure that we have a DepNode and a Fingerprint for
1278 // every upstream crate. It needs to be called once right after the tcx is
1280 // With full-fledged red/green, the method will probably become unnecessary
1281 // as this will be done on-demand.
1282 pub fn allocate_metadata_dep_nodes(self) {
1283 // We cannot use the query versions of crates() and crate_hash(), since
1284 // those would need the DepNodes that we are allocating here.
1285 for cnum
in self.cstore
.crates_untracked() {
1286 let dep_node
= DepNode
::new(self, DepConstructor
::CrateMetadata(cnum
));
1287 let crate_hash
= self.cstore
.crate_hash_untracked(cnum
);
1288 self.dep_graph
.with_task(dep_node
,
1291 |_
, x
| x
// No transformation needed
1296 // This method exercises the `in_scope_traits_map` query for all possible
1297 // values so that we have their fingerprints available in the DepGraph.
1298 // This is only required as long as we still use the old dependency tracking
1299 // which needs to have the fingerprints of all input nodes beforehand.
1300 pub fn precompute_in_scope_traits_hashes(self) {
1301 for &def_index
in self.trait_map
.keys() {
1302 self.in_scope_traits_map(def_index
);
1306 pub fn serialize_query_result_cache
<E
>(self,
1308 -> Result
<(), E
::Error
>
1309 where E
: ty
::codec
::TyEncoder
1311 self.on_disk_query_result_cache
.serialize(self.global_tcx(), self.cstore
, encoder
)
1316 impl<'a
, 'tcx
> TyCtxt
<'a
, 'tcx
, 'tcx
> {
1317 pub fn encode_metadata(self, link_meta
: &LinkMeta
, reachable
: &NodeSet
)
1318 -> (EncodedMetadata
, EncodedMetadataHashes
)
1320 self.cstore
.encode_metadata(self, link_meta
, reachable
)
1324 impl<'gcx
: 'tcx
, 'tcx
> GlobalCtxt
<'gcx
> {
1325 /// Call the closure with a local `TyCtxt` using the given arena.
1326 pub fn enter_local
<F
, R
>(&self, arena
: &'tcx DroplessArena
, f
: F
) -> R
1327 where F
: for<'a
> FnOnce(TyCtxt
<'a
, 'gcx
, 'tcx
>) -> R
1329 let interners
= CtxtInterners
::new(arena
);
1330 tls
::enter(self, &interners
, f
)
1334 /// A trait implemented for all X<'a> types which can be safely and
1335 /// efficiently converted to X<'tcx> as long as they are part of the
1336 /// provided TyCtxt<'tcx>.
1337 /// This can be done, for example, for Ty<'tcx> or &'tcx Substs<'tcx>
1338 /// by looking them up in their respective interners.
1340 /// However, this is still not the best implementation as it does
1341 /// need to compare the components, even for interned values.
1342 /// It would be more efficient if TypedArena provided a way to
1343 /// determine whether the address is in the allocated range.
1345 /// None is returned if the value or one of the components is not part
1346 /// of the provided context.
1347 /// For Ty, None can be returned if either the type interner doesn't
1348 /// contain the TypeVariants key or if the address of the interned
1349 /// pointer differs. The latter case is possible if a primitive type,
1350 /// e.g. `()` or `u8`, was interned in a different context.
1351 pub trait Lift
<'tcx
> {
1353 fn lift_to_tcx
<'a
, 'gcx
>(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>) -> Option
<Self::Lifted
>;
1356 impl<'a
, 'tcx
> Lift
<'tcx
> for Ty
<'a
> {
1357 type Lifted
= Ty
<'tcx
>;
1358 fn lift_to_tcx
<'b
, 'gcx
>(&self, tcx
: TyCtxt
<'b
, 'gcx
, 'tcx
>) -> Option
<Ty
<'tcx
>> {
1359 if tcx
.interners
.arena
.in_arena(*self as *const _
) {
1360 return Some(unsafe { mem::transmute(*self) }
);
1362 // Also try in the global tcx if we're not that.
1363 if !tcx
.is_global() {
1364 self.lift_to_tcx(tcx
.global_tcx())
1371 impl<'a
, 'tcx
> Lift
<'tcx
> for Region
<'a
> {
1372 type Lifted
= Region
<'tcx
>;
1373 fn lift_to_tcx
<'b
, 'gcx
>(&self, tcx
: TyCtxt
<'b
, 'gcx
, 'tcx
>) -> Option
<Region
<'tcx
>> {
1374 if tcx
.interners
.arena
.in_arena(*self as *const _
) {
1375 return Some(unsafe { mem::transmute(*self) }
);
1377 // Also try in the global tcx if we're not that.
1378 if !tcx
.is_global() {
1379 self.lift_to_tcx(tcx
.global_tcx())
1386 impl<'a
, 'tcx
> Lift
<'tcx
> for &'a Const
<'a
> {
1387 type Lifted
= &'tcx Const
<'tcx
>;
1388 fn lift_to_tcx
<'b
, 'gcx
>(&self, tcx
: TyCtxt
<'b
, 'gcx
, 'tcx
>) -> Option
<&'tcx Const
<'tcx
>> {
1389 if tcx
.interners
.arena
.in_arena(*self as *const _
) {
1390 return Some(unsafe { mem::transmute(*self) }
);
1392 // Also try in the global tcx if we're not that.
1393 if !tcx
.is_global() {
1394 self.lift_to_tcx(tcx
.global_tcx())
1401 impl<'a
, 'tcx
> Lift
<'tcx
> for &'a Substs
<'a
> {
1402 type Lifted
= &'tcx Substs
<'tcx
>;
1403 fn lift_to_tcx
<'b
, 'gcx
>(&self, tcx
: TyCtxt
<'b
, 'gcx
, 'tcx
>) -> Option
<&'tcx Substs
<'tcx
>> {
1404 if self.len() == 0 {
1405 return Some(Slice
::empty());
1407 if tcx
.interners
.arena
.in_arena(&self[..] as *const _
) {
1408 return Some(unsafe { mem::transmute(*self) }
);
1410 // Also try in the global tcx if we're not that.
1411 if !tcx
.is_global() {
1412 self.lift_to_tcx(tcx
.global_tcx())
1419 impl<'a
, 'tcx
> Lift
<'tcx
> for &'a Slice
<Ty
<'a
>> {
1420 type Lifted
= &'tcx Slice
<Ty
<'tcx
>>;
1421 fn lift_to_tcx
<'b
, 'gcx
>(&self, tcx
: TyCtxt
<'b
, 'gcx
, 'tcx
>)
1422 -> Option
<&'tcx Slice
<Ty
<'tcx
>>> {
1423 if self.len() == 0 {
1424 return Some(Slice
::empty());
1426 if tcx
.interners
.arena
.in_arena(*self as *const _
) {
1427 return Some(unsafe { mem::transmute(*self) }
);
1429 // Also try in the global tcx if we're not that.
1430 if !tcx
.is_global() {
1431 self.lift_to_tcx(tcx
.global_tcx())
1438 impl<'a
, 'tcx
> Lift
<'tcx
> for &'a Slice
<ExistentialPredicate
<'a
>> {
1439 type Lifted
= &'tcx Slice
<ExistentialPredicate
<'tcx
>>;
1440 fn lift_to_tcx
<'b
, 'gcx
>(&self, tcx
: TyCtxt
<'b
, 'gcx
, 'tcx
>)
1441 -> Option
<&'tcx Slice
<ExistentialPredicate
<'tcx
>>> {
1442 if self.is_empty() {
1443 return Some(Slice
::empty());
1445 if tcx
.interners
.arena
.in_arena(*self as *const _
) {
1446 return Some(unsafe { mem::transmute(*self) }
);
1448 // Also try in the global tcx if we're not that.
1449 if !tcx
.is_global() {
1450 self.lift_to_tcx(tcx
.global_tcx())
1457 impl<'a
, 'tcx
> Lift
<'tcx
> for &'a Slice
<Predicate
<'a
>> {
1458 type Lifted
= &'tcx Slice
<Predicate
<'tcx
>>;
1459 fn lift_to_tcx
<'b
, 'gcx
>(&self, tcx
: TyCtxt
<'b
, 'gcx
, 'tcx
>)
1460 -> Option
<&'tcx Slice
<Predicate
<'tcx
>>> {
1461 if self.is_empty() {
1462 return Some(Slice
::empty());
1464 if tcx
.interners
.arena
.in_arena(*self as *const _
) {
1465 return Some(unsafe { mem::transmute(*self) }
);
1467 // Also try in the global tcx if we're not that.
1468 if !tcx
.is_global() {
1469 self.lift_to_tcx(tcx
.global_tcx())
1477 use super::{CtxtInterners, GlobalCtxt, TyCtxt}
;
1479 use std
::cell
::Cell
;
1483 /// Marker types used for the scoped TLS slot.
1484 /// The type context cannot be used directly because the scoped TLS
1485 /// in libstd doesn't allow types generic over lifetimes.
1486 enum ThreadLocalGlobalCtxt {}
1487 enum ThreadLocalInterners {}
1490 static TLS_TCX
: Cell
<Option
<(*const ThreadLocalGlobalCtxt
,
1491 *const ThreadLocalInterners
)>> = Cell
::new(None
)
1494 fn span_debug(span
: syntax_pos
::Span
, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1496 write
!(f
, "{}", tcx
.sess
.codemap().span_to_string(span
))
1500 pub fn enter_global
<'gcx
, F
, R
>(gcx
: GlobalCtxt
<'gcx
>, f
: F
) -> R
1501 where F
: for<'a
> FnOnce(TyCtxt
<'a
, 'gcx
, 'gcx
>) -> R
1503 syntax_pos
::SPAN_DEBUG
.with(|span_dbg
| {
1504 let original_span_debug
= span_dbg
.get();
1505 span_dbg
.set(span_debug
);
1506 let result
= enter(&gcx
, &gcx
.global_interners
, f
);
1507 span_dbg
.set(original_span_debug
);
1512 pub fn enter
<'a
, 'gcx
: 'tcx
, 'tcx
, F
, R
>(gcx
: &'a GlobalCtxt
<'gcx
>,
1513 interners
: &'a CtxtInterners
<'tcx
>,
1515 where F
: FnOnce(TyCtxt
<'a
, 'gcx
, 'tcx
>) -> R
1517 let gcx_ptr
= gcx
as *const _
as *const ThreadLocalGlobalCtxt
;
1518 let interners_ptr
= interners
as *const _
as *const ThreadLocalInterners
;
1519 TLS_TCX
.with(|tls
| {
1520 let prev
= tls
.get();
1521 tls
.set(Some((gcx_ptr
, interners_ptr
)));
1522 let ret
= f(TyCtxt
{
1531 pub fn with
<F
, R
>(f
: F
) -> R
1532 where F
: for<'a
, 'gcx
, 'tcx
> FnOnce(TyCtxt
<'a
, 'gcx
, 'tcx
>) -> R
1534 TLS_TCX
.with(|tcx
| {
1535 let (gcx
, interners
) = tcx
.get().unwrap();
1536 let gcx
= unsafe { &*(gcx as *const GlobalCtxt) }
;
1537 let interners
= unsafe { &*(interners as *const CtxtInterners) }
;
1545 pub fn with_opt
<F
, R
>(f
: F
) -> R
1546 where F
: for<'a
, 'gcx
, 'tcx
> FnOnce(Option
<TyCtxt
<'a
, 'gcx
, 'tcx
>>) -> R
1548 if TLS_TCX
.with(|tcx
| tcx
.get().is_some()) {
1549 with(|v
| f(Some(v
)))
1556 macro_rules
! sty_debug_print
{
1557 ($ctxt
: expr
, $
($variant
: ident
),*) => {{
1558 // curious inner module to allow variant names to be used as
1560 #[allow(non_snake_case)]
1562 use ty
::{self, TyCtxt}
;
1563 use ty
::context
::Interned
;
1565 #[derive(Copy, Clone)]
1568 region_infer
: usize,
1573 pub fn go(tcx
: TyCtxt
) {
1574 let mut total
= DebugStat
{
1576 region_infer
: 0, ty_infer
: 0, both_infer
: 0,
1578 $
(let mut $variant
= total
;)*
1581 for &Interned(t
) in tcx
.interners
.type_
.borrow().iter() {
1582 let variant
= match t
.sty
{
1583 ty
::TyBool
| ty
::TyChar
| ty
::TyInt(..) | ty
::TyUint(..) |
1584 ty
::TyFloat(..) | ty
::TyStr
| ty
::TyNever
=> continue,
1585 ty
::TyError
=> /* unimportant */ continue,
1586 $
(ty
::$
variant(..) => &mut $variant
,)*
1588 let region
= t
.flags
.intersects(ty
::TypeFlags
::HAS_RE_INFER
);
1589 let ty
= t
.flags
.intersects(ty
::TypeFlags
::HAS_TY_INFER
);
1593 if region { total.region_infer += 1; variant.region_infer += 1 }
1594 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1595 if region
&& ty { total.both_infer += 1; variant.both_infer += 1 }
1597 println
!("Ty interner total ty region both");
1598 $
(println
!(" {:18}: {uses:6} {usespc:4.1}%, \
1599 {ty:4.1}% {region:5.1}% {both:4.1}%",
1600 stringify
!($variant
),
1601 uses
= $variant
.total
,
1602 usespc
= $variant
.total
as f64 * 100.0 / total
.total
as f64,
1603 ty
= $variant
.ty_infer
as f64 * 100.0 / total
.total
as f64,
1604 region
= $variant
.region_infer
as f64 * 100.0 / total
.total
as f64,
1605 both
= $variant
.both_infer
as f64 * 100.0 / total
.total
as f64);
1607 println
!(" total {uses:6} \
1608 {ty:4.1}% {region:5.1}% {both:4.1}%",
1610 ty
= total
.ty_infer
as f64 * 100.0 / total
.total
as f64,
1611 region
= total
.region_infer
as f64 * 100.0 / total
.total
as f64,
1612 both
= total
.both_infer
as f64 * 100.0 / total
.total
as f64)
1620 impl<'a
, 'tcx
> TyCtxt
<'a
, 'tcx
, 'tcx
> {
1621 pub fn print_debug_stats(self) {
1624 TyAdt
, TyArray
, TySlice
, TyRawPtr
, TyRef
, TyFnDef
, TyFnPtr
, TyGenerator
, TyForeign
,
1625 TyDynamic
, TyClosure
, TyTuple
, TyParam
, TyInfer
, TyProjection
, TyAnon
);
1627 println
!("Substs interner: #{}", self.interners
.substs
.borrow().len());
1628 println
!("Region interner: #{}", self.interners
.region
.borrow().len());
1629 println
!("Stability interner: #{}", self.stability_interner
.borrow().len());
1630 println
!("Layout interner: #{}", self.layout_interner
.borrow().len());
1635 /// An entry in an interner.
1636 struct Interned
<'tcx
, T
: 'tcx
+?Sized
>(&'tcx T
);
1638 // NB: An Interned<Ty> compares and hashes as a sty.
1639 impl<'tcx
> PartialEq
for Interned
<'tcx
, TyS
<'tcx
>> {
1640 fn eq(&self, other
: &Interned
<'tcx
, TyS
<'tcx
>>) -> bool
{
1641 self.0.sty
== other
.0.sty
1645 impl<'tcx
> Eq
for Interned
<'tcx
, TyS
<'tcx
>> {}
1647 impl<'tcx
> Hash
for Interned
<'tcx
, TyS
<'tcx
>> {
1648 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1653 impl<'tcx
: 'lcx
, 'lcx
> Borrow
<TypeVariants
<'lcx
>> for Interned
<'tcx
, TyS
<'tcx
>> {
1654 fn borrow
<'a
>(&'a
self) -> &'a TypeVariants
<'lcx
> {
1659 // NB: An Interned<Slice<T>> compares and hashes as its elements.
1660 impl<'tcx
, T
: PartialEq
> PartialEq
for Interned
<'tcx
, Slice
<T
>> {
1661 fn eq(&self, other
: &Interned
<'tcx
, Slice
<T
>>) -> bool
{
1662 self.0[..] == other
.0[..]
1666 impl<'tcx
, T
: Eq
> Eq
for Interned
<'tcx
, Slice
<T
>> {}
1668 impl<'tcx
, T
: Hash
> Hash
for Interned
<'tcx
, Slice
<T
>> {
1669 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1674 impl<'tcx
: 'lcx
, 'lcx
> Borrow
<[Ty
<'lcx
>]> for Interned
<'tcx
, Slice
<Ty
<'tcx
>>> {
1675 fn borrow
<'a
>(&'a
self) -> &'a
[Ty
<'lcx
>] {
1680 impl<'tcx
: 'lcx
, 'lcx
> Borrow
<[Kind
<'lcx
>]> for Interned
<'tcx
, Substs
<'tcx
>> {
1681 fn borrow
<'a
>(&'a
self) -> &'a
[Kind
<'lcx
>] {
1686 impl<'tcx
> Borrow
<RegionKind
> for Interned
<'tcx
, RegionKind
> {
1687 fn borrow
<'a
>(&'a
self) -> &'a RegionKind
{
1692 impl<'tcx
: 'lcx
, 'lcx
> Borrow
<[ExistentialPredicate
<'lcx
>]>
1693 for Interned
<'tcx
, Slice
<ExistentialPredicate
<'tcx
>>> {
1694 fn borrow
<'a
>(&'a
self) -> &'a
[ExistentialPredicate
<'lcx
>] {
1699 impl<'tcx
: 'lcx
, 'lcx
> Borrow
<[Predicate
<'lcx
>]>
1700 for Interned
<'tcx
, Slice
<Predicate
<'tcx
>>> {
1701 fn borrow
<'a
>(&'a
self) -> &'a
[Predicate
<'lcx
>] {
1706 impl<'tcx
: 'lcx
, 'lcx
> Borrow
<Const
<'lcx
>> for Interned
<'tcx
, Const
<'tcx
>> {
1707 fn borrow
<'a
>(&'a
self) -> &'a Const
<'lcx
> {
1712 macro_rules
! intern_method
{
1713 ($lt_tcx
:tt
, $name
:ident
: $method
:ident($alloc
:ty
,
1714 $alloc_method
:ident
,
1717 $needs_infer
:expr
) -> $ty
:ty
) => {
1718 impl<'a
, 'gcx
, $lt_tcx
> TyCtxt
<'a
, 'gcx
, $lt_tcx
> {
1719 pub fn $
method(self, v
: $alloc
) -> &$lt_tcx $ty
{
1721 let key
= ($alloc_to_key
)(&v
);
1722 if let Some(i
) = self.interners
.$name
.borrow().get(key
) {
1725 if !self.is_global() {
1726 if let Some(i
) = self.global_interners
.$name
.borrow().get(key
) {
1732 // HACK(eddyb) Depend on flags being accurate to
1733 // determine that all contents are in the global tcx.
1734 // See comments on Lift for why we can't use that.
1735 if !($needs_infer
)(&v
) {
1736 if !self.is_global() {
1740 let i
= ($alloc_to_ret
)(self.global_interners
.arena
.$
alloc_method(v
));
1741 self.global_interners
.$name
.borrow_mut().insert(Interned(i
));
1745 // Make sure we don't end up with inference
1746 // types/regions in the global tcx.
1747 if self.is_global() {
1748 bug
!("Attempted to intern `{:?}` which contains \
1749 inference types/regions in the global type context",
1754 let i
= ($alloc_to_ret
)(self.interners
.arena
.$
alloc_method(v
));
1755 self.interners
.$name
.borrow_mut().insert(Interned(i
));
1762 macro_rules
! direct_interners
{
1763 ($lt_tcx
:tt
, $
($name
:ident
: $method
:ident($needs_infer
:expr
) -> $ty
:ty
),+) => {
1764 $
(impl<$lt_tcx
> PartialEq
for Interned
<$lt_tcx
, $ty
> {
1765 fn eq(&self, other
: &Self) -> bool
{
1770 impl<$lt_tcx
> Eq
for Interned
<$lt_tcx
, $ty
> {}
1772 impl<$lt_tcx
> Hash
for Interned
<$lt_tcx
, $ty
> {
1773 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1778 intern_method
!($lt_tcx
, $name
: $
method($ty
, alloc
, |x
| x
, |x
| x
, $needs_infer
) -> $ty
);)+
1782 pub fn keep_local
<'tcx
, T
: ty
::TypeFoldable
<'tcx
>>(x
: &T
) -> bool
{
1783 x
.has_type_flags(ty
::TypeFlags
::KEEP_IN_LOCAL_TCX
)
1786 direct_interners
!('tcx
,
1787 region
: mk_region(|r
| {
1789 &ty
::ReVar(_
) | &ty
::ReSkolemized(..) => true,
1793 const_
: mk_const(|c
: &Const
| keep_local(&c
.ty
) || keep_local(&c
.val
)) -> Const
<'tcx
>
1796 macro_rules
! slice_interners
{
1797 ($
($field
:ident
: $method
:ident($ty
:ident
)),+) => (
1798 $
(intern_method
!('tcx
, $field
: $
method(&[$ty
<'tcx
>], alloc_slice
, Deref
::deref
,
1799 |xs
: &[$ty
]| -> &Slice
<$ty
> {
1800 unsafe { mem::transmute(xs) }
1801 }, |xs
: &[$ty
]| xs
.iter().any(keep_local
)) -> Slice
<$ty
<'tcx
>>);)+
1806 existential_predicates
: _intern_existential_predicates(ExistentialPredicate
),
1807 predicates
: _intern_predicates(Predicate
),
1808 type_list
: _intern_type_list(Ty
),
1809 substs
: _intern_substs(Kind
)
1812 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
1813 /// Create an unsafe fn ty based on a safe fn ty.
1814 pub fn safe_to_unsafe_fn_ty(self, sig
: PolyFnSig
<'tcx
>) -> Ty
<'tcx
> {
1815 assert_eq
!(sig
.unsafety(), hir
::Unsafety
::Normal
);
1816 self.mk_fn_ptr(sig
.map_bound(|sig
| ty
::FnSig
{
1817 unsafety
: hir
::Unsafety
::Unsafe
,
1822 // Interns a type/name combination, stores the resulting box in cx.interners,
1823 // and returns the box as cast to an unsafe ptr (see comments for Ty above).
1824 pub fn mk_ty(self, st
: TypeVariants
<'tcx
>) -> Ty
<'tcx
> {
1825 let global_interners
= if !self.is_global() {
1826 Some(&self.global_interners
)
1830 self.interners
.intern_ty(st
, global_interners
)
1833 pub fn mk_mach_int(self, tm
: ast
::IntTy
) -> Ty
<'tcx
> {
1835 ast
::IntTy
::Is
=> self.types
.isize,
1836 ast
::IntTy
::I8
=> self.types
.i8,
1837 ast
::IntTy
::I16
=> self.types
.i16,
1838 ast
::IntTy
::I32
=> self.types
.i32,
1839 ast
::IntTy
::I64
=> self.types
.i64,
1840 ast
::IntTy
::I128
=> self.types
.i128
,
1844 pub fn mk_mach_uint(self, tm
: ast
::UintTy
) -> Ty
<'tcx
> {
1846 ast
::UintTy
::Us
=> self.types
.usize,
1847 ast
::UintTy
::U8
=> self.types
.u8,
1848 ast
::UintTy
::U16
=> self.types
.u16,
1849 ast
::UintTy
::U32
=> self.types
.u32,
1850 ast
::UintTy
::U64
=> self.types
.u64,
1851 ast
::UintTy
::U128
=> self.types
.u128
,
1855 pub fn mk_mach_float(self, tm
: ast
::FloatTy
) -> Ty
<'tcx
> {
1857 ast
::FloatTy
::F32
=> self.types
.f32,
1858 ast
::FloatTy
::F64
=> self.types
.f64,
1862 pub fn mk_str(self) -> Ty
<'tcx
> {
1866 pub fn mk_static_str(self) -> Ty
<'tcx
> {
1867 self.mk_imm_ref(self.types
.re_static
, self.mk_str())
1870 pub fn mk_adt(self, def
: &'tcx AdtDef
, substs
: &'tcx Substs
<'tcx
>) -> Ty
<'tcx
> {
1871 // take a copy of substs so that we own the vectors inside
1872 self.mk_ty(TyAdt(def
, substs
))
1875 pub fn mk_foreign(self, def_id
: DefId
) -> Ty
<'tcx
> {
1876 self.mk_ty(TyForeign(def_id
))
1879 pub fn mk_box(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1880 let def_id
= self.require_lang_item(lang_items
::OwnedBoxLangItem
);
1881 let adt_def
= self.adt_def(def_id
);
1882 let substs
= self.mk_substs(iter
::once(Kind
::from(ty
)));
1883 self.mk_ty(TyAdt(adt_def
, substs
))
1886 pub fn mk_ptr(self, tm
: TypeAndMut
<'tcx
>) -> Ty
<'tcx
> {
1887 self.mk_ty(TyRawPtr(tm
))
1890 pub fn mk_ref(self, r
: Region
<'tcx
>, tm
: TypeAndMut
<'tcx
>) -> Ty
<'tcx
> {
1891 self.mk_ty(TyRef(r
, tm
))
1894 pub fn mk_mut_ref(self, r
: Region
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1895 self.mk_ref(r
, TypeAndMut {ty: ty, mutbl: hir::MutMutable}
)
1898 pub fn mk_imm_ref(self, r
: Region
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1899 self.mk_ref(r
, TypeAndMut {ty: ty, mutbl: hir::MutImmutable}
)
1902 pub fn mk_mut_ptr(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1903 self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutMutable}
)
1906 pub fn mk_imm_ptr(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1907 self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutImmutable}
)
1910 pub fn mk_nil_ptr(self) -> Ty
<'tcx
> {
1911 self.mk_imm_ptr(self.mk_nil())
1914 pub fn mk_array(self, ty
: Ty
<'tcx
>, n
: u64) -> Ty
<'tcx
> {
1915 let n
= ConstUsize
::new(n
, self.sess
.target
.usize_ty
).unwrap();
1916 self.mk_array_const_usize(ty
, n
)
1919 pub fn mk_array_const_usize(self, ty
: Ty
<'tcx
>, n
: ConstUsize
) -> Ty
<'tcx
> {
1920 self.mk_ty(TyArray(ty
, self.mk_const(ty
::Const
{
1921 val
: ConstVal
::Integral(ConstInt
::Usize(n
)),
1922 ty
: self.types
.usize
1926 pub fn mk_slice(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
1927 self.mk_ty(TySlice(ty
))
1930 pub fn intern_tup(self, ts
: &[Ty
<'tcx
>], defaulted
: bool
) -> Ty
<'tcx
> {
1931 self.mk_ty(TyTuple(self.intern_type_list(ts
), defaulted
))
1934 pub fn mk_tup
<I
: InternAs
<[Ty
<'tcx
>], Ty
<'tcx
>>>(self, iter
: I
,
1935 defaulted
: bool
) -> I
::Output
{
1936 iter
.intern_with(|ts
| self.mk_ty(TyTuple(self.intern_type_list(ts
), defaulted
)))
1939 pub fn mk_nil(self) -> Ty
<'tcx
> {
1940 self.intern_tup(&[], false)
1943 pub fn mk_diverging_default(self) -> Ty
<'tcx
> {
1944 if self.sess
.features
.borrow().never_type
{
1947 self.intern_tup(&[], true)
1951 pub fn mk_bool(self) -> Ty
<'tcx
> {
1955 pub fn mk_fn_def(self, def_id
: DefId
,
1956 substs
: &'tcx Substs
<'tcx
>) -> Ty
<'tcx
> {
1957 self.mk_ty(TyFnDef(def_id
, substs
))
1960 pub fn mk_fn_ptr(self, fty
: PolyFnSig
<'tcx
>) -> Ty
<'tcx
> {
1961 self.mk_ty(TyFnPtr(fty
))
1966 obj
: ty
::Binder
<&'tcx Slice
<ExistentialPredicate
<'tcx
>>>,
1967 reg
: ty
::Region
<'tcx
>
1969 self.mk_ty(TyDynamic(obj
, reg
))
1972 pub fn mk_projection(self,
1974 substs
: &'tcx Substs
<'tcx
>)
1976 self.mk_ty(TyProjection(ProjectionTy
{
1982 pub fn mk_closure(self,
1984 substs
: &'tcx Substs
<'tcx
>)
1986 self.mk_closure_from_closure_substs(closure_id
, ClosureSubsts
{
1991 pub fn mk_closure_from_closure_substs(self,
1993 closure_substs
: ClosureSubsts
<'tcx
>)
1995 self.mk_ty(TyClosure(closure_id
, closure_substs
))
1998 pub fn mk_generator(self,
2000 closure_substs
: ClosureSubsts
<'tcx
>,
2001 interior
: GeneratorInterior
<'tcx
>)
2003 self.mk_ty(TyGenerator(id
, closure_substs
, interior
))
2006 pub fn mk_var(self, v
: TyVid
) -> Ty
<'tcx
> {
2007 self.mk_infer(TyVar(v
))
2010 pub fn mk_int_var(self, v
: IntVid
) -> Ty
<'tcx
> {
2011 self.mk_infer(IntVar(v
))
2014 pub fn mk_float_var(self, v
: FloatVid
) -> Ty
<'tcx
> {
2015 self.mk_infer(FloatVar(v
))
2018 pub fn mk_infer(self, it
: InferTy
) -> Ty
<'tcx
> {
2019 self.mk_ty(TyInfer(it
))
2022 pub fn mk_param(self,
2024 name
: Name
) -> Ty
<'tcx
> {
2025 self.mk_ty(TyParam(ParamTy { idx: index, name: name }
))
2028 pub fn mk_self_type(self) -> Ty
<'tcx
> {
2029 self.mk_param(0, keywords
::SelfType
.name())
2032 pub fn mk_param_from_def(self, def
: &ty
::TypeParameterDef
) -> Ty
<'tcx
> {
2033 self.mk_param(def
.index
, def
.name
)
2036 pub fn mk_anon(self, def_id
: DefId
, substs
: &'tcx Substs
<'tcx
>) -> Ty
<'tcx
> {
2037 self.mk_ty(TyAnon(def_id
, substs
))
2040 pub fn intern_existential_predicates(self, eps
: &[ExistentialPredicate
<'tcx
>])
2041 -> &'tcx Slice
<ExistentialPredicate
<'tcx
>> {
2042 assert
!(!eps
.is_empty());
2043 assert
!(eps
.windows(2).all(|w
| w
[0].cmp(self, &w
[1]) != Ordering
::Greater
));
2044 self._intern_existential_predicates(eps
)
2047 pub fn intern_predicates(self, preds
: &[Predicate
<'tcx
>])
2048 -> &'tcx Slice
<Predicate
<'tcx
>> {
2049 // FIXME consider asking the input slice to be sorted to avoid
2050 // re-interning permutations, in which case that would be asserted
2052 if preds
.len() == 0 {
2053 // The macro-generated method below asserts we don't intern an empty slice.
2056 self._intern_predicates(preds
)
2060 pub fn intern_type_list(self, ts
: &[Ty
<'tcx
>]) -> &'tcx Slice
<Ty
<'tcx
>> {
2064 self._intern_type_list(ts
)
2068 pub fn intern_substs(self, ts
: &[Kind
<'tcx
>]) -> &'tcx Slice
<Kind
<'tcx
>> {
2072 self._intern_substs(ts
)
2076 pub fn mk_fn_sig
<I
>(self,
2080 unsafety
: hir
::Unsafety
,
2082 -> <I
::Item
as InternIteratorElement
<Ty
<'tcx
>, ty
::FnSig
<'tcx
>>>::Output
2084 I
::Item
: InternIteratorElement
<Ty
<'tcx
>, ty
::FnSig
<'tcx
>>
2086 inputs
.chain(iter
::once(output
)).intern_with(|xs
| ty
::FnSig
{
2087 inputs_and_output
: self.intern_type_list(xs
),
2088 variadic
, unsafety
, abi
2092 pub fn mk_existential_predicates
<I
: InternAs
<[ExistentialPredicate
<'tcx
>],
2093 &'tcx Slice
<ExistentialPredicate
<'tcx
>>>>(self, iter
: I
)
2095 iter
.intern_with(|xs
| self.intern_existential_predicates(xs
))
2098 pub fn mk_predicates
<I
: InternAs
<[Predicate
<'tcx
>],
2099 &'tcx Slice
<Predicate
<'tcx
>>>>(self, iter
: I
)
2101 iter
.intern_with(|xs
| self.intern_predicates(xs
))
2104 pub fn mk_type_list
<I
: InternAs
<[Ty
<'tcx
>],
2105 &'tcx Slice
<Ty
<'tcx
>>>>(self, iter
: I
) -> I
::Output
{
2106 iter
.intern_with(|xs
| self.intern_type_list(xs
))
2109 pub fn mk_substs
<I
: InternAs
<[Kind
<'tcx
>],
2110 &'tcx Slice
<Kind
<'tcx
>>>>(self, iter
: I
) -> I
::Output
{
2111 iter
.intern_with(|xs
| self.intern_substs(xs
))
2114 pub fn mk_substs_trait(self,
2117 -> &'tcx Substs
<'tcx
>
2119 self.mk_substs(iter
::once(s
).chain(t
.into_iter().cloned()).map(Kind
::from
))
2122 pub fn lint_node
<S
: Into
<MultiSpan
>>(self,
2123 lint
: &'
static Lint
,
2127 self.struct_span_lint_node(lint
, id
, span
.into(), msg
).emit()
2130 pub fn lint_node_note
<S
: Into
<MultiSpan
>>(self,
2131 lint
: &'
static Lint
,
2136 let mut err
= self.struct_span_lint_node(lint
, id
, span
.into(), msg
);
2141 pub fn lint_level_at_node(self, lint
: &'
static Lint
, mut id
: NodeId
)
2142 -> (lint
::Level
, lint
::LintSource
)
2144 // Right now we insert a `with_ignore` node in the dep graph here to
2145 // ignore the fact that `lint_levels` below depends on the entire crate.
2146 // For now this'll prevent false positives of recompiling too much when
2147 // anything changes.
2149 // Once red/green incremental compilation lands we should be able to
2150 // remove this because while the crate changes often the lint level map
2151 // will change rarely.
2152 self.dep_graph
.with_ignore(|| {
2153 let sets
= self.lint_levels(LOCAL_CRATE
);
2155 let hir_id
= self.hir
.definitions().node_to_hir_id(id
);
2156 if let Some(pair
) = sets
.level_and_source(lint
, hir_id
) {
2159 let next
= self.hir
.get_parent_node(id
);
2161 bug
!("lint traversal reached the root of the crate");
2168 pub fn struct_span_lint_node
<S
: Into
<MultiSpan
>>(self,
2169 lint
: &'
static Lint
,
2173 -> DiagnosticBuilder
<'tcx
>
2175 let (level
, src
) = self.lint_level_at_node(lint
, id
);
2176 lint
::struct_lint_level(self.sess
, lint
, level
, src
, Some(span
.into()), msg
)
2179 pub fn struct_lint_node(self, lint
: &'
static Lint
, id
: NodeId
, msg
: &str)
2180 -> DiagnosticBuilder
<'tcx
>
2182 let (level
, src
) = self.lint_level_at_node(lint
, id
);
2183 lint
::struct_lint_level(self.sess
, lint
, level
, src
, None
, msg
)
2186 pub fn in_scope_traits(self, id
: HirId
) -> Option
<Rc
<StableVec
<TraitCandidate
>>> {
2187 self.in_scope_traits_map(id
.owner
)
2188 .and_then(|map
| map
.get(&id
.local_id
).cloned())
2191 pub fn named_region(self, id
: HirId
) -> Option
<resolve_lifetime
::Region
> {
2192 self.named_region_map(id
.owner
)
2193 .and_then(|map
| map
.get(&id
.local_id
).cloned())
2196 pub fn is_late_bound(self, id
: HirId
) -> bool
{
2197 self.is_late_bound_map(id
.owner
)
2198 .map(|set
| set
.contains(&id
.local_id
))
2202 pub fn object_lifetime_defaults(self, id
: HirId
)
2203 -> Option
<Rc
<Vec
<ObjectLifetimeDefault
>>>
2205 self.object_lifetime_defaults_map(id
.owner
)
2206 .and_then(|map
| map
.get(&id
.local_id
).cloned())
2210 pub trait InternAs
<T
: ?Sized
, R
> {
2212 fn intern_with
<F
>(self, f
: F
) -> Self::Output
2213 where F
: FnOnce(&T
) -> R
;
2216 impl<I
, T
, R
, E
> InternAs
<[T
], R
> for I
2217 where E
: InternIteratorElement
<T
, R
>,
2218 I
: Iterator
<Item
=E
> {
2219 type Output
= E
::Output
;
2220 fn intern_with
<F
>(self, f
: F
) -> Self::Output
2221 where F
: FnOnce(&[T
]) -> R
{
2222 E
::intern_with(self, f
)
2226 pub trait InternIteratorElement
<T
, R
>: Sized
{
2228 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
;
2231 impl<T
, R
> InternIteratorElement
<T
, R
> for T
{
2233 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
{
2234 f(&iter
.collect
::<AccumulateVec
<[_
; 8]>>())
2238 impl<'a
, T
, R
> InternIteratorElement
<T
, R
> for &'a T
2242 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
{
2243 f(&iter
.cloned().collect
::<AccumulateVec
<[_
; 8]>>())
2247 impl<T
, R
, E
> InternIteratorElement
<T
, R
> for Result
<T
, E
> {
2248 type Output
= Result
<R
, E
>;
2249 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
{
2250 Ok(f(&iter
.collect
::<Result
<AccumulateVec
<[_
; 8]>, _
>>()?
))
2254 struct NamedRegionMap
{
2255 defs
: FxHashMap
<DefIndex
, Rc
<FxHashMap
<ItemLocalId
, resolve_lifetime
::Region
>>>,
2256 late_bound
: FxHashMap
<DefIndex
, Rc
<FxHashSet
<ItemLocalId
>>>,
2257 object_lifetime_defaults
:
2260 Rc
<FxHashMap
<ItemLocalId
, Rc
<Vec
<ObjectLifetimeDefault
>>>>,
2264 pub fn provide(providers
: &mut ty
::maps
::Providers
) {
2265 // FIXME(#44234) - almost all of these queries have no sub-queries and
2266 // therefore no actual inputs, they're just reading tables calculated in
2267 // resolve! Does this work? Unsure! That's what the issue is about
2268 providers
.in_scope_traits_map
= |tcx
, id
| tcx
.gcx
.trait_map
.get(&id
).cloned();
2269 providers
.module_exports
= |tcx
, id
| tcx
.gcx
.export_map
.get(&id
).cloned();
2270 providers
.named_region_map
= |tcx
, id
| tcx
.gcx
.named_region_map
.defs
.get(&id
).cloned();
2271 providers
.is_late_bound_map
= |tcx
, id
| tcx
.gcx
.named_region_map
.late_bound
.get(&id
).cloned();
2272 providers
.object_lifetime_defaults_map
= |tcx
, id
| {
2273 tcx
.gcx
.named_region_map
.object_lifetime_defaults
.get(&id
).cloned()
2275 providers
.crate_name
= |tcx
, id
| {
2276 assert_eq
!(id
, LOCAL_CRATE
);
2279 providers
.get_lang_items
= |tcx
, id
| {
2280 assert_eq
!(id
, LOCAL_CRATE
);
2281 // FIXME(#42293) Right now we insert a `with_ignore` node in the dep
2282 // graph here to ignore the fact that `get_lang_items` below depends on
2283 // the entire crate. For now this'll prevent false positives of
2284 // recompiling too much when anything changes.
2286 // Once red/green incremental compilation lands we should be able to
2287 // remove this because while the crate changes often the lint level map
2288 // will change rarely.
2289 tcx
.dep_graph
.with_ignore(|| Rc
::new(middle
::lang_items
::collect(tcx
)))
2291 providers
.freevars
= |tcx
, id
| tcx
.gcx
.freevars
.get(&id
).cloned();
2292 providers
.maybe_unused_trait_import
= |tcx
, id
| {
2293 tcx
.maybe_unused_trait_imports
.contains(&id
)
2295 providers
.maybe_unused_extern_crates
= |tcx
, cnum
| {
2296 assert_eq
!(cnum
, LOCAL_CRATE
);
2297 Rc
::new(tcx
.maybe_unused_extern_crates
.clone())
2300 providers
.stability_index
= |tcx
, cnum
| {
2301 assert_eq
!(cnum
, LOCAL_CRATE
);
2302 Rc
::new(stability
::Index
::new(tcx
))
2304 providers
.lookup_stability
= |tcx
, id
| {
2305 assert_eq
!(id
.krate
, LOCAL_CRATE
);
2306 let id
= tcx
.hir
.definitions().def_index_to_hir_id(id
.index
);
2307 tcx
.stability().local_stability(id
)
2309 providers
.lookup_deprecation_entry
= |tcx
, id
| {
2310 assert_eq
!(id
.krate
, LOCAL_CRATE
);
2311 let id
= tcx
.hir
.definitions().def_index_to_hir_id(id
.index
);
2312 tcx
.stability().local_deprecation_entry(id
)
2314 providers
.extern_mod_stmt_cnum
= |tcx
, id
| {
2315 let id
= tcx
.hir
.as_local_node_id(id
).unwrap();
2316 tcx
.cstore
.extern_mod_stmt_cnum_untracked(id
)
2318 providers
.all_crate_nums
= |tcx
, cnum
| {
2319 assert_eq
!(cnum
, LOCAL_CRATE
);
2320 Rc
::new(tcx
.cstore
.crates_untracked())
2322 providers
.postorder_cnums
= |tcx
, cnum
| {
2323 assert_eq
!(cnum
, LOCAL_CRATE
);
2324 Rc
::new(tcx
.cstore
.postorder_cnums_untracked())
2326 providers
.output_filenames
= |tcx
, cnum
| {
2327 assert_eq
!(cnum
, LOCAL_CRATE
);
2328 tcx
.output_filenames
.clone()
2330 providers
.has_copy_closures
= |tcx
, cnum
| {
2331 assert_eq
!(cnum
, LOCAL_CRATE
);
2332 tcx
.sess
.features
.borrow().copy_closures
2334 providers
.has_clone_closures
= |tcx
, cnum
| {
2335 assert_eq
!(cnum
, LOCAL_CRATE
);
2336 tcx
.sess
.features
.borrow().clone_closures
2338 providers
.fully_normalize_monormophic_ty
= |tcx
, ty
| {
2339 tcx
.fully_normalize_associated_types_in(&ty
)