1 //! Type context book-keeping.
3 use crate::arena
::Arena
;
4 use crate::dep_graph
::{self, DepConstructor, DepGraph}
;
5 use crate::hir
::exports
::ExportMap
;
6 use crate::ich
::{NodeIdHashingMode, StableHashingContext}
;
7 use crate::infer
::canonical
::{Canonical, CanonicalVarInfo, CanonicalVarInfos}
;
8 use crate::lint
::{struct_lint_level, LintDiagnosticBuilder, LintSource}
;
10 use crate::middle
::cstore
::{CrateStoreDyn, EncodedMetadata}
;
11 use crate::middle
::resolve_lifetime
::{self, ObjectLifetimeDefault}
;
12 use crate::middle
::stability
;
13 use crate::mir
::interpret
::{self, Allocation, ConstValue, Scalar}
;
14 use crate::mir
::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted}
;
16 use crate::ty
::query
::{self, TyCtxtAt}
;
17 use crate::ty
::steal
::Steal
;
18 use crate::ty
::subst
::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts}
;
19 use crate::ty
::TyKind
::*;
21 self, AdtDef
, AdtKind
, BindingMode
, BoundVar
, CanonicalPolyFnSig
, Const
, ConstVid
, DefIdTree
,
22 ExistentialPredicate
, FloatVar
, FloatVid
, GenericParamDefKind
, InferConst
, InferTy
, IntVar
,
23 IntVid
, List
, ParamConst
, ParamTy
, PolyFnSig
, Predicate
, PredicateInner
, PredicateKind
,
24 ProjectionTy
, Region
, RegionKind
, ReprOptions
, TraitObjectVisitor
, Ty
, TyKind
, TyS
, TyVar
,
28 use rustc_ast
::expand
::allocator
::AllocatorKind
;
29 use rustc_attr
as attr
;
30 use rustc_data_structures
::fx
::{FxHashMap, FxHashSet}
;
31 use rustc_data_structures
::profiling
::SelfProfilerRef
;
32 use rustc_data_structures
::sharded
::{IntoPointer, ShardedHashMap}
;
33 use rustc_data_structures
::stable_hasher
::{
34 hash_stable_hashmap
, HashStable
, StableHasher
, StableVec
,
36 use rustc_data_structures
::sync
::{self, Lock, Lrc, WorkerLocal}
;
37 use rustc_errors
::ErrorReported
;
39 use rustc_hir
::def
::{DefKind, Res}
;
40 use rustc_hir
::def_id
::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE}
;
41 use rustc_hir
::definitions
::{DefPathHash, Definitions}
;
42 use rustc_hir
::intravisit
::Visitor
;
43 use rustc_hir
::lang_items
::LangItem
;
44 use rustc_hir
::{HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate}
;
45 use rustc_index
::vec
::{Idx, IndexVec}
;
46 use rustc_macros
::HashStable
;
47 use rustc_session
::config
::{BorrowckMode, CrateType, OutputFilenames}
;
48 use rustc_session
::lint
::{Level, Lint}
;
49 use rustc_session
::Session
;
50 use rustc_span
::source_map
::MultiSpan
;
51 use rustc_span
::symbol
::{kw, sym, Symbol}
;
52 use rustc_span
::{Span, DUMMY_SP}
;
53 use rustc_target
::abi
::{Layout, TargetDataLayout, VariantIdx}
;
54 use rustc_target
::spec
::abi
;
56 use smallvec
::SmallVec
;
58 use std
::borrow
::Borrow
;
59 use std
::cmp
::Ordering
;
60 use std
::collections
::hash_map
::{self, Entry}
;
62 use std
::hash
::{Hash, Hasher}
;
65 use std
::ops
::{Bound, Deref}
;
68 /// A type that is not publicly constructable. This prevents people from making `TyKind::Error`
69 /// except through `tcx.err*()`, which are in this module.
70 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
71 #[derive(TyEncodable, TyDecodable, HashStable)]
72 pub struct DelaySpanBugEmitted(());
74 type InternedSet
<'tcx
, T
> = ShardedHashMap
<Interned
<'tcx
, T
>, ()>;
76 pub struct CtxtInterners
<'tcx
> {
77 /// The arena that types, regions, etc. are allocated from.
78 arena
: &'tcx WorkerLocal
<Arena
<'tcx
>>,
80 /// Specifically use a speedy hash algorithm for these hash sets, since
81 /// they're accessed quite often.
82 type_
: InternedSet
<'tcx
, TyS
<'tcx
>>,
83 type_list
: InternedSet
<'tcx
, List
<Ty
<'tcx
>>>,
84 substs
: InternedSet
<'tcx
, InternalSubsts
<'tcx
>>,
85 canonical_var_infos
: InternedSet
<'tcx
, List
<CanonicalVarInfo
>>,
86 region
: InternedSet
<'tcx
, RegionKind
>,
87 existential_predicates
: InternedSet
<'tcx
, List
<ExistentialPredicate
<'tcx
>>>,
88 predicate
: InternedSet
<'tcx
, PredicateInner
<'tcx
>>,
89 predicates
: InternedSet
<'tcx
, List
<Predicate
<'tcx
>>>,
90 projs
: InternedSet
<'tcx
, List
<ProjectionKind
>>,
91 place_elems
: InternedSet
<'tcx
, List
<PlaceElem
<'tcx
>>>,
92 const_
: InternedSet
<'tcx
, Const
<'tcx
>>,
94 chalk_environment_clause_list
: InternedSet
<'tcx
, List
<traits
::ChalkEnvironmentClause
<'tcx
>>>,
97 impl<'tcx
> CtxtInterners
<'tcx
> {
98 fn new(arena
: &'tcx WorkerLocal
<Arena
<'tcx
>>) -> CtxtInterners
<'tcx
> {
101 type_
: Default
::default(),
102 type_list
: Default
::default(),
103 substs
: Default
::default(),
104 region
: Default
::default(),
105 existential_predicates
: Default
::default(),
106 canonical_var_infos
: Default
::default(),
107 predicate
: Default
::default(),
108 predicates
: Default
::default(),
109 projs
: Default
::default(),
110 place_elems
: Default
::default(),
111 const_
: Default
::default(),
112 chalk_environment_clause_list
: Default
::default(),
117 #[allow(rustc::usage_of_ty_tykind)]
119 fn intern_ty(&self, kind
: TyKind
<'tcx
>) -> Ty
<'tcx
> {
121 .intern(kind
, |kind
| {
122 let flags
= super::flags
::FlagComputation
::for_kind(&kind
);
124 let ty_struct
= TyS
{
127 outer_exclusive_binder
: flags
.outer_exclusive_binder
,
130 Interned(self.arena
.alloc(ty_struct
))
136 fn intern_predicate(&self, kind
: PredicateKind
<'tcx
>) -> &'tcx PredicateInner
<'tcx
> {
138 .intern(kind
, |kind
| {
139 let flags
= super::flags
::FlagComputation
::for_predicate(&kind
);
141 let predicate_struct
= PredicateInner
{
144 outer_exclusive_binder
: flags
.outer_exclusive_binder
,
147 Interned(self.arena
.alloc(predicate_struct
))
153 pub struct CommonTypes
<'tcx
> {
173 pub self_param
: Ty
<'tcx
>,
175 /// Dummy type used for the `Self` of a `TraitRef` created for converting
176 /// a trait object, and which gets removed in `ExistentialTraitRef`.
177 /// This type must not appear anywhere in other converted types.
178 pub trait_object_dummy_self
: Ty
<'tcx
>,
181 pub struct CommonLifetimes
<'tcx
> {
182 /// `ReEmpty` in the root universe.
183 pub re_root_empty
: Region
<'tcx
>,
186 pub re_static
: Region
<'tcx
>,
188 /// Erased region, used after type-checking
189 pub re_erased
: Region
<'tcx
>,
192 pub struct CommonConsts
<'tcx
> {
193 pub unit
: &'tcx Const
<'tcx
>,
196 pub struct LocalTableInContext
<'a
, V
> {
197 hir_owner
: LocalDefId
,
198 data
: &'a ItemLocalMap
<V
>,
201 /// Validate that the given HirId (respectively its `local_id` part) can be
202 /// safely used as a key in the maps of a TypeckResults. For that to be
203 /// the case, the HirId must have the same `owner` as all the other IDs in
204 /// this table (signified by `hir_owner`). Otherwise the HirId
205 /// would be in a different frame of reference and using its `local_id`
206 /// would result in lookup errors, or worse, in silently wrong data being
208 fn validate_hir_id_for_typeck_results(hir_owner
: LocalDefId
, hir_id
: hir
::HirId
) {
209 if hir_id
.owner
!= hir_owner
{
210 ty
::tls
::with(|tcx
| {
212 "node {} with HirId::owner {:?} cannot be placed in TypeckResults with hir_owner {:?}",
213 tcx
.hir().node_to_string(hir_id
),
221 impl<'a
, V
> LocalTableInContext
<'a
, V
> {
222 pub fn contains_key(&self, id
: hir
::HirId
) -> bool
{
223 validate_hir_id_for_typeck_results(self.hir_owner
, id
);
224 self.data
.contains_key(&id
.local_id
)
227 pub fn get(&self, id
: hir
::HirId
) -> Option
<&V
> {
228 validate_hir_id_for_typeck_results(self.hir_owner
, id
);
229 self.data
.get(&id
.local_id
)
232 pub fn iter(&self) -> hash_map
::Iter
<'_
, hir
::ItemLocalId
, V
> {
237 impl<'a
, V
> ::std
::ops
::Index
<hir
::HirId
> for LocalTableInContext
<'a
, V
> {
240 fn index(&self, key
: hir
::HirId
) -> &V
{
241 self.get(key
).expect("LocalTableInContext: key not found")
245 pub struct LocalTableInContextMut
<'a
, V
> {
246 hir_owner
: LocalDefId
,
247 data
: &'a
mut ItemLocalMap
<V
>,
250 impl<'a
, V
> LocalTableInContextMut
<'a
, V
> {
251 pub fn get_mut(&mut self, id
: hir
::HirId
) -> Option
<&mut V
> {
252 validate_hir_id_for_typeck_results(self.hir_owner
, id
);
253 self.data
.get_mut(&id
.local_id
)
256 pub fn entry(&mut self, id
: hir
::HirId
) -> Entry
<'_
, hir
::ItemLocalId
, V
> {
257 validate_hir_id_for_typeck_results(self.hir_owner
, id
);
258 self.data
.entry(id
.local_id
)
261 pub fn insert(&mut self, id
: hir
::HirId
, val
: V
) -> Option
<V
> {
262 validate_hir_id_for_typeck_results(self.hir_owner
, id
);
263 self.data
.insert(id
.local_id
, val
)
266 pub fn remove(&mut self, id
: hir
::HirId
) -> Option
<V
> {
267 validate_hir_id_for_typeck_results(self.hir_owner
, id
);
268 self.data
.remove(&id
.local_id
)
272 /// All information necessary to validate and reveal an `impl Trait`.
273 #[derive(TyEncodable, TyDecodable, Debug, HashStable)]
274 pub struct ResolvedOpaqueTy
<'tcx
> {
275 /// The revealed type as seen by this function.
276 pub concrete_type
: Ty
<'tcx
>,
277 /// Generic parameters on the opaque type as passed by this function.
278 /// For `type Foo<A, B> = impl Bar<A, B>; fn foo<T, U>() -> Foo<T, U> { .. }`
279 /// this is `[T, U]`, not `[A, B]`.
280 pub substs
: SubstsRef
<'tcx
>,
283 /// Whenever a value may be live across a generator yield, the type of that value winds up in the
284 /// `GeneratorInteriorTypeCause` struct. This struct adds additional information about such
285 /// captured types that can be useful for diagnostics. In particular, it stores the span that
286 /// caused a given type to be recorded, along with the scope that enclosed the value (which can
287 /// be used to find the await that the value is live across).
291 /// ```ignore (pseudo-Rust)
299 /// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for
300 /// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`.
301 #[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
302 pub struct GeneratorInteriorTypeCause
<'tcx
> {
303 /// Type of the captured binding.
305 /// Span of the binding that was captured.
307 /// Span of the scope of the captured binding.
308 pub scope_span
: Option
<Span
>,
309 /// Span of `.await` or `yield` expression.
310 pub yield_span
: Span
,
311 /// Expr which the type evaluated from.
312 pub expr
: Option
<hir
::HirId
>,
315 #[derive(TyEncodable, TyDecodable, Debug)]
316 pub struct TypeckResults
<'tcx
> {
317 /// The `HirId::owner` all `ItemLocalId`s in this table are relative to.
318 pub hir_owner
: LocalDefId
,
320 /// Resolved definitions for `<T>::X` associated paths and
321 /// method calls, including those of overloaded operators.
322 type_dependent_defs
: ItemLocalMap
<Result
<(DefKind
, DefId
), ErrorReported
>>,
324 /// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
325 /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
326 /// about the field you also need definition of the variant to which the field
327 /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
328 field_indices
: ItemLocalMap
<usize>,
330 /// Stores the types for various nodes in the AST. Note that this table
331 /// is not guaranteed to be populated until after typeck. See
332 /// typeck::check::fn_ctxt for details.
333 node_types
: ItemLocalMap
<Ty
<'tcx
>>,
335 /// Stores the type parameters which were substituted to obtain the type
336 /// of this node. This only applies to nodes that refer to entities
337 /// parameterized by type parameters, such as generic fns, types, or
339 node_substs
: ItemLocalMap
<SubstsRef
<'tcx
>>,
341 /// This will either store the canonicalized types provided by the user
342 /// or the substitutions that the user explicitly gave (if any) attached
343 /// to `id`. These will not include any inferred values. The canonical form
344 /// is used to capture things like `_` or other unspecified values.
346 /// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
347 /// canonical substitutions would include only `for<X> { Vec<X> }`.
349 /// See also `AscribeUserType` statement in MIR.
350 user_provided_types
: ItemLocalMap
<CanonicalUserType
<'tcx
>>,
352 /// Stores the canonicalized types provided by the user. See also
353 /// `AscribeUserType` statement in MIR.
354 pub user_provided_sigs
: DefIdMap
<CanonicalPolyFnSig
<'tcx
>>,
356 adjustments
: ItemLocalMap
<Vec
<ty
::adjustment
::Adjustment
<'tcx
>>>,
358 /// Stores the actual binding mode for all instances of hir::BindingAnnotation.
359 pat_binding_modes
: ItemLocalMap
<BindingMode
>,
361 /// Stores the types which were implicitly dereferenced in pattern binding modes
362 /// for later usage in THIR lowering. For example,
365 /// match &&Some(5i32) {
370 /// leads to a `vec![&&Option<i32>, &Option<i32>]`. Empty vectors are not stored.
373 /// https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions
374 pat_adjustments
: ItemLocalMap
<Vec
<Ty
<'tcx
>>>,
377 pub upvar_capture_map
: ty
::UpvarCaptureMap
<'tcx
>,
379 /// Records the reasons that we picked the kind of each closure;
380 /// not all closures are present in the map.
381 closure_kind_origins
: ItemLocalMap
<(Span
, Symbol
)>,
383 /// For each fn, records the "liberated" types of its arguments
384 /// and return type. Liberated means that all bound regions
385 /// (including late-bound regions) are replaced with free
386 /// equivalents. This table is not used in codegen (since regions
387 /// are erased there) and hence is not serialized to metadata.
388 liberated_fn_sigs
: ItemLocalMap
<ty
::FnSig
<'tcx
>>,
390 /// For each FRU expression, record the normalized types of the fields
391 /// of the struct - this is needed because it is non-trivial to
392 /// normalize while preserving regions. This table is used only in
393 /// MIR construction and hence is not serialized to metadata.
394 fru_field_types
: ItemLocalMap
<Vec
<Ty
<'tcx
>>>,
396 /// For every coercion cast we add the HIR node ID of the cast
397 /// expression to this set.
398 coercion_casts
: ItemLocalSet
,
400 /// Set of trait imports actually used in the method resolution.
401 /// This is used for warning unused imports. During type
402 /// checking, this `Lrc` should not be cloned: it must have a ref-count
403 /// of 1 so that we can insert things into the set mutably.
404 pub used_trait_imports
: Lrc
<FxHashSet
<LocalDefId
>>,
406 /// If any errors occurred while type-checking this body,
407 /// this field will be set to `Some(ErrorReported)`.
408 pub tainted_by_errors
: Option
<ErrorReported
>,
410 /// All the opaque types that are restricted to concrete types
411 /// by this function.
412 pub concrete_opaque_types
: FxHashMap
<DefId
, ResolvedOpaqueTy
<'tcx
>>,
414 /// Given the closure ID this map provides the list of UpvarIDs used by it.
415 /// The upvarID contains the HIR node ID and it also contains the full path
416 /// leading to the member of the struct or tuple that is used instead of the
418 pub closure_captures
: ty
::UpvarListMap
,
420 /// Stores the type, expression, span and optional scope span of all types
421 /// that are live across the yield of this generator (if a generator).
422 pub generator_interior_types
: Vec
<GeneratorInteriorTypeCause
<'tcx
>>,
425 impl<'tcx
> TypeckResults
<'tcx
> {
426 pub fn new(hir_owner
: LocalDefId
) -> TypeckResults
<'tcx
> {
429 type_dependent_defs
: Default
::default(),
430 field_indices
: Default
::default(),
431 user_provided_types
: Default
::default(),
432 user_provided_sigs
: Default
::default(),
433 node_types
: Default
::default(),
434 node_substs
: Default
::default(),
435 adjustments
: Default
::default(),
436 pat_binding_modes
: Default
::default(),
437 pat_adjustments
: Default
::default(),
438 upvar_capture_map
: Default
::default(),
439 closure_kind_origins
: Default
::default(),
440 liberated_fn_sigs
: Default
::default(),
441 fru_field_types
: Default
::default(),
442 coercion_casts
: Default
::default(),
443 used_trait_imports
: Lrc
::new(Default
::default()),
444 tainted_by_errors
: None
,
445 concrete_opaque_types
: Default
::default(),
446 closure_captures
: Default
::default(),
447 generator_interior_types
: Default
::default(),
451 /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
452 pub fn qpath_res(&self, qpath
: &hir
::QPath
<'_
>, id
: hir
::HirId
) -> Res
{
454 hir
::QPath
::Resolved(_
, ref path
) => path
.res
,
455 hir
::QPath
::TypeRelative(..) | hir
::QPath
::LangItem(..) => self
456 .type_dependent_def(id
)
457 .map_or(Res
::Err
, |(kind
, def_id
)| Res
::Def(kind
, def_id
)),
461 pub fn type_dependent_defs(
463 ) -> LocalTableInContext
<'_
, Result
<(DefKind
, DefId
), ErrorReported
>> {
464 LocalTableInContext { hir_owner: self.hir_owner, data: &self.type_dependent_defs }
467 pub fn type_dependent_def(&self, id
: HirId
) -> Option
<(DefKind
, DefId
)> {
468 validate_hir_id_for_typeck_results(self.hir_owner
, id
);
469 self.type_dependent_defs
.get(&id
.local_id
).cloned().and_then(|r
| r
.ok())
472 pub fn type_dependent_def_id(&self, id
: HirId
) -> Option
<DefId
> {
473 self.type_dependent_def(id
).map(|(_
, def_id
)| def_id
)
476 pub fn type_dependent_defs_mut(
478 ) -> LocalTableInContextMut
<'_
, Result
<(DefKind
, DefId
), ErrorReported
>> {
479 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs }
482 pub fn field_indices(&self) -> LocalTableInContext
<'_
, usize> {
483 LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices }
486 pub fn field_indices_mut(&mut self) -> LocalTableInContextMut
<'_
, usize> {
487 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
490 pub fn user_provided_types(&self) -> LocalTableInContext
<'_
, CanonicalUserType
<'tcx
>> {
491 LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
494 pub fn user_provided_types_mut(
496 ) -> LocalTableInContextMut
<'_
, CanonicalUserType
<'tcx
>> {
497 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.user_provided_types }
500 pub fn node_types(&self) -> LocalTableInContext
<'_
, Ty
<'tcx
>> {
501 LocalTableInContext { hir_owner: self.hir_owner, data: &self.node_types }
504 pub fn node_types_mut(&mut self) -> LocalTableInContextMut
<'_
, Ty
<'tcx
>> {
505 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types }
508 pub fn node_type(&self, id
: hir
::HirId
) -> Ty
<'tcx
> {
509 self.node_type_opt(id
).unwrap_or_else(|| {
510 bug
!("node_type: no type for node `{}`", tls
::with(|tcx
| tcx
.hir().node_to_string(id
)))
514 pub fn node_type_opt(&self, id
: hir
::HirId
) -> Option
<Ty
<'tcx
>> {
515 validate_hir_id_for_typeck_results(self.hir_owner
, id
);
516 self.node_types
.get(&id
.local_id
).cloned()
519 pub fn node_substs_mut(&mut self) -> LocalTableInContextMut
<'_
, SubstsRef
<'tcx
>> {
520 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_substs }
523 pub fn node_substs(&self, id
: hir
::HirId
) -> SubstsRef
<'tcx
> {
524 validate_hir_id_for_typeck_results(self.hir_owner
, id
);
525 self.node_substs
.get(&id
.local_id
).cloned().unwrap_or_else(|| InternalSubsts
::empty())
528 pub fn node_substs_opt(&self, id
: hir
::HirId
) -> Option
<SubstsRef
<'tcx
>> {
529 validate_hir_id_for_typeck_results(self.hir_owner
, id
);
530 self.node_substs
.get(&id
.local_id
).cloned()
533 // Returns the type of a pattern as a monotype. Like @expr_ty, this function
534 // doesn't provide type parameter substitutions.
535 pub fn pat_ty(&self, pat
: &hir
::Pat
<'_
>) -> Ty
<'tcx
> {
536 self.node_type(pat
.hir_id
)
539 pub fn pat_ty_opt(&self, pat
: &hir
::Pat
<'_
>) -> Option
<Ty
<'tcx
>> {
540 self.node_type_opt(pat
.hir_id
)
543 // Returns the type of an expression as a monotype.
545 // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
546 // some cases, we insert `Adjustment` annotations such as auto-deref or
547 // auto-ref. The type returned by this function does not consider such
548 // adjustments. See `expr_ty_adjusted()` instead.
550 // NB (2): This type doesn't provide type parameter substitutions; e.g., if you
551 // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
552 // instead of "fn(ty) -> T with T = isize".
553 pub fn expr_ty(&self, expr
: &hir
::Expr
<'_
>) -> Ty
<'tcx
> {
554 self.node_type(expr
.hir_id
)
557 pub fn expr_ty_opt(&self, expr
: &hir
::Expr
<'_
>) -> Option
<Ty
<'tcx
>> {
558 self.node_type_opt(expr
.hir_id
)
561 pub fn adjustments(&self) -> LocalTableInContext
<'_
, Vec
<ty
::adjustment
::Adjustment
<'tcx
>>> {
562 LocalTableInContext { hir_owner: self.hir_owner, data: &self.adjustments }
565 pub fn adjustments_mut(
567 ) -> LocalTableInContextMut
<'_
, Vec
<ty
::adjustment
::Adjustment
<'tcx
>>> {
568 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.adjustments }
571 pub fn expr_adjustments(&self, expr
: &hir
::Expr
<'_
>) -> &[ty
::adjustment
::Adjustment
<'tcx
>] {
572 validate_hir_id_for_typeck_results(self.hir_owner
, expr
.hir_id
);
573 self.adjustments
.get(&expr
.hir_id
.local_id
).map_or(&[], |a
| &a
[..])
576 /// Returns the type of `expr`, considering any `Adjustment`
577 /// entry recorded for that expression.
578 pub fn expr_ty_adjusted(&self, expr
: &hir
::Expr
<'_
>) -> Ty
<'tcx
> {
579 self.expr_adjustments(expr
).last().map_or_else(|| self.expr_ty(expr
), |adj
| adj
.target
)
582 pub fn expr_ty_adjusted_opt(&self, expr
: &hir
::Expr
<'_
>) -> Option
<Ty
<'tcx
>> {
583 self.expr_adjustments(expr
).last().map(|adj
| adj
.target
).or_else(|| self.expr_ty_opt(expr
))
586 pub fn is_method_call(&self, expr
: &hir
::Expr
<'_
>) -> bool
{
587 // Only paths and method calls/overloaded operators have
588 // entries in type_dependent_defs, ignore the former here.
589 if let hir
::ExprKind
::Path(_
) = expr
.kind
{
593 match self.type_dependent_defs().get(expr
.hir_id
) {
594 Some(Ok((DefKind
::AssocFn
, _
))) => true,
599 pub fn extract_binding_mode(&self, s
: &Session
, id
: HirId
, sp
: Span
) -> Option
<BindingMode
> {
600 self.pat_binding_modes().get(id
).copied().or_else(|| {
601 s
.delay_span_bug(sp
, "missing binding mode");
606 pub fn pat_binding_modes(&self) -> LocalTableInContext
<'_
, BindingMode
> {
607 LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_binding_modes }
610 pub fn pat_binding_modes_mut(&mut self) -> LocalTableInContextMut
<'_
, BindingMode
> {
611 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_binding_modes }
614 pub fn pat_adjustments(&self) -> LocalTableInContext
<'_
, Vec
<Ty
<'tcx
>>> {
615 LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_adjustments }
618 pub fn pat_adjustments_mut(&mut self) -> LocalTableInContextMut
<'_
, Vec
<Ty
<'tcx
>>> {
619 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
622 pub fn upvar_capture(&self, upvar_id
: ty
::UpvarId
) -> ty
::UpvarCapture
<'tcx
> {
623 self.upvar_capture_map
[&upvar_id
]
626 pub fn closure_kind_origins(&self) -> LocalTableInContext
<'_
, (Span
, Symbol
)> {
627 LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
630 pub fn closure_kind_origins_mut(&mut self) -> LocalTableInContextMut
<'_
, (Span
, Symbol
)> {
631 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.closure_kind_origins }
634 pub fn liberated_fn_sigs(&self) -> LocalTableInContext
<'_
, ty
::FnSig
<'tcx
>> {
635 LocalTableInContext { hir_owner: self.hir_owner, data: &self.liberated_fn_sigs }
638 pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut
<'_
, ty
::FnSig
<'tcx
>> {
639 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.liberated_fn_sigs }
642 pub fn fru_field_types(&self) -> LocalTableInContext
<'_
, Vec
<Ty
<'tcx
>>> {
643 LocalTableInContext { hir_owner: self.hir_owner, data: &self.fru_field_types }
646 pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut
<'_
, Vec
<Ty
<'tcx
>>> {
647 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.fru_field_types }
650 pub fn is_coercion_cast(&self, hir_id
: hir
::HirId
) -> bool
{
651 validate_hir_id_for_typeck_results(self.hir_owner
, hir_id
);
652 self.coercion_casts
.contains(&hir_id
.local_id
)
655 pub fn set_coercion_cast(&mut self, id
: ItemLocalId
) {
656 self.coercion_casts
.insert(id
);
659 pub fn coercion_casts(&self) -> &ItemLocalSet
{
664 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for TypeckResults
<'tcx
> {
665 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
666 let ty
::TypeckResults
{
668 ref type_dependent_defs
,
670 ref user_provided_types
,
671 ref user_provided_sigs
,
675 ref pat_binding_modes
,
677 ref upvar_capture_map
,
678 ref closure_kind_origins
,
679 ref liberated_fn_sigs
,
684 ref used_trait_imports
,
686 ref concrete_opaque_types
,
687 ref closure_captures
,
688 ref generator_interior_types
,
691 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
692 type_dependent_defs
.hash_stable(hcx
, hasher
);
693 field_indices
.hash_stable(hcx
, hasher
);
694 user_provided_types
.hash_stable(hcx
, hasher
);
695 user_provided_sigs
.hash_stable(hcx
, hasher
);
696 node_types
.hash_stable(hcx
, hasher
);
697 node_substs
.hash_stable(hcx
, hasher
);
698 adjustments
.hash_stable(hcx
, hasher
);
699 pat_binding_modes
.hash_stable(hcx
, hasher
);
700 pat_adjustments
.hash_stable(hcx
, hasher
);
701 hash_stable_hashmap(hcx
, hasher
, upvar_capture_map
, |up_var_id
, hcx
| {
702 let ty
::UpvarId { var_path, closure_expr_id }
= *up_var_id
;
704 assert_eq
!(var_path
.hir_id
.owner
, hir_owner
);
707 hcx
.local_def_path_hash(var_path
.hir_id
.owner
),
708 var_path
.hir_id
.local_id
,
709 hcx
.local_def_path_hash(closure_expr_id
),
713 closure_kind_origins
.hash_stable(hcx
, hasher
);
714 liberated_fn_sigs
.hash_stable(hcx
, hasher
);
715 fru_field_types
.hash_stable(hcx
, hasher
);
716 coercion_casts
.hash_stable(hcx
, hasher
);
717 used_trait_imports
.hash_stable(hcx
, hasher
);
718 tainted_by_errors
.hash_stable(hcx
, hasher
);
719 concrete_opaque_types
.hash_stable(hcx
, hasher
);
720 closure_captures
.hash_stable(hcx
, hasher
);
721 generator_interior_types
.hash_stable(hcx
, hasher
);
726 rustc_index
::newtype_index
! {
727 pub struct UserTypeAnnotationIndex
{
729 DEBUG_FORMAT
= "UserType({})",
730 const START_INDEX
= 0,
734 /// Mapping of type annotation indices to canonical user type annotations.
735 pub type CanonicalUserTypeAnnotations
<'tcx
> =
736 IndexVec
<UserTypeAnnotationIndex
, CanonicalUserTypeAnnotation
<'tcx
>>;
738 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
739 pub struct CanonicalUserTypeAnnotation
<'tcx
> {
740 pub user_ty
: CanonicalUserType
<'tcx
>,
742 pub inferred_ty
: Ty
<'tcx
>,
745 /// Canonicalized user type annotation.
746 pub type CanonicalUserType
<'tcx
> = Canonical
<'tcx
, UserType
<'tcx
>>;
748 impl CanonicalUserType
<'tcx
> {
749 /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`,
750 /// i.e., each thing is mapped to a canonical variable with the same index.
751 pub fn is_identity(&self) -> bool
{
753 UserType
::Ty(_
) => false,
754 UserType
::TypeOf(_
, user_substs
) => {
755 if user_substs
.user_self_ty
.is_some() {
759 user_substs
.substs
.iter().zip(BoundVar
::new(0)..).all(|(kind
, cvar
)| {
760 match kind
.unpack() {
761 GenericArgKind
::Type(ty
) => match ty
.kind
{
762 ty
::Bound(debruijn
, b
) => {
763 // We only allow a `ty::INNERMOST` index in substitutions.
764 assert_eq
!(debruijn
, ty
::INNERMOST
);
770 GenericArgKind
::Lifetime(r
) => match r
{
771 ty
::ReLateBound(debruijn
, br
) => {
772 // We only allow a `ty::INNERMOST` index in substitutions.
773 assert_eq
!(*debruijn
, ty
::INNERMOST
);
774 cvar
== br
.assert_bound_var()
779 GenericArgKind
::Const(ct
) => match ct
.val
{
780 ty
::ConstKind
::Bound(debruijn
, b
) => {
781 // We only allow a `ty::INNERMOST` index in substitutions.
782 assert_eq
!(debruijn
, ty
::INNERMOST
);
794 /// A user-given type annotation attached to a constant. These arise
795 /// from constants that are named via paths, like `Foo::<A>::new` and
797 #[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
798 #[derive(HashStable, TypeFoldable, Lift)]
799 pub enum UserType
<'tcx
> {
802 /// The canonical type is the result of `type_of(def_id)` with the
803 /// given substitutions applied.
804 TypeOf(DefId
, UserSubsts
<'tcx
>),
807 impl<'tcx
> CommonTypes
<'tcx
> {
808 fn new(interners
: &CtxtInterners
<'tcx
>) -> CommonTypes
<'tcx
> {
809 let mk
= |ty
| interners
.intern_ty(ty
);
812 unit
: mk(Tuple(List
::empty())),
816 isize: mk(Int(ast
::IntTy
::Isize
)),
817 i8: mk(Int(ast
::IntTy
::I8
)),
818 i16: mk(Int(ast
::IntTy
::I16
)),
819 i32: mk(Int(ast
::IntTy
::I32
)),
820 i64: mk(Int(ast
::IntTy
::I64
)),
821 i128
: mk(Int(ast
::IntTy
::I128
)),
822 usize: mk(Uint(ast
::UintTy
::Usize
)),
823 u8: mk(Uint(ast
::UintTy
::U8
)),
824 u16: mk(Uint(ast
::UintTy
::U16
)),
825 u32: mk(Uint(ast
::UintTy
::U32
)),
826 u64: mk(Uint(ast
::UintTy
::U64
)),
827 u128
: mk(Uint(ast
::UintTy
::U128
)),
828 f32: mk(Float(ast
::FloatTy
::F32
)),
829 f64: mk(Float(ast
::FloatTy
::F64
)),
831 self_param
: mk(ty
::Param(ty
::ParamTy { index: 0, name: kw::SelfUpper }
)),
833 trait_object_dummy_self
: mk(Infer(ty
::FreshTy(0))),
838 impl<'tcx
> CommonLifetimes
<'tcx
> {
839 fn new(interners
: &CtxtInterners
<'tcx
>) -> CommonLifetimes
<'tcx
> {
840 let mk
= |r
| interners
.region
.intern(r
, |r
| Interned(interners
.arena
.alloc(r
))).0;
843 re_root_empty
: mk(RegionKind
::ReEmpty(ty
::UniverseIndex
::ROOT
)),
844 re_static
: mk(RegionKind
::ReStatic
),
845 re_erased
: mk(RegionKind
::ReErased
),
850 impl<'tcx
> CommonConsts
<'tcx
> {
851 fn new(interners
: &CtxtInterners
<'tcx
>, types
: &CommonTypes
<'tcx
>) -> CommonConsts
<'tcx
> {
852 let mk_const
= |c
| interners
.const_
.intern(c
, |c
| Interned(interners
.arena
.alloc(c
))).0;
855 unit
: mk_const(ty
::Const
{
856 val
: ty
::ConstKind
::Value(ConstValue
::Scalar(Scalar
::zst())),
863 // This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime
866 pub struct FreeRegionInfo
{
867 // `LocalDefId` corresponding to FreeRegion
868 pub def_id
: LocalDefId
,
869 // the bound region corresponding to FreeRegion
870 pub boundregion
: ty
::BoundRegion
,
871 // checks if bound region is in Impl Item
872 pub is_impl_item
: bool
,
875 /// The central data structure of the compiler. It stores references
876 /// to the various **arenas** and also houses the results of the
877 /// various **compiler queries** that have been performed. See the
878 /// [rustc dev guide] for more details.
880 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html
881 #[derive(Copy, Clone)]
882 #[rustc_diagnostic_item = "TyCtxt"]
883 pub struct TyCtxt
<'tcx
> {
884 gcx
: &'tcx GlobalCtxt
<'tcx
>,
887 impl<'tcx
> Deref
for TyCtxt
<'tcx
> {
888 type Target
= &'tcx GlobalCtxt
<'tcx
>;
890 fn deref(&self) -> &Self::Target
{
895 pub struct GlobalCtxt
<'tcx
> {
896 pub arena
: &'tcx WorkerLocal
<Arena
<'tcx
>>,
898 interners
: CtxtInterners
<'tcx
>,
900 pub(crate) cstore
: Box
<CrateStoreDyn
>,
902 pub sess
: &'tcx Session
,
904 /// This only ever stores a `LintStore` but we don't want a dependency on that type here.
906 /// FIXME(Centril): consider `dyn LintStoreMarker` once
907 /// we can upcast to `Any` for some additional type safety.
908 pub lint_store
: Lrc
<dyn Any
+ sync
::Sync
+ sync
::Send
>,
910 pub dep_graph
: DepGraph
,
912 pub prof
: SelfProfilerRef
,
914 /// Common types, pre-interned for your convenience.
915 pub types
: CommonTypes
<'tcx
>,
917 /// Common lifetimes, pre-interned for your convenience.
918 pub lifetimes
: CommonLifetimes
<'tcx
>,
920 /// Common consts, pre-interned for your convenience.
921 pub consts
: CommonConsts
<'tcx
>,
923 /// Resolutions of `extern crate` items produced by resolver.
924 extern_crate_map
: FxHashMap
<LocalDefId
, CrateNum
>,
926 /// Map indicating what traits are in scope for places where this
927 /// is relevant; generated by resolve.
928 trait_map
: FxHashMap
<LocalDefId
, FxHashMap
<ItemLocalId
, StableVec
<TraitCandidate
>>>,
930 /// Export map produced by name resolution.
931 export_map
: ExportMap
<LocalDefId
>,
933 pub(crate) untracked_crate
: &'tcx hir
::Crate
<'tcx
>,
934 pub(crate) definitions
: &'tcx Definitions
,
936 /// A map from `DefPathHash` -> `DefId`. Includes `DefId`s from the local crate
937 /// as well as all upstream crates. Only populated in incremental mode.
938 pub def_path_hash_to_def_id
: Option
<FxHashMap
<DefPathHash
, DefId
>>,
940 pub queries
: query
::Queries
<'tcx
>,
942 maybe_unused_trait_imports
: FxHashSet
<LocalDefId
>,
943 maybe_unused_extern_crates
: Vec
<(LocalDefId
, Span
)>,
944 /// A map of glob use to a set of names it actually imports. Currently only
945 /// used in save-analysis.
946 glob_map
: FxHashMap
<LocalDefId
, FxHashSet
<Symbol
>>,
947 /// Extern prelude entries. The value is `true` if the entry was introduced
948 /// via `extern crate` item and not `--extern` option or compiler built-in.
949 pub extern_prelude
: FxHashMap
<Symbol
, bool
>,
951 // Internal caches for metadata decoding. No need to track deps on this.
952 pub ty_rcache
: Lock
<FxHashMap
<ty
::CReaderCacheKey
, Ty
<'tcx
>>>,
953 pub pred_rcache
: Lock
<FxHashMap
<ty
::CReaderCacheKey
, Predicate
<'tcx
>>>,
955 /// Caches the results of trait selection. This cache is used
956 /// for things that do not have to do with the parameters in scope.
957 pub selection_cache
: traits
::SelectionCache
<'tcx
>,
959 /// Caches the results of trait evaluation. This cache is used
960 /// for things that do not have to do with the parameters in scope.
961 /// Merge this with `selection_cache`?
962 pub evaluation_cache
: traits
::EvaluationCache
<'tcx
>,
964 /// The definite name of the current crate after taking into account
965 /// attributes, commandline parameters, etc.
966 pub crate_name
: Symbol
,
968 /// Data layout specification for the current target.
969 pub data_layout
: TargetDataLayout
,
971 /// `#[stable]` and `#[unstable]` attributes
972 stability_interner
: ShardedHashMap
<&'tcx attr
::Stability
, ()>,
974 /// `#[rustc_const_stable]` and `#[rustc_const_unstable]` attributes
975 const_stability_interner
: ShardedHashMap
<&'tcx attr
::ConstStability
, ()>,
977 /// Stores the value of constants (and deduplicates the actual memory)
978 allocation_interner
: ShardedHashMap
<&'tcx Allocation
, ()>,
980 /// Stores memory for globals (statics/consts).
981 pub(crate) alloc_map
: Lock
<interpret
::AllocMap
<'tcx
>>,
983 layout_interner
: ShardedHashMap
<&'tcx Layout
, ()>,
985 output_filenames
: Arc
<OutputFilenames
>,
988 impl<'tcx
> TyCtxt
<'tcx
> {
989 pub fn typeck_opt_const_arg(
991 def
: ty
::WithOptConstParam
<LocalDefId
>,
992 ) -> &'tcx TypeckResults
<'tcx
> {
993 if let Some(param_did
) = def
.const_param_did
{
994 self.typeck_const_arg((def
.did
, param_did
))
1000 pub fn alloc_steal_mir(self, mir
: Body
<'tcx
>) -> &'tcx Steal
<Body
<'tcx
>> {
1001 self.arena
.alloc(Steal
::new(mir
))
1004 pub fn alloc_steal_promoted(
1006 promoted
: IndexVec
<Promoted
, Body
<'tcx
>>,
1007 ) -> &'tcx Steal
<IndexVec
<Promoted
, Body
<'tcx
>>> {
1008 self.arena
.alloc(Steal
::new(promoted
))
1011 pub fn alloc_adt_def(
1015 variants
: IndexVec
<VariantIdx
, ty
::VariantDef
>,
1017 ) -> &'tcx ty
::AdtDef
{
1018 self.arena
.alloc(ty
::AdtDef
::new(self, did
, kind
, variants
, repr
))
1021 pub fn intern_const_alloc(self, alloc
: Allocation
) -> &'tcx Allocation
{
1022 self.allocation_interner
.intern(alloc
, |alloc
| self.arena
.alloc(alloc
))
1025 /// Allocates a read-only byte or string literal for `mir::interpret`.
1026 pub fn allocate_bytes(self, bytes
: &[u8]) -> interpret
::AllocId
{
1027 // Create an allocation that just contains these bytes.
1028 let alloc
= interpret
::Allocation
::from_byte_aligned_bytes(bytes
);
1029 let alloc
= self.intern_const_alloc(alloc
);
1030 self.create_memory_alloc(alloc
)
1033 pub fn intern_stability(self, stab
: attr
::Stability
) -> &'tcx attr
::Stability
{
1034 self.stability_interner
.intern(stab
, |stab
| self.arena
.alloc(stab
))
1037 pub fn intern_const_stability(self, stab
: attr
::ConstStability
) -> &'tcx attr
::ConstStability
{
1038 self.const_stability_interner
.intern(stab
, |stab
| self.arena
.alloc(stab
))
1041 pub fn intern_layout(self, layout
: Layout
) -> &'tcx Layout
{
1042 self.layout_interner
.intern(layout
, |layout
| self.arena
.alloc(layout
))
1045 /// Returns a range of the start/end indices specified with the
1046 /// `rustc_layout_scalar_valid_range` attribute.
1047 pub fn layout_scalar_valid_range(self, def_id
: DefId
) -> (Bound
<u128
>, Bound
<u128
>) {
1048 let attrs
= self.get_attrs(def_id
);
1050 let attr
= match attrs
.iter().find(|a
| self.sess
.check_name(a
, name
)) {
1052 None
=> return Bound
::Unbounded
,
1054 debug
!("layout_scalar_valid_range: attr={:?}", attr
);
1055 for meta
in attr
.meta_item_list().expect("rustc_layout_scalar_valid_range takes args") {
1056 match meta
.literal().expect("attribute takes lit").kind
{
1057 ast
::LitKind
::Int(a
, _
) => return Bound
::Included(a
),
1058 _
=> span_bug
!(attr
.span
, "rustc_layout_scalar_valid_range expects int arg"),
1061 span_bug
!(attr
.span
, "no arguments to `rustc_layout_scalar_valid_range` attribute");
1064 get(sym
::rustc_layout_scalar_valid_range_start
),
1065 get(sym
::rustc_layout_scalar_valid_range_end
),
1069 pub fn lift
<T
: ?Sized
+ Lift
<'tcx
>>(self, value
: &T
) -> Option
<T
::Lifted
> {
1070 value
.lift_to_tcx(self)
1073 /// Creates a type context and call the closure with a `TyCtxt` reference
1074 /// to the context. The closure enforces that the type context and any interned
1075 /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
1076 /// reference to the context, to allow formatting values that need it.
1077 pub fn create_global_ctxt(
1079 lint_store
: Lrc
<dyn Any
+ sync
::Send
+ sync
::Sync
>,
1080 local_providers
: ty
::query
::Providers
,
1081 extern_providers
: ty
::query
::Providers
,
1082 arena
: &'tcx WorkerLocal
<Arena
<'tcx
>>,
1083 resolutions
: ty
::ResolverOutputs
,
1084 krate
: &'tcx hir
::Crate
<'tcx
>,
1085 definitions
: &'tcx Definitions
,
1086 dep_graph
: DepGraph
,
1087 on_disk_query_result_cache
: query
::OnDiskCache
<'tcx
>,
1089 output_filenames
: &OutputFilenames
,
1090 ) -> GlobalCtxt
<'tcx
> {
1091 let data_layout
= TargetDataLayout
::parse(&s
.target
.target
).unwrap_or_else(|err
| {
1094 let interners
= CtxtInterners
::new(arena
);
1095 let common_types
= CommonTypes
::new(&interners
);
1096 let common_lifetimes
= CommonLifetimes
::new(&interners
);
1097 let common_consts
= CommonConsts
::new(&interners
, &common_types
);
1098 let cstore
= resolutions
.cstore
;
1099 let crates
= cstore
.crates_untracked();
1100 let max_cnum
= crates
.iter().map(|c
| c
.as_usize()).max().unwrap_or(0);
1101 let mut providers
= IndexVec
::from_elem_n(extern_providers
, max_cnum
+ 1);
1102 providers
[LOCAL_CRATE
] = local_providers
;
1104 let def_path_hash_to_def_id
= if s
.opts
.build_dep_graph() {
1105 let capacity
= definitions
.def_path_table().num_def_ids()
1106 + crates
.iter().map(|cnum
| cstore
.num_def_ids(*cnum
)).sum
::<usize>();
1107 let mut map
= FxHashMap
::with_capacity_and_hasher(capacity
, Default
::default());
1109 map
.extend(definitions
.def_path_table().all_def_path_hashes_and_def_ids(LOCAL_CRATE
));
1110 for cnum
in &crates
{
1111 map
.extend(cstore
.all_def_path_hashes_and_def_ids(*cnum
).into_iter());
1119 let mut trait_map
: FxHashMap
<_
, FxHashMap
<_
, _
>> = FxHashMap
::default();
1120 for (hir_id
, v
) in krate
.trait_map
.iter() {
1121 let map
= trait_map
.entry(hir_id
.owner
).or_default();
1122 map
.insert(hir_id
.local_id
, StableVec
::new(v
.to_vec()));
1132 prof
: s
.prof
.clone(),
1133 types
: common_types
,
1134 lifetimes
: common_lifetimes
,
1135 consts
: common_consts
,
1136 extern_crate_map
: resolutions
.extern_crate_map
,
1138 export_map
: resolutions
.export_map
,
1139 maybe_unused_trait_imports
: resolutions
.maybe_unused_trait_imports
,
1140 maybe_unused_extern_crates
: resolutions
.maybe_unused_extern_crates
,
1141 glob_map
: resolutions
.glob_map
,
1142 extern_prelude
: resolutions
.extern_prelude
,
1143 untracked_crate
: krate
,
1145 def_path_hash_to_def_id
,
1146 queries
: query
::Queries
::new(providers
, extern_providers
, on_disk_query_result_cache
),
1147 ty_rcache
: Default
::default(),
1148 pred_rcache
: Default
::default(),
1149 selection_cache
: Default
::default(),
1150 evaluation_cache
: Default
::default(),
1151 crate_name
: Symbol
::intern(crate_name
),
1153 layout_interner
: Default
::default(),
1154 stability_interner
: Default
::default(),
1155 const_stability_interner
: Default
::default(),
1156 allocation_interner
: Default
::default(),
1157 alloc_map
: Lock
::new(interpret
::AllocMap
::new()),
1158 output_filenames
: Arc
::new(output_filenames
.clone()),
1162 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
1164 pub fn ty_error(self) -> Ty
<'tcx
> {
1165 self.ty_error_with_message(DUMMY_SP
, "TyKind::Error constructed but no error reported")
1168 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
1169 /// ensure it gets used.
1171 pub fn ty_error_with_message
<S
: Into
<MultiSpan
>>(self, span
: S
, msg
: &str) -> Ty
<'tcx
> {
1172 self.sess
.delay_span_bug(span
, msg
);
1173 self.mk_ty(Error(DelaySpanBugEmitted(())))
1176 /// Like `err` but for constants.
1178 pub fn const_error(self, ty
: Ty
<'tcx
>) -> &'tcx Const
<'tcx
> {
1180 .delay_span_bug(DUMMY_SP
, "ty::ConstKind::Error constructed but no error reported.");
1181 self.mk_const(ty
::Const { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty }
)
1184 pub fn consider_optimizing
<T
: Fn() -> String
>(&self, msg
: T
) -> bool
{
1185 let cname
= self.crate_name(LOCAL_CRATE
).as_str();
1186 self.sess
.consider_optimizing(&cname
, msg
)
1189 pub fn lib_features(self) -> &'tcx middle
::lib_features
::LibFeatures
{
1190 self.get_lib_features(LOCAL_CRATE
)
1193 /// Obtain all lang items of this crate and all dependencies (recursively)
1194 pub fn lang_items(self) -> &'tcx rustc_hir
::lang_items
::LanguageItems
{
1195 self.get_lang_items(LOCAL_CRATE
)
1198 /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
1199 /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
1200 pub fn get_diagnostic_item(self, name
: Symbol
) -> Option
<DefId
> {
1201 self.all_diagnostic_items(LOCAL_CRATE
).get(&name
).copied()
1204 /// Check whether the diagnostic item with the given `name` has the given `DefId`.
1205 pub fn is_diagnostic_item(self, name
: Symbol
, did
: DefId
) -> bool
{
1206 self.diagnostic_items(did
.krate
).get(&name
) == Some(&did
)
1209 pub fn stability(self) -> &'tcx stability
::Index
<'tcx
> {
1210 self.stability_index(LOCAL_CRATE
)
1213 pub fn crates(self) -> &'tcx
[CrateNum
] {
1214 self.all_crate_nums(LOCAL_CRATE
)
1217 pub fn allocator_kind(self) -> Option
<AllocatorKind
> {
1218 self.cstore
.allocator_kind()
1221 pub fn features(self) -> &'tcx rustc_feature
::Features
{
1222 self.features_query(LOCAL_CRATE
)
1225 pub fn def_key(self, id
: DefId
) -> rustc_hir
::definitions
::DefKey
{
1226 if let Some(id
) = id
.as_local() { self.hir().def_key(id) }
else { self.cstore.def_key(id) }
1229 /// Converts a `DefId` into its fully expanded `DefPath` (every
1230 /// `DefId` is really just an interned `DefPath`).
1232 /// Note that if `id` is not local to this crate, the result will
1233 /// be a non-local `DefPath`.
1234 pub fn def_path(self, id
: DefId
) -> rustc_hir
::definitions
::DefPath
{
1235 if let Some(id
) = id
.as_local() {
1236 self.hir().def_path(id
)
1238 self.cstore
.def_path(id
)
1242 /// Returns whether or not the crate with CrateNum 'cnum'
1243 /// is marked as a private dependency
1244 pub fn is_private_dep(self, cnum
: CrateNum
) -> bool
{
1245 if cnum
== LOCAL_CRATE { false }
else { self.cstore.crate_is_private_dep_untracked(cnum) }
1249 pub fn def_path_hash(self, def_id
: DefId
) -> rustc_hir
::definitions
::DefPathHash
{
1250 if let Some(def_id
) = def_id
.as_local() {
1251 self.definitions
.def_path_hash(def_id
)
1253 self.cstore
.def_path_hash(def_id
)
1257 pub fn def_path_debug_str(self, def_id
: DefId
) -> String
{
1258 // We are explicitly not going through queries here in order to get
1259 // crate name and disambiguator since this code is called from debug!()
1260 // statements within the query system and we'd run into endless
1261 // recursion otherwise.
1262 let (crate_name
, crate_disambiguator
) = if def_id
.is_local() {
1263 (self.crate_name
, self.sess
.local_crate_disambiguator())
1266 self.cstore
.crate_name_untracked(def_id
.krate
),
1267 self.cstore
.crate_disambiguator_untracked(def_id
.krate
),
1274 // Don't print the whole crate disambiguator. That's just
1275 // annoying in debug output.
1276 &(crate_disambiguator
.to_fingerprint().to_hex())[..4],
1277 self.def_path(def_id
).to_string_no_crate()
1281 pub fn metadata_encoding_version(self) -> Vec
<u8> {
1282 self.cstore
.metadata_encoding_version().to_vec()
1285 pub fn encode_metadata(self) -> EncodedMetadata
{
1286 let _prof_timer
= self.prof
.verbose_generic_activity("generate_crate_metadata");
1287 self.cstore
.encode_metadata(self)
1290 // Note that this is *untracked* and should only be used within the query
1291 // system if the result is otherwise tracked through queries
1292 pub fn cstore_as_any(self) -> &'tcx
dyn Any
{
1293 self.cstore
.as_any()
1297 pub fn create_stable_hashing_context(self) -> StableHashingContext
<'tcx
> {
1298 let krate
= self.gcx
.untracked_crate
;
1300 StableHashingContext
::new(self.sess
, krate
, self.definitions
, &*self.cstore
)
1304 pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext
<'tcx
> {
1305 let krate
= self.gcx
.untracked_crate
;
1307 StableHashingContext
::ignore_spans(self.sess
, krate
, self.definitions
, &*self.cstore
)
1310 // This method makes sure that we have a DepNode and a Fingerprint for
1311 // every upstream crate. It needs to be called once right after the tcx is
1313 // With full-fledged red/green, the method will probably become unnecessary
1314 // as this will be done on-demand.
1315 pub fn allocate_metadata_dep_nodes(self) {
1316 // We cannot use the query versions of crates() and crate_hash(), since
1317 // those would need the DepNodes that we are allocating here.
1318 for cnum
in self.cstore
.crates_untracked() {
1319 let dep_node
= DepConstructor
::CrateMetadata(self, cnum
);
1320 let crate_hash
= self.cstore
.crate_hash_untracked(cnum
);
1321 self.dep_graph
.with_task(
1325 |_
, x
| x
, // No transformation needed
1326 dep_graph
::hash_result
,
1331 pub fn serialize_query_result_cache
<E
>(self, encoder
: &mut E
) -> Result
<(), E
::Error
>
1333 E
: ty
::codec
::OpaqueEncoder
,
1335 self.queries
.on_disk_cache
.serialize(self, encoder
)
1338 /// If `true`, we should use the MIR-based borrowck, but also
1339 /// fall back on the AST borrowck if the MIR-based one errors.
1340 pub fn migrate_borrowck(self) -> bool
{
1341 self.borrowck_mode().migrate()
1344 /// What mode(s) of borrowck should we run? AST? MIR? both?
1345 /// (Also considers the `#![feature(nll)]` setting.)
1346 pub fn borrowck_mode(self) -> BorrowckMode
{
1347 // Here are the main constraints we need to deal with:
1349 // 1. An opts.borrowck_mode of `BorrowckMode::Migrate` is
1350 // synonymous with no `-Z borrowck=...` flag at all.
1352 // 2. We want to allow developers on the Nightly channel
1353 // to opt back into the "hard error" mode for NLL,
1354 // (which they can do via specifying `#![feature(nll)]`
1355 // explicitly in their crate).
1357 // So, this precedence list is how pnkfelix chose to work with
1358 // the above constraints:
1360 // * `#![feature(nll)]` *always* means use NLL with hard
1361 // errors. (To simplify the code here, it now even overrides
1362 // a user's attempt to specify `-Z borrowck=compare`, which
1363 // we arguably do not need anymore and should remove.)
1365 // * Otherwise, if no `-Z borrowck=...` then use migrate mode
1367 // * Otherwise, use the behavior requested via `-Z borrowck=...`
1369 if self.features().nll
{
1370 return BorrowckMode
::Mir
;
1373 self.sess
.opts
.borrowck_mode
1376 /// If `true`, we should use lazy normalization for constants, otherwise
1377 /// we still evaluate them eagerly.
1379 pub fn lazy_normalization(self) -> bool
{
1380 let features
= self.features();
1381 // Note: We do not enable lazy normalization for `features.min_const_generics`.
1382 features
.const_generics
|| features
.lazy_normalization_consts
1386 pub fn local_crate_exports_generics(self) -> bool
{
1387 debug_assert
!(self.sess
.opts
.share_generics());
1389 self.sess
.crate_types().iter().any(|crate_type
| {
1391 CrateType
::Executable
1392 | CrateType
::Staticlib
1393 | CrateType
::ProcMacro
1394 | CrateType
::Cdylib
=> false,
1396 // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
1397 // We want to block export of generics from dylibs,
1398 // but we must fix rust-lang/rust#65890 before we can
1399 // do that robustly.
1400 CrateType
::Dylib
=> true,
1402 CrateType
::Rlib
=> true,
1407 // Returns the `DefId` and the `BoundRegion` corresponding to the given region.
1408 pub fn is_suitable_region(&self, region
: Region
<'tcx
>) -> Option
<FreeRegionInfo
> {
1409 let (suitable_region_binding_scope
, bound_region
) = match *region
{
1410 ty
::ReFree(ref free_region
) => {
1411 (free_region
.scope
.expect_local(), free_region
.bound_region
)
1413 ty
::ReEarlyBound(ref ebr
) => (
1414 self.parent(ebr
.def_id
).unwrap().expect_local(),
1415 ty
::BoundRegion
::BrNamed(ebr
.def_id
, ebr
.name
),
1417 _
=> return None
, // not a free region
1420 let hir_id
= self.hir().local_def_id_to_hir_id(suitable_region_binding_scope
);
1421 let is_impl_item
= match self.hir().find(hir_id
) {
1422 Some(Node
::Item(..) | Node
::TraitItem(..)) => false,
1423 Some(Node
::ImplItem(..)) => {
1424 self.is_bound_region_in_impl_item(suitable_region_binding_scope
)
1429 Some(FreeRegionInfo
{
1430 def_id
: suitable_region_binding_scope
,
1431 boundregion
: bound_region
,
1436 /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
1437 pub fn return_type_impl_or_dyn_traits(
1439 scope_def_id
: LocalDefId
,
1440 ) -> Vec
<&'tcx hir
::Ty
<'tcx
>> {
1441 let hir_id
= self.hir().local_def_id_to_hir_id(scope_def_id
);
1442 let hir_output
= match self.hir().get(hir_id
) {
1443 Node
::Item(hir
::Item
{
1447 decl
: hir
::FnDecl { output: hir::FnRetTy::Return(ty), .. }
,
1454 | Node
::ImplItem(hir
::ImplItem
{
1456 hir
::ImplItemKind
::Fn(
1458 decl
: hir
::FnDecl { output: hir::FnRetTy::Return(ty), .. }
,
1465 | Node
::TraitItem(hir
::TraitItem
{
1467 hir
::TraitItemKind
::Fn(
1469 decl
: hir
::FnDecl { output: hir::FnRetTy::Return(ty), .. }
,
1479 let mut v
= TraitObjectVisitor(vec
![], self.hir());
1480 v
.visit_ty(hir_output
);
1484 pub fn return_type_impl_trait(&self, scope_def_id
: LocalDefId
) -> Option
<(Ty
<'tcx
>, Span
)> {
1485 // HACK: `type_of_def_id()` will fail on these (#55796), so return `None`.
1486 let hir_id
= self.hir().local_def_id_to_hir_id(scope_def_id
);
1487 match self.hir().get(hir_id
) {
1488 Node
::Item(item
) => {
1490 ItemKind
::Fn(..) => { /* `type_of_def_id()` will work */ }
1496 _
=> { /* `type_of_def_id()` will work or panic */ }
1499 let ret_ty
= self.type_of(scope_def_id
);
1501 ty
::FnDef(_
, _
) => {
1502 let sig
= ret_ty
.fn_sig(*self);
1503 let output
= self.erase_late_bound_regions(&sig
.output());
1504 if output
.is_impl_trait() {
1505 let fn_decl
= self.hir().fn_decl_by_hir_id(hir_id
).unwrap();
1506 Some((output
, fn_decl
.output
.span()))
1515 // Checks if the bound region is in Impl Item.
1516 pub fn is_bound_region_in_impl_item(&self, suitable_region_binding_scope
: LocalDefId
) -> bool
{
1518 self.associated_item(suitable_region_binding_scope
.to_def_id()).container
.id();
1519 if self.impl_trait_ref(container_id
).is_some() {
1520 // For now, we do not try to target impls of traits. This is
1521 // because this message is going to suggest that the user
1522 // change the fn signature, but they may not be free to do so,
1523 // since the signature must match the trait.
1525 // FIXME(#42706) -- in some cases, we could do better here.
1531 /// Determines whether identifiers in the assembly have strict naming rules.
1532 /// Currently, only NVPTX* targets need it.
1533 pub fn has_strict_asm_symbol_naming(&self) -> bool
{
1534 self.sess
.target
.target
.arch
.contains("nvptx")
1537 /// Returns `&'static core::panic::Location<'static>`.
1538 pub fn caller_location_ty(&self) -> Ty
<'tcx
> {
1540 self.lifetimes
.re_static
,
1541 self.type_of(self.require_lang_item(LangItem
::PanicLocation
, None
))
1542 .subst(*self, self.mk_substs([self.lifetimes
.re_static
.into()].iter())),
1546 /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
1547 pub fn article_and_description(&self, def_id
: DefId
) -> (&'
static str, &'
static str) {
1548 match self.def_kind(def_id
) {
1549 DefKind
::Generator
=> match self.generator_kind(def_id
).unwrap() {
1550 rustc_hir
::GeneratorKind
::Async(..) => ("an", "async closure"),
1551 rustc_hir
::GeneratorKind
::Gen
=> ("a", "generator"),
1553 def_kind
=> (def_kind
.article(), def_kind
.descr(def_id
)),
1558 /// A trait implemented for all `X<'a>` types that can be safely and
1559 /// efficiently converted to `X<'tcx>` as long as they are part of the
1560 /// provided `TyCtxt<'tcx>`.
1561 /// This can be done, for example, for `Ty<'tcx>` or `SubstsRef<'tcx>`
1562 /// by looking them up in their respective interners.
1564 /// However, this is still not the best implementation as it does
1565 /// need to compare the components, even for interned values.
1566 /// It would be more efficient if `TypedArena` provided a way to
1567 /// determine whether the address is in the allocated range.
1569 /// `None` is returned if the value or one of the components is not part
1570 /// of the provided context.
1571 /// For `Ty`, `None` can be returned if either the type interner doesn't
1572 /// contain the `TyKind` key or if the address of the interned
1573 /// pointer differs. The latter case is possible if a primitive type,
1574 /// e.g., `()` or `u8`, was interned in a different context.
1575 pub trait Lift
<'tcx
>: fmt
::Debug
{
1576 type Lifted
: fmt
::Debug
+ 'tcx
;
1577 fn lift_to_tcx(&self, tcx
: TyCtxt
<'tcx
>) -> Option
<Self::Lifted
>;
1580 macro_rules
! nop_lift
{
1581 ($set
:ident
; $ty
:ty
=> $lifted
:ty
) => {
1582 impl<'a
, 'tcx
> Lift
<'tcx
> for $ty
{
1583 type Lifted
= $lifted
;
1584 fn lift_to_tcx(&self, tcx
: TyCtxt
<'tcx
>) -> Option
<Self::Lifted
> {
1585 if tcx
.interners
.$set
.contains_pointer_to(&Interned(*self)) {
1586 Some(unsafe { mem::transmute(*self) }
)
1595 macro_rules
! nop_list_lift
{
1596 ($set
:ident
; $ty
:ty
=> $lifted
:ty
) => {
1597 impl<'a
, 'tcx
> Lift
<'tcx
> for &'a List
<$ty
> {
1598 type Lifted
= &'tcx List
<$lifted
>;
1599 fn lift_to_tcx(&self, tcx
: TyCtxt
<'tcx
>) -> Option
<Self::Lifted
> {
1600 if self.is_empty() {
1601 return Some(List
::empty());
1603 if tcx
.interners
.$set
.contains_pointer_to(&Interned(*self)) {
1604 Some(unsafe { mem::transmute(*self) }
)
1613 nop_lift
! {type_; Ty<'a> => Ty<'tcx>}
1614 nop_lift
! {region; Region<'a> => Region<'tcx>}
1615 nop_lift
! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
1616 nop_lift
! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
1618 nop_list_lift
! {type_list; Ty<'a> => Ty<'tcx>}
1619 nop_list_lift
! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
1620 nop_list_lift
! {predicates; Predicate<'a> => Predicate<'tcx>}
1621 nop_list_lift
! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo}
1622 nop_list_lift
! {projs; ProjectionKind => ProjectionKind}
1624 // This is the impl for `&'a InternalSubsts<'a>`.
1625 nop_list_lift
! {substs; GenericArg<'a> => GenericArg<'tcx>}
1628 use super::{ptr_eq, GlobalCtxt, TyCtxt}
;
1630 use crate::dep_graph
::{DepKind, TaskDeps}
;
1631 use crate::ty
::query
;
1632 use rustc_data_structures
::sync
::{self, Lock}
;
1633 use rustc_data_structures
::thin_vec
::ThinVec
;
1634 use rustc_errors
::Diagnostic
;
1637 #[cfg(not(parallel_compiler))]
1638 use std
::cell
::Cell
;
1640 #[cfg(parallel_compiler)]
1641 use rustc_rayon_core
as rayon_core
;
1643 /// This is the implicit state of rustc. It contains the current
1644 /// `TyCtxt` and query. It is updated when creating a local interner or
1645 /// executing a new query. Whenever there's a `TyCtxt` value available
1646 /// you should also have access to an `ImplicitCtxt` through the functions
1649 pub struct ImplicitCtxt
<'a
, 'tcx
> {
1650 /// The current `TyCtxt`.
1651 pub tcx
: TyCtxt
<'tcx
>,
1653 /// The current query job, if any. This is updated by `JobOwner::start` in
1654 /// `ty::query::plumbing` when executing a query.
1655 pub query
: Option
<query
::QueryJobId
<DepKind
>>,
1657 /// Where to store diagnostics for the current query job, if any.
1658 /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
1659 pub diagnostics
: Option
<&'a Lock
<ThinVec
<Diagnostic
>>>,
1661 /// Used to prevent layout from recursing too deeply.
1662 pub layout_depth
: usize,
1664 /// The current dep graph task. This is used to add dependencies to queries
1665 /// when executing them.
1666 pub task_deps
: Option
<&'a Lock
<TaskDeps
>>,
1669 impl<'a
, 'tcx
> ImplicitCtxt
<'a
, 'tcx
> {
1670 pub fn new(gcx
: &'tcx GlobalCtxt
<'tcx
>) -> Self {
1671 let tcx
= TyCtxt { gcx }
;
1672 ImplicitCtxt { tcx, query: None, diagnostics: None, layout_depth: 0, task_deps: None }
1676 /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
1677 /// to `value` during the call to `f`. It is restored to its previous value after.
1678 /// This is used to set the pointer to the new `ImplicitCtxt`.
1679 #[cfg(parallel_compiler)]
1681 fn set_tlv
<F
: FnOnce() -> R
, R
>(value
: usize, f
: F
) -> R
{
1682 rayon_core
::tlv
::with(value
, f
)
1685 /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
1686 /// This is used to get the pointer to the current `ImplicitCtxt`.
1687 #[cfg(parallel_compiler)]
1689 pub fn get_tlv() -> usize {
1690 rayon_core
::tlv
::get()
1693 #[cfg(not(parallel_compiler))]
1695 /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
1696 static TLV
: Cell
<usize> = Cell
::new(0);
1699 /// Sets TLV to `value` during the call to `f`.
1700 /// It is restored to its previous value after.
1701 /// This is used to set the pointer to the new `ImplicitCtxt`.
1702 #[cfg(not(parallel_compiler))]
1704 fn set_tlv
<F
: FnOnce() -> R
, R
>(value
: usize, f
: F
) -> R
{
1705 let old
= get_tlv();
1706 let _reset
= rustc_data_structures
::OnDrop(move || TLV
.with(|tlv
| tlv
.set(old
)));
1707 TLV
.with(|tlv
| tlv
.set(value
));
1711 /// Gets the pointer to the current `ImplicitCtxt`.
1712 #[cfg(not(parallel_compiler))]
1714 fn get_tlv() -> usize {
1715 TLV
.with(|tlv
| tlv
.get())
1718 /// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
1720 pub fn enter_context
<'a
, 'tcx
, F
, R
>(context
: &ImplicitCtxt
<'a
, 'tcx
>, f
: F
) -> R
1722 F
: FnOnce(&ImplicitCtxt
<'a
, 'tcx
>) -> R
,
1724 set_tlv(context
as *const _
as usize, || f(&context
))
1727 /// Allows access to the current `ImplicitCtxt` in a closure if one is available.
1729 pub fn with_context_opt
<F
, R
>(f
: F
) -> R
1731 F
: for<'a
, 'tcx
> FnOnce(Option
<&ImplicitCtxt
<'a
, 'tcx
>>) -> R
,
1733 let context
= get_tlv();
1737 // We could get a `ImplicitCtxt` pointer from another thread.
1738 // Ensure that `ImplicitCtxt` is `Sync`.
1739 sync
::assert_sync
::<ImplicitCtxt
<'_
, '_
>>();
1741 unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
1745 /// Allows access to the current `ImplicitCtxt`.
1746 /// Panics if there is no `ImplicitCtxt` available.
1748 pub fn with_context
<F
, R
>(f
: F
) -> R
1750 F
: for<'a
, 'tcx
> FnOnce(&ImplicitCtxt
<'a
, 'tcx
>) -> R
,
1752 with_context_opt(|opt_context
| f(opt_context
.expect("no ImplicitCtxt stored in tls")))
1755 /// Allows access to the current `ImplicitCtxt` whose tcx field is the same as the tcx argument
1756 /// passed in. This means the closure is given an `ImplicitCtxt` with the same `'tcx` lifetime
1757 /// as the `TyCtxt` passed in.
1758 /// This will panic if you pass it a `TyCtxt` which is different from the current
1759 /// `ImplicitCtxt`'s `tcx` field.
1761 pub fn with_related_context
<'tcx
, F
, R
>(tcx
: TyCtxt
<'tcx
>, f
: F
) -> R
1763 F
: FnOnce(&ImplicitCtxt
<'_
, 'tcx
>) -> R
,
1765 with_context(|context
| unsafe {
1766 assert
!(ptr_eq(context
.tcx
.gcx
, tcx
.gcx
));
1767 let context
: &ImplicitCtxt
<'_
, '_
> = mem
::transmute(context
);
1772 /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
1773 /// Panics if there is no `ImplicitCtxt` available.
1775 pub fn with
<F
, R
>(f
: F
) -> R
1777 F
: for<'tcx
> FnOnce(TyCtxt
<'tcx
>) -> R
,
1779 with_context(|context
| f(context
.tcx
))
1782 /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
1783 /// The closure is passed None if there is no `ImplicitCtxt` available.
1785 pub fn with_opt
<F
, R
>(f
: F
) -> R
1787 F
: for<'tcx
> FnOnce(Option
<TyCtxt
<'tcx
>>) -> R
,
1789 with_context_opt(|opt_context
| f(opt_context
.map(|context
| context
.tcx
)))
1793 macro_rules
! sty_debug_print
{
1794 ($fmt
: expr
, $ctxt
: expr
, $
($variant
: ident
),*) => {{
1795 // Curious inner module to allow variant names to be used as
1797 #[allow(non_snake_case)]
1799 use crate::ty
::{self, TyCtxt}
;
1800 use crate::ty
::context
::Interned
;
1802 #[derive(Copy, Clone)]
1811 pub fn go(fmt
: &mut std
::fmt
::Formatter
<'_
>, tcx
: TyCtxt
<'_
>) -> std
::fmt
::Result
{
1812 let mut total
= DebugStat
{
1819 $
(let mut $variant
= total
;)*
1821 let shards
= tcx
.interners
.type_
.lock_shards();
1822 let types
= shards
.iter().flat_map(|shard
| shard
.keys());
1823 for &Interned(t
) in types
{
1824 let variant
= match t
.kind
{
1825 ty
::Bool
| ty
::Char
| ty
::Int(..) | ty
::Uint(..) |
1826 ty
::Float(..) | ty
::Str
| ty
::Never
=> continue,
1827 ty
::Error(_
) => /* unimportant */ continue,
1828 $
(ty
::$
variant(..) => &mut $variant
,)*
1830 let lt
= t
.flags
.intersects(ty
::TypeFlags
::HAS_RE_INFER
);
1831 let ty
= t
.flags
.intersects(ty
::TypeFlags
::HAS_TY_INFER
);
1832 let ct
= t
.flags
.intersects(ty
::TypeFlags
::HAS_CT_INFER
);
1836 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1837 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1838 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1839 if lt
&& ty
&& ct { total.all_infer += 1; variant.all_infer += 1 }
1841 writeln
!(fmt
, "Ty interner total ty lt ct all")?
;
1842 $
(writeln
!(fmt
, " {:18}: {uses:6} {usespc:4.1}%, \
1843 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1844 stringify
!($variant
),
1845 uses
= $variant
.total
,
1846 usespc
= $variant
.total
as f64 * 100.0 / total
.total
as f64,
1847 ty
= $variant
.ty_infer
as f64 * 100.0 / total
.total
as f64,
1848 lt
= $variant
.lt_infer
as f64 * 100.0 / total
.total
as f64,
1849 ct
= $variant
.ct_infer
as f64 * 100.0 / total
.total
as f64,
1850 all
= $variant
.all_infer
as f64 * 100.0 / total
.total
as f64)?
;
1852 writeln
!(fmt
, " total {uses:6} \
1853 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1855 ty
= total
.ty_infer
as f64 * 100.0 / total
.total
as f64,
1856 lt
= total
.lt_infer
as f64 * 100.0 / total
.total
as f64,
1857 ct
= total
.ct_infer
as f64 * 100.0 / total
.total
as f64,
1858 all
= total
.all_infer
as f64 * 100.0 / total
.total
as f64)
1862 inner
::go($fmt
, $ctxt
)
1866 impl<'tcx
> TyCtxt
<'tcx
> {
1867 pub fn debug_stats(self) -> impl std
::fmt
::Debug
+ 'tcx
{
1868 struct DebugStats
<'tcx
>(TyCtxt
<'tcx
>);
1870 impl std
::fmt
::Debug
for DebugStats
<'tcx
> {
1871 fn fmt(&self, fmt
: &mut std
::fmt
::Formatter
<'_
>) -> std
::fmt
::Result
{
1896 writeln
!(fmt
, "InternalSubsts interner: #{}", self.0.interners
.substs
.len())?
;
1897 writeln
!(fmt
, "Region interner: #{}", self.0.interners
.region
.len())?
;
1898 writeln
!(fmt
, "Stability interner: #{}", self.0.stability_interner
.len())?
;
1901 "Const Stability interner: #{}",
1902 self.0.const_stability_interner
.len()
1904 writeln
!(fmt
, "Allocation interner: #{}", self.0.allocation_interner
.len())?
;
1905 writeln
!(fmt
, "Layout interner: #{}", self.0.layout_interner
.len())?
;
1915 /// An entry in an interner.
1916 struct Interned
<'tcx
, T
: ?Sized
>(&'tcx T
);
1918 impl<'tcx
, T
: 'tcx
+ ?Sized
> Clone
for Interned
<'tcx
, T
> {
1919 fn clone(&self) -> Self {
1923 impl<'tcx
, T
: 'tcx
+ ?Sized
> Copy
for Interned
<'tcx
, T
> {}
1925 impl<'tcx
, T
: 'tcx
+ ?Sized
> IntoPointer
for Interned
<'tcx
, T
> {
1926 fn into_pointer(&self) -> *const () {
1927 self.0 as *const _
as *const ()
1930 // N.B., an `Interned<Ty>` compares and hashes as a `TyKind`.
1931 impl<'tcx
> PartialEq
for Interned
<'tcx
, TyS
<'tcx
>> {
1932 fn eq(&self, other
: &Interned
<'tcx
, TyS
<'tcx
>>) -> bool
{
1933 self.0.kind
== other
.0.kind
1937 impl<'tcx
> Eq
for Interned
<'tcx
, TyS
<'tcx
>> {}
1939 impl<'tcx
> Hash
for Interned
<'tcx
, TyS
<'tcx
>> {
1940 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1945 #[allow(rustc::usage_of_ty_tykind)]
1946 impl<'tcx
> Borrow
<TyKind
<'tcx
>> for Interned
<'tcx
, TyS
<'tcx
>> {
1947 fn borrow
<'a
>(&'a
self) -> &'a TyKind
<'tcx
> {
1951 // N.B., an `Interned<PredicateInner>` compares and hashes as a `PredicateKind`.
1952 impl<'tcx
> PartialEq
for Interned
<'tcx
, PredicateInner
<'tcx
>> {
1953 fn eq(&self, other
: &Interned
<'tcx
, PredicateInner
<'tcx
>>) -> bool
{
1954 self.0.kind
== other
.0.kind
1958 impl<'tcx
> Eq
for Interned
<'tcx
, PredicateInner
<'tcx
>> {}
1960 impl<'tcx
> Hash
for Interned
<'tcx
, PredicateInner
<'tcx
>> {
1961 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1966 impl<'tcx
> Borrow
<PredicateKind
<'tcx
>> for Interned
<'tcx
, PredicateInner
<'tcx
>> {
1967 fn borrow
<'a
>(&'a
self) -> &'a PredicateKind
<'tcx
> {
1972 // N.B., an `Interned<List<T>>` compares and hashes as its elements.
1973 impl<'tcx
, T
: PartialEq
> PartialEq
for Interned
<'tcx
, List
<T
>> {
1974 fn eq(&self, other
: &Interned
<'tcx
, List
<T
>>) -> bool
{
1975 self.0[..] == other
.0[..]
1979 impl<'tcx
, T
: Eq
> Eq
for Interned
<'tcx
, List
<T
>> {}
1981 impl<'tcx
, T
: Hash
> Hash
for Interned
<'tcx
, List
<T
>> {
1982 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
1987 impl<'tcx
, T
> Borrow
<[T
]> for Interned
<'tcx
, List
<T
>> {
1988 fn borrow
<'a
>(&'a
self) -> &'a
[T
] {
1993 impl<'tcx
> Borrow
<RegionKind
> for Interned
<'tcx
, RegionKind
> {
1994 fn borrow(&self) -> &RegionKind
{
1999 impl<'tcx
> Borrow
<Const
<'tcx
>> for Interned
<'tcx
, Const
<'tcx
>> {
2000 fn borrow
<'a
>(&'a
self) -> &'a Const
<'tcx
> {
2005 impl<'tcx
> Borrow
<PredicateKind
<'tcx
>> for Interned
<'tcx
, PredicateKind
<'tcx
>> {
2006 fn borrow
<'a
>(&'a
self) -> &'a PredicateKind
<'tcx
> {
2011 macro_rules
! direct_interners
{
2012 ($
($name
:ident
: $method
:ident($ty
:ty
),)+) => {
2013 $
(impl<'tcx
> PartialEq
for Interned
<'tcx
, $ty
> {
2014 fn eq(&self, other
: &Self) -> bool
{
2019 impl<'tcx
> Eq
for Interned
<'tcx
, $ty
> {}
2021 impl<'tcx
> Hash
for Interned
<'tcx
, $ty
> {
2022 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
2027 impl<'tcx
> TyCtxt
<'tcx
> {
2028 pub fn $
method(self, v
: $ty
) -> &'tcx $ty
{
2029 self.interners
.$name
.intern_ref(&v
, || {
2030 Interned(self.interners
.arena
.alloc(v
))
2038 region
: mk_region(RegionKind
),
2039 const_
: mk_const(Const
<'tcx
>),
2042 macro_rules
! slice_interners
{
2043 ($
($field
:ident
: $method
:ident($ty
:ty
)),+) => (
2044 $
(impl<'tcx
> TyCtxt
<'tcx
> {
2045 pub fn $
method(self, v
: &[$ty
]) -> &'tcx List
<$ty
> {
2046 self.interners
.$field
.intern_ref(v
, || {
2047 Interned(List
::from_arena(&*self.arena
, v
))
2055 type_list
: _intern_type_list(Ty
<'tcx
>),
2056 substs
: _intern_substs(GenericArg
<'tcx
>),
2057 canonical_var_infos
: _intern_canonical_var_infos(CanonicalVarInfo
),
2058 existential_predicates
: _intern_existential_predicates(ExistentialPredicate
<'tcx
>),
2059 predicates
: _intern_predicates(Predicate
<'tcx
>),
2060 projs
: _intern_projs(ProjectionKind
),
2061 place_elems
: _intern_place_elems(PlaceElem
<'tcx
>),
2062 chalk_environment_clause_list
:
2063 _intern_chalk_environment_clause_list(traits
::ChalkEnvironmentClause
<'tcx
>)
2066 impl<'tcx
> TyCtxt
<'tcx
> {
2067 /// Given a `fn` type, returns an equivalent `unsafe fn` type;
2068 /// that is, a `fn` type that is equivalent in every way for being
2070 pub fn safe_to_unsafe_fn_ty(self, sig
: PolyFnSig
<'tcx
>) -> Ty
<'tcx
> {
2071 assert_eq
!(sig
.unsafety(), hir
::Unsafety
::Normal
);
2072 self.mk_fn_ptr(sig
.map_bound(|sig
| ty
::FnSig { unsafety: hir::Unsafety::Unsafe, ..sig }
))
2075 /// Given a closure signature, returns an equivalent fn signature. Detuples
2076 /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
2077 /// you would get a `fn(u32, i32)`.
2078 /// `unsafety` determines the unsafety of the fn signature. If you pass
2079 /// `hir::Unsafety::Unsafe` in the previous example, then you would get
2080 /// an `unsafe fn (u32, i32)`.
2081 /// It cannot convert a closure that requires unsafe.
2082 pub fn signature_unclosure(
2084 sig
: PolyFnSig
<'tcx
>,
2085 unsafety
: hir
::Unsafety
,
2086 ) -> PolyFnSig
<'tcx
> {
2088 let params_iter
= match s
.inputs()[0].kind
{
2089 ty
::Tuple(params
) => params
.into_iter().map(|k
| k
.expect_ty()),
2092 self.mk_fn_sig(params_iter
, s
.output(), s
.c_variadic
, unsafety
, abi
::Abi
::Rust
)
2096 /// Same a `self.mk_region(kind)`, but avoids accessing the interners if
2099 pub fn reuse_or_mk_region(self, r
: Region
<'tcx
>, kind
: RegionKind
) -> Region
<'tcx
> {
2100 if *r
== kind { r }
else { self.mk_region(kind) }
2103 #[allow(rustc::usage_of_ty_tykind)]
2105 pub fn mk_ty(self, st
: TyKind
<'tcx
>) -> Ty
<'tcx
> {
2106 self.interners
.intern_ty(st
)
2110 pub fn mk_predicate(self, kind
: PredicateKind
<'tcx
>) -> Predicate
<'tcx
> {
2111 let inner
= self.interners
.intern_predicate(kind
);
2116 pub fn reuse_or_mk_predicate(
2118 pred
: Predicate
<'tcx
>,
2119 kind
: PredicateKind
<'tcx
>,
2120 ) -> Predicate
<'tcx
> {
2121 if *pred
.kind() != kind { self.mk_predicate(kind) }
else { pred }
2124 pub fn mk_mach_int(self, tm
: ast
::IntTy
) -> Ty
<'tcx
> {
2126 ast
::IntTy
::Isize
=> self.types
.isize,
2127 ast
::IntTy
::I8
=> self.types
.i8,
2128 ast
::IntTy
::I16
=> self.types
.i16,
2129 ast
::IntTy
::I32
=> self.types
.i32,
2130 ast
::IntTy
::I64
=> self.types
.i64,
2131 ast
::IntTy
::I128
=> self.types
.i128
,
2135 pub fn mk_mach_uint(self, tm
: ast
::UintTy
) -> Ty
<'tcx
> {
2137 ast
::UintTy
::Usize
=> self.types
.usize,
2138 ast
::UintTy
::U8
=> self.types
.u8,
2139 ast
::UintTy
::U16
=> self.types
.u16,
2140 ast
::UintTy
::U32
=> self.types
.u32,
2141 ast
::UintTy
::U64
=> self.types
.u64,
2142 ast
::UintTy
::U128
=> self.types
.u128
,
2146 pub fn mk_mach_float(self, tm
: ast
::FloatTy
) -> Ty
<'tcx
> {
2148 ast
::FloatTy
::F32
=> self.types
.f32,
2149 ast
::FloatTy
::F64
=> self.types
.f64,
2154 pub fn mk_static_str(self) -> Ty
<'tcx
> {
2155 self.mk_imm_ref(self.lifetimes
.re_static
, self.types
.str_
)
2159 pub fn mk_adt(self, def
: &'tcx AdtDef
, substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2160 // Take a copy of substs so that we own the vectors inside.
2161 self.mk_ty(Adt(def
, substs
))
2165 pub fn mk_foreign(self, def_id
: DefId
) -> Ty
<'tcx
> {
2166 self.mk_ty(Foreign(def_id
))
2169 fn mk_generic_adt(self, wrapper_def_id
: DefId
, ty_param
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2170 let adt_def
= self.adt_def(wrapper_def_id
);
2172 InternalSubsts
::for_item(self, wrapper_def_id
, |param
, substs
| match param
.kind
{
2173 GenericParamDefKind
::Lifetime
| GenericParamDefKind
::Const
=> bug
!(),
2174 GenericParamDefKind
::Type { has_default, .. }
=> {
2175 if param
.index
== 0 {
2178 assert
!(has_default
);
2179 self.type_of(param
.def_id
).subst(self, substs
).into()
2183 self.mk_ty(Adt(adt_def
, substs
))
2187 pub fn mk_box(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2188 let def_id
= self.require_lang_item(LangItem
::OwnedBox
, None
);
2189 self.mk_generic_adt(def_id
, ty
)
2193 pub fn mk_lang_item(self, ty
: Ty
<'tcx
>, item
: LangItem
) -> Option
<Ty
<'tcx
>> {
2194 let def_id
= self.lang_items().require(item
).ok()?
;
2195 Some(self.mk_generic_adt(def_id
, ty
))
2199 pub fn mk_diagnostic_item(self, ty
: Ty
<'tcx
>, name
: Symbol
) -> Option
<Ty
<'tcx
>> {
2200 let def_id
= self.get_diagnostic_item(name
)?
;
2201 Some(self.mk_generic_adt(def_id
, ty
))
2205 pub fn mk_maybe_uninit(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2206 let def_id
= self.require_lang_item(LangItem
::MaybeUninit
, None
);
2207 self.mk_generic_adt(def_id
, ty
)
2211 pub fn mk_ptr(self, tm
: TypeAndMut
<'tcx
>) -> Ty
<'tcx
> {
2212 self.mk_ty(RawPtr(tm
))
2216 pub fn mk_ref(self, r
: Region
<'tcx
>, tm
: TypeAndMut
<'tcx
>) -> Ty
<'tcx
> {
2217 self.mk_ty(Ref(r
, tm
.ty
, tm
.mutbl
))
2221 pub fn mk_mut_ref(self, r
: Region
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2222 self.mk_ref(r
, TypeAndMut { ty, mutbl: hir::Mutability::Mut }
)
2226 pub fn mk_imm_ref(self, r
: Region
<'tcx
>, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2227 self.mk_ref(r
, TypeAndMut { ty, mutbl: hir::Mutability::Not }
)
2231 pub fn mk_mut_ptr(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2232 self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Mut }
)
2236 pub fn mk_imm_ptr(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2237 self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Not }
)
2241 pub fn mk_nil_ptr(self) -> Ty
<'tcx
> {
2242 self.mk_imm_ptr(self.mk_unit())
2246 pub fn mk_array(self, ty
: Ty
<'tcx
>, n
: u64) -> Ty
<'tcx
> {
2247 self.mk_ty(Array(ty
, ty
::Const
::from_usize(self, n
)))
2251 pub fn mk_slice(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
2252 self.mk_ty(Slice(ty
))
2256 pub fn intern_tup(self, ts
: &[Ty
<'tcx
>]) -> Ty
<'tcx
> {
2257 let kinds
: Vec
<_
> = ts
.iter().map(|&t
| GenericArg
::from(t
)).collect();
2258 self.mk_ty(Tuple(self.intern_substs(&kinds
)))
2261 pub fn mk_tup
<I
: InternAs
<[Ty
<'tcx
>], Ty
<'tcx
>>>(self, iter
: I
) -> I
::Output
{
2262 iter
.intern_with(|ts
| {
2263 let kinds
: Vec
<_
> = ts
.iter().map(|&t
| GenericArg
::from(t
)).collect();
2264 self.mk_ty(Tuple(self.intern_substs(&kinds
)))
2269 pub fn mk_unit(self) -> Ty
<'tcx
> {
2274 pub fn mk_diverging_default(self) -> Ty
<'tcx
> {
2275 if self.features().never_type_fallback { self.types.never }
else { self.types.unit }
2279 pub fn mk_fn_def(self, def_id
: DefId
, substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2280 self.mk_ty(FnDef(def_id
, substs
))
2284 pub fn mk_fn_ptr(self, fty
: PolyFnSig
<'tcx
>) -> Ty
<'tcx
> {
2285 self.mk_ty(FnPtr(fty
))
2291 obj
: ty
::Binder
<&'tcx List
<ExistentialPredicate
<'tcx
>>>,
2292 reg
: ty
::Region
<'tcx
>,
2294 self.mk_ty(Dynamic(obj
, reg
))
2298 pub fn mk_projection(self, item_def_id
: DefId
, substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2299 self.mk_ty(Projection(ProjectionTy { item_def_id, substs }
))
2303 pub fn mk_closure(self, closure_id
: DefId
, closure_substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2304 self.mk_ty(Closure(closure_id
, closure_substs
))
2308 pub fn mk_generator(
2311 generator_substs
: SubstsRef
<'tcx
>,
2312 movability
: hir
::Movability
,
2314 self.mk_ty(Generator(id
, generator_substs
, movability
))
2318 pub fn mk_generator_witness(self, types
: ty
::Binder
<&'tcx List
<Ty
<'tcx
>>>) -> Ty
<'tcx
> {
2319 self.mk_ty(GeneratorWitness(types
))
2323 pub fn mk_ty_var(self, v
: TyVid
) -> Ty
<'tcx
> {
2324 self.mk_ty_infer(TyVar(v
))
2328 pub fn mk_const_var(self, v
: ConstVid
<'tcx
>, ty
: Ty
<'tcx
>) -> &'tcx Const
<'tcx
> {
2329 self.mk_const(ty
::Const { val: ty::ConstKind::Infer(InferConst::Var(v)), ty }
)
2333 pub fn mk_int_var(self, v
: IntVid
) -> Ty
<'tcx
> {
2334 self.mk_ty_infer(IntVar(v
))
2338 pub fn mk_float_var(self, v
: FloatVid
) -> Ty
<'tcx
> {
2339 self.mk_ty_infer(FloatVar(v
))
2343 pub fn mk_ty_infer(self, it
: InferTy
) -> Ty
<'tcx
> {
2344 self.mk_ty(Infer(it
))
2348 pub fn mk_const_infer(self, ic
: InferConst
<'tcx
>, ty
: Ty
<'tcx
>) -> &'tcx ty
::Const
<'tcx
> {
2349 self.mk_const(ty
::Const { val: ty::ConstKind::Infer(ic), ty }
)
2353 pub fn mk_ty_param(self, index
: u32, name
: Symbol
) -> Ty
<'tcx
> {
2354 self.mk_ty(Param(ParamTy { index, name }
))
2358 pub fn mk_const_param(self, index
: u32, name
: Symbol
, ty
: Ty
<'tcx
>) -> &'tcx Const
<'tcx
> {
2359 self.mk_const(ty
::Const { val: ty::ConstKind::Param(ParamConst { index, name }
), ty
})
2362 pub fn mk_param_from_def(self, param
: &ty
::GenericParamDef
) -> GenericArg
<'tcx
> {
2364 GenericParamDefKind
::Lifetime
=> {
2365 self.mk_region(ty
::ReEarlyBound(param
.to_early_bound_region_data())).into()
2367 GenericParamDefKind
::Type { .. }
=> self.mk_ty_param(param
.index
, param
.name
).into(),
2368 GenericParamDefKind
::Const
=> {
2369 self.mk_const_param(param
.index
, param
.name
, self.type_of(param
.def_id
)).into()
2375 pub fn mk_opaque(self, def_id
: DefId
, substs
: SubstsRef
<'tcx
>) -> Ty
<'tcx
> {
2376 self.mk_ty(Opaque(def_id
, substs
))
2379 pub fn mk_place_field(self, place
: Place
<'tcx
>, f
: Field
, ty
: Ty
<'tcx
>) -> Place
<'tcx
> {
2380 self.mk_place_elem(place
, PlaceElem
::Field(f
, ty
))
2383 pub fn mk_place_deref(self, place
: Place
<'tcx
>) -> Place
<'tcx
> {
2384 self.mk_place_elem(place
, PlaceElem
::Deref
)
2387 pub fn mk_place_downcast(
2390 adt_def
: &'tcx AdtDef
,
2391 variant_index
: VariantIdx
,
2395 PlaceElem
::Downcast(Some(adt_def
.variants
[variant_index
].ident
.name
), variant_index
),
2399 pub fn mk_place_downcast_unnamed(
2402 variant_index
: VariantIdx
,
2404 self.mk_place_elem(place
, PlaceElem
::Downcast(None
, variant_index
))
2407 pub fn mk_place_index(self, place
: Place
<'tcx
>, index
: Local
) -> Place
<'tcx
> {
2408 self.mk_place_elem(place
, PlaceElem
::Index(index
))
2411 /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2412 /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2414 pub fn mk_place_elem(self, place
: Place
<'tcx
>, elem
: PlaceElem
<'tcx
>) -> Place
<'tcx
> {
2415 let mut projection
= place
.projection
.to_vec();
2416 projection
.push(elem
);
2418 Place { local: place.local, projection: self.intern_place_elems(&projection) }
2421 pub fn intern_existential_predicates(
2423 eps
: &[ExistentialPredicate
<'tcx
>],
2424 ) -> &'tcx List
<ExistentialPredicate
<'tcx
>> {
2425 assert
!(!eps
.is_empty());
2426 assert
!(eps
.windows(2).all(|w
| w
[0].stable_cmp(self, &w
[1]) != Ordering
::Greater
));
2427 self._intern_existential_predicates(eps
)
2430 pub fn intern_predicates(self, preds
: &[Predicate
<'tcx
>]) -> &'tcx List
<Predicate
<'tcx
>> {
2431 // FIXME consider asking the input slice to be sorted to avoid
2432 // re-interning permutations, in which case that would be asserted
2434 if preds
.is_empty() {
2435 // The macro-generated method below asserts we don't intern an empty slice.
2438 self._intern_predicates(preds
)
2442 pub fn intern_type_list(self, ts
: &[Ty
<'tcx
>]) -> &'tcx List
<Ty
<'tcx
>> {
2443 if ts
.is_empty() { List::empty() }
else { self._intern_type_list(ts) }
2446 pub fn intern_substs(self, ts
: &[GenericArg
<'tcx
>]) -> &'tcx List
<GenericArg
<'tcx
>> {
2447 if ts
.is_empty() { List::empty() }
else { self._intern_substs(ts) }
2450 pub fn intern_projs(self, ps
: &[ProjectionKind
]) -> &'tcx List
<ProjectionKind
> {
2451 if ps
.is_empty() { List::empty() }
else { self._intern_projs(ps) }
2454 pub fn intern_place_elems(self, ts
: &[PlaceElem
<'tcx
>]) -> &'tcx List
<PlaceElem
<'tcx
>> {
2455 if ts
.is_empty() { List::empty() }
else { self._intern_place_elems(ts) }
2458 pub fn intern_canonical_var_infos(self, ts
: &[CanonicalVarInfo
]) -> CanonicalVarInfos
<'tcx
> {
2459 if ts
.is_empty() { List::empty() }
else { self._intern_canonical_var_infos(ts) }
2462 pub fn intern_chalk_environment_clause_list(
2464 ts
: &[traits
::ChalkEnvironmentClause
<'tcx
>],
2465 ) -> &'tcx List
<traits
::ChalkEnvironmentClause
<'tcx
>> {
2466 if ts
.is_empty() { List::empty() }
else { self._intern_chalk_environment_clause_list(ts) }
2469 pub fn mk_fn_sig
<I
>(
2474 unsafety
: hir
::Unsafety
,
2476 ) -> <I
::Item
as InternIteratorElement
<Ty
<'tcx
>, ty
::FnSig
<'tcx
>>>::Output
2478 I
: Iterator
<Item
: InternIteratorElement
<Ty
<'tcx
>, ty
::FnSig
<'tcx
>>>,
2480 inputs
.chain(iter
::once(output
)).intern_with(|xs
| ty
::FnSig
{
2481 inputs_and_output
: self.intern_type_list(xs
),
2488 pub fn mk_existential_predicates
<
2489 I
: InternAs
<[ExistentialPredicate
<'tcx
>], &'tcx List
<ExistentialPredicate
<'tcx
>>>,
2494 iter
.intern_with(|xs
| self.intern_existential_predicates(xs
))
2497 pub fn mk_predicates
<I
: InternAs
<[Predicate
<'tcx
>], &'tcx List
<Predicate
<'tcx
>>>>(
2501 iter
.intern_with(|xs
| self.intern_predicates(xs
))
2504 pub fn mk_type_list
<I
: InternAs
<[Ty
<'tcx
>], &'tcx List
<Ty
<'tcx
>>>>(self, iter
: I
) -> I
::Output
{
2505 iter
.intern_with(|xs
| self.intern_type_list(xs
))
2508 pub fn mk_substs
<I
: InternAs
<[GenericArg
<'tcx
>], &'tcx List
<GenericArg
<'tcx
>>>>(
2512 iter
.intern_with(|xs
| self.intern_substs(xs
))
2515 pub fn mk_place_elems
<I
: InternAs
<[PlaceElem
<'tcx
>], &'tcx List
<PlaceElem
<'tcx
>>>>(
2519 iter
.intern_with(|xs
| self.intern_place_elems(xs
))
2522 pub fn mk_substs_trait(self, self_ty
: Ty
<'tcx
>, rest
: &[GenericArg
<'tcx
>]) -> SubstsRef
<'tcx
> {
2523 self.mk_substs(iter
::once(self_ty
.into()).chain(rest
.iter().cloned()))
2526 pub fn mk_chalk_environment_clause_list
<
2528 [traits
::ChalkEnvironmentClause
<'tcx
>],
2529 &'tcx List
<traits
::ChalkEnvironmentClause
<'tcx
>>,
2535 iter
.intern_with(|xs
| self.intern_chalk_environment_clause_list(xs
))
2538 /// Walks upwards from `id` to find a node which might change lint levels with attributes.
2539 /// It stops at `bound` and just returns it if reached.
2540 pub fn maybe_lint_level_root_bounded(self, mut id
: HirId
, bound
: HirId
) -> HirId
{
2541 let hir
= self.hir();
2547 if hir
.attrs(id
).iter().any(|attr
| Level
::from_symbol(attr
.name_or_empty()).is_some()) {
2550 let next
= hir
.get_parent_node(id
);
2552 bug
!("lint traversal reached the root of the crate");
2558 pub fn lint_level_at_node(
2560 lint
: &'
static Lint
,
2562 ) -> (Level
, LintSource
) {
2563 let sets
= self.lint_levels(LOCAL_CRATE
);
2565 if let Some(pair
) = sets
.level_and_source(lint
, id
, self.sess
) {
2568 let next
= self.hir().get_parent_node(id
);
2570 bug
!("lint traversal reached the root of the crate");
2576 pub fn struct_span_lint_hir(
2578 lint
: &'
static Lint
,
2580 span
: impl Into
<MultiSpan
>,
2581 decorate
: impl for<'a
> FnOnce(LintDiagnosticBuilder
<'a
>),
2583 let (level
, src
) = self.lint_level_at_node(lint
, hir_id
);
2584 struct_lint_level(self.sess
, lint
, level
, src
, Some(span
.into()), decorate
);
2587 pub fn struct_lint_node(
2589 lint
: &'
static Lint
,
2591 decorate
: impl for<'a
> FnOnce(LintDiagnosticBuilder
<'a
>),
2593 let (level
, src
) = self.lint_level_at_node(lint
, id
);
2594 struct_lint_level(self.sess
, lint
, level
, src
, None
, decorate
);
2597 pub fn in_scope_traits(self, id
: HirId
) -> Option
<&'tcx StableVec
<TraitCandidate
>> {
2598 self.in_scope_traits_map(id
.owner
).and_then(|map
| map
.get(&id
.local_id
))
2601 pub fn named_region(self, id
: HirId
) -> Option
<resolve_lifetime
::Region
> {
2602 self.named_region_map(id
.owner
).and_then(|map
| map
.get(&id
.local_id
).cloned())
2605 pub fn is_late_bound(self, id
: HirId
) -> bool
{
2606 self.is_late_bound_map(id
.owner
).map(|set
| set
.contains(&id
.local_id
)).unwrap_or(false)
2609 pub fn object_lifetime_defaults(self, id
: HirId
) -> Option
<&'tcx
[ObjectLifetimeDefault
]> {
2610 self.object_lifetime_defaults_map(id
.owner
)
2611 .and_then(|map
| map
.get(&id
.local_id
).map(|v
| &**v
))
2615 impl TyCtxtAt
<'tcx
> {
2616 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
2618 pub fn ty_error(self) -> Ty
<'tcx
> {
2619 self.tcx
.ty_error_with_message(self.span
, "TyKind::Error constructed but no error reported")
2622 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to
2623 /// ensure it gets used.
2625 pub fn ty_error_with_message(self, msg
: &str) -> Ty
<'tcx
> {
2626 self.tcx
.ty_error_with_message(self.span
, msg
)
2630 pub trait InternAs
<T
: ?Sized
, R
> {
2632 fn intern_with
<F
>(self, f
: F
) -> Self::Output
2637 impl<I
, T
, R
, E
> InternAs
<[T
], R
> for I
2639 E
: InternIteratorElement
<T
, R
>,
2640 I
: Iterator
<Item
= E
>,
2642 type Output
= E
::Output
;
2643 fn intern_with
<F
>(self, f
: F
) -> Self::Output
2645 F
: FnOnce(&[T
]) -> R
,
2647 E
::intern_with(self, f
)
2651 pub trait InternIteratorElement
<T
, R
>: Sized
{
2653 fn intern_with
<I
: Iterator
<Item
= Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
;
2656 impl<T
, R
> InternIteratorElement
<T
, R
> for T
{
2658 fn intern_with
<I
: Iterator
<Item
= Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
{
2659 f(&iter
.collect
::<SmallVec
<[_
; 8]>>())
2663 impl<'a
, T
, R
> InternIteratorElement
<T
, R
> for &'a T
2668 fn intern_with
<I
: Iterator
<Item
= Self>, F
: FnOnce(&[T
]) -> R
>(iter
: I
, f
: F
) -> Self::Output
{
2669 f(&iter
.cloned().collect
::<SmallVec
<[_
; 8]>>())
2673 impl<T
, R
, E
> InternIteratorElement
<T
, R
> for Result
<T
, E
> {
2674 type Output
= Result
<R
, E
>;
2675 fn intern_with
<I
: Iterator
<Item
= Self>, F
: FnOnce(&[T
]) -> R
>(
2679 // This code is hot enough that it's worth specializing for the most
2680 // common length lists, to avoid the overhead of `SmallVec` creation.
2681 // The match arms are in order of frequency. The 1, 2, and 0 cases are
2682 // typically hit in ~95% of cases. We assume that if the upper and
2683 // lower bounds from `size_hint` agree they are correct.
2684 Ok(match iter
.size_hint() {
2686 let t0
= iter
.next().unwrap()?
;
2687 assert
!(iter
.next().is_none());
2691 let t0
= iter
.next().unwrap()?
;
2692 let t1
= iter
.next().unwrap()?
;
2693 assert
!(iter
.next().is_none());
2697 assert
!(iter
.next().is_none());
2700 _
=> f(&iter
.collect
::<Result
<SmallVec
<[_
; 8]>, _
>>()?
),
2705 // We are comparing types with different invariant lifetimes, so `ptr::eq`
2706 // won't work for us.
2707 fn ptr_eq
<T
, U
>(t
: *const T
, u
: *const U
) -> bool
{
2708 t
as *const () == u
as *const ()
2711 pub fn provide(providers
: &mut ty
::query
::Providers
) {
2712 providers
.in_scope_traits_map
= |tcx
, id
| tcx
.gcx
.trait_map
.get(&id
);
2713 providers
.module_exports
= |tcx
, id
| tcx
.gcx
.export_map
.get(&id
).map(|v
| &v
[..]);
2714 providers
.crate_name
= |tcx
, id
| {
2715 assert_eq
!(id
, LOCAL_CRATE
);
2718 providers
.maybe_unused_trait_import
= |tcx
, id
| tcx
.maybe_unused_trait_imports
.contains(&id
);
2719 providers
.maybe_unused_extern_crates
= |tcx
, cnum
| {
2720 assert_eq
!(cnum
, LOCAL_CRATE
);
2721 &tcx
.maybe_unused_extern_crates
[..]
2723 providers
.names_imported_by_glob_use
=
2724 |tcx
, id
| tcx
.arena
.alloc(tcx
.glob_map
.get(&id
).cloned().unwrap_or_default());
2726 providers
.lookup_stability
= |tcx
, id
| {
2727 let id
= tcx
.hir().local_def_id_to_hir_id(id
.expect_local());
2728 tcx
.stability().local_stability(id
)
2730 providers
.lookup_const_stability
= |tcx
, id
| {
2731 let id
= tcx
.hir().local_def_id_to_hir_id(id
.expect_local());
2732 tcx
.stability().local_const_stability(id
)
2734 providers
.lookup_deprecation_entry
= |tcx
, id
| {
2735 let id
= tcx
.hir().local_def_id_to_hir_id(id
.expect_local());
2736 tcx
.stability().local_deprecation_entry(id
)
2738 providers
.extern_mod_stmt_cnum
= |tcx
, id
| tcx
.extern_crate_map
.get(&id
).cloned();
2739 providers
.all_crate_nums
= |tcx
, cnum
| {
2740 assert_eq
!(cnum
, LOCAL_CRATE
);
2741 tcx
.arena
.alloc_slice(&tcx
.cstore
.crates_untracked())
2743 providers
.output_filenames
= |tcx
, cnum
| {
2744 assert_eq
!(cnum
, LOCAL_CRATE
);
2745 tcx
.output_filenames
.clone()
2747 providers
.features_query
= |tcx
, cnum
| {
2748 assert_eq
!(cnum
, LOCAL_CRATE
);
2749 tcx
.sess
.features_untracked()
2751 providers
.is_panic_runtime
= |tcx
, cnum
| {
2752 assert_eq
!(cnum
, LOCAL_CRATE
);
2753 tcx
.sess
.contains_name(tcx
.hir().krate_attrs(), sym
::panic_runtime
)
2755 providers
.is_compiler_builtins
= |tcx
, cnum
| {
2756 assert_eq
!(cnum
, LOCAL_CRATE
);
2757 tcx
.sess
.contains_name(tcx
.hir().krate_attrs(), sym
::compiler_builtins
)
2759 providers
.has_panic_handler
= |tcx
, cnum
| {
2760 assert_eq
!(cnum
, LOCAL_CRATE
);
2761 // We want to check if the panic handler was defined in this crate
2762 tcx
.lang_items().panic_impl().map_or(false, |did
| did
.is_local())