1 // ignore-tidy-filelength
2 //! Type context book-keeping.
4 use crate::arena
::Arena
;
5 use crate::dep_graph
::DepGraph
;
6 use crate::dep_graph
::{self, DepNode, DepConstructor}
;
7 use crate::session
::Session
;
8 use crate::session
::config
::{BorrowckMode, OutputFilenames}
;
9 use crate::session
::config
::CrateType
;
11 use crate::middle
::lang_items
::PanicLocationLangItem
;
12 use crate::hir
::{self, TraitCandidate, HirId, ItemKind, ItemLocalId, Node}
;
13 use crate::hir
::def
::{Res, DefKind, Export}
;
14 use crate::hir
::def_id
::{CrateNum, DefId, DefIndex, LOCAL_CRATE}
;
15 use crate::hir
::map
as hir_map
;
16 use crate::hir
::map
::DefPathHash
;
17 use crate::lint
::{self, Lint}
;
18 use crate::ich
::{StableHashingContext, NodeIdHashingMode}
;
19 use crate::infer
::canonical
::{Canonical, CanonicalVarInfo, CanonicalVarInfos}
;
20 use crate::infer
::outlives
::free_region_map
::FreeRegionMap
;
21 use crate::middle
::cstore
::CrateStoreDyn
;
22 use crate::middle
::cstore
::EncodedMetadata
;
23 use crate::middle
::lang_items
;
24 use crate::middle
::resolve_lifetime
::{self, ObjectLifetimeDefault}
;
25 use crate::middle
::stability
;
26 use crate::mir
::{BodyAndCache, Field, interpret, Local, Place, PlaceElem, ProjectionKind, Promoted}
;
27 use crate::mir
::interpret
::{ConstValue, Allocation, Scalar}
;
28 use crate::ty
::subst
::{GenericArg, InternalSubsts, SubstsRef, Subst}
;
29 use crate::ty
::ReprOptions
;
31 use crate::traits
::{Clause, Clauses, GoalKind, Goal, Goals}
;
32 use crate::ty
::{self, DefIdTree, Ty, TypeAndMut}
;
33 use crate::ty
::{TyS, TyKind, List}
;
34 use crate::ty
::{AdtKind, AdtDef, Region, Const}
;
35 use crate::ty
::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate}
;
36 use crate::ty
::RegionKind
;
37 use crate::ty
::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid, ConstVid}
;
38 use crate::ty
::TyKind
::*;
39 use crate::ty
::{InferConst, ParamConst}
;
40 use crate::ty
::GenericParamDefKind
;
41 use crate::ty
::layout
::{LayoutDetails, TargetDataLayout, VariantIdx}
;
43 use crate::ty
::steal
::Steal
;
44 use crate::ty
::subst
::{UserSubsts, GenericArgKind}
;
45 use crate::ty
::{BoundVar, BindingMode}
;
46 use crate::ty
::CanonicalPolyFnSig
;
47 use crate::util
::common
::ErrorReported
;
48 use crate::util
::nodemap
::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet, NodeMap}
;
49 use crate::util
::nodemap
::{FxHashMap, FxHashSet}
;
51 use errors
::DiagnosticBuilder
;
52 use arena
::SyncDroplessArena
;
53 use smallvec
::SmallVec
;
54 use rustc_data_structures
::profiling
::SelfProfilerRef
;
55 use rustc_data_structures
::stable_hasher
::{
56 HashStable
, StableHasher
, StableVec
, hash_stable_hashmap
,
58 use rustc_index
::vec
::{Idx, IndexVec}
;
59 use rustc_data_structures
::sharded
::ShardedHashMap
;
60 use rustc_data_structures
::sync
::{Lrc, Lock, WorkerLocal}
;
62 use std
::borrow
::Borrow
;
63 use std
::cmp
::Ordering
;
64 use std
::collections
::hash_map
::{self, Entry}
;
65 use std
::hash
::{Hash, Hasher}
;
68 use std
::ops
::{Deref, Bound}
;
71 use rustc_target
::spec
::abi
;
72 use rustc_macros
::HashStable
;
75 use syntax
::source_map
::MultiSpan
;
76 use syntax
::symbol
::{Symbol, kw, sym}
;
78 use syntax
::expand
::allocator
::AllocatorKind
;
80 pub struct AllArenas
{
81 pub interner
: SyncDroplessArena
,
85 pub fn new() -> Self {
87 interner
: SyncDroplessArena
::default(),
92 type InternedSet
<'tcx
, T
> = ShardedHashMap
<Interned
<'tcx
, T
>, ()>;
94 pub struct CtxtInterners
<'tcx
> {
95 /// The arena that types, regions, etc. are allocated from.
96 arena
: &'tcx SyncDroplessArena
,
98 /// Specifically use a speedy hash algorithm for these hash sets, since
99 /// they're accessed quite often.
100 type_
: InternedSet
<'tcx
, TyS
<'tcx
>>,
101 type_list
: InternedSet
<'tcx
, List
<Ty
<'tcx
>>>,
102 substs
: InternedSet
<'tcx
, InternalSubsts
<'tcx
>>,
103 canonical_var_infos
: InternedSet
<'tcx
, List
<CanonicalVarInfo
>>,
104 region
: InternedSet
<'tcx
, RegionKind
>,
105 existential_predicates
: InternedSet
<'tcx
, List
<ExistentialPredicate
<'tcx
>>>,
106 predicates
: InternedSet
<'tcx
, List
<Predicate
<'tcx
>>>,
107 clauses
: InternedSet
<'tcx
, List
<Clause
<'tcx
>>>,
108 goal
: InternedSet
<'tcx
, GoalKind
<'tcx
>>,
109 goal_list
: InternedSet
<'tcx
, List
<Goal
<'tcx
>>>,
110 projs
: InternedSet
<'tcx
, List
<ProjectionKind
>>,
111 place_elems
: InternedSet
<'tcx
, List
<PlaceElem
<'tcx
>>>,
112 const_
: InternedSet
<'tcx
, Const
<'tcx
>>,
115 impl<'tcx
> CtxtInterners
<'tcx
> {
116 fn new(arena
: &'tcx SyncDroplessArena
) -> CtxtInterners
<'tcx
> {
119 type_
: Default
::default(),
120 type_list
: Default
::default(),
121 substs
: Default
::default(),
122 region
: Default
::default(),
123 existential_predicates
: Default
::default(),
124 canonical_var_infos
: Default
::default(),
125 predicates
: Default
::default(),
126 clauses
: Default
::default(),
127 goal
: Default
::default(),
128 goal_list
: Default
::default(),
129 projs
: Default
::default(),
130 place_elems
: Default
::default(),
131 const_
: Default
::default(),
136 #[allow(rustc::usage_of_ty_tykind)]
141 self.type_
.intern(kind
, |kind
| {
142 let flags
= super::flags
::FlagComputation
::for_kind(&kind
);
144 let ty_struct
= TyS
{
147 outer_exclusive_binder
: flags
.outer_exclusive_binder
,
150 Interned(self.arena
.alloc(ty_struct
))
155 pub struct CommonTypes
<'tcx
> {
174 pub self_param
: Ty
<'tcx
>,
177 /// Dummy type used for the `Self` of a `TraitRef` created for converting
178 /// a trait object, and which gets removed in `ExistentialTraitRef`.
179 /// This type must not appear anywhere in other converted types.
180 pub trait_object_dummy_self
: Ty
<'tcx
>,
183 pub struct CommonLifetimes
<'tcx
> {
184 pub re_empty
: Region
<'tcx
>,
185 pub re_static
: Region
<'tcx
>,
186 pub re_erased
: Region
<'tcx
>,
189 pub struct CommonConsts
<'tcx
> {
190 pub err
: &'tcx Const
<'tcx
>,
193 pub struct LocalTableInContext
<'a
, V
> {
194 local_id_root
: Option
<DefId
>,
195 data
: &'a ItemLocalMap
<V
>
198 /// Validate that the given HirId (respectively its `local_id` part) can be
199 /// safely used as a key in the tables of a TypeckTable. For that to be
200 /// the case, the HirId must have the same `owner` as all the other IDs in
201 /// this table (signified by `local_id_root`). Otherwise the HirId
202 /// would be in a different frame of reference and using its `local_id`
203 /// would result in lookup errors, or worse, in silently wrong data being
205 fn validate_hir_id_for_typeck_tables(local_id_root
: Option
<DefId
>,
208 if let Some(local_id_root
) = local_id_root
{
209 if hir_id
.owner
!= local_id_root
.index
{
210 ty
::tls
::with(|tcx
| {
211 bug
!("node {} with HirId::owner {:?} cannot be placed in \
212 TypeckTables with local_id_root {:?}",
213 tcx
.hir().node_to_string(hir_id
),
214 DefId
::local(hir_id
.owner
),
219 // We use "Null Object" TypeckTables in some of the analysis passes.
220 // These are just expected to be empty and their `local_id_root` is
221 // `None`. Therefore we cannot verify whether a given `HirId` would
222 // be a valid key for the given table. Instead we make sure that
223 // nobody tries to write to such a Null Object table.
225 bug
!("access to invalid TypeckTables")
230 impl<'a
, V
> LocalTableInContext
<'a
, V
> {
231 pub fn contains_key(&self, id
: hir
::HirId
) -> bool
{
232 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
233 self.data
.contains_key(&id
.local_id
)
236 pub fn get(&self, id
: hir
::HirId
) -> Option
<&V
> {
237 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
238 self.data
.get(&id
.local_id
)
241 pub fn iter(&self) -> hash_map
::Iter
<'_
, hir
::ItemLocalId
, V
> {
246 impl<'a
, V
> ::std
::ops
::Index
<hir
::HirId
> for LocalTableInContext
<'a
, V
> {
249 fn index(&self, key
: hir
::HirId
) -> &V
{
250 self.get(key
).expect("LocalTableInContext: key not found")
254 pub struct LocalTableInContextMut
<'a
, V
> {
255 local_id_root
: Option
<DefId
>,
256 data
: &'a
mut ItemLocalMap
<V
>
259 impl<'a
, V
> LocalTableInContextMut
<'a
, V
> {
260 pub fn get_mut(&mut self, id
: hir
::HirId
) -> Option
<&mut V
> {
261 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
262 self.data
.get_mut(&id
.local_id
)
265 pub fn entry(&mut self, id
: hir
::HirId
) -> Entry
<'_
, hir
::ItemLocalId
, V
> {
266 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
267 self.data
.entry(id
.local_id
)
270 pub fn insert(&mut self, id
: hir
::HirId
, val
: V
) -> Option
<V
> {
271 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
272 self.data
.insert(id
.local_id
, val
)
275 pub fn remove(&mut self, id
: hir
::HirId
) -> Option
<V
> {
276 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, true);
277 self.data
.remove(&id
.local_id
)
281 /// All information necessary to validate and reveal an `impl Trait`.
282 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
283 pub struct ResolvedOpaqueTy
<'tcx
> {
284 /// The revealed type as seen by this function.
285 pub concrete_type
: Ty
<'tcx
>,
286 /// Generic parameters on the opaque type as passed by this function.
287 /// For `type Foo<A, B> = impl Bar<A, B>; fn foo<T, U>() -> Foo<T, U> { .. }`
288 /// this is `[T, U]`, not `[A, B]`.
289 pub substs
: SubstsRef
<'tcx
>,
292 /// Whenever a value may be live across a generator yield, the type of that value winds up in the
293 /// `GeneratorInteriorTypeCause` struct. This struct adds additional information about such
294 /// captured types that can be useful for diagnostics. In particular, it stores the span that
295 /// caused a given type to be recorded, along with the scope that enclosed the value (which can
296 /// be used to find the await that the value is live across).
300 /// ```ignore (pseudo-Rust)
308 /// Here, we would store the type `T`, the span of the value `x`, and the "scope-span" for
309 /// the scope that contains `x`.
310 #[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, PartialEq)]
311 #[derive(HashStable, TypeFoldable)]
312 pub struct GeneratorInteriorTypeCause
<'tcx
> {
313 /// Type of the captured binding.
315 /// Span of the binding that was captured.
317 /// Span of the scope of the captured binding.
318 pub scope_span
: Option
<Span
>,
321 #[derive(RustcEncodable, RustcDecodable, Debug)]
322 pub struct TypeckTables
<'tcx
> {
323 /// The HirId::owner all ItemLocalIds in this table are relative to.
324 pub local_id_root
: Option
<DefId
>,
326 /// Resolved definitions for `<T>::X` associated paths and
327 /// method calls, including those of overloaded operators.
328 type_dependent_defs
: ItemLocalMap
<Result
<(DefKind
, DefId
), ErrorReported
>>,
330 /// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
331 /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
332 /// about the field you also need definition of the variant to which the field
333 /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
334 field_indices
: ItemLocalMap
<usize>,
336 /// Stores the types for various nodes in the AST. Note that this table
337 /// is not guaranteed to be populated until after typeck. See
338 /// typeck::check::fn_ctxt for details.
339 node_types
: ItemLocalMap
<Ty
<'tcx
>>,
341 /// Stores the type parameters which were substituted to obtain the type
342 /// of this node. This only applies to nodes that refer to entities
343 /// parameterized by type parameters, such as generic fns, types, or
345 node_substs
: ItemLocalMap
<SubstsRef
<'tcx
>>,
347 /// This will either store the canonicalized types provided by the user
348 /// or the substitutions that the user explicitly gave (if any) attached
349 /// to `id`. These will not include any inferred values. The canonical form
350 /// is used to capture things like `_` or other unspecified values.
352 /// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
353 /// canonical substitutions would include only `for<X> { Vec<X> }`.
355 /// See also `AscribeUserType` statement in MIR.
356 user_provided_types
: ItemLocalMap
<CanonicalUserType
<'tcx
>>,
358 /// Stores the canonicalized types provided by the user. See also
359 /// `AscribeUserType` statement in MIR.
360 pub user_provided_sigs
: DefIdMap
<CanonicalPolyFnSig
<'tcx
>>,
362 adjustments
: ItemLocalMap
<Vec
<ty
::adjustment
::Adjustment
<'tcx
>>>,
364 /// Stores the actual binding mode for all instances of hir::BindingAnnotation.
365 pat_binding_modes
: ItemLocalMap
<BindingMode
>,
367 /// Stores the types which were implicitly dereferenced in pattern binding modes
368 /// for later usage in HAIR lowering. For example,
371 /// match &&Some(5i32) {
376 /// leads to a `vec![&&Option<i32>, &Option<i32>]`. Empty vectors are not stored.
379 /// https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions
380 pat_adjustments
: ItemLocalMap
<Vec
<Ty
<'tcx
>>>,
383 pub upvar_capture_map
: ty
::UpvarCaptureMap
<'tcx
>,
385 /// Records the reasons that we picked the kind of each closure;
386 /// not all closures are present in the map.
387 closure_kind_origins
: ItemLocalMap
<(Span
, ast
::Name
)>,
389 /// For each fn, records the "liberated" types of its arguments
390 /// and return type. Liberated means that all bound regions
391 /// (including late-bound regions) are replaced with free
392 /// equivalents. This table is not used in codegen (since regions
393 /// are erased there) and hence is not serialized to metadata.
394 liberated_fn_sigs
: ItemLocalMap
<ty
::FnSig
<'tcx
>>,
396 /// For each FRU expression, record the normalized types of the fields
397 /// of the struct - this is needed because it is non-trivial to
398 /// normalize while preserving regions. This table is used only in
399 /// MIR construction and hence is not serialized to metadata.
400 fru_field_types
: ItemLocalMap
<Vec
<Ty
<'tcx
>>>,
402 /// For every coercion cast we add the HIR node ID of the cast
403 /// expression to this set.
404 coercion_casts
: ItemLocalSet
,
406 /// Set of trait imports actually used in the method resolution.
407 /// This is used for warning unused imports. During type
408 /// checking, this `Lrc` should not be cloned: it must have a ref-count
409 /// of 1 so that we can insert things into the set mutably.
410 pub used_trait_imports
: Lrc
<DefIdSet
>,
412 /// If any errors occurred while type-checking this body,
413 /// this field will be set to `true`.
414 pub tainted_by_errors
: bool
,
416 /// Stores the free-region relationships that were deduced from
417 /// its where-clauses and parameter types. These are then
418 /// read-again by borrowck.
419 pub free_region_map
: FreeRegionMap
<'tcx
>,
421 /// All the opaque types that are restricted to concrete types
422 /// by this function.
423 pub concrete_opaque_types
: FxHashMap
<DefId
, ResolvedOpaqueTy
<'tcx
>>,
425 /// Given the closure ID this map provides the list of UpvarIDs used by it.
426 /// The upvarID contains the HIR node ID and it also contains the full path
427 /// leading to the member of the struct or tuple that is used instead of the
429 pub upvar_list
: ty
::UpvarListMap
,
431 /// Stores the type, span and optional scope span of all types
432 /// that are live across the yield of this generator (if a generator).
433 pub generator_interior_types
: Vec
<GeneratorInteriorTypeCause
<'tcx
>>,
436 impl<'tcx
> TypeckTables
<'tcx
> {
437 pub fn empty(local_id_root
: Option
<DefId
>) -> TypeckTables
<'tcx
> {
440 type_dependent_defs
: Default
::default(),
441 field_indices
: Default
::default(),
442 user_provided_types
: Default
::default(),
443 user_provided_sigs
: Default
::default(),
444 node_types
: Default
::default(),
445 node_substs
: Default
::default(),
446 adjustments
: Default
::default(),
447 pat_binding_modes
: Default
::default(),
448 pat_adjustments
: Default
::default(),
449 upvar_capture_map
: Default
::default(),
450 closure_kind_origins
: Default
::default(),
451 liberated_fn_sigs
: Default
::default(),
452 fru_field_types
: Default
::default(),
453 coercion_casts
: Default
::default(),
454 used_trait_imports
: Lrc
::new(Default
::default()),
455 tainted_by_errors
: false,
456 free_region_map
: Default
::default(),
457 concrete_opaque_types
: Default
::default(),
458 upvar_list
: Default
::default(),
459 generator_interior_types
: Default
::default(),
463 /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
464 pub fn qpath_res(&self, qpath
: &hir
::QPath
, id
: hir
::HirId
) -> Res
{
466 hir
::QPath
::Resolved(_
, ref path
) => path
.res
,
467 hir
::QPath
::TypeRelative(..) => self.type_dependent_def(id
)
468 .map_or(Res
::Err
, |(kind
, def_id
)| Res
::Def(kind
, def_id
)),
472 pub fn type_dependent_defs(
474 ) -> LocalTableInContext
<'_
, Result
<(DefKind
, DefId
), ErrorReported
>> {
475 LocalTableInContext
{
476 local_id_root
: self.local_id_root
,
477 data
: &self.type_dependent_defs
481 pub fn type_dependent_def(&self, id
: HirId
) -> Option
<(DefKind
, DefId
)> {
482 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
483 self.type_dependent_defs
.get(&id
.local_id
).cloned().and_then(|r
| r
.ok())
486 pub fn type_dependent_def_id(&self, id
: HirId
) -> Option
<DefId
> {
487 self.type_dependent_def(id
).map(|(_
, def_id
)| def_id
)
490 pub fn type_dependent_defs_mut(
492 ) -> LocalTableInContextMut
<'_
, Result
<(DefKind
, DefId
), ErrorReported
>> {
493 LocalTableInContextMut
{
494 local_id_root
: self.local_id_root
,
495 data
: &mut self.type_dependent_defs
499 pub fn field_indices(&self) -> LocalTableInContext
<'_
, usize> {
500 LocalTableInContext
{
501 local_id_root
: self.local_id_root
,
502 data
: &self.field_indices
506 pub fn field_indices_mut(&mut self) -> LocalTableInContextMut
<'_
, usize> {
507 LocalTableInContextMut
{
508 local_id_root
: self.local_id_root
,
509 data
: &mut self.field_indices
513 pub fn user_provided_types(
515 ) -> LocalTableInContext
<'_
, CanonicalUserType
<'tcx
>> {
516 LocalTableInContext
{
517 local_id_root
: self.local_id_root
,
518 data
: &self.user_provided_types
522 pub fn user_provided_types_mut(
524 ) -> LocalTableInContextMut
<'_
, CanonicalUserType
<'tcx
>> {
525 LocalTableInContextMut
{
526 local_id_root
: self.local_id_root
,
527 data
: &mut self.user_provided_types
531 pub fn node_types(&self) -> LocalTableInContext
<'_
, Ty
<'tcx
>> {
532 LocalTableInContext
{
533 local_id_root
: self.local_id_root
,
534 data
: &self.node_types
538 pub fn node_types_mut(&mut self) -> LocalTableInContextMut
<'_
, Ty
<'tcx
>> {
539 LocalTableInContextMut
{
540 local_id_root
: self.local_id_root
,
541 data
: &mut self.node_types
545 pub fn node_type(&self, id
: hir
::HirId
) -> Ty
<'tcx
> {
546 self.node_type_opt(id
).unwrap_or_else(||
547 bug
!("node_type: no type for node `{}`",
548 tls
::with(|tcx
| tcx
.hir().node_to_string(id
)))
552 pub fn node_type_opt(&self, id
: hir
::HirId
) -> Option
<Ty
<'tcx
>> {
553 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
554 self.node_types
.get(&id
.local_id
).cloned()
557 pub fn node_substs_mut(&mut self) -> LocalTableInContextMut
<'_
, SubstsRef
<'tcx
>> {
558 LocalTableInContextMut
{
559 local_id_root
: self.local_id_root
,
560 data
: &mut self.node_substs
564 pub fn node_substs(&self, id
: hir
::HirId
) -> SubstsRef
<'tcx
> {
565 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
566 self.node_substs
.get(&id
.local_id
).cloned().unwrap_or_else(|| InternalSubsts
::empty())
569 pub fn node_substs_opt(&self, id
: hir
::HirId
) -> Option
<SubstsRef
<'tcx
>> {
570 validate_hir_id_for_typeck_tables(self.local_id_root
, id
, false);
571 self.node_substs
.get(&id
.local_id
).cloned()
574 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
575 // doesn't provide type parameter substitutions.
576 pub fn pat_ty(&self, pat
: &hir
::Pat
) -> Ty
<'tcx
> {
577 self.node_type(pat
.hir_id
)
580 pub fn pat_ty_opt(&self, pat
: &hir
::Pat
) -> Option
<Ty
<'tcx
>> {
581 self.node_type_opt(pat
.hir_id
)
584 // Returns the type of an expression as a monotype.
586 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
587 // some cases, we insert `Adjustment` annotations such as auto-deref or
588 // auto-ref. The type returned by this function does not consider such
589 // adjustments. See `expr_ty_adjusted()` instead.
591 // NB (2): This type doesn't provide type parameter substitutions; e.g., if you
592 // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
593 // instead of "fn(ty) -> T with T = isize".
594 pub fn expr_ty(&self, expr
: &hir
::Expr
) -> Ty
<'tcx
> {
595 self.node_type(expr
.hir_id
)
598 pub fn expr_ty_opt(&self, expr
: &hir
::Expr
) -> Option
<Ty
<'tcx
>> {
599 self.node_type_opt(expr
.hir_id
)
602 pub fn adjustments(&self) -> LocalTableInContext
<'_
, Vec
<ty
::adjustment
::Adjustment
<'tcx
>>> {
603 LocalTableInContext
{
604 local_id_root
: self.local_id_root
,
605 data
: &self.adjustments
609 pub fn adjustments_mut(&mut self)
610 -> LocalTableInContextMut
<'_
, Vec
<ty
::adjustment
::Adjustment
<'tcx
>>> {
611 LocalTableInContextMut
{
612 local_id_root
: self.local_id_root
,
613 data
: &mut self.adjustments
617 pub fn expr_adjustments(&self, expr
: &hir
::Expr
)
618 -> &[ty
::adjustment
::Adjustment
<'tcx
>] {
619 validate_hir_id_for_typeck_tables(self.local_id_root
, expr
.hir_id
, false);
620 self.adjustments
.get(&expr
.hir_id
.local_id
).map_or(&[], |a
| &a
[..])
623 /// Returns the type of `expr`, considering any `Adjustment`
624 /// entry recorded for that expression.
625 pub fn expr_ty_adjusted(&self, expr
: &hir
::Expr
) -> Ty
<'tcx
> {
626 self.expr_adjustments(expr
)
628 .map_or_else(|| self.expr_ty(expr
), |adj
| adj
.target
)
631 pub fn expr_ty_adjusted_opt(&self, expr
: &hir
::Expr
) -> Option
<Ty
<'tcx
>> {
632 self.expr_adjustments(expr
)
634 .map(|adj
| adj
.target
)
635 .or_else(|| self.expr_ty_opt(expr
))
638 pub fn is_method_call(&self, expr
: &hir
::Expr
) -> bool
{
639 // Only paths and method calls/overloaded operators have
640 // entries in type_dependent_defs, ignore the former here.
641 if let hir
::ExprKind
::Path(_
) = expr
.kind
{
645 match self.type_dependent_defs().get(expr
.hir_id
) {
646 Some(Ok((DefKind
::Method
, _
))) => true,
651 pub fn pat_binding_modes(&self) -> LocalTableInContext
<'_
, BindingMode
> {
652 LocalTableInContext
{
653 local_id_root
: self.local_id_root
,
654 data
: &self.pat_binding_modes
658 pub fn pat_binding_modes_mut(&mut self)
659 -> LocalTableInContextMut
<'_
, BindingMode
> {
660 LocalTableInContextMut
{
661 local_id_root
: self.local_id_root
,
662 data
: &mut self.pat_binding_modes
666 pub fn pat_adjustments(&self) -> LocalTableInContext
<'_
, Vec
<Ty
<'tcx
>>> {
667 LocalTableInContext
{
668 local_id_root
: self.local_id_root
,
669 data
: &self.pat_adjustments
,
673 pub fn pat_adjustments_mut(&mut self)
674 -> LocalTableInContextMut
<'_
, Vec
<Ty
<'tcx
>>> {
675 LocalTableInContextMut
{
676 local_id_root
: self.local_id_root
,
677 data
: &mut self.pat_adjustments
,
681 pub fn upvar_capture(&self, upvar_id
: ty
::UpvarId
) -> ty
::UpvarCapture
<'tcx
> {
682 self.upvar_capture_map
[&upvar_id
]
685 pub fn closure_kind_origins(&self) -> LocalTableInContext
<'_
, (Span
, ast
::Name
)> {
686 LocalTableInContext
{
687 local_id_root
: self.local_id_root
,
688 data
: &self.closure_kind_origins
692 pub fn closure_kind_origins_mut(&mut self) -> LocalTableInContextMut
<'_
, (Span
, ast
::Name
)> {
693 LocalTableInContextMut
{
694 local_id_root
: self.local_id_root
,
695 data
: &mut self.closure_kind_origins
699 pub fn liberated_fn_sigs(&self) -> LocalTableInContext
<'_
, ty
::FnSig
<'tcx
>> {
700 LocalTableInContext
{
701 local_id_root
: self.local_id_root
,
702 data
: &self.liberated_fn_sigs
706 pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut
<'_
, ty
::FnSig
<'tcx
>> {
707 LocalTableInContextMut
{
708 local_id_root
: self.local_id_root
,
709 data
: &mut self.liberated_fn_sigs
713 pub fn fru_field_types(&self) -> LocalTableInContext
<'_
, Vec
<Ty
<'tcx
>>> {
714 LocalTableInContext
{
715 local_id_root
: self.local_id_root
,
716 data
: &self.fru_field_types
720 pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut
<'_
, Vec
<Ty
<'tcx
>>> {
721 LocalTableInContextMut
{
722 local_id_root
: self.local_id_root
,
723 data
: &mut self.fru_field_types
727 pub fn is_coercion_cast(&self, hir_id
: hir
::HirId
) -> bool
{
728 validate_hir_id_for_typeck_tables(self.local_id_root
, hir_id
, true);
729 self.coercion_casts
.contains(&hir_id
.local_id
)
732 pub fn set_coercion_cast(&mut self, id
: ItemLocalId
) {
733 self.coercion_casts
.insert(id
);
736 pub fn coercion_casts(&self) -> &ItemLocalSet
{
742 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for TypeckTables
<'tcx
> {
743 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
744 let ty
::TypeckTables
{
746 ref type_dependent_defs
,
748 ref user_provided_types
,
749 ref user_provided_sigs
,
753 ref pat_binding_modes
,
755 ref upvar_capture_map
,
756 ref closure_kind_origins
,
757 ref liberated_fn_sigs
,
762 ref used_trait_imports
,
765 ref concrete_opaque_types
,
767 ref generator_interior_types
,
771 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
772 type_dependent_defs
.hash_stable(hcx
, hasher
);
773 field_indices
.hash_stable(hcx
, hasher
);
774 user_provided_types
.hash_stable(hcx
, hasher
);
775 user_provided_sigs
.hash_stable(hcx
, hasher
);
776 node_types
.hash_stable(hcx
, hasher
);
777 node_substs
.hash_stable(hcx
, hasher
);
778 adjustments
.hash_stable(hcx
, hasher
);
779 pat_binding_modes
.hash_stable(hcx
, hasher
);
780 pat_adjustments
.hash_stable(hcx
, hasher
);
781 hash_stable_hashmap(hcx
, hasher
, upvar_capture_map
, |up_var_id
, hcx
| {
788 local_id_root
.expect("trying to hash invalid TypeckTables");
790 let var_owner_def_id
= DefId
{
791 krate
: local_id_root
.krate
,
792 index
: var_path
.hir_id
.owner
,
794 let closure_def_id
= DefId
{
795 krate
: local_id_root
.krate
,
796 index
: closure_expr_id
.to_def_id().index
,
798 (hcx
.def_path_hash(var_owner_def_id
),
799 var_path
.hir_id
.local_id
,
800 hcx
.def_path_hash(closure_def_id
))
803 closure_kind_origins
.hash_stable(hcx
, hasher
);
804 liberated_fn_sigs
.hash_stable(hcx
, hasher
);
805 fru_field_types
.hash_stable(hcx
, hasher
);
806 coercion_casts
.hash_stable(hcx
, hasher
);
807 used_trait_imports
.hash_stable(hcx
, hasher
);
808 tainted_by_errors
.hash_stable(hcx
, hasher
);
809 free_region_map
.hash_stable(hcx
, hasher
);
810 concrete_opaque_types
.hash_stable(hcx
, hasher
);
811 upvar_list
.hash_stable(hcx
, hasher
);
812 generator_interior_types
.hash_stable(hcx
, hasher
);
817 rustc_index
::newtype_index
! {
818 pub struct UserTypeAnnotationIndex
{
820 DEBUG_FORMAT
= "UserType({})",
821 const START_INDEX
= 0,
825 /// Mapping of type annotation indices to canonical user type annotations.
826 pub type CanonicalUserTypeAnnotations
<'tcx
> =
827 IndexVec
<UserTypeAnnotationIndex
, CanonicalUserTypeAnnotation
<'tcx
>>;
829 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
830 pub struct CanonicalUserTypeAnnotation
<'tcx
> {
831 pub user_ty
: CanonicalUserType
<'tcx
>,
833 pub inferred_ty
: Ty
<'tcx
>,
836 /// Canonicalized user type annotation.
837 pub type CanonicalUserType
<'tcx
> = Canonical
<'tcx
, UserType
<'tcx
>>;
839 impl CanonicalUserType
<'tcx
> {
840 /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`,
841 /// i.e., each thing is mapped to a canonical variable with the same index.
842 pub fn is_identity(&self) -> bool
{
844 UserType
::Ty(_
) => false,
845 UserType
::TypeOf(_
, user_substs
) => {
846 if user_substs
.user_self_ty
.is_some() {
850 user_substs
.substs
.iter().zip(BoundVar
::new(0)..).all(|(kind
, cvar
)| {
851 match kind
.unpack() {
852 GenericArgKind
::Type(ty
) => match ty
.kind
{
853 ty
::Bound(debruijn
, b
) => {
854 // We only allow a `ty::INNERMOST` index in substitutions.
855 assert_eq
!(debruijn
, ty
::INNERMOST
);
861 GenericArgKind
::Lifetime(r
) => match r
{
862 ty
::ReLateBound(debruijn
, br
) => {
863 // We only allow a `ty::INNERMOST` index in substitutions.
864 assert_eq
!(*debruijn
, ty
::INNERMOST
);
865 cvar
== br
.assert_bound_var()
870 GenericArgKind
::Const(ct
) => match ct
.val
{
871 ty
::ConstKind
::Bound(debruijn
, b
) => {
872 // We only allow a `ty::INNERMOST` index in substitutions.
873 assert_eq
!(debruijn
, ty
::INNERMOST
);
885 /// A user-given type annotation attached to a constant. These arise
886 /// from constants that are named via paths, like `Foo::<A>::new` and
888 #[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
889 #[derive(HashStable, TypeFoldable, Lift)]
890 pub enum UserType
<'tcx
> {
893 /// The canonical type is the result of `type_of(def_id)` with the
894 /// given substitutions applied.
895 TypeOf(DefId
, UserSubsts
<'tcx
>),
898 impl<'tcx
> CommonTypes
<'tcx
> {
899 fn new(interners
: &CtxtInterners
<'tcx
>) -> CommonTypes
<'tcx
> {
900 let mk
= |ty
| interners
.intern_ty(ty
);
903 unit
: mk(Tuple(List
::empty())),
908 isize: mk(Int(ast
::IntTy
::Isize
)),
909 i8: mk(Int(ast
::IntTy
::I8
)),
910 i16: mk(Int(ast
::IntTy
::I16
)),
911 i32: mk(Int(ast
::IntTy
::I32
)),
912 i64: mk(Int(ast
::IntTy
::I64
)),
913 i128
: mk(Int(ast
::IntTy
::I128
)),
914 usize: mk(Uint(ast
::UintTy
::Usize
)),
915 u8: mk(Uint(ast
::UintTy
::U8
)),
916 u16: mk(Uint(ast
::UintTy
::U16
)),
917 u32: mk(Uint(ast
::UintTy
::U32
)),
918 u64: mk(Uint(ast
::UintTy
::U64
)),
919 u128
: mk(Uint(ast
::UintTy
::U128
)),
920 f32: mk(Float(ast
::FloatTy
::F32
)),
921 f64: mk(Float(ast
::FloatTy
::F64
)),
922 self_param
: mk(ty
::Param(ty
::ParamTy
{
927 trait_object_dummy_self
: mk(Infer(ty
::FreshTy(0))),
932 impl<'tcx
> CommonLifetimes
<'tcx
> {
933 fn new(interners
: &CtxtInterners
<'tcx
>) -> CommonLifetimes
<'tcx
> {
935 interners
.region
.intern(r
, |r
| {
936 Interned(interners
.arena
.alloc(r
))
941 re_empty
: mk(RegionKind
::ReEmpty
),
942 re_static
: mk(RegionKind
::ReStatic
),
943 re_erased
: mk(RegionKind
::ReErased
),
948 impl<'tcx
> CommonConsts
<'tcx
> {
949 fn new(interners
: &CtxtInterners
<'tcx
>, types
: &CommonTypes
<'tcx
>) -> CommonConsts
<'tcx
> {
951 interners
.const_
.intern(c
, |c
| {
952 Interned(interners
.arena
.alloc(c
))
957 err
: mk_const(ty
::Const
{
958 val
: ty
::ConstKind
::Value(ConstValue
::Scalar(Scalar
::zst())),
965 // This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime
968 pub struct FreeRegionInfo
{
969 // def id corresponding to FreeRegion
971 // the bound region corresponding to FreeRegion
972 pub boundregion
: ty
::BoundRegion
,
973 // checks if bound region is in Impl Item
974 pub is_impl_item
: bool
,
977 /// The central data structure of the compiler. It stores references
978 /// to the various **arenas** and also houses the results of the
979 /// various **compiler queries** that have been performed. See the
980 /// [rustc guide] for more details.
982 /// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html
983 #[derive(Copy, Clone)]
984 #[rustc_diagnostic_item = "TyCtxt"]
985 pub struct TyCtxt
<'tcx
> {
986 gcx
: &'tcx GlobalCtxt
<'tcx
>,
989 impl<'tcx
> Deref
for TyCtxt
<'tcx
> {
990 type Target
= &'tcx GlobalCtxt
<'tcx
>;
992 fn deref(&self) -> &Self::Target
{
997 pub struct GlobalCtxt
<'tcx
> {
998 pub arena
: &'tcx WorkerLocal
<Arena
<'tcx
>>,
1000 interners
: CtxtInterners
<'tcx
>,
1002 cstore
: Box
<CrateStoreDyn
>,
1004 pub sess
: &'tcx Session
,
1006 pub lint_store
: Lrc
<lint
::LintStore
>,
1008 pub dep_graph
: DepGraph
,
1010 pub prof
: SelfProfilerRef
,
1012 /// Common types, pre-interned for your convenience.
1013 pub types
: CommonTypes
<'tcx
>,
1015 /// Common lifetimes, pre-interned for your convenience.
1016 pub lifetimes
: CommonLifetimes
<'tcx
>,
1018 /// Common consts, pre-interned for your convenience.
1019 pub consts
: CommonConsts
<'tcx
>,
1021 /// Resolutions of `extern crate` items produced by resolver.
1022 extern_crate_map
: NodeMap
<CrateNum
>,
1024 /// Map indicating what traits are in scope for places where this
1025 /// is relevant; generated by resolve.
1026 trait_map
: FxHashMap
<DefIndex
,
1027 FxHashMap
<ItemLocalId
,
1028 StableVec
<TraitCandidate
>>>,
1030 /// Export map produced by name resolution.
1031 export_map
: FxHashMap
<DefId
, Vec
<Export
<hir
::HirId
>>>,
1033 hir_map
: hir_map
::Map
<'tcx
>,
1035 /// A map from `DefPathHash` -> `DefId`. Includes `DefId`s from the local crate
1036 /// as well as all upstream crates. Only populated in incremental mode.
1037 pub def_path_hash_to_def_id
: Option
<FxHashMap
<DefPathHash
, DefId
>>,
1039 pub queries
: query
::Queries
<'tcx
>,
1041 maybe_unused_trait_imports
: FxHashSet
<DefId
>,
1042 maybe_unused_extern_crates
: Vec
<(DefId
, Span
)>,
1043 /// A map of glob use to a set of names it actually imports. Currently only
1044 /// used in save-analysis.
1045 glob_map
: FxHashMap
<DefId
, FxHashSet
<ast
::Name
>>,
1046 /// Extern prelude entries. The value is `true` if the entry was introduced
1047 /// via `extern crate` item and not `--extern` option or compiler built-in.
1048 pub extern_prelude
: FxHashMap
<ast
::Name
, bool
>,
1050 // Internal cache for metadata decoding. No need to track deps on this.
1051 pub rcache
: Lock
<FxHashMap
<ty
::CReaderCacheKey
, Ty
<'tcx
>>>,
1053 /// Caches the results of trait selection. This cache is used
1054 /// for things that do not have to do with the parameters in scope.
1055 pub selection_cache
: traits
::SelectionCache
<'tcx
>,
1057 /// Caches the results of trait evaluation. This cache is used
1058 /// for things that do not have to do with the parameters in scope.
1059 /// Merge this with `selection_cache`?
1060 pub evaluation_cache
: traits
::EvaluationCache
<'tcx
>,
1062 /// The definite name of the current crate after taking into account
1063 /// attributes, commandline parameters, etc.
1064 pub crate_name
: Symbol
,
1066 /// Data layout specification for the current target.
1067 pub data_layout
: TargetDataLayout
,
1069 /// `#[stable]` and `#[unstable]` attributes
1070 stability_interner
: ShardedHashMap
<&'tcx attr
::Stability
, ()>,
1072 /// `#[rustc_const_stable]` and `#[rustc_const_unstable]` attributes
1073 const_stability_interner
: ShardedHashMap
<&'tcx attr
::ConstStability
, ()>,
1075 /// Stores the value of constants (and deduplicates the actual memory)
1076 allocation_interner
: ShardedHashMap
<&'tcx Allocation
, ()>,
1078 pub alloc_map
: Lock
<interpret
::AllocMap
<'tcx
>>,
1080 layout_interner
: ShardedHashMap
<&'tcx LayoutDetails
, ()>,
1082 output_filenames
: Arc
<OutputFilenames
>,
1085 impl<'tcx
> TyCtxt
<'tcx
> {
1087 pub fn hir(self) -> &'tcx hir_map
::Map
<'tcx
> {
1091 pub fn alloc_steal_mir(self, mir
: BodyAndCache
<'tcx
>) -> &'tcx Steal
<BodyAndCache
<'tcx
>> {
1092 self.arena
.alloc(Steal
::new(mir
))
1095 pub fn alloc_steal_promoted(self, promoted
: IndexVec
<Promoted
, BodyAndCache
<'tcx
>>) ->
1096 &'tcx Steal
<IndexVec
<Promoted
, BodyAndCache
<'tcx
>>> {
1097 self.arena
.alloc(Steal
::new(promoted
))
1100 pub fn intern_promoted(self, promoted
: IndexVec
<Promoted
, BodyAndCache
<'tcx
>>) ->
1101 &'tcx IndexVec
<Promoted
, BodyAndCache
<'tcx
>> {
1102 self.arena
.alloc(promoted
)
1105 pub fn alloc_adt_def(
1109 variants
: IndexVec
<VariantIdx
, ty
::VariantDef
>,
1111 ) -> &'tcx ty
::AdtDef
{
1112 let def
= ty
::AdtDef
::new(self, did
, kind
, variants
, repr
);
1113 self.arena
.alloc(def
)
1116 pub fn intern_const_alloc(self, alloc
: Allocation
) -> &'tcx Allocation
{
1117 self.allocation_interner
.intern(alloc
, |alloc
| {
1118 self.arena
.alloc(alloc
)
1122 /// Allocates a read-only byte or string literal for `mir::interpret`.
1123 pub fn allocate_bytes(self, bytes
: &[u8]) -> interpret
::AllocId
{
1124 // Create an allocation that just contains these bytes.
1125 let alloc
= interpret
::Allocation
::from_byte_aligned_bytes(bytes
);
1126 let alloc
= self.intern_const_alloc(alloc
);
1127 self.alloc_map
.lock().create_memory_alloc(alloc
)
1130 pub fn intern_stability(self, stab
: attr
::Stability
) -> &'tcx attr
::Stability
{
1131 self.stability_interner
.intern(stab
, |stab
| {
1132 self.arena
.alloc(stab
)
1136 pub fn intern_const_stability(self, stab
: attr
::ConstStability
) -> &'tcx attr
::ConstStability
{
1137 self.const_stability_interner
.intern(stab
, |stab
| {
1138 self.arena
.alloc(stab
)
1142 pub fn intern_layout(self, layout
: LayoutDetails
) -> &'tcx LayoutDetails
{
1143 self.layout_interner
.intern(layout
, |layout
| {
1144 self.arena
.alloc(layout
)
1148 /// Returns a range of the start/end indices specified with the
1149 /// `rustc_layout_scalar_valid_range` attribute.
1150 pub fn layout_scalar_valid_range(self, def_id
: DefId
) -> (Bound
<u128
>, Bound
<u128
>) {
1151 let attrs
= self.get_attrs(def_id
);
1153 let attr
= match attrs
.iter().find(|a
| a
.check_name(name
)) {
1155 None
=> return Bound
::Unbounded
,
1157 for meta
in attr
.meta_item_list().expect("rustc_layout_scalar_valid_range takes args") {
1158 match meta
.literal().expect("attribute takes lit").kind
{
1159 ast
::LitKind
::Int(a
, _
) => return Bound
::Included(a
),
1160 _
=> span_bug
!(attr
.span
, "rustc_layout_scalar_valid_range expects int arg"),
1163 span_bug
!(attr
.span
, "no arguments to `rustc_layout_scalar_valid_range` attribute");
1165 (get(sym
::rustc_layout_scalar_valid_range_start
),
1166 get(sym
::rustc_layout_scalar_valid_range_end
))
1169 pub fn lift
<T
: ?Sized
+ Lift
<'tcx
>>(self, value
: &T
) -> Option
<T
::Lifted
> {
1170 value
.lift_to_tcx(self)
1173 /// Creates a type context and call the closure with a `TyCtxt` reference
1174 /// to the context. The closure enforces that the type context and any interned
1175 /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
1176 /// reference to the context, to allow formatting values that need it.
1177 pub fn create_global_ctxt(
1179 lint_store
: Lrc
<lint
::LintStore
>,
1180 local_providers
: ty
::query
::Providers
<'tcx
>,
1181 extern_providers
: ty
::query
::Providers
<'tcx
>,
1182 arenas
: &'tcx AllArenas
,
1183 arena
: &'tcx WorkerLocal
<Arena
<'tcx
>>,
1184 resolutions
: ty
::ResolverOutputs
,
1185 hir
: hir_map
::Map
<'tcx
>,
1186 on_disk_query_result_cache
: query
::OnDiskCache
<'tcx
>,
1188 output_filenames
: &OutputFilenames
,
1189 ) -> GlobalCtxt
<'tcx
> {
1190 let data_layout
= TargetDataLayout
::parse(&s
.target
.target
).unwrap_or_else(|err
| {
1193 let interners
= CtxtInterners
::new(&arenas
.interner
);
1194 let common_types
= CommonTypes
::new(&interners
);
1195 let common_lifetimes
= CommonLifetimes
::new(&interners
);
1196 let common_consts
= CommonConsts
::new(&interners
, &common_types
);
1197 let dep_graph
= hir
.dep_graph
.clone();
1198 let cstore
= resolutions
.cstore
;
1199 let crates
= cstore
.crates_untracked();
1200 let max_cnum
= crates
.iter().map(|c
| c
.as_usize()).max().unwrap_or(0);
1201 let mut providers
= IndexVec
::from_elem_n(extern_providers
, max_cnum
+ 1);
1202 providers
[LOCAL_CRATE
] = local_providers
;
1204 let def_path_hash_to_def_id
= if s
.opts
.build_dep_graph() {
1205 let def_path_tables
= crates
1207 .map(|&cnum
| (cnum
, cstore
.def_path_table(cnum
)))
1208 .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
.clone().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
));
1242 prof
: s
.prof
.clone(),
1243 types
: common_types
,
1244 lifetimes
: common_lifetimes
,
1245 consts
: common_consts
,
1246 extern_crate_map
: resolutions
.extern_crate_map
,
1248 export_map
: resolutions
.export_map
.into_iter().map(|(k
, v
)| {
1249 let exports
: Vec
<_
> = v
.into_iter().map(|e
| {
1250 e
.map_id(|id
| hir
.node_to_hir_id(id
))
1254 maybe_unused_trait_imports
:
1255 resolutions
.maybe_unused_trait_imports
1257 .map(|id
| hir
.local_def_id_from_node_id(id
))
1259 maybe_unused_extern_crates
:
1260 resolutions
.maybe_unused_extern_crates
1262 .map(|(id
, sp
)| (hir
.local_def_id_from_node_id(id
), sp
))
1264 glob_map
: resolutions
.glob_map
.into_iter().map(|(id
, names
)| {
1265 (hir
.local_def_id_from_node_id(id
), names
)
1267 extern_prelude
: resolutions
.extern_prelude
,
1269 def_path_hash_to_def_id
,
1270 queries
: query
::Queries
::new(
1273 on_disk_query_result_cache
,
1275 rcache
: Default
::default(),
1276 selection_cache
: Default
::default(),
1277 evaluation_cache
: Default
::default(),
1278 crate_name
: Symbol
::intern(crate_name
),
1280 layout_interner
: Default
::default(),
1281 stability_interner
: Default
::default(),
1282 const_stability_interner
: Default
::default(),
1283 allocation_interner
: Default
::default(),
1284 alloc_map
: Lock
::new(interpret
::AllocMap
::new()),
1285 output_filenames
: Arc
::new(output_filenames
.clone()),
1289 pub fn consider_optimizing
<T
: Fn() -> String
>(&self, msg
: T
) -> bool
{
1290 let cname
= self.crate_name(LOCAL_CRATE
).as_str();
1291 self.sess
.consider_optimizing(&cname
, msg
)
1294 pub fn lib_features(self) -> &'tcx middle
::lib_features
::LibFeatures
{
1295 self.get_lib_features(LOCAL_CRATE
)
1298 /// Obtain all lang items of this crate and all dependencies (recursively)
1299 pub fn lang_items(self) -> &'tcx middle
::lang_items
::LanguageItems
{
1300 self.get_lang_items(LOCAL_CRATE
)
1303 /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
1304 /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
1305 pub fn get_diagnostic_item(self, name
: Symbol
) -> Option
<DefId
> {
1306 self.all_diagnostic_items(LOCAL_CRATE
).get(&name
).copied()
1309 /// Check whether the diagnostic item with the given `name` has the given `DefId`.
1310 pub fn is_diagnostic_item(self, name
: Symbol
, did
: DefId
) -> bool
{
1311 self.diagnostic_items(did
.krate
).get(&name
) == Some(&did
)
1314 pub fn stability(self) -> &'tcx stability
::Index
<'tcx
> {
1315 self.stability_index(LOCAL_CRATE
)
1318 pub fn crates(self) -> &'tcx
[CrateNum
] {
1319 self.all_crate_nums(LOCAL_CRATE
)
1322 pub fn allocator_kind(self) -> Option
<AllocatorKind
> {
1323 self.cstore
.allocator_kind()
1326 pub fn features(self) -> &'tcx rustc_feature
::Features
{
1327 self.features_query(LOCAL_CRATE
)
1330 pub fn def_key(self, id
: DefId
) -> hir_map
::DefKey
{
1332 self.hir().def_key(id
)
1334 self.cstore
.def_key(id
)
1338 /// Converts a `DefId` into its fully expanded `DefPath` (every
1339 /// `DefId` is really just an interned `DefPath`).
1341 /// Note that if `id` is not local to this crate, the result will
1342 /// be a non-local `DefPath`.
1343 pub fn def_path(self, id
: DefId
) -> hir_map
::DefPath
{
1345 self.hir().def_path(id
)
1347 self.cstore
.def_path(id
)
1351 /// Returns whether or not the crate with CrateNum 'cnum'
1352 /// is marked as a private dependency
1353 pub fn is_private_dep(self, cnum
: CrateNum
) -> bool
{
1354 if cnum
== LOCAL_CRATE
{
1357 self.cstore
.crate_is_private_dep_untracked(cnum
)
1362 pub fn def_path_hash(self, def_id
: DefId
) -> hir_map
::DefPathHash
{
1363 if def_id
.is_local() {
1364 self.hir().definitions().def_path_hash(def_id
.index
)
1366 self.cstore
.def_path_hash(def_id
)
1370 pub fn def_path_debug_str(self, def_id
: DefId
) -> String
{
1371 // We are explicitly not going through queries here in order to get
1372 // crate name and disambiguator since this code is called from debug!()
1373 // statements within the query system and we'd run into endless
1374 // recursion otherwise.
1375 let (crate_name
, crate_disambiguator
) = if def_id
.is_local() {
1376 (self.crate_name
.clone(),
1377 self.sess
.local_crate_disambiguator())
1379 (self.cstore
.crate_name_untracked(def_id
.krate
),
1380 self.cstore
.crate_disambiguator_untracked(def_id
.krate
))
1385 // Don't print the whole crate disambiguator. That's just
1386 // annoying in debug output.
1387 &(crate_disambiguator
.to_fingerprint().to_hex())[..4],
1388 self.def_path(def_id
).to_string_no_crate())
1391 pub fn metadata_encoding_version(self) -> Vec
<u8> {
1392 self.cstore
.metadata_encoding_version().to_vec()
1395 pub fn encode_metadata(self)-> EncodedMetadata
{
1396 let _prof_timer
= self.prof
.generic_activity("generate_crate_metadata");
1397 self.cstore
.encode_metadata(self)
1400 // Note that this is *untracked* and should only be used within the query
1401 // system if the result is otherwise tracked through queries
1402 pub fn cstore_as_any(self) -> &'tcx
dyn Any
{
1403 self.cstore
.as_any()
1407 pub fn create_stable_hashing_context(self) -> StableHashingContext
<'tcx
> {
1408 let krate
= self.gcx
.hir_map
.forest
.untracked_krate();
1410 StableHashingContext
::new(self.sess
,
1412 self.hir().definitions(),
1416 // This method makes sure that we have a DepNode and a Fingerprint for
1417 // every upstream crate. It needs to be called once right after the tcx is
1419 // With full-fledged red/green, the method will probably become unnecessary
1420 // as this will be done on-demand.
1421 pub fn allocate_metadata_dep_nodes(self) {
1422 // We cannot use the query versions of crates() and crate_hash(), since
1423 // those would need the DepNodes that we are allocating here.
1424 for cnum
in self.cstore
.crates_untracked() {
1425 let dep_node
= DepNode
::new(self, DepConstructor
::CrateMetadata(cnum
));
1426 let crate_hash
= self.cstore
.crate_hash_untracked(cnum
);
1427 self.dep_graph
.with_task(dep_node
,
1430 |_
, x
| x
, // No transformation needed
1431 dep_graph
::hash_result
,
1436 pub fn serialize_query_result_cache
<E
>(self,
1438 -> Result
<(), E
::Error
>
1439 where E
: ty
::codec
::TyEncoder
1441 self.queries
.on_disk_cache
.serialize(self, encoder
)
1444 /// If `true`, we should use the MIR-based borrowck, but also
1445 /// fall back on the AST borrowck if the MIR-based one errors.
1446 pub fn migrate_borrowck(self) -> bool
{
1447 self.borrowck_mode().migrate()
1450 /// If `true`, make MIR codegen for `match` emit a temp that holds a
1451 /// borrow of the input to the match expression.
1452 pub fn generate_borrow_of_any_match_input(&self) -> bool
{
1453 self.emit_read_for_match()
1456 /// If `true`, make MIR codegen for `match` emit FakeRead
1457 /// statements (which simulate the maximal effect of executing the
1458 /// patterns in a match arm).
1459 pub fn emit_read_for_match(&self) -> bool
{
1460 !self.sess
.opts
.debugging_opts
.nll_dont_emit_read_for_match
1463 /// What mode(s) of borrowck should we run? AST? MIR? both?
1464 /// (Also considers the `#![feature(nll)]` setting.)
1465 pub fn borrowck_mode(&self) -> BorrowckMode
{
1466 // Here are the main constraints we need to deal with:
1468 // 1. An opts.borrowck_mode of `BorrowckMode::Migrate` is
1469 // synonymous with no `-Z borrowck=...` flag at all.
1471 // 2. We want to allow developers on the Nightly channel
1472 // to opt back into the "hard error" mode for NLL,
1473 // (which they can do via specifying `#![feature(nll)]`
1474 // explicitly in their crate).
1476 // So, this precedence list is how pnkfelix chose to work with
1477 // the above constraints:
1479 // * `#![feature(nll)]` *always* means use NLL with hard
1480 // errors. (To simplify the code here, it now even overrides
1481 // a user's attempt to specify `-Z borrowck=compare`, which
1482 // we arguably do not need anymore and should remove.)
1484 // * Otherwise, if no `-Z borrowck=...` then use migrate mode
1486 // * Otherwise, use the behavior requested via `-Z borrowck=...`
1488 if self.features().nll { return BorrowckMode::Mir; }
1490 self.sess
.opts
.borrowck_mode
1494 pub fn local_crate_exports_generics(self) -> bool
{
1495 debug_assert
!(self.sess
.opts
.share_generics());
1497 self.sess
.crate_types
.borrow().iter().any(|crate_type
| {
1499 CrateType
::Executable
|
1500 CrateType
::Staticlib
|
1501 CrateType
::ProcMacro
|
1502 CrateType
::Cdylib
=> false,
1504 // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
1505 // We want to block export of generics from dylibs,
1506 // but we must fix rust-lang/rust#65890 before we can
1507 // do that robustly.
1508 CrateType
::Dylib
=> true,
1510 CrateType
::Rlib
=> true,
1515 // Returns the `DefId` and the `BoundRegion` corresponding to the given region.
1516 pub fn is_suitable_region(&self, region
: Region
<'tcx
>) -> Option
<FreeRegionInfo
> {
1517 let (suitable_region_binding_scope
, bound_region
) = match *region
{
1518 ty
::ReFree(ref free_region
) => (free_region
.scope
, free_region
.bound_region
),
1519 ty
::ReEarlyBound(ref ebr
) => (
1520 self.parent(ebr
.def_id
).unwrap(),
1521 ty
::BoundRegion
::BrNamed(ebr
.def_id
, ebr
.name
),
1523 _
=> return None
, // not a free region
1526 let hir_id
= self.hir()
1527 .as_local_hir_id(suitable_region_binding_scope
)
1529 let is_impl_item
= match self.hir().find(hir_id
) {
1530 Some(Node
::Item(..)) | Some(Node
::TraitItem(..)) => false,
1531 Some(Node
::ImplItem(..)) => {
1532 self.is_bound_region_in_impl_item(suitable_region_binding_scope
)
1537 return Some(FreeRegionInfo
{
1538 def_id
: suitable_region_binding_scope
,
1539 boundregion
: bound_region
,
1544 pub fn return_type_impl_trait(
1546 scope_def_id
: DefId
,
1547 ) -> Option
<(Ty
<'tcx
>, Span
)> {
1548 // HACK: `type_of_def_id()` will fail on these (#55796), so return `None`.
1549 let hir_id
= self.hir().as_local_hir_id(scope_def_id
).unwrap();
1550 match self.hir().get(hir_id
) {
1551 Node
::Item(item
) => {
1553 ItemKind
::Fn(..) => { /* `type_of_def_id()` will work */ }
1559 _
=> { /* `type_of_def_id()` will work or panic */ }
1562 let ret_ty
= self.type_of(scope_def_id
);
1564 ty
::FnDef(_
, _
) => {
1565 let sig
= ret_ty
.fn_sig(*self);
1566 let output
= self.erase_late_bound_regions(&sig
.output());
1567 if output
.is_impl_trait() {
1568 let fn_decl
= self.hir().fn_decl_by_hir_id(hir_id
).unwrap();
1569 Some((output
, fn_decl
.output
.span()))
1578 // Checks if the bound region is in Impl Item.
1579 pub fn is_bound_region_in_impl_item(
1581 suitable_region_binding_scope
: DefId
,
1583 let container_id
= self.associated_item(suitable_region_binding_scope
)
1586 if self.impl_trait_ref(container_id
).is_some() {
1587 // For now, we do not try to target impls of traits. This is
1588 // because this message is going to suggest that the user
1589 // change the fn signature, but they may not be free to do so,
1590 // since the signature must match the trait.
1592 // FIXME(#42706) -- in some cases, we could do better here.
1598 /// Determines whether identifiers in the assembly have strict naming rules.
1599 /// Currently, only NVPTX* targets need it.
1600 pub fn has_strict_asm_symbol_naming(&self) -> bool
{
1601 self.sess
.target
.target
.arch
.contains("nvptx")
1604 /// Returns `&'static core::panic::Location<'static>`.
1605 pub fn caller_location_ty(&self) -> Ty
<'tcx
> {
1607 self.lifetimes
.re_static
,
1608 self.type_of(self.require_lang_item(PanicLocationLangItem
, None
))
1609 .subst(*self, self.mk_substs([self.lifetimes
.re_static
.into()].iter())),
1614 impl<'tcx
> GlobalCtxt
<'tcx
> {
1615 /// Calls the closure with a local `TyCtxt` using the given arena.
1616 /// `interners` is a slot passed so we can create a CtxtInterners
1617 /// with the same lifetime as `arena`.
1618 pub fn enter_local
<F
, R
>(&'tcx
self, f
: F
) -> R
1620 F
: FnOnce(TyCtxt
<'tcx
>) -> R
,
1625 ty
::tls
::with_related_context(tcx
, |icx
| {
1626 let new_icx
= ty
::tls
::ImplicitCtxt
{
1628 query
: icx
.query
.clone(),
1629 diagnostics
: icx
.diagnostics
,
1630 layout_depth
: icx
.layout_depth
,
1631 task_deps
: icx
.task_deps
,
1633 ty
::tls
::enter_context(&new_icx
, |_
| {
1640 /// A trait implemented for all `X<'a>` types that can be safely and
1641 /// efficiently converted to `X<'tcx>` as long as they are part of the
1642 /// provided `TyCtxt<'tcx>`.
1643 /// This can be done, for example, for `Ty<'tcx>` or `SubstsRef<'tcx>`
1644 /// by looking them up in their respective interners.
1646 /// However, this is still not the best implementation as it does
1647 /// need to compare the components, even for interned values.
1648 /// It would be more efficient if `TypedArena` provided a way to
1649 /// determine whether the address is in the allocated range.
1651 /// `None` is returned if the value or one of the components is not part
1652 /// of the provided context.
1653 /// For `Ty`, `None` can be returned if either the type interner doesn't
1654 /// contain the `TyKind` key or if the address of the interned
1655 /// pointer differs. The latter case is possible if a primitive type,
1656 /// e.g., `()` or `u8`, was interned in a different context.
1657 pub trait Lift
<'tcx
>: fmt
::Debug
{
1658 type Lifted
: fmt
::Debug
+ 'tcx
;
1659 fn lift_to_tcx(&self, tcx
: TyCtxt
<'tcx
>) -> Option
<Self::Lifted
>;
1662 macro_rules
! nop_lift
{
1663 ($ty
:ty
=> $lifted
:ty
) => {
1664 impl<'a
, 'tcx
> Lift
<'tcx
> for $ty
{
1665 type Lifted
= $lifted
;
1666 fn lift_to_tcx(&self, tcx
: TyCtxt
<'tcx
>) -> Option
<Self::Lifted
> {
1667 if tcx
.interners
.arena
.in_arena(*self as *const _
) {
1668 Some(unsafe { mem::transmute(*self) }
)
1677 macro_rules
! nop_list_lift
{
1678 ($ty
:ty
=> $lifted
:ty
) => {
1679 impl<'a
, 'tcx
> Lift
<'tcx
> for &'a List
<$ty
> {
1680 type Lifted
= &'tcx List
<$lifted
>;
1681 fn lift_to_tcx(&self, tcx
: TyCtxt
<'tcx
>) -> Option
<Self::Lifted
> {
1682 if self.is_empty() {
1683 return Some(List
::empty());
1685 if tcx
.interners
.arena
.in_arena(*self as *const _
) {
1686 Some(unsafe { mem::transmute(*self) }
)
1695 nop_lift
!{Ty<'a> => Ty<'tcx>}
1696 nop_lift
!{Region<'a> => Region<'tcx>}
1697 nop_lift
!{Goal<'a> => Goal<'tcx>}
1698 nop_lift
!{&'a Const<'a> => &'tcx Const<'tcx>}
1700 nop_list_lift
!{Goal<'a> => Goal<'tcx>}
1701 nop_list_lift
!{Clause<'a> => Clause<'tcx>}
1702 nop_list_lift
!{Ty<'a> => Ty<'tcx>}
1703 nop_list_lift
!{ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
1704 nop_list_lift
!{Predicate<'a> => Predicate<'tcx>}
1705 nop_list_lift
!{CanonicalVarInfo => CanonicalVarInfo}
1706 nop_list_lift
!{ProjectionKind => ProjectionKind}
1708 // This is the impl for `&'a InternalSubsts<'a>`.
1709 nop_list_lift
!{GenericArg<'a> => GenericArg<'tcx>}
1712 use super::{GlobalCtxt, TyCtxt, ptr_eq}
;
1717 use crate::ty
::query
;
1718 use errors
::{Diagnostic, TRACK_DIAGNOSTICS}
;
1719 use rustc_data_structures
::OnDrop
;
1720 use rustc_data_structures
::sync
::{self, Lrc, Lock}
;
1721 use rustc_data_structures
::thin_vec
::ThinVec
;
1722 use crate::dep_graph
::TaskDeps
;
1724 #[cfg(not(parallel_compiler))]
1725 use std
::cell
::Cell
;
1727 #[cfg(parallel_compiler)]
1728 use rustc_rayon_core
as rayon_core
;
1730 /// This is the implicit state of rustc. It contains the current
1731 /// `TyCtxt` and query. It is updated when creating a local interner or
1732 /// executing a new query. Whenever there's a `TyCtxt` value available
1733 /// you should also have access to an `ImplicitCtxt` through the functions
1736 pub struct ImplicitCtxt
<'a
, 'tcx
> {
1737 /// The current `TyCtxt`. Initially created by `enter_global` and updated
1738 /// by `enter_local` with a new local interner.
1739 pub tcx
: TyCtxt
<'tcx
>,
1741 /// The current query job, if any. This is updated by `JobOwner::start` in
1742 /// `ty::query::plumbing` when executing a query.
1743 pub query
: Option
<Lrc
<query
::QueryJob
<'tcx
>>>,
1745 /// Where to store diagnostics for the current query job, if any.
1746 /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
1747 pub diagnostics
: Option
<&'a Lock
<ThinVec
<Diagnostic
>>>,
1749 /// Used to prevent layout from recursing too deeply.
1750 pub layout_depth
: usize,
1752 /// The current dep graph task. This is used to add dependencies to queries
1753 /// when executing them.
1754 pub task_deps
: Option
<&'a Lock
<TaskDeps
>>,
1757 /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
1758 /// to `value` during the call to `f`. It is restored to its previous value after.
1759 /// This is used to set the pointer to the new `ImplicitCtxt`.
1760 #[cfg(parallel_compiler)]
1762 fn set_tlv
<F
: FnOnce() -> R
, R
>(value
: usize, f
: F
) -> R
{
1763 rayon_core
::tlv
::with(value
, f
)
1766 /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
1767 /// This is used to get the pointer to the current `ImplicitCtxt`.
1768 #[cfg(parallel_compiler)]
1770 fn get_tlv() -> usize {
1771 rayon_core
::tlv
::get()
1774 #[cfg(not(parallel_compiler))]
1776 /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
1777 static TLV
: Cell
<usize> = Cell
::new(0);
1780 /// Sets TLV to `value` during the call to `f`.
1781 /// It is restored to its previous value after.
1782 /// This is used to set the pointer to the new `ImplicitCtxt`.
1783 #[cfg(not(parallel_compiler))]
1785 fn set_tlv
<F
: FnOnce() -> R
, R
>(value
: usize, f
: F
) -> R
{
1786 let old
= get_tlv();
1787 let _reset
= OnDrop(move || TLV
.with(|tlv
| tlv
.set(old
)));
1788 TLV
.with(|tlv
| tlv
.set(value
));
1792 /// Gets the pointer to the current `ImplicitCtxt`.
1793 #[cfg(not(parallel_compiler))]
1794 fn get_tlv() -> usize {
1795 TLV
.with(|tlv
| tlv
.get())
1798 /// This is a callback from libsyntax as it cannot access the implicit state
1799 /// in librustc otherwise.
1800 fn span_debug(span
: syntax_pos
::Span
, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1802 if let Some(tcx
) = tcx
{
1803 write
!(f
, "{}", tcx
.sess
.source_map().span_to_string(span
))
1805 syntax_pos
::default_span_debug(span
, f
)
1810 /// This is a callback from libsyntax as it cannot access the implicit state
1811 /// in librustc otherwise. It is used to when diagnostic messages are
1812 /// emitted and stores them in the current query, if there is one.
1813 fn track_diagnostic(diagnostic
: &Diagnostic
) {
1814 with_context_opt(|icx
| {
1815 if let Some(icx
) = icx
{
1816 if let Some(ref diagnostics
) = icx
.diagnostics
{
1817 let mut diagnostics
= diagnostics
.lock();
1818 diagnostics
.extend(Some(diagnostic
.clone()));
1824 /// Sets up the callbacks from libsyntax on the current thread.
1825 pub fn with_thread_locals
<F
, R
>(f
: F
) -> R
1826 where F
: FnOnce() -> R
1828 syntax_pos
::SPAN_DEBUG
.with(|span_dbg
| {
1829 let original_span_debug
= span_dbg
.get();
1830 span_dbg
.set(span_debug
);
1832 let _on_drop
= OnDrop(move || {
1833 span_dbg
.set(original_span_debug
);
1836 TRACK_DIAGNOSTICS
.with(|current
| {
1837 let original
= current
.get();
1838 current
.set(track_diagnostic
);
1840 let _on_drop
= OnDrop(move || {
1841 current
.set(original
);
1849 /// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
1851 pub fn enter_context
<'a
, 'tcx
, F
, R
>(context
: &ImplicitCtxt
<'a
, 'tcx
>, f
: F
) -> R
1853 F
: FnOnce(&ImplicitCtxt
<'a
, 'tcx
>) -> R
,
1855 set_tlv(context
as *const _
as usize, || {
1860 /// Enters `GlobalCtxt` by setting up libsyntax callbacks and
1861 /// creating a initial `TyCtxt` and `ImplicitCtxt`.
1862 /// This happens once per rustc session and `TyCtxt`s only exists
1863 /// inside the `f` function.
1864 pub fn enter_global
<'tcx
, F
, R
>(gcx
: &'tcx GlobalCtxt
<'tcx
>, f
: F
) -> R
1866 F
: FnOnce(TyCtxt
<'tcx
>) -> R
,
1868 // Update `GCX_PTR` to indicate there's a `GlobalCtxt` available.
1869 GCX_PTR
.with(|lock
| {
1870 *lock
.lock() = gcx
as *const _
as usize;
1872 // Set `GCX_PTR` back to 0 when we exit.
1873 let _on_drop
= OnDrop(move || {
1874 GCX_PTR
.with(|lock
| *lock
.lock() = 0);
1880 let icx
= ImplicitCtxt
{
1887 enter_context(&icx
, |_
| {
1892 scoped_thread_local
! {
1893 /// Stores a pointer to the `GlobalCtxt` if one is available.
1894 /// This is used to access the `GlobalCtxt` in the deadlock handler given to Rayon.
1895 pub static GCX_PTR
: Lock
<usize>
1898 /// Creates a `TyCtxt` and `ImplicitCtxt` based on the `GCX_PTR` thread local.
1899 /// This is used in the deadlock handler.
1900 pub unsafe fn with_global
<F
, R
>(f
: F
) -> R
1902 F
: for<'tcx
> FnOnce(TyCtxt
<'tcx
>) -> R
,
1904 let gcx
= GCX_PTR
.with(|lock
| *lock
.lock());
1906 let gcx
= &*(gcx
as *const GlobalCtxt
<'_
>);
1910 let icx
= ImplicitCtxt
{
1917 enter_context(&icx
, |_
| f(tcx
))
1920 /// Allows access to the current `ImplicitCtxt` in a closure if one is available.
1922 pub fn with_context_opt
<F
, R
>(f
: F
) -> R
1924 F
: for<'a
, 'tcx
> FnOnce(Option
<&ImplicitCtxt
<'a
, 'tcx
>>) -> R
,
1926 let context
= get_tlv();
1930 // We could get a `ImplicitCtxt` pointer from another thread.
1931 // Ensure that `ImplicitCtxt` is `Sync`.
1932 sync
::assert_sync
::<ImplicitCtxt
<'_
, '_
>>();
1934 unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
1938 /// Allows access to the current `ImplicitCtxt`.
1939 /// Panics if there is no `ImplicitCtxt` available.
1941 pub fn with_context
<F
, R
>(f
: F
) -> R
1943 F
: for<'a
, 'tcx
> FnOnce(&ImplicitCtxt
<'a
, 'tcx
>) -> R
,
1945 with_context_opt(|opt_context
| f(opt_context
.expect("no ImplicitCtxt stored in tls")))
1948 /// Allows access to the current `ImplicitCtxt` whose tcx field has the same global
1949 /// interner as the tcx argument passed in. This means the closure is given an `ImplicitCtxt`
1950 /// with the same `'tcx` lifetime as the `TyCtxt` passed in.
1951 /// This will panic if you pass it a `TyCtxt` which has a different global interner from
1952 /// the current `ImplicitCtxt`'s `tcx` field.
1954 pub fn with_related_context
<'tcx
, F
, R
>(tcx
: TyCtxt
<'tcx
>, f
: F
) -> R
1956 F
: FnOnce(&ImplicitCtxt
<'_
, 'tcx
>) -> R
,
1958 with_context(|context
| {
1960 assert
!(ptr_eq(context
.tcx
.gcx
, tcx
.gcx
));
1961 let context
: &ImplicitCtxt
<'_
, '_
> = mem
::transmute(context
);
1967 /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
1968 /// Panics if there is no `ImplicitCtxt` available.
1970 pub fn with
<F
, R
>(f
: F
) -> R
1972 F
: for<'tcx
> FnOnce(TyCtxt
<'tcx
>) -> R
,
1974 with_context(|context
| f(context
.tcx
))
1977 /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
1978 /// The closure is passed None if there is no `ImplicitCtxt` available.
1980 pub fn with_opt
<F
, R
>(f
: F
) -> R
1982 F
: for<'tcx
> FnOnce(Option
<TyCtxt
<'tcx
>>) -> R
,
1984 with_context_opt(|opt_context
| f(opt_context
.map(|context
| context
.tcx
)))
1988 macro_rules
! sty_debug_print
{
1989 ($ctxt
: expr
, $
($variant
: ident
),*) => {{
1990 // Curious inner module to allow variant names to be used as
1992 #[allow(non_snake_case)]
1994 use crate::ty
::{self, TyCtxt}
;
1995 use crate::ty
::context
::Interned
;
1997 #[derive(Copy, Clone)]
2006 pub fn go(tcx
: TyCtxt
<'_
>) {
2007 let mut total
= DebugStat
{
2014 $
(let mut $variant
= total
;)*
2016 let shards
= tcx
.interners
.type_
.lock_shards();
2017 let types
= shards
.iter().flat_map(|shard
| shard
.keys());
2018 for &Interned(t
) in types
{
2019 let variant
= match t
.kind
{
2020 ty
::Bool
| ty
::Char
| ty
::Int(..) | ty
::Uint(..) |
2021 ty
::Float(..) | ty
::Str
| ty
::Never
=> continue,
2022 ty
::Error
=> /* unimportant */ continue,
2023 $
(ty
::$
variant(..) => &mut $variant
,)*
2025 let lt
= t
.flags
.intersects(ty
::TypeFlags
::HAS_RE_INFER
);
2026 let ty
= t
.flags
.intersects(ty
::TypeFlags
::HAS_TY_INFER
);
2027 let ct
= t
.flags
.intersects(ty
::TypeFlags
::HAS_CT_INFER
);
2031 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2032 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2033 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2034 if lt
&& ty
&& ct { total.all_infer += 1; variant.all_infer += 1 }
2036 println
!("Ty interner total ty lt ct all");
2037 $
(println
!(" {:18}: {uses:6} {usespc:4.1}%, \
2038 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2039 stringify
!($variant
),
2040 uses
= $variant
.total
,
2041 usespc
= $variant
.total
as f64 * 100.0 / total
.total
as f64,
2042 ty
= $variant
.ty_infer
as f64 * 100.0 / total
.total
as f64,
2043 lt
= $variant
.lt_infer
as f64 * 100.0 / total
.total
as f64,
2044 ct
= $variant
.ct_infer
as f64 * 100.0 / total
.total
as f64,
2045 all
= $variant
.all_infer
as f64 * 100.0 / total
.total
as f64);
2047 println
!(" total {uses:6} \
2048 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2050 ty
= total
.ty_infer
as f64 * 100.0 / total
.total
as f64,
2051 lt
= total
.lt_infer
as f64 * 100.0 / total
.total
as f64,
2052 ct
= total
.ct_infer
as f64 * 100.0 / total
.total
as f64,
2053 all
= total
.all_infer
as f64 * 100.0 / total
.total
as f64)
2061 impl<'tcx
> TyCtxt
<'tcx
> {
2062 pub fn print_debug_stats(self) {
2065 Adt
, Array
, Slice
, RawPtr
, Ref
, FnDef
, FnPtr
, Placeholder
,
2066 Generator
, GeneratorWitness
, Dynamic
, Closure
, Tuple
, Bound
,
2067 Param
, Infer
, UnnormalizedProjection
, Projection
, Opaque
, Foreign
);
2069 println
!("InternalSubsts interner: #{}", self.interners
.substs
.len());
2070 println
!("Region interner: #{}", self.interners
.region
.len());
2071 println
!("Stability interner: #{}", self.stability_interner
.len());
2072 println
!("Const Stability interner: #{}", self.const_stability_interner
.len());
2073 println
!("Allocation interner: #{}", self.allocation_interner
.len());
2074 println
!("Layout interner: #{}", self.layout_interner
.len());
2079 /// An entry in an interner.
2080 struct Interned
<'tcx
, T
: ?Sized
>(&'tcx T
);
2082 impl<'tcx
, T
: 'tcx
+?Sized
> Clone
for Interned
<'tcx
, T
> {
2083 fn clone(&self) -> Self {
2087 impl<'tcx
, T
: 'tcx
+?Sized
> Copy
for Interned
<'tcx
, T
> {}
2089 // N.B., an `Interned<Ty>` compares and hashes as a `TyKind`.
2090 impl<'tcx
> PartialEq
for Interned
<'tcx
, TyS
<'tcx
>> {
2091 fn eq(&self, other
: &Interned
<'tcx
, TyS
<'tcx
>>) -> bool
{
2092 self.0.kind
== other
.0.kind
2096 impl<'tcx
> Eq
for Interned
<'tcx
, TyS
<'tcx
>> {}
2098 impl<'tcx
> Hash
for Interned
<'tcx
, TyS
<'tcx
>> {
2099 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
2104 #[allow(rustc::usage_of_ty_tykind)]
2105 impl<'tcx
> Borrow
<TyKind
<'tcx
>> for Interned
<'tcx
, TyS
<'tcx
>> {
2106 fn borrow
<'a
>(&'a
self) -> &'a TyKind
<'tcx
> {
2111 // N.B., an `Interned<List<T>>` compares and hashes as its elements.
2112 impl<'tcx
, T
: PartialEq
> PartialEq
for Interned
<'tcx
, List
<T
>> {
2113 fn eq(&self, other
: &Interned
<'tcx
, List
<T
>>) -> bool
{
2114 self.0[..] == other
.0[..]
2118 impl<'tcx
, T
: Eq
> Eq
for Interned
<'tcx
, List
<T
>> {}
2120 impl<'tcx
, T
: Hash
> Hash
for Interned
<'tcx
, List
<T
>> {
2121 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
2126 impl<'tcx
> Borrow
<[Ty
<'tcx
>]> for Interned
<'tcx
, List
<Ty
<'tcx
>>> {
2127 fn borrow
<'a
>(&'a
self) -> &'a
[Ty
<'tcx
>] {
2132 impl<'tcx
> Borrow
<[CanonicalVarInfo
]> for Interned
<'tcx
, List
<CanonicalVarInfo
>> {
2133 fn borrow(&self) -> &[CanonicalVarInfo
] {
2138 impl<'tcx
> Borrow
<[GenericArg
<'tcx
>]> for Interned
<'tcx
, InternalSubsts
<'tcx
>> {
2139 fn borrow
<'a
>(&'a
self) -> &'a
[GenericArg
<'tcx
>] {
2144 impl<'tcx
> Borrow
<[ProjectionKind
]>
2145 for Interned
<'tcx
, List
<ProjectionKind
>> {
2146 fn borrow(&self) -> &[ProjectionKind
] {
2151 impl<'tcx
> Borrow
<[PlaceElem
<'tcx
>]>
2152 for Interned
<'tcx
, List
<PlaceElem
<'tcx
>>> {
2153 fn borrow(&self) -> &[PlaceElem
<'tcx
>] {
2158 impl<'tcx
> Borrow
<RegionKind
> for Interned
<'tcx
, RegionKind
> {
2159 fn borrow(&self) -> &RegionKind
{
2164 impl<'tcx
> Borrow
<GoalKind
<'tcx
>> for Interned
<'tcx
, GoalKind
<'tcx
>> {
2165 fn borrow
<'a
>(&'a
self) -> &'a GoalKind
<'tcx
> {
2170 impl<'tcx
> Borrow
<[ExistentialPredicate
<'tcx
>]>
2171 for Interned
<'tcx
, List
<ExistentialPredicate
<'tcx
>>>
2173 fn borrow
<'a
>(&'a
self) -> &'a
[ExistentialPredicate
<'tcx
>] {
2178 impl<'tcx
> Borrow
<[Predicate
<'tcx
>]> for Interned
<'tcx
, List
<Predicate
<'tcx
>>> {
2179 fn borrow
<'a
>(&'a
self) -> &'a
[Predicate
<'tcx
>] {
2184 impl<'tcx
> Borrow
<Const
<'tcx
>> for Interned
<'tcx
, Const
<'tcx
>> {
2185 fn borrow
<'a
>(&'a
self) -> &'a Const
<'tcx
> {
2190 impl<'tcx
> Borrow
<[Clause
<'tcx
>]> for Interned
<'tcx
, List
<Clause
<'tcx
>>> {
2191 fn borrow
<'a
>(&'a
self) -> &'a
[Clause
<'tcx
>] {
2196 impl<'tcx
> Borrow
<[Goal
<'tcx
>]> for Interned
<'tcx
, List
<Goal
<'tcx
>>> {
2197 fn borrow
<'a
>(&'a
self) -> &'a
[Goal
<'tcx
>] {
2202 macro_rules
! direct_interners
{
2203 ($
($name
:ident
: $method
:ident($ty
:ty
)),+) => {
2204 $
(impl<'tcx
> PartialEq
for Interned
<'tcx
, $ty
> {
2205 fn eq(&self, other
: &Self) -> bool
{
2210 impl<'tcx
> Eq
for Interned
<'tcx
, $ty
> {}
2212 impl<'tcx
> Hash
for Interned
<'tcx
, $ty
> {
2213 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
2218 impl<'tcx
> TyCtxt
<'tcx
> {
2219 pub fn $
method(self, v
: $ty
) -> &'tcx $ty
{
2220 self.interners
.$name
.intern_ref(&v
, || {
2221 Interned(self.interners
.arena
.alloc(v
))
2228 pub fn keep_local
<'tcx
, T
: ty
::TypeFoldable
<'tcx
>>(x
: &T
) -> bool
{
2229 x
.has_type_flags(ty
::TypeFlags
::KEEP_IN_LOCAL_TCX
)
2233 region
: mk_region(RegionKind
),
2234 goal
: mk_goal(GoalKind
<'tcx
>),
2235 const_
: mk_const(Const
<'tcx
>)
2238 macro_rules
! slice_interners
{
2239 ($
($field
:ident
: $method
:ident($ty
:ty
)),+) => (
2240 $
(impl<'tcx
> TyCtxt
<'tcx
> {
2241 pub fn $
method(self, v
: &[$ty
]) -> &'tcx List
<$ty
> {
2242 self.interners
.$field
.intern_ref(v
, || {
2243 Interned(List
::from_arena(&self.interners
.arena
, v
))
2251 type_list
: _intern_type_list(Ty
<'tcx
>),
2252 substs
: _intern_substs(GenericArg
<'tcx
>),
2253 canonical_var_infos
: _intern_canonical_var_infos(CanonicalVarInfo
),
2254 existential_predicates
: _intern_existential_predicates(ExistentialPredicate
<'tcx
>),
2255 predicates
: _intern_predicates(Predicate
<'tcx
>),
2256 clauses
: _intern_clauses(Clause
<'tcx
>),
2257 goal_list
: _intern_goals(Goal
<'tcx
>),
2258 projs
: _intern_projs(ProjectionKind
),
2259 place_elems
: _intern_place_elems(PlaceElem
<'tcx
>)
2262 impl<'tcx
> TyCtxt
<'tcx
> {
2263 /// Given a `fn` type, returns an equivalent `unsafe fn` type;
2264 /// that is, a `fn` type that is equivalent in every way for being
2266 pub fn safe_to_unsafe_fn_ty(self, sig
: PolyFnSig
<'tcx
>) -> Ty
<'tcx
> {
2267 assert_eq
!(sig
.unsafety(), hir
::Unsafety
::Normal
);
2268 self.mk_fn_ptr(sig
.map_bound(|sig
| ty
::FnSig
{
2269 unsafety
: hir
::Unsafety
::Unsafe
,
2274 /// Given a closure signature `sig`, returns an equivalent `fn`
2275 /// type with the same signature. Detuples and so forth -- so
2276 /// e.g., if we have a sig with `Fn<(u32, i32)>` then you would get
2277 /// a `fn(u32, i32)`.
2278 /// `unsafety` determines the unsafety of the `fn` type. If you pass
2279 /// `hir::Unsafety::Unsafe` in the previous example, then you would get
2280 /// an `unsafe fn (u32, i32)`.
2281 /// It cannot convert a closure that requires unsafe.
2282 pub fn coerce_closure_fn_ty(self, sig
: PolyFnSig
<'tcx
>, unsafety
: hir
::Unsafety
) -> Ty
<'tcx
> {
2283 let converted_sig
= sig
.map_bound(|s
| {
2284 let params_iter
= match s
.inputs()[0].kind
{
2285 ty
::Tuple(params
) => {
2286 params
.into_iter().map(|k
| k
.expect_ty())
2299 self.mk_fn_ptr(converted_sig
)
2302 #[allow(rustc::usage_of_ty_tykind)]
2304 pub fn mk_ty(&self, st
: TyKind
<'tcx
>) -> Ty
<'tcx
> {
2305 self.interners
.intern_ty(st
)
2308 pub fn mk_mach_int(self, tm
: ast
::IntTy
) -> Ty
<'tcx
> {
2310 ast
::IntTy
::Isize
=> self.types
.isize,
2311 ast
::IntTy
::I8
=> self.types
.i8,
2312 ast
::IntTy
::I16
=> self.types
.i16,
2313 ast
::IntTy
::I32
=> self.types
.i32,
2314 ast
::IntTy
::I64
=> self.types
.i64,
2315 ast
::IntTy
::I128
=> self.types
.i128
,
2319 pub fn mk_mach_uint(self, tm
: ast
::UintTy
) -> Ty
<'tcx
> {
2321 ast
::UintTy
::Usize
=> self.types
.usize,
2322 ast
::UintTy
::U8
=> self.types
.u8,
2323 ast
::UintTy
::U16
=> self.types
.u16,
2324 ast
::UintTy
::U32
=> self.types
.u32,
2325 ast
::UintTy
::U64
=> self.types
.u64,
2326 ast
::UintTy
::U128
=> self.types
.u128
,
2330 pub fn mk_mach_float(self, tm
: ast
::FloatTy
) -> Ty
<'tcx
> {
2332 ast
::FloatTy
::F32
=> self.types
.f32,
2333 ast
::FloatTy
::F64
=> self.types
.f64,
2338 pub fn mk_str(self) -> Ty
<'tcx
> {
2343 pub fn mk_static_str(self) -> Ty
<'tcx
> {
2344 self.mk_imm_ref(self.lifetimes
.re_static
, self.mk_str())
2348 pub fn mk_adt(self, def
: &'tcx AdtDef
, substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2349 // Take a copy of substs so that we own the vectors inside.
2350 self.mk_ty(Adt(def
, substs
))
2354 pub fn mk_foreign(self, def_id
: DefId
) -> Ty
<'tcx
> {
2355 self.mk_ty(Foreign(def_id
))
2358 fn mk_generic_adt(self, wrapper_def_id
: DefId
, ty_param
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2359 let adt_def
= self.adt_def(wrapper_def_id
);
2360 let substs
= InternalSubsts
::for_item(self, wrapper_def_id
, |param
, substs
| {
2362 GenericParamDefKind
::Lifetime
|
2363 GenericParamDefKind
::Const
=> {
2366 GenericParamDefKind
::Type { has_default, .. }
=> {
2367 if param
.index
== 0 {
2370 assert
!(has_default
);
2371 self.type_of(param
.def_id
).subst(self, substs
).into()
2376 self.mk_ty(Adt(adt_def
, substs
))
2380 pub fn mk_box(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2381 let def_id
= self.require_lang_item(lang_items
::OwnedBoxLangItem
, None
);
2382 self.mk_generic_adt(def_id
, ty
)
2386 pub fn mk_lang_item(self, ty
: Ty
<'tcx
>, item
: lang_items
::LangItem
) -> Option
<Ty
<'tcx
>> {
2387 let def_id
= self.lang_items().require(item
).ok()?
;
2388 Some(self.mk_generic_adt(def_id
, ty
))
2392 pub fn mk_maybe_uninit(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2393 let def_id
= self.require_lang_item(lang_items
::MaybeUninitLangItem
, None
);
2394 self.mk_generic_adt(def_id
, ty
)
2398 pub fn mk_ptr(self, tm
: TypeAndMut
<'tcx
>) -> Ty
<'tcx
> {
2399 self.mk_ty(RawPtr(tm
))
2403 pub fn mk_ref(self, r
: Region
<'tcx
>, tm
: TypeAndMut
<'tcx
>) -> Ty
<'tcx
> {
2404 self.mk_ty(Ref(r
, tm
.ty
, tm
.mutbl
))
2408 pub fn mk_mut_ref(self, r
: Region
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2409 self.mk_ref(r
, TypeAndMut {ty: ty, mutbl: hir::Mutability::Mutable}
)
2413 pub fn mk_imm_ref(self, r
: Region
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2414 self.mk_ref(r
, TypeAndMut {ty: ty, mutbl: hir::Mutability::Immutable}
)
2418 pub fn mk_mut_ptr(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2419 self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::Mutability::Mutable}
)
2423 pub fn mk_imm_ptr(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2424 self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::Mutability::Immutable}
)
2428 pub fn mk_nil_ptr(self) -> Ty
<'tcx
> {
2429 self.mk_imm_ptr(self.mk_unit())
2433 pub fn mk_array(self, ty
: Ty
<'tcx
>, n
: u64) -> Ty
<'tcx
> {
2434 self.mk_ty(Array(ty
, ty
::Const
::from_usize(self, n
)))
2438 pub fn mk_slice(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2439 self.mk_ty(Slice(ty
))
2443 pub fn intern_tup(self, ts
: &[Ty
<'tcx
>]) -> Ty
<'tcx
> {
2444 let kinds
: Vec
<_
> = ts
.into_iter().map(|&t
| GenericArg
::from(t
)).collect();
2445 self.mk_ty(Tuple(self.intern_substs(&kinds
)))
2448 pub fn mk_tup
<I
: InternAs
<[Ty
<'tcx
>], Ty
<'tcx
>>>(self, iter
: I
) -> I
::Output
{
2449 iter
.intern_with(|ts
| {
2450 let kinds
: Vec
<_
> = ts
.into_iter().map(|&t
| GenericArg
::from(t
)).collect();
2451 self.mk_ty(Tuple(self.intern_substs(&kinds
)))
2456 pub fn mk_unit(self) -> Ty
<'tcx
> {
2461 pub fn mk_diverging_default(self) -> Ty
<'tcx
> {
2462 if self.features().never_type_fallback
{
2470 pub fn mk_bool(self) -> Ty
<'tcx
> {
2475 pub fn mk_fn_def(self, def_id
: DefId
,
2476 substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2477 self.mk_ty(FnDef(def_id
, substs
))
2481 pub fn mk_fn_ptr(self, fty
: PolyFnSig
<'tcx
>) -> Ty
<'tcx
> {
2482 self.mk_ty(FnPtr(fty
))
2488 obj
: ty
::Binder
<&'tcx List
<ExistentialPredicate
<'tcx
>>>,
2489 reg
: ty
::Region
<'tcx
>
2491 self.mk_ty(Dynamic(obj
, reg
))
2495 pub fn mk_projection(self,
2497 substs
: SubstsRef
<'tcx
>)
2499 self.mk_ty(Projection(ProjectionTy
{
2506 pub fn mk_closure(self, closure_id
: DefId
, closure_substs
: SubstsRef
<'tcx
>)
2508 self.mk_ty(Closure(closure_id
, closure_substs
))
2512 pub fn mk_generator(self,
2514 generator_substs
: SubstsRef
<'tcx
>,
2515 movability
: hir
::Movability
)
2517 self.mk_ty(Generator(id
, generator_substs
, movability
))
2521 pub fn mk_generator_witness(self, types
: ty
::Binder
<&'tcx List
<Ty
<'tcx
>>>) -> Ty
<'tcx
> {
2522 self.mk_ty(GeneratorWitness(types
))
2526 pub fn mk_ty_var(self, v
: TyVid
) -> Ty
<'tcx
> {
2527 self.mk_ty_infer(TyVar(v
))
2531 pub fn mk_const_var(self, v
: ConstVid
<'tcx
>, ty
: Ty
<'tcx
>) -> &'tcx Const
<'tcx
> {
2532 self.mk_const(ty
::Const
{
2533 val
: ty
::ConstKind
::Infer(InferConst
::Var(v
)),
2539 pub fn mk_int_var(self, v
: IntVid
) -> Ty
<'tcx
> {
2540 self.mk_ty_infer(IntVar(v
))
2544 pub fn mk_float_var(self, v
: FloatVid
) -> Ty
<'tcx
> {
2545 self.mk_ty_infer(FloatVar(v
))
2549 pub fn mk_ty_infer(self, it
: InferTy
) -> Ty
<'tcx
> {
2550 self.mk_ty(Infer(it
))
2554 pub fn mk_const_infer(
2556 ic
: InferConst
<'tcx
>,
2558 ) -> &'tcx ty
::Const
<'tcx
> {
2559 self.mk_const(ty
::Const
{
2560 val
: ty
::ConstKind
::Infer(ic
),
2566 pub fn mk_ty_param(self, index
: u32, name
: Symbol
) -> Ty
<'tcx
> {
2567 self.mk_ty(Param(ParamTy { index, name: name }
))
2571 pub fn mk_const_param(
2576 ) -> &'tcx Const
<'tcx
> {
2577 self.mk_const(ty
::Const
{
2578 val
: ty
::ConstKind
::Param(ParamConst { index, name }
),
2584 pub fn mk_param_from_def(self, param
: &ty
::GenericParamDef
) -> GenericArg
<'tcx
> {
2586 GenericParamDefKind
::Lifetime
=> {
2587 self.mk_region(ty
::ReEarlyBound(param
.to_early_bound_region_data())).into()
2589 GenericParamDefKind
::Type { .. }
=> self.mk_ty_param(param
.index
, param
.name
).into(),
2590 GenericParamDefKind
::Const
=> {
2591 self.mk_const_param(param
.index
, param
.name
, self.type_of(param
.def_id
)).into()
2597 pub fn mk_opaque(self, def_id
: DefId
, substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2598 self.mk_ty(Opaque(def_id
, substs
))
2601 pub fn mk_place_field(self, place
: Place
<'tcx
>, f
: Field
, ty
: Ty
<'tcx
>) -> Place
<'tcx
> {
2602 self.mk_place_elem(place
, PlaceElem
::Field(f
, ty
))
2605 pub fn mk_place_deref(self, place
: Place
<'tcx
>) -> Place
<'tcx
> {
2606 self.mk_place_elem(place
, PlaceElem
::Deref
)
2609 pub fn mk_place_downcast(
2612 adt_def
: &'tcx AdtDef
,
2613 variant_index
: VariantIdx
,
2617 PlaceElem
::Downcast(Some(adt_def
.variants
[variant_index
].ident
.name
), variant_index
),
2621 pub fn mk_place_downcast_unnamed(
2624 variant_index
: VariantIdx
,
2626 self.mk_place_elem(place
, PlaceElem
::Downcast(None
, variant_index
))
2629 pub fn mk_place_index(self, place
: Place
<'tcx
>, index
: Local
) -> Place
<'tcx
> {
2630 self.mk_place_elem(place
, PlaceElem
::Index(index
))
2633 /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2634 /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2636 pub fn mk_place_elem(self, place
: Place
<'tcx
>, elem
: PlaceElem
<'tcx
>) -> Place
<'tcx
> {
2637 let mut projection
= place
.projection
.to_vec();
2638 projection
.push(elem
);
2640 Place { base: place.base, projection: self.intern_place_elems(&projection) }
2643 pub fn intern_existential_predicates(self, eps
: &[ExistentialPredicate
<'tcx
>])
2644 -> &'tcx List
<ExistentialPredicate
<'tcx
>> {
2645 assert
!(!eps
.is_empty());
2646 assert
!(eps
.windows(2).all(|w
| w
[0].stable_cmp(self, &w
[1]) != Ordering
::Greater
));
2647 self._intern_existential_predicates(eps
)
2650 pub fn intern_predicates(self, preds
: &[Predicate
<'tcx
>])
2651 -> &'tcx List
<Predicate
<'tcx
>> {
2652 // FIXME consider asking the input slice to be sorted to avoid
2653 // re-interning permutations, in which case that would be asserted
2655 if preds
.len() == 0 {
2656 // The macro-generated method below asserts we don't intern an empty slice.
2659 self._intern_predicates(preds
)
2663 pub fn intern_type_list(self, ts
: &[Ty
<'tcx
>]) -> &'tcx List
<Ty
<'tcx
>> {
2667 self._intern_type_list(ts
)
2671 pub fn intern_substs(self, ts
: &[GenericArg
<'tcx
>]) -> &'tcx List
<GenericArg
<'tcx
>> {
2675 self._intern_substs(ts
)
2679 pub fn intern_projs(self, ps
: &[ProjectionKind
]) -> &'tcx List
<ProjectionKind
> {
2683 self._intern_projs(ps
)
2687 pub fn intern_place_elems(self, ts
: &[PlaceElem
<'tcx
>]) -> &'tcx List
<PlaceElem
<'tcx
>> {
2691 self._intern_place_elems(ts
)
2695 pub fn intern_canonical_var_infos(self, ts
: &[CanonicalVarInfo
]) -> CanonicalVarInfos
<'tcx
> {
2699 self._intern_canonical_var_infos(ts
)
2703 pub fn intern_clauses(self, ts
: &[Clause
<'tcx
>]) -> Clauses
<'tcx
> {
2707 self._intern_clauses(ts
)
2711 pub fn intern_goals(self, ts
: &[Goal
<'tcx
>]) -> Goals
<'tcx
> {
2715 self._intern_goals(ts
)
2719 pub fn mk_fn_sig
<I
>(self,
2723 unsafety
: hir
::Unsafety
,
2725 -> <I
::Item
as InternIteratorElement
<Ty
<'tcx
>, ty
::FnSig
<'tcx
>>>::Output
2727 I
: Iterator
<Item
: InternIteratorElement
<Ty
<'tcx
>, ty
::FnSig
<'tcx
>>>,
2729 inputs
.chain(iter
::once(output
)).intern_with(|xs
| ty
::FnSig
{
2730 inputs_and_output
: self.intern_type_list(xs
),
2731 c_variadic
, unsafety
, abi
2735 pub fn mk_existential_predicates
<I
: InternAs
<[ExistentialPredicate
<'tcx
>],
2736 &'tcx List
<ExistentialPredicate
<'tcx
>>>>(self, iter
: I
)
2738 iter
.intern_with(|xs
| self.intern_existential_predicates(xs
))
2741 pub fn mk_predicates
<I
: InternAs
<[Predicate
<'tcx
>],
2742 &'tcx List
<Predicate
<'tcx
>>>>(self, iter
: I
)
2744 iter
.intern_with(|xs
| self.intern_predicates(xs
))
2747 pub fn mk_type_list
<I
: InternAs
<[Ty
<'tcx
>],
2748 &'tcx List
<Ty
<'tcx
>>>>(self, iter
: I
) -> I
::Output
{
2749 iter
.intern_with(|xs
| self.intern_type_list(xs
))
2752 pub fn mk_substs
<I
: InternAs
<[GenericArg
<'tcx
>],
2753 &'tcx List
<GenericArg
<'tcx
>>>>(self, iter
: I
) -> I
::Output
{
2754 iter
.intern_with(|xs
| self.intern_substs(xs
))
2757 pub fn mk_place_elems
<I
: InternAs
<[PlaceElem
<'tcx
>],
2758 &'tcx List
<PlaceElem
<'tcx
>>>>(self, iter
: I
) -> I
::Output
{
2759 iter
.intern_with(|xs
| self.intern_place_elems(xs
))
2762 pub fn mk_substs_trait(self,
2764 rest
: &[GenericArg
<'tcx
>])
2767 self.mk_substs(iter
::once(self_ty
.into()).chain(rest
.iter().cloned()))
2770 pub fn mk_clauses
<I
: InternAs
<[Clause
<'tcx
>], Clauses
<'tcx
>>>(self, iter
: I
) -> I
::Output
{
2771 iter
.intern_with(|xs
| self.intern_clauses(xs
))
2774 pub fn mk_goals
<I
: InternAs
<[Goal
<'tcx
>], Goals
<'tcx
>>>(self, iter
: I
) -> I
::Output
{
2775 iter
.intern_with(|xs
| self.intern_goals(xs
))
2778 pub fn lint_hir
<S
: Into
<MultiSpan
>>(self,
2779 lint
: &'
static Lint
,
2783 self.struct_span_lint_hir(lint
, hir_id
, span
.into(), msg
).emit()
2786 pub fn lint_hir_note
<S
: Into
<MultiSpan
>>(self,
2787 lint
: &'
static Lint
,
2792 let mut err
= self.struct_span_lint_hir(lint
, hir_id
, span
.into(), msg
);
2797 pub fn lint_node_note
<S
: Into
<MultiSpan
>>(self,
2798 lint
: &'
static Lint
,
2803 let mut err
= self.struct_span_lint_hir(lint
, id
, span
.into(), msg
);
2808 /// Walks upwards from `id` to find a node which might change lint levels with attributes.
2809 /// It stops at `bound` and just returns it if reached.
2810 pub fn maybe_lint_level_root_bounded(
2819 if lint
::maybe_lint_level_root(self, id
) {
2822 let next
= self.hir().get_parent_node(id
);
2824 bug
!("lint traversal reached the root of the crate");
2830 pub fn lint_level_at_node(
2832 lint
: &'
static Lint
,
2834 ) -> (lint
::Level
, lint
::LintSource
) {
2835 let sets
= self.lint_levels(LOCAL_CRATE
);
2837 if let Some(pair
) = sets
.level_and_source(lint
, id
, self.sess
) {
2840 let next
= self.hir().get_parent_node(id
);
2842 bug
!("lint traversal reached the root of the crate");
2848 pub fn struct_span_lint_hir
<S
: Into
<MultiSpan
>>(self,
2849 lint
: &'
static Lint
,
2853 -> DiagnosticBuilder
<'tcx
>
2855 let (level
, src
) = self.lint_level_at_node(lint
, hir_id
);
2856 lint
::struct_lint_level(self.sess
, lint
, level
, src
, Some(span
.into()), msg
)
2859 pub fn struct_lint_node(self, lint
: &'
static Lint
, id
: HirId
, msg
: &str)
2860 -> DiagnosticBuilder
<'tcx
>
2862 let (level
, src
) = self.lint_level_at_node(lint
, id
);
2863 lint
::struct_lint_level(self.sess
, lint
, level
, src
, None
, msg
)
2866 pub fn in_scope_traits(self, id
: HirId
) -> Option
<&'tcx StableVec
<TraitCandidate
>> {
2867 self.in_scope_traits_map(id
.owner
)
2868 .and_then(|map
| map
.get(&id
.local_id
))
2871 pub fn named_region(self, id
: HirId
) -> Option
<resolve_lifetime
::Region
> {
2872 self.named_region_map(id
.owner
)
2873 .and_then(|map
| map
.get(&id
.local_id
).cloned())
2876 pub fn is_late_bound(self, id
: HirId
) -> bool
{
2877 self.is_late_bound_map(id
.owner
)
2878 .map(|set
| set
.contains(&id
.local_id
))
2882 pub fn object_lifetime_defaults(self, id
: HirId
) -> Option
<&'tcx
[ObjectLifetimeDefault
]> {
2883 self.object_lifetime_defaults_map(id
.owner
)
2884 .and_then(|map
| map
.get(&id
.local_id
).map(|v
| &**v
))
2888 pub trait InternAs
<T
: ?Sized
, R
> {
2890 fn intern_with
<F
>(self, f
: F
) -> Self::Output
2891 where F
: FnOnce(&T
) -> R
;
2894 impl<I
, T
, R
, E
> InternAs
<[T
], R
> for I
2895 where E
: InternIteratorElement
<T
, R
>,
2896 I
: Iterator
<Item
=E
> {
2897 type Output
= E
::Output
;
2898 fn intern_with
<F
>(self, f
: F
) -> Self::Output
2899 where F
: FnOnce(&[T
]) -> R
{
2900 E
::intern_with(self, f
)
2904 pub trait InternIteratorElement
<T
, R
>: Sized
{
2906 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
;
2909 impl<T
, R
> InternIteratorElement
<T
, R
> for T
{
2911 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
{
2912 f(&iter
.collect
::<SmallVec
<[_
; 8]>>())
2916 impl<'a
, T
, R
> InternIteratorElement
<T
, R
> for &'a T
2920 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
{
2921 f(&iter
.cloned().collect
::<SmallVec
<[_
; 8]>>())
2925 impl<T
, R
, E
> InternIteratorElement
<T
, R
> for Result
<T
, E
> {
2926 type Output
= Result
<R
, E
>;
2927 fn intern_with
<I
: Iterator
<Item
=Self>, F
: FnOnce(&[T
]) -> R
>(mut iter
: I
, f
: F
)
2929 // This code is hot enough that it's worth specializing for the most
2930 // common length lists, to avoid the overhead of `SmallVec` creation.
2931 // The match arms are in order of frequency. The 1, 2, and 0 cases are
2932 // typically hit in ~95% of cases. We assume that if the upper and
2933 // lower bounds from `size_hint` agree they are correct.
2934 Ok(match iter
.size_hint() {
2936 let t0
= iter
.next().unwrap()?
;
2937 assert
!(iter
.next().is_none());
2941 let t0
= iter
.next().unwrap()?
;
2942 let t1
= iter
.next().unwrap()?
;
2943 assert
!(iter
.next().is_none());
2947 assert
!(iter
.next().is_none());
2951 f(&iter
.collect
::<Result
<SmallVec
<[_
; 8]>, _
>>()?
)
2957 // We are comparing types with different invariant lifetimes, so `ptr::eq`
2958 // won't work for us.
2959 fn ptr_eq
<T
, U
>(t
: *const T
, u
: *const U
) -> bool
{
2960 t
as *const () == u
as *const ()
2963 pub fn provide(providers
: &mut ty
::query
::Providers
<'_
>) {
2964 providers
.in_scope_traits_map
= |tcx
, id
| tcx
.gcx
.trait_map
.get(&id
);
2965 providers
.module_exports
= |tcx
, id
| tcx
.gcx
.export_map
.get(&id
).map(|v
| &v
[..]);
2966 providers
.crate_name
= |tcx
, id
| {
2967 assert_eq
!(id
, LOCAL_CRATE
);
2970 providers
.get_lib_features
= |tcx
, id
| {
2971 assert_eq
!(id
, LOCAL_CRATE
);
2972 tcx
.arena
.alloc(middle
::lib_features
::collect(tcx
))
2974 providers
.get_lang_items
= |tcx
, id
| {
2975 assert_eq
!(id
, LOCAL_CRATE
);
2976 tcx
.arena
.alloc(middle
::lang_items
::collect(tcx
))
2978 providers
.diagnostic_items
= |tcx
, id
| {
2979 assert_eq
!(id
, LOCAL_CRATE
);
2980 middle
::diagnostic_items
::collect(tcx
)
2982 providers
.all_diagnostic_items
= |tcx
, id
| {
2983 assert_eq
!(id
, LOCAL_CRATE
);
2984 middle
::diagnostic_items
::collect_all(tcx
)
2986 providers
.maybe_unused_trait_import
= |tcx
, id
| {
2987 tcx
.maybe_unused_trait_imports
.contains(&id
)
2989 providers
.maybe_unused_extern_crates
= |tcx
, cnum
| {
2990 assert_eq
!(cnum
, LOCAL_CRATE
);
2991 &tcx
.maybe_unused_extern_crates
[..]
2993 providers
.names_imported_by_glob_use
= |tcx
, id
| {
2994 assert_eq
!(id
.krate
, LOCAL_CRATE
);
2995 Lrc
::new(tcx
.glob_map
.get(&id
).cloned().unwrap_or_default())
2998 providers
.stability_index
= |tcx
, cnum
| {
2999 assert_eq
!(cnum
, LOCAL_CRATE
);
3000 tcx
.arena
.alloc(stability
::Index
::new(tcx
))
3002 providers
.lookup_stability
= |tcx
, id
| {
3003 assert_eq
!(id
.krate
, LOCAL_CRATE
);
3004 let id
= tcx
.hir().definitions().def_index_to_hir_id(id
.index
);
3005 tcx
.stability().local_stability(id
)
3007 providers
.lookup_const_stability
= |tcx
, id
| {
3008 assert_eq
!(id
.krate
, LOCAL_CRATE
);
3009 let id
= tcx
.hir().definitions().def_index_to_hir_id(id
.index
);
3010 tcx
.stability().local_const_stability(id
)
3012 providers
.lookup_deprecation_entry
= |tcx
, id
| {
3013 assert_eq
!(id
.krate
, LOCAL_CRATE
);
3014 let id
= tcx
.hir().definitions().def_index_to_hir_id(id
.index
);
3015 tcx
.stability().local_deprecation_entry(id
)
3017 providers
.extern_mod_stmt_cnum
= |tcx
, id
| {
3018 let id
= tcx
.hir().as_local_node_id(id
).unwrap();
3019 tcx
.extern_crate_map
.get(&id
).cloned()
3021 providers
.all_crate_nums
= |tcx
, cnum
| {
3022 assert_eq
!(cnum
, LOCAL_CRATE
);
3023 tcx
.arena
.alloc_slice(&tcx
.cstore
.crates_untracked())
3025 providers
.output_filenames
= |tcx
, cnum
| {
3026 assert_eq
!(cnum
, LOCAL_CRATE
);
3027 tcx
.output_filenames
.clone()
3029 providers
.features_query
= |tcx
, cnum
| {
3030 assert_eq
!(cnum
, LOCAL_CRATE
);
3031 tcx
.arena
.alloc(tcx
.sess
.features_untracked().clone())
3033 providers
.is_panic_runtime
= |tcx
, cnum
| {
3034 assert_eq
!(cnum
, LOCAL_CRATE
);
3035 attr
::contains_name(tcx
.hir().krate_attrs(), sym
::panic_runtime
)
3037 providers
.is_compiler_builtins
= |tcx
, cnum
| {
3038 assert_eq
!(cnum
, LOCAL_CRATE
);
3039 attr
::contains_name(tcx
.hir().krate_attrs(), sym
::compiler_builtins
)
3041 providers
.has_panic_handler
= |tcx
, cnum
| {
3042 assert_eq
!(cnum
, LOCAL_CRATE
);
3043 // We want to check if the panic handler was defined in this crate
3044 tcx
.lang_items().panic_impl().map_or(false, |did
| did
.is_local())