1 //! Type context book-keeping.
3 use crate::arena
::Arena
;
4 use crate::dep_graph
::DepGraph
;
5 use crate::dep_graph
::{self, DepNode, DepConstructor}
;
6 use crate::session
::Session
;
7 use crate::session
::config
::{BorrowckMode, OutputFilenames}
;
8 use crate::session
::config
::CrateType
;
10 use crate::hir
::{TraitCandidate, HirId, ItemKind, ItemLocalId, Node}
;
11 use crate::hir
::def
::{Res, DefKind, Export}
;
12 use crate::hir
::def_id
::{CrateNum, DefId, DefIndex, LOCAL_CRATE}
;
13 use crate::hir
::map
as hir_map
;
14 use crate::hir
::map
::DefPathHash
;
15 use crate::lint
::{self, Lint}
;
16 use crate::ich
::{StableHashingContext, NodeIdHashingMode}
;
17 use crate::infer
::canonical
::{Canonical, CanonicalVarInfo, CanonicalVarInfos}
;
18 use crate::infer
::outlives
::free_region_map
::FreeRegionMap
;
19 use crate::middle
::cstore
::CrateStoreDyn
;
20 use crate::middle
::cstore
::EncodedMetadata
;
21 use crate::middle
::lang_items
;
22 use crate::middle
::resolve_lifetime
::{self, ObjectLifetimeDefault}
;
23 use crate::middle
::stability
;
24 use crate::mir
::{Body, interpret, ProjectionKind}
;
25 use crate::mir
::interpret
::{ConstValue, Allocation, Scalar}
;
26 use crate::ty
::subst
::{Kind, InternalSubsts, SubstsRef, Subst}
;
27 use crate::ty
::ReprOptions
;
29 use crate::traits
::{Clause, Clauses, GoalKind, Goal, Goals}
;
30 use crate::ty
::{self, DefIdTree, Ty, TypeAndMut}
;
31 use crate::ty
::{TyS, TyKind, List}
;
32 use crate::ty
::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const}
;
33 use crate::ty
::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate}
;
34 use crate::ty
::RegionKind
;
35 use crate::ty
::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid, ConstVid}
;
36 use crate::ty
::TyKind
::*;
37 use crate::ty
::{InferConst, ParamConst}
;
38 use crate::ty
::GenericParamDefKind
;
39 use crate::ty
::layout
::{LayoutDetails, TargetDataLayout, VariantIdx}
;
41 use crate::ty
::steal
::Steal
;
42 use crate::ty
::subst
::{UserSubsts, UnpackedKind}
;
43 use crate::ty
::{BoundVar, BindingMode}
;
44 use crate::ty
::CanonicalPolyFnSig
;
45 use crate::util
::common
::ErrorReported
;
46 use crate::util
::nodemap
::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet}
;
47 use crate::util
::nodemap
::{FxHashMap, FxHashSet}
;
48 use errors
::DiagnosticBuilder
;
49 use smallvec
::SmallVec
;
50 use rustc_data_structures
::stable_hasher
::{HashStable
, hash_stable_hashmap
,
51 StableHasher
, StableHasherResult
,
53 use arena
::SyncDroplessArena
;
54 use rustc_data_structures
::indexed_vec
::{Idx, IndexVec}
;
55 use rustc_data_structures
::sync
::{Lrc, Lock, WorkerLocal}
;
56 use rustc_data_structures
::sharded
::ShardedHashMap
;
58 use std
::borrow
::Borrow
;
59 use std
::cmp
::Ordering
;
60 use std
::collections
::hash_map
::{self, Entry}
;
61 use std
::hash
::{Hash, Hasher}
;
64 use std
::ops
::{Deref, Bound}
;
68 use rustc_target
::spec
::abi
;
69 use rustc_macros
::HashStable
;
72 use syntax
::source_map
::MultiSpan
;
73 use syntax
::feature_gate
;
74 use syntax
::symbol
::{Symbol, InternedString, kw, sym}
;
79 pub struct AllArenas
{
80 pub interner
: SyncDroplessArena
,
84 pub fn new() -> Self {
86 interner
: SyncDroplessArena
::default(),
91 type InternedSet
<'tcx
, T
> = ShardedHashMap
<Interned
<'tcx
, T
>, ()>;
93 pub struct CtxtInterners
<'tcx
> {
94 /// The arena that types, regions, etc are allocated from
95 arena
: &'tcx SyncDroplessArena
,
97 /// Specifically use a speedy hash algorithm for these hash sets,
98 /// they're accessed quite often.
99 type_
: InternedSet
<'tcx
, TyS
<'tcx
>>,
100 type_list
: InternedSet
<'tcx
, List
<Ty
<'tcx
>>>,
101 substs
: InternedSet
<'tcx
, InternalSubsts
<'tcx
>>,
102 canonical_var_infos
: InternedSet
<'tcx
, List
<CanonicalVarInfo
>>,
103 region
: InternedSet
<'tcx
, RegionKind
>,
104 existential_predicates
: InternedSet
<'tcx
, List
<ExistentialPredicate
<'tcx
>>>,
105 predicates
: InternedSet
<'tcx
, List
<Predicate
<'tcx
>>>,
106 clauses
: InternedSet
<'tcx
, List
<Clause
<'tcx
>>>,
107 goal
: InternedSet
<'tcx
, GoalKind
<'tcx
>>,
108 goal_list
: InternedSet
<'tcx
, List
<Goal
<'tcx
>>>,
109 projs
: InternedSet
<'tcx
, List
<ProjectionKind
>>,
110 const_
: InternedSet
<'tcx
, Const
<'tcx
>>,
113 impl<'tcx
> CtxtInterners
<'tcx
> {
114 fn new(arena
: &'tcx SyncDroplessArena
) -> CtxtInterners
<'tcx
> {
117 type_
: Default
::default(),
118 type_list
: Default
::default(),
119 substs
: Default
::default(),
120 region
: Default
::default(),
121 existential_predicates
: Default
::default(),
122 canonical_var_infos
: Default
::default(),
123 predicates
: Default
::default(),
124 clauses
: Default
::default(),
125 goal
: Default
::default(),
126 goal_list
: Default
::default(),
127 projs
: Default
::default(),
128 const_
: Default
::default(),
133 #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
138 self.type_
.intern(st
, |st
| {
139 let flags
= super::flags
::FlagComputation
::for_sty(&st
);
141 let ty_struct
= TyS
{
144 outer_exclusive_binder
: flags
.outer_exclusive_binder
,
148 Interned(self.arena
.alloc(ty_struct
))
153 pub struct Common
<'tcx
> {
154 pub empty_predicates
: ty
::GenericPredicates
<'tcx
>,
157 pub struct CommonTypes
<'tcx
> {
178 /// Dummy type used for the `Self` of a `TraitRef` created for converting
179 /// a trait object, and which gets removed in `ExistentialTraitRef`.
180 /// This type must not appear anywhere in other converted types.
181 pub trait_object_dummy_self
: Ty
<'tcx
>,
184 pub struct CommonLifetimes
<'tcx
> {
185 pub re_empty
: Region
<'tcx
>,
186 pub re_static
: Region
<'tcx
>,
187 pub re_erased
: Region
<'tcx
>,
190 pub struct CommonConsts
<'tcx
> {
191 pub err
: &'tcx Const
<'tcx
>,
194 pub struct LocalTableInContext
<'a
, V
> {
195 local_id_root
: Option
<DefId
>,
196 data
: &'a ItemLocalMap
<V
>
199 /// Validate that the given HirId (respectively its `local_id` part) can be
200 /// safely used as a key in the tables of a TypeckTable. For that to be
201 /// the case, the HirId must have the same `owner` as all the other IDs in
202 /// this table (signified by `local_id_root`). Otherwise the HirId
203 /// would be in a different frame of reference and using its `local_id`
204 /// would result in lookup errors, or worse, in silently wrong data being
206 fn validate_hir_id_for_typeck_tables(local_id_root
: Option
<DefId
>,
209 if cfg
!(debug_assertions
) {
210 if let Some(local_id_root
) = local_id_root
{
211 if hir_id
.owner
!= local_id_root
.index
{
212 ty
::tls
::with(|tcx
| {
213 bug
!("node {} with HirId::owner {:?} cannot be placed in \
214 TypeckTables with local_id_root {:?}",
215 tcx
.hir().node_to_string(hir_id
),
216 DefId
::local(hir_id
.owner
),
221 // We use "Null Object" TypeckTables in some of the analysis passes.
222 // These are just expected to be empty and their `local_id_root` is
223 // `None`. Therefore we cannot verify whether a given `HirId` would
224 // be a valid key for the given table. Instead we make sure that
225 // nobody tries to write to such a Null Object table.
227 bug
!("access to invalid TypeckTables")
233 impl<'a
, V
> LocalTableInContext
<'a
, V
> {
234 pub fn contains_key(&self, id
: hir
::HirId
) -> bool
{
235 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
236 self.data
.contains_key(&id
.local_id
)
239 pub fn get(&self, id
: hir
::HirId
) -> Option
<&V
> {
240 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
241 self.data
.get(&id
.local_id
)
244 pub fn iter(&self) -> hash_map
::Iter
<'_
, hir
::ItemLocalId
, V
> {
249 impl<'a
, V
> ::std
::ops
::Index
<hir
::HirId
> for LocalTableInContext
<'a
, V
> {
252 fn index(&self, key
: hir
::HirId
) -> &V
{
253 self.get(key
).expect("LocalTableInContext: key not found")
257 pub struct LocalTableInContextMut
<'a
, V
> {
258 local_id_root
: Option
<DefId
>,
259 data
: &'a
mut ItemLocalMap
<V
>
262 impl<'a
, V
> LocalTableInContextMut
<'a
, V
> {
263 pub fn get_mut(&mut self, id
: hir
::HirId
) -> Option
<&mut V
> {
264 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
265 self.data
.get_mut(&id
.local_id
)
268 pub fn entry(&mut self, id
: hir
::HirId
) -> Entry
<'_
, hir
::ItemLocalId
, V
> {
269 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
270 self.data
.entry(id
.local_id
)
273 pub fn insert(&mut self, id
: hir
::HirId
, val
: V
) -> Option
<V
> {
274 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
275 self.data
.insert(id
.local_id
, val
)
278 pub fn remove(&mut self, id
: hir
::HirId
) -> Option
<V
> {
279 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
280 self.data
.remove(&id
.local_id
)
284 /// All information necessary to validate and reveal an `impl Trait`.
285 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
286 pub struct ResolvedOpaqueTy
<'tcx
> {
287 /// The revealed type as seen by this function.
288 pub concrete_type
: Ty
<'tcx
>,
289 /// Generic parameters on the opaque type as passed by this function.
290 /// For `type Foo<A, B> = impl Bar<A, B>; fn foo<T, U>() -> Foo<T, U> { .. }`
291 /// this is `[T, U]`, not `[A, B]`.
292 pub substs
: SubstsRef
<'tcx
>,
295 #[derive(RustcEncodable, RustcDecodable, Debug)]
296 pub struct TypeckTables
<'tcx
> {
297 /// The HirId::owner all ItemLocalIds in this table are relative to.
298 pub local_id_root
: Option
<DefId
>,
300 /// Resolved definitions for `<T>::X` associated paths and
301 /// method calls, including those of overloaded operators.
302 type_dependent_defs
: ItemLocalMap
<Result
<(DefKind
, DefId
), ErrorReported
>>,
304 /// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
305 /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
306 /// about the field you also need definition of the variant to which the field
307 /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
308 field_indices
: ItemLocalMap
<usize>,
310 /// Stores the types for various nodes in the AST. Note that this table
311 /// is not guaranteed to be populated until after typeck. See
312 /// typeck::check::fn_ctxt for details.
313 node_types
: ItemLocalMap
<Ty
<'tcx
>>,
315 /// Stores the type parameters which were substituted to obtain the type
316 /// of this node. This only applies to nodes that refer to entities
317 /// parameterized by type parameters, such as generic fns, types, or
319 node_substs
: ItemLocalMap
<SubstsRef
<'tcx
>>,
321 /// This will either store the canonicalized types provided by the user
322 /// or the substitutions that the user explicitly gave (if any) attached
323 /// to `id`. These will not include any inferred values. The canonical form
324 /// is used to capture things like `_` or other unspecified values.
326 /// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
327 /// canonical substitutions would include only `for<X> { Vec<X> }`.
329 /// See also `AscribeUserType` statement in MIR.
330 user_provided_types
: ItemLocalMap
<CanonicalUserType
<'tcx
>>,
332 /// Stores the canonicalized types provided by the user. See also
333 /// `AscribeUserType` statement in MIR.
334 pub user_provided_sigs
: DefIdMap
<CanonicalPolyFnSig
<'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 reasons that we picked the kind of each closure;
360 /// not all closures are present in the map.
361 closure_kind_origins
: ItemLocalMap
<(Span
, ast
::Name
)>,
363 /// For each fn, records the "liberated" types of its arguments
364 /// and return type. Liberated means that all bound regions
365 /// (including late-bound regions) are replaced with free
366 /// equivalents. This table is not used in codegen (since regions
367 /// are erased there) and hence is not serialized to metadata.
368 liberated_fn_sigs
: ItemLocalMap
<ty
::FnSig
<'tcx
>>,
370 /// For each FRU expression, record the normalized types of the fields
371 /// of the struct - this is needed because it is non-trivial to
372 /// normalize while preserving regions. This table is used only in
373 /// MIR construction and hence is not serialized to metadata.
374 fru_field_types
: ItemLocalMap
<Vec
<Ty
<'tcx
>>>,
376 /// For every coercion cast we add the HIR node ID of the cast
377 /// expression to this set.
378 coercion_casts
: ItemLocalSet
,
380 /// Set of trait imports actually used in the method resolution.
381 /// This is used for warning unused imports. During type
382 /// checking, this `Lrc` should not be cloned: it must have a ref-count
383 /// of 1 so that we can insert things into the set mutably.
384 pub used_trait_imports
: Lrc
<DefIdSet
>,
386 /// If any errors occurred while type-checking this body,
387 /// this field will be set to `true`.
388 pub tainted_by_errors
: bool
,
390 /// Stores the free-region relationships that were deduced from
391 /// its where-clauses and parameter types. These are then
392 /// read-again by borrowck.
393 pub free_region_map
: FreeRegionMap
<'tcx
>,
395 /// All the opaque types that are restricted to concrete types
396 /// by this function.
397 pub concrete_opaque_types
: FxHashMap
<DefId
, ResolvedOpaqueTy
<'tcx
>>,
399 /// Given the closure ID this map provides the list of UpvarIDs used by it.
400 /// The upvarID contains the HIR node ID and it also contains the full path
401 /// leading to the member of the struct or tuple that is used instead of the
403 pub upvar_list
: ty
::UpvarListMap
,
406 impl<'tcx
> TypeckTables
<'tcx
> {
407 pub fn empty(local_id_root
: Option
<DefId
>) -> TypeckTables
<'tcx
> {
410 type_dependent_defs
: Default
::default(),
411 field_indices
: Default
::default(),
412 user_provided_types
: Default
::default(),
413 user_provided_sigs
: Default
::default(),
414 node_types
: Default
::default(),
415 node_substs
: Default
::default(),
416 adjustments
: Default
::default(),
417 pat_binding_modes
: Default
::default(),
418 pat_adjustments
: Default
::default(),
419 upvar_capture_map
: Default
::default(),
420 closure_kind_origins
: Default
::default(),
421 liberated_fn_sigs
: Default
::default(),
422 fru_field_types
: Default
::default(),
423 coercion_casts
: Default
::default(),
424 used_trait_imports
: Lrc
::new(Default
::default()),
425 tainted_by_errors
: false,
426 free_region_map
: Default
::default(),
427 concrete_opaque_types
: Default
::default(),
428 upvar_list
: Default
::default(),
432 /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
433 pub fn qpath_res(&self, qpath
: &hir
::QPath
, id
: hir
::HirId
) -> Res
{
435 hir
::QPath
::Resolved(_
, ref path
) => path
.res
,
436 hir
::QPath
::TypeRelative(..) => self.type_dependent_def(id
)
437 .map_or(Res
::Err
, |(kind
, def_id
)| Res
::Def(kind
, def_id
)),
441 pub fn type_dependent_defs(
443 ) -> LocalTableInContext
<'_
, Result
<(DefKind
, DefId
), ErrorReported
>> {
444 LocalTableInContext
{
445 local_id_root
: self.local_id_root
,
446 data
: &self.type_dependent_defs
450 pub fn type_dependent_def(&self, id
: HirId
) -> Option
<(DefKind
, DefId
)> {
451 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
452 self.type_dependent_defs
.get(&id
.local_id
).cloned().and_then(|r
| r
.ok())
455 pub fn type_dependent_def_id(&self, id
: HirId
) -> Option
<DefId
> {
456 self.type_dependent_def(id
).map(|(_
, def_id
)| def_id
)
459 pub fn type_dependent_defs_mut(
461 ) -> LocalTableInContextMut
<'_
, Result
<(DefKind
, DefId
), ErrorReported
>> {
462 LocalTableInContextMut
{
463 local_id_root
: self.local_id_root
,
464 data
: &mut self.type_dependent_defs
468 pub fn field_indices(&self) -> LocalTableInContext
<'_
, usize> {
469 LocalTableInContext
{
470 local_id_root
: self.local_id_root
,
471 data
: &self.field_indices
475 pub fn field_indices_mut(&mut self) -> LocalTableInContextMut
<'_
, usize> {
476 LocalTableInContextMut
{
477 local_id_root
: self.local_id_root
,
478 data
: &mut self.field_indices
482 pub fn user_provided_types(
484 ) -> LocalTableInContext
<'_
, CanonicalUserType
<'tcx
>> {
485 LocalTableInContext
{
486 local_id_root
: self.local_id_root
,
487 data
: &self.user_provided_types
491 pub fn user_provided_types_mut(
493 ) -> LocalTableInContextMut
<'_
, CanonicalUserType
<'tcx
>> {
494 LocalTableInContextMut
{
495 local_id_root
: self.local_id_root
,
496 data
: &mut self.user_provided_types
500 pub fn node_types(&self) -> LocalTableInContext
<'_
, Ty
<'tcx
>> {
501 LocalTableInContext
{
502 local_id_root
: self.local_id_root
,
503 data
: &self.node_types
507 pub fn node_types_mut(&mut self) -> LocalTableInContextMut
<'_
, Ty
<'tcx
>> {
508 LocalTableInContextMut
{
509 local_id_root
: self.local_id_root
,
510 data
: &mut self.node_types
514 pub fn node_type(&self, id
: hir
::HirId
) -> Ty
<'tcx
> {
515 self.node_type_opt(id
).unwrap_or_else(||
516 bug
!("node_type: no type for node `{}`",
517 tls
::with(|tcx
| tcx
.hir().node_to_string(id
)))
521 pub fn node_type_opt(&self, id
: hir
::HirId
) -> Option
<Ty
<'tcx
>> {
522 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
523 self.node_types
.get(&id
.local_id
).cloned()
526 pub fn node_substs_mut(&mut self) -> LocalTableInContextMut
<'_
, SubstsRef
<'tcx
>> {
527 LocalTableInContextMut
{
528 local_id_root
: self.local_id_root
,
529 data
: &mut self.node_substs
533 pub fn node_substs(&self, id
: hir
::HirId
) -> SubstsRef
<'tcx
> {
534 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
535 self.node_substs
.get(&id
.local_id
).cloned().unwrap_or_else(|| InternalSubsts
::empty())
538 pub fn node_substs_opt(&self, id
: hir
::HirId
) -> Option
<SubstsRef
<'tcx
>> {
539 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
540 self.node_substs
.get(&id
.local_id
).cloned()
543 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
544 // doesn't provide type parameter substitutions.
545 pub fn pat_ty(&self, pat
: &hir
::Pat
) -> Ty
<'tcx
> {
546 self.node_type(pat
.hir_id
)
549 pub fn pat_ty_opt(&self, pat
: &hir
::Pat
) -> Option
<Ty
<'tcx
>> {
550 self.node_type_opt(pat
.hir_id
)
553 // Returns the type of an expression as a monotype.
555 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
556 // some cases, we insert `Adjustment` annotations such as auto-deref or
557 // auto-ref. The type returned by this function does not consider such
558 // adjustments. See `expr_ty_adjusted()` instead.
560 // NB (2): This type doesn't provide type parameter substitutions; e.g., if you
561 // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
562 // instead of "fn(ty) -> T with T = isize".
563 pub fn expr_ty(&self, expr
: &hir
::Expr
) -> Ty
<'tcx
> {
564 self.node_type(expr
.hir_id
)
567 pub fn expr_ty_opt(&self, expr
: &hir
::Expr
) -> Option
<Ty
<'tcx
>> {
568 self.node_type_opt(expr
.hir_id
)
571 pub fn adjustments(&self) -> LocalTableInContext
<'_
, Vec
<ty
::adjustment
::Adjustment
<'tcx
>>> {
572 LocalTableInContext
{
573 local_id_root
: self.local_id_root
,
574 data
: &self.adjustments
578 pub fn adjustments_mut(&mut self)
579 -> LocalTableInContextMut
<'_
, Vec
<ty
::adjustment
::Adjustment
<'tcx
>>> {
580 LocalTableInContextMut
{
581 local_id_root
: self.local_id_root
,
582 data
: &mut self.adjustments
586 pub fn expr_adjustments(&self, expr
: &hir
::Expr
)
587 -> &[ty
::adjustment
::Adjustment
<'tcx
>] {
588 validate_hir_id_for_typeck_tables(self.local_id_root
, expr
.hir_id
, false);
589 self.adjustments
.get(&expr
.hir_id
.local_id
).map_or(&[], |a
| &a
[..])
592 /// Returns the type of `expr`, considering any `Adjustment`
593 /// entry recorded for that expression.
594 pub fn expr_ty_adjusted(&self, expr
: &hir
::Expr
) -> Ty
<'tcx
> {
595 self.expr_adjustments(expr
)
597 .map_or_else(|| self.expr_ty(expr
), |adj
| adj
.target
)
600 pub fn expr_ty_adjusted_opt(&self, expr
: &hir
::Expr
) -> Option
<Ty
<'tcx
>> {
601 self.expr_adjustments(expr
)
603 .map(|adj
| adj
.target
)
604 .or_else(|| self.expr_ty_opt(expr
))
607 pub fn is_method_call(&self, expr
: &hir
::Expr
) -> bool
{
608 // Only paths and method calls/overloaded operators have
609 // entries in type_dependent_defs, ignore the former here.
610 if let hir
::ExprKind
::Path(_
) = expr
.node
{
614 match self.type_dependent_defs().get(expr
.hir_id
) {
615 Some(Ok((DefKind
::Method
, _
))) => true,
620 pub fn pat_binding_modes(&self) -> LocalTableInContext
<'_
, BindingMode
> {
621 LocalTableInContext
{
622 local_id_root
: self.local_id_root
,
623 data
: &self.pat_binding_modes
627 pub fn pat_binding_modes_mut(&mut self)
628 -> LocalTableInContextMut
<'_
, BindingMode
> {
629 LocalTableInContextMut
{
630 local_id_root
: self.local_id_root
,
631 data
: &mut self.pat_binding_modes
635 pub fn pat_adjustments(&self) -> LocalTableInContext
<'_
, Vec
<Ty
<'tcx
>>> {
636 LocalTableInContext
{
637 local_id_root
: self.local_id_root
,
638 data
: &self.pat_adjustments
,
642 pub fn pat_adjustments_mut(&mut self)
643 -> LocalTableInContextMut
<'_
, Vec
<Ty
<'tcx
>>> {
644 LocalTableInContextMut
{
645 local_id_root
: self.local_id_root
,
646 data
: &mut self.pat_adjustments
,
650 pub fn upvar_capture(&self, upvar_id
: ty
::UpvarId
) -> ty
::UpvarCapture
<'tcx
> {
651 self.upvar_capture_map
[&upvar_id
]
654 pub fn closure_kind_origins(&self) -> LocalTableInContext
<'_
, (Span
, ast
::Name
)> {
655 LocalTableInContext
{
656 local_id_root
: self.local_id_root
,
657 data
: &self.closure_kind_origins
661 pub fn closure_kind_origins_mut(&mut self) -> LocalTableInContextMut
<'_
, (Span
, ast
::Name
)> {
662 LocalTableInContextMut
{
663 local_id_root
: self.local_id_root
,
664 data
: &mut self.closure_kind_origins
668 pub fn liberated_fn_sigs(&self) -> LocalTableInContext
<'_
, ty
::FnSig
<'tcx
>> {
669 LocalTableInContext
{
670 local_id_root
: self.local_id_root
,
671 data
: &self.liberated_fn_sigs
675 pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut
<'_
, ty
::FnSig
<'tcx
>> {
676 LocalTableInContextMut
{
677 local_id_root
: self.local_id_root
,
678 data
: &mut self.liberated_fn_sigs
682 pub fn fru_field_types(&self) -> LocalTableInContext
<'_
, Vec
<Ty
<'tcx
>>> {
683 LocalTableInContext
{
684 local_id_root
: self.local_id_root
,
685 data
: &self.fru_field_types
689 pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut
<'_
, Vec
<Ty
<'tcx
>>> {
690 LocalTableInContextMut
{
691 local_id_root
: self.local_id_root
,
692 data
: &mut self.fru_field_types
696 pub fn is_coercion_cast(&self, hir_id
: hir
::HirId
) -> bool
{
697 validate_hir_id_for_typeck_tables(self.local_id_root
, hir_id
, true);
698 self.coercion_casts
.contains(&hir_id
.local_id
)
701 pub fn set_coercion_cast(&mut self, id
: ItemLocalId
) {
702 self.coercion_casts
.insert(id
);
705 pub fn coercion_casts(&self) -> &ItemLocalSet
{
711 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for TypeckTables
<'tcx
> {
712 fn hash_stable
<W
: StableHasherResult
>(&self,
713 hcx
: &mut StableHashingContext
<'a
>,
714 hasher
: &mut StableHasher
<W
>) {
715 let ty
::TypeckTables
{
717 ref type_dependent_defs
,
719 ref user_provided_types
,
720 ref user_provided_sigs
,
724 ref pat_binding_modes
,
726 ref upvar_capture_map
,
727 ref closure_kind_origins
,
728 ref liberated_fn_sigs
,
733 ref used_trait_imports
,
736 ref concrete_opaque_types
,
741 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
742 type_dependent_defs
.hash_stable(hcx
, hasher
);
743 field_indices
.hash_stable(hcx
, hasher
);
744 user_provided_types
.hash_stable(hcx
, hasher
);
745 user_provided_sigs
.hash_stable(hcx
, hasher
);
746 node_types
.hash_stable(hcx
, hasher
);
747 node_substs
.hash_stable(hcx
, hasher
);
748 adjustments
.hash_stable(hcx
, hasher
);
749 pat_binding_modes
.hash_stable(hcx
, hasher
);
750 pat_adjustments
.hash_stable(hcx
, hasher
);
751 hash_stable_hashmap(hcx
, hasher
, upvar_capture_map
, |up_var_id
, hcx
| {
758 local_id_root
.expect("trying to hash invalid TypeckTables");
760 let var_owner_def_id
= DefId
{
761 krate
: local_id_root
.krate
,
762 index
: var_path
.hir_id
.owner
,
764 let closure_def_id
= DefId
{
765 krate
: local_id_root
.krate
,
766 index
: closure_expr_id
.to_def_id().index
,
768 (hcx
.def_path_hash(var_owner_def_id
),
769 var_path
.hir_id
.local_id
,
770 hcx
.def_path_hash(closure_def_id
))
773 closure_kind_origins
.hash_stable(hcx
, hasher
);
774 liberated_fn_sigs
.hash_stable(hcx
, hasher
);
775 fru_field_types
.hash_stable(hcx
, hasher
);
776 coercion_casts
.hash_stable(hcx
, hasher
);
777 used_trait_imports
.hash_stable(hcx
, hasher
);
778 tainted_by_errors
.hash_stable(hcx
, hasher
);
779 free_region_map
.hash_stable(hcx
, hasher
);
780 concrete_opaque_types
.hash_stable(hcx
, hasher
);
781 upvar_list
.hash_stable(hcx
, hasher
);
787 pub struct UserTypeAnnotationIndex
{
789 DEBUG_FORMAT
= "UserType({})",
790 const START_INDEX
= 0,
794 /// Mapping of type annotation indices to canonical user type annotations.
795 pub type CanonicalUserTypeAnnotations
<'tcx
> =
796 IndexVec
<UserTypeAnnotationIndex
, CanonicalUserTypeAnnotation
<'tcx
>>;
798 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
799 pub struct CanonicalUserTypeAnnotation
<'tcx
> {
800 pub user_ty
: CanonicalUserType
<'tcx
>,
802 pub inferred_ty
: Ty
<'tcx
>,
805 BraceStructTypeFoldableImpl
! {
806 impl<'tcx
> TypeFoldable
<'tcx
> for CanonicalUserTypeAnnotation
<'tcx
> {
807 user_ty
, span
, inferred_ty
811 BraceStructLiftImpl
! {
812 impl<'a
, 'tcx
> Lift
<'tcx
> for CanonicalUserTypeAnnotation
<'a
> {
813 type Lifted
= CanonicalUserTypeAnnotation
<'tcx
>;
814 user_ty
, span
, inferred_ty
818 /// Canonicalized user type annotation.
819 pub type CanonicalUserType
<'tcx
> = Canonical
<'tcx
, UserType
<'tcx
>>;
821 impl CanonicalUserType
<'tcx
> {
822 /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`,
823 /// i.e., each thing is mapped to a canonical variable with the same index.
824 pub fn is_identity(&self) -> bool
{
826 UserType
::Ty(_
) => false,
827 UserType
::TypeOf(_
, user_substs
) => {
828 if user_substs
.user_self_ty
.is_some() {
832 user_substs
.substs
.iter().zip(BoundVar
::new(0)..).all(|(kind
, cvar
)| {
833 match kind
.unpack() {
834 UnpackedKind
::Type(ty
) => match ty
.sty
{
835 ty
::Bound(debruijn
, b
) => {
836 // We only allow a `ty::INNERMOST` index in substitutions.
837 assert_eq
!(debruijn
, ty
::INNERMOST
);
843 UnpackedKind
::Lifetime(r
) => match r
{
844 ty
::ReLateBound(debruijn
, br
) => {
845 // We only allow a `ty::INNERMOST` index in substitutions.
846 assert_eq
!(*debruijn
, ty
::INNERMOST
);
847 cvar
== br
.assert_bound_var()
852 UnpackedKind
::Const(ct
) => match ct
.val
{
853 ConstValue
::Infer(InferConst
::Canonical(debruijn
, b
)) => {
854 // We only allow a `ty::INNERMOST` index in substitutions.
855 assert_eq
!(debruijn
, ty
::INNERMOST
);
867 /// A user-given type annotation attached to a constant. These arise
868 /// from constants that are named via paths, like `Foo::<A>::new` and
870 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
871 pub enum UserType
<'tcx
> {
874 /// The canonical type is the result of `type_of(def_id)` with the
875 /// given substitutions applied.
876 TypeOf(DefId
, UserSubsts
<'tcx
>),
879 EnumTypeFoldableImpl
! {
880 impl<'tcx
> TypeFoldable
<'tcx
> for UserType
<'tcx
> {
882 (UserType
::TypeOf
)(def
, substs
),
887 impl<'a
, 'tcx
> Lift
<'tcx
> for UserType
<'a
> {
888 type Lifted
= UserType
<'tcx
>;
890 (UserType
::TypeOf
)(def
, substs
),
894 impl<'tcx
> CommonTypes
<'tcx
> {
895 fn new(interners
: &CtxtInterners
<'tcx
>) -> CommonTypes
<'tcx
> {
896 let mk
= |sty
| interners
.intern_ty(sty
);
899 unit
: mk(Tuple(List
::empty())),
904 isize: mk(Int(ast
::IntTy
::Isize
)),
905 i8: mk(Int(ast
::IntTy
::I8
)),
906 i16: mk(Int(ast
::IntTy
::I16
)),
907 i32: mk(Int(ast
::IntTy
::I32
)),
908 i64: mk(Int(ast
::IntTy
::I64
)),
909 i128
: mk(Int(ast
::IntTy
::I128
)),
910 usize: mk(Uint(ast
::UintTy
::Usize
)),
911 u8: mk(Uint(ast
::UintTy
::U8
)),
912 u16: mk(Uint(ast
::UintTy
::U16
)),
913 u32: mk(Uint(ast
::UintTy
::U32
)),
914 u64: mk(Uint(ast
::UintTy
::U64
)),
915 u128
: mk(Uint(ast
::UintTy
::U128
)),
916 f32: mk(Float(ast
::FloatTy
::F32
)),
917 f64: mk(Float(ast
::FloatTy
::F64
)),
919 trait_object_dummy_self
: mk(Infer(ty
::FreshTy(0))),
924 impl<'tcx
> CommonLifetimes
<'tcx
> {
925 fn new(interners
: &CtxtInterners
<'tcx
>) -> CommonLifetimes
<'tcx
> {
927 interners
.region
.intern(r
, |r
| {
928 Interned(interners
.arena
.alloc(r
))
933 re_empty
: mk(RegionKind
::ReEmpty
),
934 re_static
: mk(RegionKind
::ReStatic
),
935 re_erased
: mk(RegionKind
::ReErased
),
940 impl<'tcx
> CommonConsts
<'tcx
> {
941 fn new(interners
: &CtxtInterners
<'tcx
>, types
: &CommonTypes
<'tcx
>) -> CommonConsts
<'tcx
> {
943 interners
.const_
.intern(c
, |c
| {
944 Interned(interners
.arena
.alloc(c
))
949 err
: mk_const(ty
::Const
{
950 val
: ConstValue
::Scalar(Scalar
::zst()),
957 // This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime
960 pub struct FreeRegionInfo
{
961 // def id corresponding to FreeRegion
963 // the bound region corresponding to FreeRegion
964 pub boundregion
: ty
::BoundRegion
,
965 // checks if bound region is in Impl Item
966 pub is_impl_item
: bool
,
969 /// The central data structure of the compiler. It stores references
970 /// to the various **arenas** and also houses the results of the
971 /// various **compiler queries** that have been performed. See the
972 /// [rustc guide] for more details.
974 /// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html
975 #[derive(Copy, Clone)]
976 pub struct TyCtxt
<'tcx
> {
977 gcx
: &'tcx GlobalCtxt
<'tcx
>,
980 impl<'tcx
> Deref
for TyCtxt
<'tcx
> {
981 type Target
= &'tcx GlobalCtxt
<'tcx
>;
983 fn deref(&self) -> &Self::Target
{
988 pub struct GlobalCtxt
<'tcx
> {
989 pub arena
: WorkerLocal
<Arena
<'tcx
>>,
991 interners
: CtxtInterners
<'tcx
>,
993 cstore
: &'tcx CrateStoreDyn
,
995 pub sess
: &'tcx Session
,
997 pub dep_graph
: DepGraph
,
1000 pub common
: Common
<'tcx
>,
1002 /// Common types, pre-interned for your convenience.
1003 pub types
: CommonTypes
<'tcx
>,
1005 /// Common lifetimes, pre-interned for your convenience.
1006 pub lifetimes
: CommonLifetimes
<'tcx
>,
1008 /// Common consts, pre-interned for your convenience.
1009 pub consts
: CommonConsts
<'tcx
>,
1011 /// Map indicating what traits are in scope for places where this
1012 /// is relevant; generated by resolve.
1013 trait_map
: FxHashMap
<DefIndex
,
1014 FxHashMap
<ItemLocalId
,
1015 StableVec
<TraitCandidate
>>>,
1017 /// Export map produced by name resolution.
1018 export_map
: FxHashMap
<DefId
, Vec
<Export
<hir
::HirId
>>>,
1020 hir_map
: hir_map
::Map
<'tcx
>,
1022 /// A map from DefPathHash -> DefId. Includes DefIds from the local crate
1023 /// as well as all upstream crates. Only populated in incremental mode.
1024 pub def_path_hash_to_def_id
: Option
<FxHashMap
<DefPathHash
, DefId
>>,
1026 pub queries
: query
::Queries
<'tcx
>,
1028 maybe_unused_trait_imports
: FxHashSet
<DefId
>,
1029 maybe_unused_extern_crates
: Vec
<(DefId
, Span
)>,
1030 /// A map of glob use to a set of names it actually imports. Currently only
1031 /// used in save-analysis.
1032 glob_map
: FxHashMap
<DefId
, FxHashSet
<ast
::Name
>>,
1033 /// Extern prelude entries. The value is `true` if the entry was introduced
1034 /// via `extern crate` item and not `--extern` option or compiler built-in.
1035 pub extern_prelude
: FxHashMap
<ast
::Name
, bool
>,
1037 // Internal cache for metadata decoding. No need to track deps on this.
1038 pub rcache
: Lock
<FxHashMap
<ty
::CReaderCacheKey
, Ty
<'tcx
>>>,
1040 /// Caches the results of trait selection. This cache is used
1041 /// for things that do not have to do with the parameters in scope.
1042 pub selection_cache
: traits
::SelectionCache
<'tcx
>,
1044 /// Caches the results of trait evaluation. This cache is used
1045 /// for things that do not have to do with the parameters in scope.
1046 /// Merge this with `selection_cache`?
1047 pub evaluation_cache
: traits
::EvaluationCache
<'tcx
>,
1049 /// The definite name of the current crate after taking into account
1050 /// attributes, commandline parameters, etc.
1051 pub crate_name
: Symbol
,
1053 /// Data layout specification for the current target.
1054 pub data_layout
: TargetDataLayout
,
1056 stability_interner
: ShardedHashMap
<&'tcx attr
::Stability
, ()>,
1058 /// Stores the value of constants (and deduplicates the actual memory)
1059 allocation_interner
: ShardedHashMap
<&'tcx Allocation
, ()>,
1061 pub alloc_map
: Lock
<interpret
::AllocMap
<'tcx
>>,
1063 layout_interner
: ShardedHashMap
<&'tcx LayoutDetails
, ()>,
1065 /// A general purpose channel to throw data out the back towards LLVM worker
1068 /// This is intended to only get used during the codegen phase of the compiler
1069 /// when satisfying the query for a particular codegen unit. Internally in
1070 /// the query it'll send data along this channel to get processed later.
1071 pub tx_to_llvm_workers
: Lock
<mpsc
::Sender
<Box
<dyn Any
+ Send
>>>,
1073 output_filenames
: Arc
<OutputFilenames
>,
1076 impl<'tcx
> TyCtxt
<'tcx
> {
1077 /// Gets the global `TyCtxt`.
1079 pub fn global_tcx(self) -> TyCtxt
<'tcx
> {
1086 pub fn hir(self) -> &'tcx hir_map
::Map
<'tcx
> {
1090 pub fn alloc_steal_mir(self, mir
: Body
<'tcx
>) -> &'tcx Steal
<Body
<'tcx
>> {
1091 self.arena
.alloc(Steal
::new(mir
))
1094 pub fn alloc_adt_def(
1098 variants
: IndexVec
<VariantIdx
, ty
::VariantDef
>,
1100 ) -> &'tcx ty
::AdtDef
{
1101 let def
= ty
::AdtDef
::new(self, did
, kind
, variants
, repr
);
1102 self.arena
.alloc(def
)
1105 pub fn intern_const_alloc(self, alloc
: Allocation
) -> &'tcx Allocation
{
1106 self.allocation_interner
.intern(alloc
, |alloc
| {
1107 self.arena
.alloc(alloc
)
1111 /// Allocates a byte or string literal for `mir::interpret`, read-only
1112 pub fn allocate_bytes(self, bytes
: &[u8]) -> interpret
::AllocId
{
1113 // create an allocation that just contains these bytes
1114 let alloc
= interpret
::Allocation
::from_byte_aligned_bytes(bytes
);
1115 let alloc
= self.intern_const_alloc(alloc
);
1116 self.alloc_map
.lock().create_memory_alloc(alloc
)
1119 pub fn intern_stability(self, stab
: attr
::Stability
) -> &'tcx attr
::Stability
{
1120 self.stability_interner
.intern(stab
, |stab
| {
1121 self.arena
.alloc(stab
)
1125 pub fn intern_layout(self, layout
: LayoutDetails
) -> &'tcx LayoutDetails
{
1126 self.layout_interner
.intern(layout
, |layout
| {
1127 self.arena
.alloc(layout
)
1131 /// Returns a range of the start/end indices specified with the
1132 /// `rustc_layout_scalar_valid_range` attribute.
1133 pub fn layout_scalar_valid_range(self, def_id
: DefId
) -> (Bound
<u128
>, Bound
<u128
>) {
1134 let attrs
= self.get_attrs(def_id
);
1136 let attr
= match attrs
.iter().find(|a
| a
.check_name(name
)) {
1138 None
=> return Bound
::Unbounded
,
1140 for meta
in attr
.meta_item_list().expect("rustc_layout_scalar_valid_range takes args") {
1141 match meta
.literal().expect("attribute takes lit").node
{
1142 ast
::LitKind
::Int(a
, _
) => return Bound
::Included(a
),
1143 _
=> span_bug
!(attr
.span
, "rustc_layout_scalar_valid_range expects int arg"),
1146 span_bug
!(attr
.span
, "no arguments to `rustc_layout_scalar_valid_range` attribute");
1148 (get(sym
::rustc_layout_scalar_valid_range_start
),
1149 get(sym
::rustc_layout_scalar_valid_range_end
))
1152 pub fn lift
<T
: ?Sized
+ Lift
<'tcx
>>(self, value
: &T
) -> Option
<T
::Lifted
> {
1153 value
.lift_to_tcx(self)
1156 /// Like lift, but only tries in the global tcx.
1157 pub fn lift_to_global
<T
: ?Sized
+ Lift
<'tcx
>>(self, value
: &T
) -> Option
<T
::Lifted
> {
1158 value
.lift_to_tcx(self.global_tcx())
1161 /// Creates a type context and call the closure with a `TyCtxt` reference
1162 /// to the context. The closure enforces that the type context and any interned
1163 /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
1164 /// reference to the context, to allow formatting values that need it.
1165 pub fn create_global_ctxt(
1167 cstore
: &'tcx CrateStoreDyn
,
1168 local_providers
: ty
::query
::Providers
<'tcx
>,
1169 extern_providers
: ty
::query
::Providers
<'tcx
>,
1170 arenas
: &'tcx AllArenas
,
1171 resolutions
: ty
::Resolutions
,
1172 hir
: hir_map
::Map
<'tcx
>,
1173 on_disk_query_result_cache
: query
::OnDiskCache
<'tcx
>,
1175 tx
: mpsc
::Sender
<Box
<dyn Any
+ Send
>>,
1176 output_filenames
: &OutputFilenames
,
1177 ) -> GlobalCtxt
<'tcx
> {
1178 let data_layout
= TargetDataLayout
::parse(&s
.target
.target
).unwrap_or_else(|err
| {
1181 let interners
= CtxtInterners
::new(&arenas
.interner
);
1182 let common
= Common
{
1183 empty_predicates
: ty
::GenericPredicates
{
1188 let common_types
= CommonTypes
::new(&interners
);
1189 let common_lifetimes
= CommonLifetimes
::new(&interners
);
1190 let common_consts
= CommonConsts
::new(&interners
, &common_types
);
1191 let dep_graph
= hir
.dep_graph
.clone();
1192 let max_cnum
= cstore
.crates_untracked().iter().map(|c
| c
.as_usize()).max().unwrap_or(0);
1193 let mut providers
= IndexVec
::from_elem_n(extern_providers
, max_cnum
+ 1);
1194 providers
[LOCAL_CRATE
] = local_providers
;
1196 let def_path_hash_to_def_id
= if s
.opts
.build_dep_graph() {
1197 let upstream_def_path_tables
: Vec
<(CrateNum
, Lrc
<_
>)> = cstore
1200 .map(|&cnum
| (cnum
, cstore
.def_path_table(cnum
)))
1203 let def_path_tables
= || {
1204 upstream_def_path_tables
1206 .map(|&(cnum
, ref rc
)| (cnum
, &**rc
))
1207 .chain(iter
::once((LOCAL_CRATE
, hir
.definitions().def_path_table())))
1210 // Precompute the capacity of the hashmap so we don't have to
1211 // re-allocate when populating it.
1212 let capacity
= def_path_tables().map(|(_
, t
)| t
.size()).sum
::<usize>();
1214 let mut map
: FxHashMap
<_
, _
> = FxHashMap
::with_capacity_and_hasher(
1216 ::std
::default::Default
::default()
1219 for (cnum
, def_path_table
) in def_path_tables() {
1220 def_path_table
.add_def_path_hashes_to(cnum
, &mut map
);
1228 let mut trait_map
: FxHashMap
<_
, FxHashMap
<_
, _
>> = FxHashMap
::default();
1229 for (k
, v
) in resolutions
.trait_map
{
1230 let hir_id
= hir
.node_to_hir_id(k
);
1231 let map
= trait_map
.entry(hir_id
.owner
).or_default();
1232 map
.insert(hir_id
.local_id
, StableVec
::new(v
));
1238 arena
: WorkerLocal
::new(|_
| Arena
::default()),
1242 types
: common_types
,
1243 lifetimes
: common_lifetimes
,
1244 consts
: common_consts
,
1246 export_map
: resolutions
.export_map
.into_iter().map(|(k
, v
)| {
1247 let exports
: Vec
<_
> = v
.into_iter().map(|e
| {
1248 e
.map_id(|id
| hir
.node_to_hir_id(id
))
1252 maybe_unused_trait_imports
:
1253 resolutions
.maybe_unused_trait_imports
1255 .map(|id
| hir
.local_def_id_from_node_id(id
))
1257 maybe_unused_extern_crates
:
1258 resolutions
.maybe_unused_extern_crates
1260 .map(|(id
, sp
)| (hir
.local_def_id_from_node_id(id
), sp
))
1262 glob_map
: resolutions
.glob_map
.into_iter().map(|(id
, names
)| {
1263 (hir
.local_def_id_from_node_id(id
), names
)
1265 extern_prelude
: resolutions
.extern_prelude
,
1267 def_path_hash_to_def_id
,
1268 queries
: query
::Queries
::new(
1271 on_disk_query_result_cache
,
1273 rcache
: Default
::default(),
1274 selection_cache
: Default
::default(),
1275 evaluation_cache
: Default
::default(),
1276 crate_name
: Symbol
::intern(crate_name
),
1278 layout_interner
: Default
::default(),
1279 stability_interner
: Default
::default(),
1280 allocation_interner
: Default
::default(),
1281 alloc_map
: Lock
::new(interpret
::AllocMap
::new()),
1282 tx_to_llvm_workers
: Lock
::new(tx
),
1283 output_filenames
: Arc
::new(output_filenames
.clone()),
1287 pub fn consider_optimizing
<T
: Fn() -> String
>(&self, msg
: T
) -> bool
{
1288 let cname
= self.crate_name(LOCAL_CRATE
).as_str();
1289 self.sess
.consider_optimizing(&cname
, msg
)
1292 pub fn lib_features(self) -> &'tcx middle
::lib_features
::LibFeatures
{
1293 self.get_lib_features(LOCAL_CRATE
)
1296 pub fn lang_items(self) -> &'tcx middle
::lang_items
::LanguageItems
{
1297 self.get_lang_items(LOCAL_CRATE
)
1300 pub fn stability(self) -> &'tcx stability
::Index
<'tcx
> {
1301 self.stability_index(LOCAL_CRATE
)
1304 pub fn crates(self) -> &'tcx
[CrateNum
] {
1305 self.all_crate_nums(LOCAL_CRATE
)
1308 pub fn features(self) -> &'tcx feature_gate
::Features
{
1309 self.features_query(LOCAL_CRATE
)
1312 pub fn def_key(self, id
: DefId
) -> hir_map
::DefKey
{
1314 self.hir().def_key(id
)
1316 self.cstore
.def_key(id
)
1320 /// Converts a `DefId` into its fully expanded `DefPath` (every
1321 /// `DefId` is really just an interned def-path).
1323 /// Note that if `id` is not local to this crate, the result will
1324 /// be a non-local `DefPath`.
1325 pub fn def_path(self, id
: DefId
) -> hir_map
::DefPath
{
1327 self.hir().def_path(id
)
1329 self.cstore
.def_path(id
)
1333 /// Returns whether or not the crate with CrateNum 'cnum'
1334 /// is marked as a private dependency
1335 pub fn is_private_dep(self, cnum
: CrateNum
) -> bool
{
1336 if cnum
== LOCAL_CRATE
{
1339 self.cstore
.crate_is_private_dep_untracked(cnum
)
1344 pub fn def_path_hash(self, def_id
: DefId
) -> hir_map
::DefPathHash
{
1345 if def_id
.is_local() {
1346 self.hir().definitions().def_path_hash(def_id
.index
)
1348 self.cstore
.def_path_hash(def_id
)
1352 pub fn def_path_debug_str(self, def_id
: DefId
) -> String
{
1353 // We are explicitly not going through queries here in order to get
1354 // crate name and disambiguator since this code is called from debug!()
1355 // statements within the query system and we'd run into endless
1356 // recursion otherwise.
1357 let (crate_name
, crate_disambiguator
) = if def_id
.is_local() {
1358 (self.crate_name
.clone(),
1359 self.sess
.local_crate_disambiguator())
1361 (self.cstore
.crate_name_untracked(def_id
.krate
),
1362 self.cstore
.crate_disambiguator_untracked(def_id
.krate
))
1367 // Don't print the whole crate disambiguator. That's just
1368 // annoying in debug output.
1369 &(crate_disambiguator
.to_fingerprint().to_hex())[..4],
1370 self.def_path(def_id
).to_string_no_crate())
1373 pub fn metadata_encoding_version(self) -> Vec
<u8> {
1374 self.cstore
.metadata_encoding_version().to_vec()
1377 // Note that this is *untracked* and should only be used within the query
1378 // system if the result is otherwise tracked through queries
1379 pub fn crate_data_as_rc_any(self, cnum
: CrateNum
) -> Lrc
<dyn Any
> {
1380 self.cstore
.crate_data_as_rc_any(cnum
)
1384 pub fn create_stable_hashing_context(self) -> StableHashingContext
<'tcx
> {
1385 let krate
= self.gcx
.hir_map
.forest
.untracked_krate();
1387 StableHashingContext
::new(self.sess
,
1389 self.hir().definitions(),
1393 // This method makes sure that we have a DepNode and a Fingerprint for
1394 // every upstream crate. It needs to be called once right after the tcx is
1396 // With full-fledged red/green, the method will probably become unnecessary
1397 // as this will be done on-demand.
1398 pub fn allocate_metadata_dep_nodes(self) {
1399 // We cannot use the query versions of crates() and crate_hash(), since
1400 // those would need the DepNodes that we are allocating here.
1401 for cnum
in self.cstore
.crates_untracked() {
1402 let dep_node
= DepNode
::new(self, DepConstructor
::CrateMetadata(cnum
));
1403 let crate_hash
= self.cstore
.crate_hash_untracked(cnum
);
1404 self.dep_graph
.with_task(dep_node
,
1407 |_
, x
| x
, // No transformation needed
1408 dep_graph
::hash_result
,
1413 pub fn serialize_query_result_cache
<E
>(self,
1415 -> Result
<(), E
::Error
>
1416 where E
: ty
::codec
::TyEncoder
1418 self.queries
.on_disk_cache
.serialize(self.global_tcx(), encoder
)
1421 /// If true, we should use the AST-based borrowck (we may *also* use
1422 /// the MIR-based borrowck).
1423 pub fn use_ast_borrowck(self) -> bool
{
1424 self.borrowck_mode().use_ast()
1427 /// If true, we should use the MIR-based borrow check, but also
1428 /// fall back on the AST borrow check if the MIR-based one errors.
1429 pub fn migrate_borrowck(self) -> bool
{
1430 self.borrowck_mode().migrate()
1433 /// If true, make MIR codegen for `match` emit a temp that holds a
1434 /// borrow of the input to the match expression.
1435 pub fn generate_borrow_of_any_match_input(&self) -> bool
{
1436 self.emit_read_for_match()
1439 /// If true, make MIR codegen for `match` emit FakeRead
1440 /// statements (which simulate the maximal effect of executing the
1441 /// patterns in a match arm).
1442 pub fn emit_read_for_match(&self) -> bool
{
1443 !self.sess
.opts
.debugging_opts
.nll_dont_emit_read_for_match
1446 /// What mode(s) of borrowck should we run? AST? MIR? both?
1447 /// (Also considers the `#![feature(nll)]` setting.)
1448 pub fn borrowck_mode(&self) -> BorrowckMode
{
1449 // Here are the main constraints we need to deal with:
1451 // 1. An opts.borrowck_mode of `BorrowckMode::Migrate` is
1452 // synonymous with no `-Z borrowck=...` flag at all.
1454 // 2. We want to allow developers on the Nightly channel
1455 // to opt back into the "hard error" mode for NLL,
1456 // (which they can do via specifying `#![feature(nll)]`
1457 // explicitly in their crate).
1459 // So, this precedence list is how pnkfelix chose to work with
1460 // the above constraints:
1462 // * `#![feature(nll)]` *always* means use NLL with hard
1463 // errors. (To simplify the code here, it now even overrides
1464 // a user's attempt to specify `-Z borrowck=compare`, which
1465 // we arguably do not need anymore and should remove.)
1467 // * Otherwise, if no `-Z borrowck=...` then use migrate mode
1469 // * Otherwise, use the behavior requested via `-Z borrowck=...`
1471 if self.features().nll { return BorrowckMode::Mir; }
1473 self.sess
.opts
.borrowck_mode
1477 pub fn local_crate_exports_generics(self) -> bool
{
1478 debug_assert
!(self.sess
.opts
.share_generics());
1480 self.sess
.crate_types
.borrow().iter().any(|crate_type
| {
1482 CrateType
::Executable
|
1483 CrateType
::Staticlib
|
1484 CrateType
::ProcMacro
|
1485 CrateType
::Cdylib
=> false,
1487 CrateType
::Dylib
=> true,
1492 // This method returns the DefId and the BoundRegion corresponding to the given region.
1493 pub fn is_suitable_region(&self, region
: Region
<'tcx
>) -> Option
<FreeRegionInfo
> {
1494 let (suitable_region_binding_scope
, bound_region
) = match *region
{
1495 ty
::ReFree(ref free_region
) => (free_region
.scope
, free_region
.bound_region
),
1496 ty
::ReEarlyBound(ref ebr
) => (
1497 self.parent(ebr
.def_id
).unwrap(),
1498 ty
::BoundRegion
::BrNamed(ebr
.def_id
, ebr
.name
),
1500 _
=> return None
, // not a free region
1503 let hir_id
= self.hir()
1504 .as_local_hir_id(suitable_region_binding_scope
)
1506 let is_impl_item
= match self.hir().find(hir_id
) {
1507 Some(Node
::Item(..)) | Some(Node
::TraitItem(..)) => false,
1508 Some(Node
::ImplItem(..)) => {
1509 self.is_bound_region_in_impl_item(suitable_region_binding_scope
)
1514 return Some(FreeRegionInfo
{
1515 def_id
: suitable_region_binding_scope
,
1516 boundregion
: bound_region
,
1517 is_impl_item
: is_impl_item
,
1521 pub fn return_type_impl_trait(
1523 scope_def_id
: DefId
,
1524 ) -> Option
<Ty
<'tcx
>> {
1525 // HACK: `type_of_def_id()` will fail on these (#55796), so return None
1526 let hir_id
= self.hir().as_local_hir_id(scope_def_id
).unwrap();
1527 match self.hir().get(hir_id
) {
1528 Node
::Item(item
) => {
1530 ItemKind
::Fn(..) => { /* type_of_def_id() will work */ }
1536 _
=> { /* type_of_def_id() will work or panic */ }
1539 let ret_ty
= self.type_of(scope_def_id
);
1541 ty
::FnDef(_
, _
) => {
1542 let sig
= ret_ty
.fn_sig(*self);
1543 let output
= self.erase_late_bound_regions(&sig
.output());
1544 if output
.is_impl_trait() {
1554 // Here we check if the bound region is in Impl Item.
1555 pub fn is_bound_region_in_impl_item(
1557 suitable_region_binding_scope
: DefId
,
1559 let container_id
= self.associated_item(suitable_region_binding_scope
)
1562 if self.impl_trait_ref(container_id
).is_some() {
1563 // For now, we do not try to target impls of traits. This is
1564 // because this message is going to suggest that the user
1565 // change the fn signature, but they may not be free to do so,
1566 // since the signature must match the trait.
1568 // FIXME(#42706) -- in some cases, we could do better here.
1574 /// Determine whether identifiers in the assembly have strict naming rules.
1575 /// Currently, only NVPTX* targets need it.
1576 pub fn has_strict_asm_symbol_naming(&self) -> bool
{
1577 self.gcx
.sess
.target
.target
.arch
.contains("nvptx")
1581 impl<'tcx
> TyCtxt
<'tcx
> {
1582 pub fn encode_metadata(self)
1585 self.cstore
.encode_metadata(self)
1589 impl<'tcx
> GlobalCtxt
<'tcx
> {
1590 /// Call the closure with a local `TyCtxt` using the given arena.
1591 /// `interners` is a slot passed so we can create a CtxtInterners
1592 /// with the same lifetime as `arena`.
1593 pub fn enter_local
<F
, R
>(&'tcx
self, f
: F
) -> R
1595 F
: FnOnce(TyCtxt
<'tcx
>) -> R
,
1600 ty
::tls
::with_related_context(tcx
.global_tcx(), |icx
| {
1601 let new_icx
= ty
::tls
::ImplicitCtxt
{
1603 query
: icx
.query
.clone(),
1604 diagnostics
: icx
.diagnostics
,
1605 layout_depth
: icx
.layout_depth
,
1606 task_deps
: icx
.task_deps
,
1608 ty
::tls
::enter_context(&new_icx
, |_
| {
1615 /// A trait implemented for all `X<'a>` types that can be safely and
1616 /// efficiently converted to `X<'tcx>` as long as they are part of the
1617 /// provided `TyCtxt<'tcx>`.
1618 /// This can be done, for example, for `Ty<'tcx>` or `SubstsRef<'tcx>`
1619 /// by looking them up in their respective interners.
1621 /// However, this is still not the best implementation as it does
1622 /// need to compare the components, even for interned values.
1623 /// It would be more efficient if `TypedArena` provided a way to
1624 /// determine whether the address is in the allocated range.
1626 /// None is returned if the value or one of the components is not part
1627 /// of the provided context.
1628 /// For `Ty`, `None` can be returned if either the type interner doesn't
1629 /// contain the `TyKind` key or if the address of the interned
1630 /// pointer differs. The latter case is possible if a primitive type,
1631 /// e.g., `()` or `u8`, was interned in a different context.
1632 pub trait Lift
<'tcx
>: fmt
::Debug
{
1633 type Lifted
: fmt
::Debug
+ 'tcx
;
1634 fn lift_to_tcx(&self, tcx
: TyCtxt
<'tcx
>) -> Option
<Self::Lifted
>;
1638 macro_rules
! nop_lift
{
1639 ($ty
:ty
=> $lifted
:ty
) => {
1640 impl<'a
, 'tcx
> Lift
<'tcx
> for $ty
{
1641 type Lifted
= $lifted
;
1642 fn lift_to_tcx(&self, tcx
: TyCtxt
<'tcx
>) -> Option
<Self::Lifted
> {
1643 if tcx
.interners
.arena
.in_arena(*self as *const _
) {
1644 Some(unsafe { mem::transmute(*self) }
)
1653 macro_rules
! nop_list_lift
{
1654 ($ty
:ty
=> $lifted
:ty
) => {
1655 impl<'a
, 'tcx
> Lift
<'tcx
> for &'a List
<$ty
> {
1656 type Lifted
= &'tcx List
<$lifted
>;
1657 fn lift_to_tcx(&self, tcx
: TyCtxt
<'tcx
>) -> Option
<Self::Lifted
> {
1658 if self.is_empty() {
1659 return Some(List
::empty());
1661 if tcx
.interners
.arena
.in_arena(*self as *const _
) {
1662 Some(unsafe { mem::transmute(*self) }
)
1671 nop_lift
!{Ty<'a> => Ty<'tcx>}
1672 nop_lift
!{Region<'a> => Region<'tcx>}
1673 nop_lift
!{Goal<'a> => Goal<'tcx>}
1674 nop_lift
!{&'a Const<'a> => &'tcx Const<'tcx>}
1676 nop_list_lift
!{Goal<'a> => Goal<'tcx>}
1677 nop_list_lift
!{Clause<'a> => Clause<'tcx>}
1678 nop_list_lift
!{Ty<'a> => Ty<'tcx>}
1679 nop_list_lift
!{ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
1680 nop_list_lift
!{Predicate<'a> => Predicate<'tcx>}
1681 nop_list_lift
!{CanonicalVarInfo => CanonicalVarInfo}
1682 nop_list_lift
!{ProjectionKind => ProjectionKind}
1684 // this is the impl for `&'a InternalSubsts<'a>`
1685 nop_list_lift
!{Kind<'a> => Kind<'tcx>}
1688 use super::{GlobalCtxt, TyCtxt, ptr_eq}
;
1693 use crate::ty
::query
;
1694 use errors
::{Diagnostic, TRACK_DIAGNOSTICS}
;
1695 use rustc_data_structures
::OnDrop
;
1696 use rustc_data_structures
::sync
::{self, Lrc, Lock}
;
1697 use rustc_data_structures
::thin_vec
::ThinVec
;
1698 use crate::dep_graph
::TaskDeps
;
1700 #[cfg(not(parallel_compiler))]
1701 use std
::cell
::Cell
;
1703 #[cfg(parallel_compiler)]
1704 use rustc_rayon_core
as rayon_core
;
1706 /// This is the implicit state of rustc. It contains the current
1707 /// TyCtxt and query. It is updated when creating a local interner or
1708 /// executing a new query. Whenever there's a TyCtxt value available
1709 /// you should also have access to an ImplicitCtxt through the functions
1712 pub struct ImplicitCtxt
<'a
, 'tcx
> {
1713 /// The current TyCtxt. Initially created by `enter_global` and updated
1714 /// by `enter_local` with a new local interner
1715 pub tcx
: TyCtxt
<'tcx
>,
1717 /// The current query job, if any. This is updated by JobOwner::start in
1718 /// ty::query::plumbing when executing a query
1719 pub query
: Option
<Lrc
<query
::QueryJob
<'tcx
>>>,
1721 /// Where to store diagnostics for the current query job, if any.
1722 /// This is updated by JobOwner::start in ty::query::plumbing when executing a query
1723 pub diagnostics
: Option
<&'a Lock
<ThinVec
<Diagnostic
>>>,
1725 /// Used to prevent layout from recursing too deeply.
1726 pub layout_depth
: usize,
1728 /// The current dep graph task. This is used to add dependencies to queries
1729 /// when executing them
1730 pub task_deps
: Option
<&'a Lock
<TaskDeps
>>,
1733 /// Sets Rayon's thread local variable which is preserved for Rayon jobs
1734 /// to `value` during the call to `f`. It is restored to its previous value after.
1735 /// This is used to set the pointer to the new ImplicitCtxt.
1736 #[cfg(parallel_compiler)]
1738 fn set_tlv
<F
: FnOnce() -> R
, R
>(value
: usize, f
: F
) -> R
{
1739 rayon_core
::tlv
::with(value
, f
)
1742 /// Gets Rayon's thread local variable which is preserved for Rayon jobs.
1743 /// This is used to get the pointer to the current ImplicitCtxt.
1744 #[cfg(parallel_compiler)]
1746 fn get_tlv() -> usize {
1747 rayon_core
::tlv
::get()
1750 #[cfg(not(parallel_compiler))]
1752 /// A thread local variable which stores a pointer to the current ImplicitCtxt.
1753 static TLV
: Cell
<usize> = Cell
::new(0);
1756 /// Sets TLV to `value` during the call to `f`.
1757 /// It is restored to its previous value after.
1758 /// This is used to set the pointer to the new ImplicitCtxt.
1759 #[cfg(not(parallel_compiler))]
1761 fn set_tlv
<F
: FnOnce() -> R
, R
>(value
: usize, f
: F
) -> R
{
1762 let old
= get_tlv();
1763 let _reset
= OnDrop(move || TLV
.with(|tlv
| tlv
.set(old
)));
1764 TLV
.with(|tlv
| tlv
.set(value
));
1768 /// This is used to get the pointer to the current ImplicitCtxt.
1769 #[cfg(not(parallel_compiler))]
1770 fn get_tlv() -> usize {
1771 TLV
.with(|tlv
| tlv
.get())
1774 /// This is a callback from libsyntax as it cannot access the implicit state
1775 /// in librustc otherwise
1776 fn span_debug(span
: syntax_pos
::Span
, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1778 if let Some(tcx
) = tcx
{
1779 write
!(f
, "{}", tcx
.sess
.source_map().span_to_string(span
))
1781 syntax_pos
::default_span_debug(span
, f
)
1786 /// This is a callback from libsyntax as it cannot access the implicit state
1787 /// in librustc otherwise. It is used to when diagnostic messages are
1788 /// emitted and stores them in the current query, if there is one.
1789 fn track_diagnostic(diagnostic
: &Diagnostic
) {
1790 with_context_opt(|icx
| {
1791 if let Some(icx
) = icx
{
1792 if let Some(ref diagnostics
) = icx
.diagnostics
{
1793 let mut diagnostics
= diagnostics
.lock();
1794 diagnostics
.extend(Some(diagnostic
.clone()));
1800 /// Sets up the callbacks from libsyntax on the current thread
1801 pub fn with_thread_locals
<F
, R
>(f
: F
) -> R
1802 where F
: FnOnce() -> R
1804 syntax_pos
::SPAN_DEBUG
.with(|span_dbg
| {
1805 let original_span_debug
= span_dbg
.get();
1806 span_dbg
.set(span_debug
);
1808 let _on_drop
= OnDrop(move || {
1809 span_dbg
.set(original_span_debug
);
1812 TRACK_DIAGNOSTICS
.with(|current
| {
1813 let original
= current
.get();
1814 current
.set(track_diagnostic
);
1816 let _on_drop
= OnDrop(move || {
1817 current
.set(original
);
1825 /// Sets `context` as the new current ImplicitCtxt for the duration of the function `f`
1827 pub fn enter_context
<'a
, 'tcx
, F
, R
>(context
: &ImplicitCtxt
<'a
, 'tcx
>, f
: F
) -> R
1829 F
: FnOnce(&ImplicitCtxt
<'a
, 'tcx
>) -> R
,
1831 set_tlv(context
as *const _
as usize, || {
1836 /// Enters GlobalCtxt by setting up libsyntax callbacks and
1837 /// creating a initial TyCtxt and ImplicitCtxt.
1838 /// This happens once per rustc session and TyCtxts only exists
1839 /// inside the `f` function.
1840 pub fn enter_global
<'tcx
, F
, R
>(gcx
: &'tcx GlobalCtxt
<'tcx
>, f
: F
) -> R
1842 F
: FnOnce(TyCtxt
<'tcx
>) -> R
,
1844 // Update GCX_PTR to indicate there's a GlobalCtxt available
1845 GCX_PTR
.with(|lock
| {
1846 *lock
.lock() = gcx
as *const _
as usize;
1848 // Set GCX_PTR back to 0 when we exit
1849 let _on_drop
= OnDrop(move || {
1850 GCX_PTR
.with(|lock
| *lock
.lock() = 0);
1856 let icx
= ImplicitCtxt
{
1863 enter_context(&icx
, |_
| {
1868 scoped_thread_local
! {
1869 /// Stores a pointer to the GlobalCtxt if one is available.
1870 /// This is used to access the GlobalCtxt in the deadlock handler given to Rayon.
1871 pub static GCX_PTR
: Lock
<usize>
1874 /// Creates a TyCtxt and ImplicitCtxt based on the GCX_PTR thread local.
1875 /// This is used in the deadlock handler.
1876 pub unsafe fn with_global
<F
, R
>(f
: F
) -> R
1878 F
: for<'tcx
> FnOnce(TyCtxt
<'tcx
>) -> R
,
1880 let gcx
= GCX_PTR
.with(|lock
| *lock
.lock());
1882 let gcx
= &*(gcx
as *const GlobalCtxt
<'_
>);
1886 let icx
= ImplicitCtxt
{
1893 enter_context(&icx
, |_
| f(tcx
))
1896 /// Allows access to the current ImplicitCtxt in a closure if one is available
1898 pub fn with_context_opt
<F
, R
>(f
: F
) -> R
1900 F
: for<'a
, 'tcx
> FnOnce(Option
<&ImplicitCtxt
<'a
, 'tcx
>>) -> R
,
1902 let context
= get_tlv();
1906 // We could get a ImplicitCtxt pointer from another thread.
1907 // Ensure that ImplicitCtxt is Sync
1908 sync
::assert_sync
::<ImplicitCtxt
<'_
, '_
>>();
1910 unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
1914 /// Allows access to the current ImplicitCtxt.
1915 /// Panics if there is no ImplicitCtxt available
1917 pub fn with_context
<F
, R
>(f
: F
) -> R
1919 F
: for<'a
, 'tcx
> FnOnce(&ImplicitCtxt
<'a
, 'tcx
>) -> R
,
1921 with_context_opt(|opt_context
| f(opt_context
.expect("no ImplicitCtxt stored in tls")))
1924 /// Allows access to the current ImplicitCtxt whose tcx field has the same global
1925 /// interner as the tcx argument passed in. This means the closure is given an ImplicitCtxt
1926 /// with the same 'tcx lifetime as the TyCtxt passed in.
1927 /// This will panic if you pass it a TyCtxt which has a different global interner from
1928 /// the current ImplicitCtxt's tcx field.
1930 pub fn with_related_context
<'tcx
, F
, R
>(tcx
: TyCtxt
<'tcx
>, f
: F
) -> R
1932 F
: FnOnce(&ImplicitCtxt
<'_
, 'tcx
>) -> R
,
1934 with_context(|context
| {
1936 assert
!(ptr_eq(context
.tcx
.gcx
, tcx
.gcx
));
1937 let context
: &ImplicitCtxt
<'_
, '_
> = mem
::transmute(context
);
1943 /// Allows access to the TyCtxt in the current ImplicitCtxt.
1944 /// Panics if there is no ImplicitCtxt available
1946 pub fn with
<F
, R
>(f
: F
) -> R
1948 F
: for<'tcx
> FnOnce(TyCtxt
<'tcx
>) -> R
,
1950 with_context(|context
| f(context
.tcx
))
1953 /// Allows access to the TyCtxt in the current ImplicitCtxt.
1954 /// The closure is passed None if there is no ImplicitCtxt available
1956 pub fn with_opt
<F
, R
>(f
: F
) -> R
1958 F
: for<'tcx
> FnOnce(Option
<TyCtxt
<'tcx
>>) -> R
,
1960 with_context_opt(|opt_context
| f(opt_context
.map(|context
| context
.tcx
)))
1964 macro_rules
! sty_debug_print
{
1965 ($ctxt
: expr
, $
($variant
: ident
),*) => {{
1966 // curious inner module to allow variant names to be used as
1968 #[allow(non_snake_case)]
1970 use crate::ty
::{self, TyCtxt}
;
1971 use crate::ty
::context
::Interned
;
1973 #[derive(Copy, Clone)]
1982 pub fn go(tcx
: TyCtxt
<'_
>) {
1983 let mut total
= DebugStat
{
1990 $
(let mut $variant
= total
;)*
1992 let shards
= tcx
.interners
.type_
.lock_shards();
1993 let types
= shards
.iter().flat_map(|shard
| shard
.keys());
1994 for &Interned(t
) in types
{
1995 let variant
= match t
.sty
{
1996 ty
::Bool
| ty
::Char
| ty
::Int(..) | ty
::Uint(..) |
1997 ty
::Float(..) | ty
::Str
| ty
::Never
=> continue,
1998 ty
::Error
=> /* unimportant */ continue,
1999 $
(ty
::$
variant(..) => &mut $variant
,)*
2001 let lt
= t
.flags
.intersects(ty
::TypeFlags
::HAS_RE_INFER
);
2002 let ty
= t
.flags
.intersects(ty
::TypeFlags
::HAS_TY_INFER
);
2003 let ct
= t
.flags
.intersects(ty
::TypeFlags
::HAS_CT_INFER
);
2007 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2008 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2009 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2010 if lt
&& ty
&& ct { total.all_infer += 1; variant.all_infer += 1 }
2012 println
!("Ty interner total ty lt ct all");
2013 $
(println
!(" {:18}: {uses:6} {usespc:4.1}%, \
2014 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2015 stringify
!($variant
),
2016 uses
= $variant
.total
,
2017 usespc
= $variant
.total
as f64 * 100.0 / total
.total
as f64,
2018 ty
= $variant
.ty_infer
as f64 * 100.0 / total
.total
as f64,
2019 lt
= $variant
.lt_infer
as f64 * 100.0 / total
.total
as f64,
2020 ct
= $variant
.ct_infer
as f64 * 100.0 / total
.total
as f64,
2021 all
= $variant
.all_infer
as f64 * 100.0 / total
.total
as f64);
2023 println
!(" total {uses:6} \
2024 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2026 ty
= total
.ty_infer
as f64 * 100.0 / total
.total
as f64,
2027 lt
= total
.lt_infer
as f64 * 100.0 / total
.total
as f64,
2028 ct
= total
.ct_infer
as f64 * 100.0 / total
.total
as f64,
2029 all
= total
.all_infer
as f64 * 100.0 / total
.total
as f64)
2037 impl<'tcx
> TyCtxt
<'tcx
> {
2038 pub fn print_debug_stats(self) {
2041 Adt
, Array
, Slice
, RawPtr
, Ref
, FnDef
, FnPtr
, Placeholder
,
2042 Generator
, GeneratorWitness
, Dynamic
, Closure
, Tuple
, Bound
,
2043 Param
, Infer
, UnnormalizedProjection
, Projection
, Opaque
, Foreign
);
2045 println
!("InternalSubsts interner: #{}", self.interners
.substs
.len());
2046 println
!("Region interner: #{}", self.interners
.region
.len());
2047 println
!("Stability interner: #{}", self.stability_interner
.len());
2048 println
!("Allocation interner: #{}", self.allocation_interner
.len());
2049 println
!("Layout interner: #{}", self.layout_interner
.len());
2054 /// An entry in an interner.
2055 struct Interned
<'tcx
, T
: ?Sized
>(&'tcx T
);
2057 impl<'tcx
, T
: 'tcx
+?Sized
> Clone
for Interned
<'tcx
, T
> {
2058 fn clone(&self) -> Self {
2062 impl<'tcx
, T
: 'tcx
+?Sized
> Copy
for Interned
<'tcx
, T
> {}
2064 // N.B., an `Interned<Ty>` compares and hashes as a sty.
2065 impl<'tcx
> PartialEq
for Interned
<'tcx
, TyS
<'tcx
>> {
2066 fn eq(&self, other
: &Interned
<'tcx
, TyS
<'tcx
>>) -> bool
{
2067 self.0.sty
== other
.0.sty
2071 impl<'tcx
> Eq
for Interned
<'tcx
, TyS
<'tcx
>> {}
2073 impl<'tcx
> Hash
for Interned
<'tcx
, TyS
<'tcx
>> {
2074 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
2079 #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
2080 impl<'tcx
> Borrow
<TyKind
<'tcx
>> for Interned
<'tcx
, TyS
<'tcx
>> {
2081 fn borrow
<'a
>(&'a
self) -> &'a TyKind
<'tcx
> {
2086 // N.B., an `Interned<List<T>>` compares and hashes as its elements.
2087 impl<'tcx
, T
: PartialEq
> PartialEq
for Interned
<'tcx
, List
<T
>> {
2088 fn eq(&self, other
: &Interned
<'tcx
, List
<T
>>) -> bool
{
2089 self.0[..] == other
.0[..]
2093 impl<'tcx
, T
: Eq
> Eq
for Interned
<'tcx
, List
<T
>> {}
2095 impl<'tcx
, T
: Hash
> Hash
for Interned
<'tcx
, List
<T
>> {
2096 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
2101 impl<'tcx
> Borrow
<[Ty
<'tcx
>]> for Interned
<'tcx
, List
<Ty
<'tcx
>>> {
2102 fn borrow
<'a
>(&'a
self) -> &'a
[Ty
<'tcx
>] {
2107 impl<'tcx
> Borrow
<[CanonicalVarInfo
]> for Interned
<'tcx
, List
<CanonicalVarInfo
>> {
2108 fn borrow(&self) -> &[CanonicalVarInfo
] {
2113 impl<'tcx
> Borrow
<[Kind
<'tcx
>]> for Interned
<'tcx
, InternalSubsts
<'tcx
>> {
2114 fn borrow
<'a
>(&'a
self) -> &'a
[Kind
<'tcx
>] {
2119 impl<'tcx
> Borrow
<[ProjectionKind
]>
2120 for Interned
<'tcx
, List
<ProjectionKind
>> {
2121 fn borrow(&self) -> &[ProjectionKind
] {
2126 impl<'tcx
> Borrow
<RegionKind
> for Interned
<'tcx
, RegionKind
> {
2127 fn borrow(&self) -> &RegionKind
{
2132 impl<'tcx
> Borrow
<GoalKind
<'tcx
>> for Interned
<'tcx
, GoalKind
<'tcx
>> {
2133 fn borrow
<'a
>(&'a
self) -> &'a GoalKind
<'tcx
> {
2138 impl<'tcx
> Borrow
<[ExistentialPredicate
<'tcx
>]>
2139 for Interned
<'tcx
, List
<ExistentialPredicate
<'tcx
>>>
2141 fn borrow
<'a
>(&'a
self) -> &'a
[ExistentialPredicate
<'tcx
>] {
2146 impl<'tcx
> Borrow
<[Predicate
<'tcx
>]> for Interned
<'tcx
, List
<Predicate
<'tcx
>>> {
2147 fn borrow
<'a
>(&'a
self) -> &'a
[Predicate
<'tcx
>] {
2152 impl<'tcx
> Borrow
<Const
<'tcx
>> for Interned
<'tcx
, Const
<'tcx
>> {
2153 fn borrow
<'a
>(&'a
self) -> &'a Const
<'tcx
> {
2158 impl<'tcx
> Borrow
<[Clause
<'tcx
>]> for Interned
<'tcx
, List
<Clause
<'tcx
>>> {
2159 fn borrow
<'a
>(&'a
self) -> &'a
[Clause
<'tcx
>] {
2164 impl<'tcx
> Borrow
<[Goal
<'tcx
>]> for Interned
<'tcx
, List
<Goal
<'tcx
>>> {
2165 fn borrow
<'a
>(&'a
self) -> &'a
[Goal
<'tcx
>] {
2170 macro_rules
! intern_method
{
2171 ($lt_tcx
:tt
, $name
:ident
: $method
:ident($alloc
:ty
,
2173 $alloc_to_key
:expr
) -> $ty
:ty
) => {
2174 impl<$lt_tcx
> TyCtxt
<$lt_tcx
> {
2175 pub fn $
method(self, v
: $alloc
) -> &$lt_tcx $ty
{
2176 let key
= ($alloc_to_key
)(&v
);
2178 self.interners
.$name
.intern_ref(key
, || {
2179 Interned($
alloc_method(&self.interners
.arena
, v
))
2187 macro_rules
! direct_interners
{
2188 ($lt_tcx
:tt
, $
($name
:ident
: $method
:ident($ty
:ty
)),+) => {
2189 $
(impl<$lt_tcx
> PartialEq
for Interned
<$lt_tcx
, $ty
> {
2190 fn eq(&self, other
: &Self) -> bool
{
2195 impl<$lt_tcx
> Eq
for Interned
<$lt_tcx
, $ty
> {}
2197 impl<$lt_tcx
> Hash
for Interned
<$lt_tcx
, $ty
> {
2198 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
2206 |a
: &$lt_tcx SyncDroplessArena
, v
| -> &$lt_tcx $ty { a.alloc(v) }
,
2211 pub fn keep_local
<'tcx
, T
: ty
::TypeFoldable
<'tcx
>>(x
: &T
) -> bool
{
2212 x
.has_type_flags(ty
::TypeFlags
::KEEP_IN_LOCAL_TCX
)
2215 direct_interners
!('tcx
,
2216 region
: mk_region(RegionKind
),
2217 goal
: mk_goal(GoalKind
<'tcx
>),
2218 const_
: mk_const(Const
<'tcx
>)
2221 macro_rules
! slice_interners
{
2222 ($
($field
:ident
: $method
:ident($ty
:ty
)),+) => (
2223 $
(intern_method
!( 'tcx
, $field
: $
method(
2225 |a
, v
| List
::from_arena(a
, v
),
2226 Deref
::deref
) -> List
<$ty
>);)+
2231 existential_predicates
: _intern_existential_predicates(ExistentialPredicate
<'tcx
>),
2232 predicates
: _intern_predicates(Predicate
<'tcx
>),
2233 type_list
: _intern_type_list(Ty
<'tcx
>),
2234 substs
: _intern_substs(Kind
<'tcx
>),
2235 clauses
: _intern_clauses(Clause
<'tcx
>),
2236 goal_list
: _intern_goals(Goal
<'tcx
>),
2237 projs
: _intern_projs(ProjectionKind
)
2240 // This isn't a perfect fit: CanonicalVarInfo slices are always
2241 // allocated in the global arena, so this `intern_method!` macro is
2242 // overly general. But we just return false for the code that checks
2243 // whether they belong in the thread-local arena, so no harm done, and
2244 // seems better than open-coding the rest.
2247 canonical_var_infos
: _intern_canonical_var_infos(
2248 &[CanonicalVarInfo
],
2249 |a
, v
| List
::from_arena(a
, v
),
2251 ) -> List
<CanonicalVarInfo
>
2254 impl<'tcx
> TyCtxt
<'tcx
> {
2255 /// Given a `fn` type, returns an equivalent `unsafe fn` type;
2256 /// that is, a `fn` type that is equivalent in every way for being
2258 pub fn safe_to_unsafe_fn_ty(self, sig
: PolyFnSig
<'tcx
>) -> Ty
<'tcx
> {
2259 assert_eq
!(sig
.unsafety(), hir
::Unsafety
::Normal
);
2260 self.mk_fn_ptr(sig
.map_bound(|sig
| ty
::FnSig
{
2261 unsafety
: hir
::Unsafety
::Unsafe
,
2266 /// Given a closure signature `sig`, returns an equivalent `fn`
2267 /// type with the same signature. Detuples and so forth -- so
2268 /// e.g., if we have a sig with `Fn<(u32, i32)>` then you would get
2269 /// a `fn(u32, i32)`.
2270 /// `unsafety` determines the unsafety of the `fn` type. If you pass
2271 /// `hir::Unsafety::Unsafe` in the previous example, then you would get
2272 /// an `unsafe fn (u32, i32)`.
2273 /// It cannot convert a closure that requires unsafe.
2274 pub fn coerce_closure_fn_ty(self, sig
: PolyFnSig
<'tcx
>, unsafety
: hir
::Unsafety
) -> Ty
<'tcx
> {
2275 let converted_sig
= sig
.map_bound(|s
| {
2276 let params_iter
= match s
.inputs()[0].sty
{
2277 ty
::Tuple(params
) => {
2278 params
.into_iter().map(|k
| k
.expect_ty())
2291 self.mk_fn_ptr(converted_sig
)
2294 #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
2296 pub fn mk_ty(&self, st
: TyKind
<'tcx
>) -> Ty
<'tcx
> {
2297 self.interners
.intern_ty(st
)
2300 pub fn mk_mach_int(self, tm
: ast
::IntTy
) -> Ty
<'tcx
> {
2302 ast
::IntTy
::Isize
=> self.types
.isize,
2303 ast
::IntTy
::I8
=> self.types
.i8,
2304 ast
::IntTy
::I16
=> self.types
.i16,
2305 ast
::IntTy
::I32
=> self.types
.i32,
2306 ast
::IntTy
::I64
=> self.types
.i64,
2307 ast
::IntTy
::I128
=> self.types
.i128
,
2311 pub fn mk_mach_uint(self, tm
: ast
::UintTy
) -> Ty
<'tcx
> {
2313 ast
::UintTy
::Usize
=> self.types
.usize,
2314 ast
::UintTy
::U8
=> self.types
.u8,
2315 ast
::UintTy
::U16
=> self.types
.u16,
2316 ast
::UintTy
::U32
=> self.types
.u32,
2317 ast
::UintTy
::U64
=> self.types
.u64,
2318 ast
::UintTy
::U128
=> self.types
.u128
,
2322 pub fn mk_mach_float(self, tm
: ast
::FloatTy
) -> Ty
<'tcx
> {
2324 ast
::FloatTy
::F32
=> self.types
.f32,
2325 ast
::FloatTy
::F64
=> self.types
.f64,
2330 pub fn mk_str(self) -> Ty
<'tcx
> {
2335 pub fn mk_static_str(self) -> Ty
<'tcx
> {
2336 self.mk_imm_ref(self.lifetimes
.re_static
, self.mk_str())
2340 pub fn mk_adt(self, def
: &'tcx AdtDef
, substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2341 // take a copy of substs so that we own the vectors inside
2342 self.mk_ty(Adt(def
, substs
))
2346 pub fn mk_foreign(self, def_id
: DefId
) -> Ty
<'tcx
> {
2347 self.mk_ty(Foreign(def_id
))
2350 fn mk_generic_adt(self, wrapper_def_id
: DefId
, ty_param
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2351 let adt_def
= self.adt_def(wrapper_def_id
);
2352 let substs
= InternalSubsts
::for_item(self, wrapper_def_id
, |param
, substs
| {
2354 GenericParamDefKind
::Lifetime
|
2355 GenericParamDefKind
::Const
=> {
2358 GenericParamDefKind
::Type { has_default, .. }
=> {
2359 if param
.index
== 0 {
2362 assert
!(has_default
);
2363 self.type_of(param
.def_id
).subst(self, substs
).into()
2368 self.mk_ty(Adt(adt_def
, substs
))
2372 pub fn mk_box(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2373 let def_id
= self.require_lang_item(lang_items
::OwnedBoxLangItem
);
2374 self.mk_generic_adt(def_id
, ty
)
2378 pub fn mk_maybe_uninit(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2379 let def_id
= self.require_lang_item(lang_items
::MaybeUninitLangItem
);
2380 self.mk_generic_adt(def_id
, ty
)
2384 pub fn mk_ptr(self, tm
: TypeAndMut
<'tcx
>) -> Ty
<'tcx
> {
2385 self.mk_ty(RawPtr(tm
))
2389 pub fn mk_ref(self, r
: Region
<'tcx
>, tm
: TypeAndMut
<'tcx
>) -> Ty
<'tcx
> {
2390 self.mk_ty(Ref(r
, tm
.ty
, tm
.mutbl
))
2394 pub fn mk_mut_ref(self, r
: Region
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2395 self.mk_ref(r
, TypeAndMut {ty: ty, mutbl: hir::MutMutable}
)
2399 pub fn mk_imm_ref(self, r
: Region
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2400 self.mk_ref(r
, TypeAndMut {ty: ty, mutbl: hir::MutImmutable}
)
2404 pub fn mk_mut_ptr(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2405 self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutMutable}
)
2409 pub fn mk_imm_ptr(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2410 self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutImmutable}
)
2414 pub fn mk_nil_ptr(self) -> Ty
<'tcx
> {
2415 self.mk_imm_ptr(self.mk_unit())
2419 pub fn mk_array(self, ty
: Ty
<'tcx
>, n
: u64) -> Ty
<'tcx
> {
2420 self.mk_ty(Array(ty
, ty
::Const
::from_usize(self.global_tcx(), n
)))
2424 pub fn mk_slice(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2425 self.mk_ty(Slice(ty
))
2429 pub fn intern_tup(self, ts
: &[Ty
<'tcx
>]) -> Ty
<'tcx
> {
2430 let kinds
: Vec
<_
> = ts
.into_iter().map(|&t
| Kind
::from(t
)).collect();
2431 self.mk_ty(Tuple(self.intern_substs(&kinds
)))
2434 pub fn mk_tup
<I
: InternAs
<[Ty
<'tcx
>], Ty
<'tcx
>>>(self, iter
: I
) -> I
::Output
{
2435 iter
.intern_with(|ts
| {
2436 let kinds
: Vec
<_
> = ts
.into_iter().map(|&t
| Kind
::from(t
)).collect();
2437 self.mk_ty(Tuple(self.intern_substs(&kinds
)))
2442 pub fn mk_unit(self) -> Ty
<'tcx
> {
2447 pub fn mk_diverging_default(self) -> Ty
<'tcx
> {
2448 if self.features().never_type
{
2451 self.intern_tup(&[])
2456 pub fn mk_bool(self) -> Ty
<'tcx
> {
2461 pub fn mk_fn_def(self, def_id
: DefId
,
2462 substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2463 self.mk_ty(FnDef(def_id
, substs
))
2467 pub fn mk_fn_ptr(self, fty
: PolyFnSig
<'tcx
>) -> Ty
<'tcx
> {
2468 self.mk_ty(FnPtr(fty
))
2474 obj
: ty
::Binder
<&'tcx List
<ExistentialPredicate
<'tcx
>>>,
2475 reg
: ty
::Region
<'tcx
>
2477 self.mk_ty(Dynamic(obj
, reg
))
2481 pub fn mk_projection(self,
2483 substs
: SubstsRef
<'tcx
>)
2485 self.mk_ty(Projection(ProjectionTy
{
2492 pub fn mk_closure(self, closure_id
: DefId
, closure_substs
: ClosureSubsts
<'tcx
>)
2494 self.mk_ty(Closure(closure_id
, closure_substs
))
2498 pub fn mk_generator(self,
2500 generator_substs
: GeneratorSubsts
<'tcx
>,
2501 movability
: hir
::GeneratorMovability
)
2503 self.mk_ty(Generator(id
, generator_substs
, movability
))
2507 pub fn mk_generator_witness(self, types
: ty
::Binder
<&'tcx List
<Ty
<'tcx
>>>) -> Ty
<'tcx
> {
2508 self.mk_ty(GeneratorWitness(types
))
2512 pub fn mk_ty_var(self, v
: TyVid
) -> Ty
<'tcx
> {
2513 self.mk_ty_infer(TyVar(v
))
2517 pub fn mk_const_var(self, v
: ConstVid
<'tcx
>, ty
: Ty
<'tcx
>) -> &'tcx Const
<'tcx
> {
2518 self.mk_const(ty
::Const
{
2519 val
: ConstValue
::Infer(InferConst
::Var(v
)),
2525 pub fn mk_int_var(self, v
: IntVid
) -> Ty
<'tcx
> {
2526 self.mk_ty_infer(IntVar(v
))
2530 pub fn mk_float_var(self, v
: FloatVid
) -> Ty
<'tcx
> {
2531 self.mk_ty_infer(FloatVar(v
))
2535 pub fn mk_ty_infer(self, it
: InferTy
) -> Ty
<'tcx
> {
2536 self.mk_ty(Infer(it
))
2540 pub fn mk_const_infer(
2542 ic
: InferConst
<'tcx
>,
2544 ) -> &'tcx ty
::Const
<'tcx
> {
2545 self.mk_const(ty
::Const
{
2546 val
: ConstValue
::Infer(ic
),
2552 pub fn mk_ty_param(self, index
: u32, name
: InternedString
) -> Ty
<'tcx
> {
2553 self.mk_ty(Param(ParamTy { index, name: name }
))
2557 pub fn mk_const_param(
2560 name
: InternedString
,
2562 ) -> &'tcx Const
<'tcx
> {
2563 self.mk_const(ty
::Const
{
2564 val
: ConstValue
::Param(ParamConst { index, name }
),
2570 pub fn mk_self_type(self) -> Ty
<'tcx
> {
2571 self.mk_ty_param(0, kw
::SelfUpper
.as_interned_str())
2574 pub fn mk_param_from_def(self, param
: &ty
::GenericParamDef
) -> Kind
<'tcx
> {
2576 GenericParamDefKind
::Lifetime
=> {
2577 self.mk_region(ty
::ReEarlyBound(param
.to_early_bound_region_data())).into()
2579 GenericParamDefKind
::Type { .. }
=> self.mk_ty_param(param
.index
, param
.name
).into(),
2580 GenericParamDefKind
::Const
=> {
2581 self.mk_const_param(param
.index
, param
.name
, self.type_of(param
.def_id
)).into()
2587 pub fn mk_opaque(self, def_id
: DefId
, substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2588 self.mk_ty(Opaque(def_id
, substs
))
2591 pub fn intern_existential_predicates(self, eps
: &[ExistentialPredicate
<'tcx
>])
2592 -> &'tcx List
<ExistentialPredicate
<'tcx
>> {
2593 assert
!(!eps
.is_empty());
2594 assert
!(eps
.windows(2).all(|w
| w
[0].stable_cmp(self, &w
[1]) != Ordering
::Greater
));
2595 self._intern_existential_predicates(eps
)
2598 pub fn intern_predicates(self, preds
: &[Predicate
<'tcx
>])
2599 -> &'tcx List
<Predicate
<'tcx
>> {
2600 // FIXME consider asking the input slice to be sorted to avoid
2601 // re-interning permutations, in which case that would be asserted
2603 if preds
.len() == 0 {
2604 // The macro-generated method below asserts we don't intern an empty slice.
2607 self._intern_predicates(preds
)
2611 pub fn intern_type_list(self, ts
: &[Ty
<'tcx
>]) -> &'tcx List
<Ty
<'tcx
>> {
2615 self._intern_type_list(ts
)
2619 pub fn intern_substs(self, ts
: &[Kind
<'tcx
>]) -> &'tcx List
<Kind
<'tcx
>> {
2623 self._intern_substs(ts
)
2627 pub fn intern_projs(self, ps
: &[ProjectionKind
]) -> &'tcx List
<ProjectionKind
> {
2631 self._intern_projs(ps
)
2635 pub fn intern_canonical_var_infos(self, ts
: &[CanonicalVarInfo
]) -> CanonicalVarInfos
<'tcx
> {
2639 self.global_tcx()._intern_canonical_var_infos(ts
)
2643 pub fn intern_clauses(self, ts
: &[Clause
<'tcx
>]) -> Clauses
<'tcx
> {
2647 self._intern_clauses(ts
)
2651 pub fn intern_goals(self, ts
: &[Goal
<'tcx
>]) -> Goals
<'tcx
> {
2655 self._intern_goals(ts
)
2659 pub fn mk_fn_sig
<I
>(self,
2663 unsafety
: hir
::Unsafety
,
2665 -> <I
::Item
as InternIteratorElement
<Ty
<'tcx
>, ty
::FnSig
<'tcx
>>>::Output
2667 I
: Iterator
<Item
: InternIteratorElement
<Ty
<'tcx
>, ty
::FnSig
<'tcx
>>>,
2669 inputs
.chain(iter
::once(output
)).intern_with(|xs
| ty
::FnSig
{
2670 inputs_and_output
: self.intern_type_list(xs
),
2671 c_variadic
, unsafety
, abi
2675 pub fn mk_existential_predicates
<I
: InternAs
<[ExistentialPredicate
<'tcx
>],
2676 &'tcx List
<ExistentialPredicate
<'tcx
>>>>(self, iter
: I
)
2678 iter
.intern_with(|xs
| self.intern_existential_predicates(xs
))
2681 pub fn mk_predicates
<I
: InternAs
<[Predicate
<'tcx
>],
2682 &'tcx List
<Predicate
<'tcx
>>>>(self, iter
: I
)
2684 iter
.intern_with(|xs
| self.intern_predicates(xs
))
2687 pub fn mk_type_list
<I
: InternAs
<[Ty
<'tcx
>],
2688 &'tcx List
<Ty
<'tcx
>>>>(self, iter
: I
) -> I
::Output
{
2689 iter
.intern_with(|xs
| self.intern_type_list(xs
))
2692 pub fn mk_substs
<I
: InternAs
<[Kind
<'tcx
>],
2693 &'tcx List
<Kind
<'tcx
>>>>(self, iter
: I
) -> I
::Output
{
2694 iter
.intern_with(|xs
| self.intern_substs(xs
))
2697 pub fn mk_substs_trait(self,
2699 rest
: &[Kind
<'tcx
>])
2702 self.mk_substs(iter
::once(self_ty
.into()).chain(rest
.iter().cloned()))
2705 pub fn mk_clauses
<I
: InternAs
<[Clause
<'tcx
>], Clauses
<'tcx
>>>(self, iter
: I
) -> I
::Output
{
2706 iter
.intern_with(|xs
| self.intern_clauses(xs
))
2709 pub fn mk_goals
<I
: InternAs
<[Goal
<'tcx
>], Goals
<'tcx
>>>(self, iter
: I
) -> I
::Output
{
2710 iter
.intern_with(|xs
| self.intern_goals(xs
))
2713 pub fn lint_hir
<S
: Into
<MultiSpan
>>(self,
2714 lint
: &'
static Lint
,
2718 self.struct_span_lint_hir(lint
, hir_id
, span
.into(), msg
).emit()
2721 pub fn lint_hir_note
<S
: Into
<MultiSpan
>>(self,
2722 lint
: &'
static Lint
,
2727 let mut err
= self.struct_span_lint_hir(lint
, hir_id
, span
.into(), msg
);
2732 pub fn lint_node_note
<S
: Into
<MultiSpan
>>(self,
2733 lint
: &'
static Lint
,
2738 let mut err
= self.struct_span_lint_hir(lint
, id
, span
.into(), msg
);
2743 /// Walks upwards from `id` to find a node which might change lint levels with attributes.
2744 /// It stops at `bound` and just returns it if reached.
2745 pub fn maybe_lint_level_root_bounded(
2754 if lint
::maybe_lint_level_root(self, id
) {
2757 let next
= self.hir().get_parent_node(id
);
2759 bug
!("lint traversal reached the root of the crate");
2765 pub fn lint_level_at_node(
2767 lint
: &'
static Lint
,
2769 ) -> (lint
::Level
, lint
::LintSource
) {
2770 let sets
= self.lint_levels(LOCAL_CRATE
);
2772 if let Some(pair
) = sets
.level_and_source(lint
, id
, self.sess
) {
2775 let next
= self.hir().get_parent_node(id
);
2777 bug
!("lint traversal reached the root of the crate");
2783 pub fn struct_span_lint_hir
<S
: Into
<MultiSpan
>>(self,
2784 lint
: &'
static Lint
,
2788 -> DiagnosticBuilder
<'tcx
>
2790 let (level
, src
) = self.lint_level_at_node(lint
, hir_id
);
2791 lint
::struct_lint_level(self.sess
, lint
, level
, src
, Some(span
.into()), msg
)
2794 pub fn struct_lint_node(self, lint
: &'
static Lint
, id
: HirId
, msg
: &str)
2795 -> DiagnosticBuilder
<'tcx
>
2797 let (level
, src
) = self.lint_level_at_node(lint
, id
);
2798 lint
::struct_lint_level(self.sess
, lint
, level
, src
, None
, msg
)
2801 pub fn in_scope_traits(self, id
: HirId
) -> Option
<&'tcx StableVec
<TraitCandidate
>> {
2802 self.in_scope_traits_map(id
.owner
)
2803 .and_then(|map
| map
.get(&id
.local_id
))
2806 pub fn named_region(self, id
: HirId
) -> Option
<resolve_lifetime
::Region
> {
2807 self.named_region_map(id
.owner
)
2808 .and_then(|map
| map
.get(&id
.local_id
).cloned())
2811 pub fn is_late_bound(self, id
: HirId
) -> bool
{
2812 self.is_late_bound_map(id
.owner
)
2813 .map(|set
| set
.contains(&id
.local_id
))
2817 pub fn object_lifetime_defaults(self, id
: HirId
) -> Option
<&'tcx
[ObjectLifetimeDefault
]> {
2818 self.object_lifetime_defaults_map(id
.owner
)
2819 .and_then(|map
| map
.get(&id
.local_id
).map(|v
| &**v
))
2823 pub trait InternAs
<T
: ?Sized
, R
> {
2825 fn intern_with
<F
>(self, f
: F
) -> Self::Output
2826 where F
: FnOnce(&T
) -> R
;
2829 impl<I
, T
, R
, E
> InternAs
<[T
], R
> for I
2830 where E
: InternIteratorElement
<T
, R
>,
2831 I
: Iterator
<Item
=E
> {
2832 type Output
= E
::Output
;
2833 fn intern_with
<F
>(self, f
: F
) -> Self::Output
2834 where F
: FnOnce(&[T
]) -> R
{
2835 E
::intern_with(self, f
)
2839 pub trait InternIteratorElement
<T
, R
>: Sized
{
2841 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
;
2844 impl<T
, R
> InternIteratorElement
<T
, R
> for T
{
2846 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
{
2847 f(&iter
.collect
::<SmallVec
<[_
; 8]>>())
2851 impl<'a
, T
, R
> InternIteratorElement
<T
, R
> for &'a T
2855 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
{
2856 f(&iter
.cloned().collect
::<SmallVec
<[_
; 8]>>())
2860 impl<T
, R
, E
> InternIteratorElement
<T
, R
> for Result
<T
, E
> {
2861 type Output
= Result
<R
, E
>;
2862 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
{
2863 Ok(f(&iter
.collect
::<Result
<SmallVec
<[_
; 8]>, _
>>()?
))
2867 // We are comparing types with different invariant lifetimes, so `ptr::eq`
2868 // won't work for us.
2869 fn ptr_eq
<T
, U
>(t
: *const T
, u
: *const U
) -> bool
{
2870 t
as *const () == u
as *const ()
2873 pub fn provide(providers
: &mut ty
::query
::Providers
<'_
>) {
2874 providers
.in_scope_traits_map
= |tcx
, id
| tcx
.gcx
.trait_map
.get(&id
);
2875 providers
.module_exports
= |tcx
, id
| tcx
.gcx
.export_map
.get(&id
).map(|v
| &v
[..]);
2876 providers
.crate_name
= |tcx
, id
| {
2877 assert_eq
!(id
, LOCAL_CRATE
);
2880 providers
.get_lib_features
= |tcx
, id
| {
2881 assert_eq
!(id
, LOCAL_CRATE
);
2882 tcx
.arena
.alloc(middle
::lib_features
::collect(tcx
))
2884 providers
.get_lang_items
= |tcx
, id
| {
2885 assert_eq
!(id
, LOCAL_CRATE
);
2886 tcx
.arena
.alloc(middle
::lang_items
::collect(tcx
))
2888 providers
.maybe_unused_trait_import
= |tcx
, id
| {
2889 tcx
.maybe_unused_trait_imports
.contains(&id
)
2891 providers
.maybe_unused_extern_crates
= |tcx
, cnum
| {
2892 assert_eq
!(cnum
, LOCAL_CRATE
);
2893 &tcx
.maybe_unused_extern_crates
[..]
2895 providers
.names_imported_by_glob_use
= |tcx
, id
| {
2896 assert_eq
!(id
.krate
, LOCAL_CRATE
);
2897 Lrc
::new(tcx
.glob_map
.get(&id
).cloned().unwrap_or_default())
2900 providers
.stability_index
= |tcx
, cnum
| {
2901 assert_eq
!(cnum
, LOCAL_CRATE
);
2902 tcx
.arena
.alloc(stability
::Index
::new(tcx
))
2904 providers
.lookup_stability
= |tcx
, id
| {
2905 assert_eq
!(id
.krate
, LOCAL_CRATE
);
2906 let id
= tcx
.hir().definitions().def_index_to_hir_id(id
.index
);
2907 tcx
.stability().local_stability(id
)
2909 providers
.lookup_deprecation_entry
= |tcx
, id
| {
2910 assert_eq
!(id
.krate
, LOCAL_CRATE
);
2911 let id
= tcx
.hir().definitions().def_index_to_hir_id(id
.index
);
2912 tcx
.stability().local_deprecation_entry(id
)
2914 providers
.extern_mod_stmt_cnum
= |tcx
, id
| {
2915 let id
= tcx
.hir().as_local_node_id(id
).unwrap();
2916 tcx
.cstore
.extern_mod_stmt_cnum_untracked(id
)
2918 providers
.all_crate_nums
= |tcx
, cnum
| {
2919 assert_eq
!(cnum
, LOCAL_CRATE
);
2920 tcx
.arena
.alloc_slice(&tcx
.cstore
.crates_untracked())
2922 providers
.postorder_cnums
= |tcx
, cnum
| {
2923 assert_eq
!(cnum
, LOCAL_CRATE
);
2924 tcx
.arena
.alloc_slice(&tcx
.cstore
.postorder_cnums_untracked())
2926 providers
.output_filenames
= |tcx
, cnum
| {
2927 assert_eq
!(cnum
, LOCAL_CRATE
);
2928 tcx
.output_filenames
.clone()
2930 providers
.features_query
= |tcx
, cnum
| {
2931 assert_eq
!(cnum
, LOCAL_CRATE
);
2932 tcx
.arena
.alloc(tcx
.sess
.features_untracked().clone())
2934 providers
.is_panic_runtime
= |tcx
, cnum
| {
2935 assert_eq
!(cnum
, LOCAL_CRATE
);
2936 attr
::contains_name(tcx
.hir().krate_attrs(), sym
::panic_runtime
)
2938 providers
.is_compiler_builtins
= |tcx
, cnum
| {
2939 assert_eq
!(cnum
, LOCAL_CRATE
);
2940 attr
::contains_name(tcx
.hir().krate_attrs(), sym
::compiler_builtins
)