rustc_middle/ty/
context.rs

1//! Type context book-keeping.
2
3#![allow(rustc::usage_of_ty_tykind)]
4
5pub mod tls;
6
7use std::assert_matches::debug_assert_matches;
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::{PhantomData, PointeeSized};
14use std::ops::{Bound, Deref};
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::fingerprint::Fingerprint;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::jobserver::Proxy;
25use rustc_data_structures::profiling::SelfProfilerRef;
26use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
27use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
28use rustc_data_structures::steal::Steal;
29use rustc_data_structures::sync::{
30    self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
31};
32use rustc_errors::{
33    Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, LintEmitter, MultiSpan,
34};
35use rustc_hir::attrs::AttributeKind;
36use rustc_hir::def::{CtorKind, CtorOf, DefKind};
37use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
38use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
39use rustc_hir::intravisit::VisitorExt;
40use rustc_hir::lang_items::LangItem;
41use rustc_hir::limit::Limit;
42use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate, find_attr};
43use rustc_index::IndexVec;
44use rustc_macros::{HashStable, TyDecodable, TyEncodable};
45use rustc_query_system::cache::WithDepNode;
46use rustc_query_system::dep_graph::DepNodeIndex;
47use rustc_query_system::ich::StableHashingContext;
48use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
49use rustc_session::Session;
50use rustc_session::config::CrateType;
51use rustc_session::cstore::{CrateStoreDyn, Untracked};
52use rustc_session::lint::Lint;
53use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
54use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
55use rustc_type_ir::TyKind::*;
56use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem};
57pub use rustc_type_ir::lift::Lift;
58use rustc_type_ir::{
59    CollectAndApply, Interner, TypeFlags, TypeFoldable, WithCachedTypeInfo, elaborate, search_graph,
60};
61use tracing::{debug, instrument};
62
63use crate::arena::Arena;
64use crate::dep_graph::{DepGraph, DepKindStruct};
65use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind, CanonicalVarKinds};
66use crate::lint::lint_level;
67use crate::metadata::ModChild;
68use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
69use crate::middle::resolve_bound_vars;
70use crate::mir::interpret::{self, Allocation, ConstAllocation};
71use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
72use crate::query::plumbing::QuerySystem;
73use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
74use crate::thir::Thir;
75use crate::traits;
76use crate::traits::solve::{
77    self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, PredefinedOpaques,
78    QueryResult, inspect,
79};
80use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
81use crate::ty::{
82    self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
83    GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, ParamTy,
84    Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
85    PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
86    ValTree, ValTreeKind, Visibility,
87};
88
89#[allow(rustc::usage_of_ty_tykind)]
90impl<'tcx> Interner for TyCtxt<'tcx> {
91    fn next_trait_solver_globally(self) -> bool {
92        self.next_trait_solver_globally()
93    }
94
95    type DefId = DefId;
96    type LocalDefId = LocalDefId;
97    type TraitId = DefId;
98    type ForeignId = DefId;
99    type FunctionId = DefId;
100    type ClosureId = DefId;
101    type CoroutineClosureId = DefId;
102    type CoroutineId = DefId;
103    type AdtId = DefId;
104    type ImplId = DefId;
105    type Span = Span;
106
107    type GenericArgs = ty::GenericArgsRef<'tcx>;
108
109    type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
110    type GenericArg = ty::GenericArg<'tcx>;
111    type Term = ty::Term<'tcx>;
112    type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
113
114    type BoundVarKind = ty::BoundVariableKind;
115    type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
116
117    fn mk_predefined_opaques_in_body(
118        self,
119        data: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)],
120    ) -> Self::PredefinedOpaques {
121        self.mk_predefined_opaques_in_body(data)
122    }
123    type LocalDefIds = &'tcx ty::List<LocalDefId>;
124    type CanonicalVarKinds = CanonicalVarKinds<'tcx>;
125    fn mk_canonical_var_kinds(
126        self,
127        kinds: &[ty::CanonicalVarKind<Self>],
128    ) -> Self::CanonicalVarKinds {
129        self.mk_canonical_var_kinds(kinds)
130    }
131
132    type ExternalConstraints = ExternalConstraints<'tcx>;
133    fn mk_external_constraints(
134        self,
135        data: ExternalConstraintsData<Self>,
136    ) -> ExternalConstraints<'tcx> {
137        self.mk_external_constraints(data)
138    }
139    type DepNodeIndex = DepNodeIndex;
140    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
141        self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
142    }
143    type Ty = Ty<'tcx>;
144    type Tys = &'tcx List<Ty<'tcx>>;
145
146    type FnInputTys = &'tcx [Ty<'tcx>];
147    type ParamTy = ParamTy;
148    type BoundTy = ty::BoundTy;
149    type Symbol = Symbol;
150
151    type PlaceholderTy = ty::PlaceholderType;
152    type ErrorGuaranteed = ErrorGuaranteed;
153    type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
154
155    type AllocId = crate::mir::interpret::AllocId;
156    type Pat = Pattern<'tcx>;
157    type PatList = &'tcx List<Pattern<'tcx>>;
158    type Safety = hir::Safety;
159    type Abi = ExternAbi;
160    type Const = ty::Const<'tcx>;
161    type PlaceholderConst = ty::PlaceholderConst;
162
163    type ParamConst = ty::ParamConst;
164    type BoundConst = ty::BoundConst;
165    type ValueConst = ty::Value<'tcx>;
166    type ExprConst = ty::Expr<'tcx>;
167    type ValTree = ty::ValTree<'tcx>;
168
169    type Region = Region<'tcx>;
170    type EarlyParamRegion = ty::EarlyParamRegion;
171    type LateParamRegion = ty::LateParamRegion;
172    type BoundRegion = ty::BoundRegion;
173    type PlaceholderRegion = ty::PlaceholderRegion;
174
175    type RegionAssumptions = &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>;
176
177    type ParamEnv = ty::ParamEnv<'tcx>;
178    type Predicate = Predicate<'tcx>;
179
180    type Clause = Clause<'tcx>;
181    type Clauses = ty::Clauses<'tcx>;
182
183    type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
184    fn mk_tracked<T: fmt::Debug + Clone>(
185        self,
186        data: T,
187        dep_node: DepNodeIndex,
188    ) -> Self::Tracked<T> {
189        WithDepNode::new(dep_node, data)
190    }
191    fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
192        tracked.get(self)
193    }
194
195    fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
196        f(&mut *self.new_solver_evaluation_cache.lock())
197    }
198
199    fn canonical_param_env_cache_get_or_insert<R>(
200        self,
201        param_env: ty::ParamEnv<'tcx>,
202        f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry<Self>,
203        from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry<Self>) -> R,
204    ) -> R {
205        let mut cache = self.new_solver_canonical_param_env_cache.lock();
206        let entry = cache.entry(param_env).or_insert_with(f);
207        from_entry(entry)
208    }
209
210    fn assert_evaluation_is_concurrent(&self) {
211        // Turns out, the assumption for this function isn't perfect.
212        // See trait-system-refactor-initiative#234.
213    }
214
215    fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
216        self.expand_abstract_consts(t)
217    }
218
219    type GenericsOf = &'tcx ty::Generics;
220
221    fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
222        self.generics_of(def_id)
223    }
224
225    type VariancesOf = &'tcx [ty::Variance];
226
227    fn variances_of(self, def_id: DefId) -> Self::VariancesOf {
228        self.variances_of(def_id)
229    }
230
231    fn opt_alias_variances(
232        self,
233        kind: impl Into<ty::AliasTermKind>,
234        def_id: DefId,
235    ) -> Option<&'tcx [ty::Variance]> {
236        self.opt_alias_variances(kind, def_id)
237    }
238
239    fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
240        self.type_of(def_id)
241    }
242    fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
243        self.type_of_opaque_hir_typeck(def_id)
244    }
245
246    type AdtDef = ty::AdtDef<'tcx>;
247    fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
248        self.adt_def(adt_def_id)
249    }
250
251    fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
252        match self.def_kind(alias.def_id) {
253            DefKind::AssocTy => {
254                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
255                {
256                    ty::Inherent
257                } else {
258                    ty::Projection
259                }
260            }
261            DefKind::OpaqueTy => ty::Opaque,
262            DefKind::TyAlias => ty::Free,
263            kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
264        }
265    }
266
267    fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind {
268        match self.def_kind(alias.def_id) {
269            DefKind::AssocTy => {
270                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
271                {
272                    ty::AliasTermKind::InherentTy
273                } else {
274                    ty::AliasTermKind::ProjectionTy
275                }
276            }
277            DefKind::AssocConst => {
278                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
279                {
280                    ty::AliasTermKind::InherentConst
281                } else {
282                    ty::AliasTermKind::ProjectionConst
283                }
284            }
285            DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
286            DefKind::TyAlias => ty::AliasTermKind::FreeTy,
287            DefKind::Const => ty::AliasTermKind::FreeConst,
288            DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
289                ty::AliasTermKind::UnevaluatedConst
290            }
291            kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
292        }
293    }
294
295    fn trait_ref_and_own_args_for_alias(
296        self,
297        def_id: DefId,
298        args: ty::GenericArgsRef<'tcx>,
299    ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
300        debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
301        let trait_def_id = self.parent(def_id);
302        debug_assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
303        let trait_ref = ty::TraitRef::from_assoc(self, trait_def_id, args);
304        (trait_ref, &args[trait_ref.args.len()..])
305    }
306
307    fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
308        self.mk_args(args)
309    }
310
311    fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
312    where
313        I: Iterator<Item = T>,
314        T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
315    {
316        self.mk_args_from_iter(args)
317    }
318
319    fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
320        self.check_args_compatible(def_id, args)
321    }
322
323    fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
324        self.debug_assert_args_compatible(def_id, args);
325    }
326
327    /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
328    /// are compatible with the `DefId`. Since we're missing a `Self` type, stick on
329    /// a dummy self type and forward to `debug_assert_args_compatible`.
330    fn debug_assert_existential_args_compatible(
331        self,
332        def_id: Self::DefId,
333        args: Self::GenericArgs,
334    ) {
335        // FIXME: We could perhaps add a `skip: usize` to `debug_assert_args_compatible`
336        // to avoid needing to reintern the set of args...
337        if cfg!(debug_assertions) {
338            self.debug_assert_args_compatible(
339                def_id,
340                self.mk_args_from_iter(
341                    [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
342                ),
343            );
344        }
345    }
346
347    fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
348    where
349        I: Iterator<Item = T>,
350        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
351    {
352        self.mk_type_list_from_iter(args)
353    }
354
355    fn parent(self, def_id: DefId) -> DefId {
356        self.parent(def_id)
357    }
358
359    fn recursion_limit(self) -> usize {
360        self.recursion_limit().0
361    }
362
363    type Features = &'tcx rustc_feature::Features;
364
365    fn features(self) -> Self::Features {
366        self.features()
367    }
368
369    fn coroutine_hidden_types(
370        self,
371        def_id: DefId,
372    ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> {
373        self.coroutine_hidden_types(def_id)
374    }
375
376    fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
377        self.fn_sig(def_id)
378    }
379
380    fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
381        self.coroutine_movability(def_id)
382    }
383
384    fn coroutine_for_closure(self, def_id: DefId) -> DefId {
385        self.coroutine_for_closure(def_id)
386    }
387
388    fn generics_require_sized_self(self, def_id: DefId) -> bool {
389        self.generics_require_sized_self(def_id)
390    }
391
392    fn item_bounds(
393        self,
394        def_id: DefId,
395    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
396        self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
397    }
398
399    fn item_self_bounds(
400        self,
401        def_id: DefId,
402    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
403        self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
404    }
405
406    fn item_non_self_bounds(
407        self,
408        def_id: DefId,
409    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
410        self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
411    }
412
413    fn predicates_of(
414        self,
415        def_id: DefId,
416    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
417        ty::EarlyBinder::bind(
418            self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
419        )
420    }
421
422    fn own_predicates_of(
423        self,
424        def_id: DefId,
425    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
426        ty::EarlyBinder::bind(
427            self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
428        )
429    }
430
431    fn explicit_super_predicates_of(
432        self,
433        def_id: DefId,
434    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
435        self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
436    }
437
438    fn explicit_implied_predicates_of(
439        self,
440        def_id: DefId,
441    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
442        self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
443    }
444
445    fn impl_super_outlives(
446        self,
447        impl_def_id: DefId,
448    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
449        self.impl_super_outlives(impl_def_id)
450    }
451
452    fn impl_is_const(self, def_id: DefId) -> bool {
453        debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
454        self.is_conditionally_const(def_id)
455    }
456
457    fn fn_is_const(self, def_id: DefId) -> bool {
458        debug_assert_matches!(
459            self.def_kind(def_id),
460            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
461        );
462        self.is_conditionally_const(def_id)
463    }
464
465    fn alias_has_const_conditions(self, def_id: DefId) -> bool {
466        debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
467        self.is_conditionally_const(def_id)
468    }
469
470    fn const_conditions(
471        self,
472        def_id: DefId,
473    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
474        ty::EarlyBinder::bind(
475            self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
476        )
477    }
478
479    fn explicit_implied_const_bounds(
480        self,
481        def_id: DefId,
482    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
483        ty::EarlyBinder::bind(
484            self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
485        )
486    }
487
488    fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
489        self.impl_self_is_guaranteed_unsized(impl_def_id)
490    }
491
492    fn has_target_features(self, def_id: DefId) -> bool {
493        !self.codegen_fn_attrs(def_id).target_features.is_empty()
494    }
495
496    fn require_lang_item(self, lang_item: SolverLangItem) -> DefId {
497        self.require_lang_item(solver_lang_item_to_lang_item(lang_item), DUMMY_SP)
498    }
499
500    fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> DefId {
501        self.require_lang_item(solver_trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
502    }
503
504    fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> DefId {
505        self.require_lang_item(solver_adt_lang_item_to_lang_item(lang_item), DUMMY_SP)
506    }
507
508    fn is_lang_item(self, def_id: DefId, lang_item: SolverLangItem) -> bool {
509        self.is_lang_item(def_id, solver_lang_item_to_lang_item(lang_item))
510    }
511
512    fn is_trait_lang_item(self, def_id: DefId, lang_item: SolverTraitLangItem) -> bool {
513        self.is_lang_item(def_id, solver_trait_lang_item_to_lang_item(lang_item))
514    }
515
516    fn is_adt_lang_item(self, def_id: DefId, lang_item: SolverAdtLangItem) -> bool {
517        self.is_lang_item(def_id, solver_adt_lang_item_to_lang_item(lang_item))
518    }
519
520    fn is_default_trait(self, def_id: DefId) -> bool {
521        self.is_default_trait(def_id)
522    }
523
524    fn as_lang_item(self, def_id: DefId) -> Option<SolverLangItem> {
525        lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?)
526    }
527
528    fn as_trait_lang_item(self, def_id: DefId) -> Option<SolverTraitLangItem> {
529        lang_item_to_solver_trait_lang_item(self.lang_items().from_def_id(def_id)?)
530    }
531
532    fn as_adt_lang_item(self, def_id: DefId) -> Option<SolverAdtLangItem> {
533        lang_item_to_solver_adt_lang_item(self.lang_items().from_def_id(def_id)?)
534    }
535
536    fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
537        self.associated_items(def_id)
538            .in_definition_order()
539            .filter(|assoc_item| assoc_item.is_type())
540            .map(|assoc_item| assoc_item.def_id)
541    }
542
543    // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`,
544    // since we want to skip over blanket impls for non-rigid aliases, and also we
545    // only want to consider types that *actually* unify with float/int vars.
546    fn for_each_relevant_impl(
547        self,
548        trait_def_id: DefId,
549        self_ty: Ty<'tcx>,
550        mut f: impl FnMut(DefId),
551    ) {
552        let tcx = self;
553        let trait_impls = tcx.trait_impls_of(trait_def_id);
554        let mut consider_impls_for_simplified_type = |simp| {
555            if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
556                for &impl_def_id in impls_for_type {
557                    f(impl_def_id);
558                }
559            }
560        };
561
562        match self_ty.kind() {
563            ty::Bool
564            | ty::Char
565            | ty::Int(_)
566            | ty::Uint(_)
567            | ty::Float(_)
568            | ty::Adt(_, _)
569            | ty::Foreign(_)
570            | ty::Str
571            | ty::Array(_, _)
572            | ty::Pat(_, _)
573            | ty::Slice(_)
574            | ty::RawPtr(_, _)
575            | ty::Ref(_, _, _)
576            | ty::FnDef(_, _)
577            | ty::FnPtr(..)
578            | ty::Dynamic(_, _)
579            | ty::Closure(..)
580            | ty::CoroutineClosure(..)
581            | ty::Coroutine(_, _)
582            | ty::Never
583            | ty::Tuple(_)
584            | ty::UnsafeBinder(_) => {
585                let simp = ty::fast_reject::simplify_type(
586                    tcx,
587                    self_ty,
588                    ty::fast_reject::TreatParams::AsRigid,
589                )
590                .unwrap();
591                consider_impls_for_simplified_type(simp);
592            }
593
594            // HACK: For integer and float variables we have to manually look at all impls
595            // which have some integer or float as a self type.
596            ty::Infer(ty::IntVar(_)) => {
597                use ty::IntTy::*;
598                use ty::UintTy::*;
599                // This causes a compiler error if any new integer kinds are added.
600                let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
601                let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
602                let possible_integers = [
603                    // signed integers
604                    ty::SimplifiedType::Int(I8),
605                    ty::SimplifiedType::Int(I16),
606                    ty::SimplifiedType::Int(I32),
607                    ty::SimplifiedType::Int(I64),
608                    ty::SimplifiedType::Int(I128),
609                    ty::SimplifiedType::Int(Isize),
610                    // unsigned integers
611                    ty::SimplifiedType::Uint(U8),
612                    ty::SimplifiedType::Uint(U16),
613                    ty::SimplifiedType::Uint(U32),
614                    ty::SimplifiedType::Uint(U64),
615                    ty::SimplifiedType::Uint(U128),
616                    ty::SimplifiedType::Uint(Usize),
617                ];
618                for simp in possible_integers {
619                    consider_impls_for_simplified_type(simp);
620                }
621            }
622
623            ty::Infer(ty::FloatVar(_)) => {
624                // This causes a compiler error if any new float kinds are added.
625                let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
626                let possible_floats = [
627                    ty::SimplifiedType::Float(ty::FloatTy::F16),
628                    ty::SimplifiedType::Float(ty::FloatTy::F32),
629                    ty::SimplifiedType::Float(ty::FloatTy::F64),
630                    ty::SimplifiedType::Float(ty::FloatTy::F128),
631                ];
632
633                for simp in possible_floats {
634                    consider_impls_for_simplified_type(simp);
635                }
636            }
637
638            // The only traits applying to aliases and placeholders are blanket impls.
639            //
640            // Impls which apply to an alias after normalization are handled by
641            // `assemble_candidates_after_normalizing_self_ty`.
642            ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
643
644            // FIXME: These should ideally not exist as a self type. It would be nice for
645            // the builtin auto trait impls of coroutines to instead directly recurse
646            // into the witness.
647            ty::CoroutineWitness(..) => (),
648
649            // These variants should not exist as a self type.
650            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
651            | ty::Param(_)
652            | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
653        }
654
655        #[allow(rustc::usage_of_type_ir_traits)]
656        self.for_each_blanket_impl(trait_def_id, f)
657    }
658    fn for_each_blanket_impl(self, trait_def_id: DefId, mut f: impl FnMut(DefId)) {
659        let trait_impls = self.trait_impls_of(trait_def_id);
660        for &impl_def_id in trait_impls.blanket_impls() {
661            f(impl_def_id);
662        }
663    }
664
665    fn has_item_definition(self, def_id: DefId) -> bool {
666        self.defaultness(def_id).has_value()
667    }
668
669    fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
670        self.specializes((impl_def_id, victim_def_id))
671    }
672
673    fn impl_is_default(self, impl_def_id: DefId) -> bool {
674        self.defaultness(impl_def_id).is_default()
675    }
676
677    fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
678        self.impl_trait_ref(impl_def_id).unwrap()
679    }
680
681    fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
682        self.impl_polarity(impl_def_id)
683    }
684
685    fn trait_is_auto(self, trait_def_id: DefId) -> bool {
686        self.trait_is_auto(trait_def_id)
687    }
688
689    fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
690        self.trait_is_coinductive(trait_def_id)
691    }
692
693    fn trait_is_alias(self, trait_def_id: DefId) -> bool {
694        self.trait_is_alias(trait_def_id)
695    }
696
697    fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
698        self.is_dyn_compatible(trait_def_id)
699    }
700
701    fn trait_is_fundamental(self, def_id: DefId) -> bool {
702        self.trait_def(def_id).is_fundamental
703    }
704
705    fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
706        self.trait_def(trait_def_id).implement_via_object
707    }
708
709    fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
710        self.trait_def(trait_def_id).safety.is_unsafe()
711    }
712
713    fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
714        self.is_impl_trait_in_trait(def_id)
715    }
716
717    fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
718        self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
719    }
720
721    fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
722        self.is_general_coroutine(coroutine_def_id)
723    }
724
725    fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
726        self.coroutine_is_async(coroutine_def_id)
727    }
728
729    fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
730        self.coroutine_is_gen(coroutine_def_id)
731    }
732
733    fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
734        self.coroutine_is_async_gen(coroutine_def_id)
735    }
736
737    type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
738    fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
739        self.unsizing_params_for_adt(adt_def_id)
740    }
741
742    fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
743        self,
744        binder: ty::Binder<'tcx, T>,
745    ) -> ty::Binder<'tcx, T> {
746        self.anonymize_bound_vars(binder)
747    }
748
749    fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
750        self.opaque_types_defined_by(defining_anchor)
751    }
752
753    fn opaque_types_and_coroutines_defined_by(
754        self,
755        defining_anchor: Self::LocalDefId,
756    ) -> Self::LocalDefIds {
757        let coroutines_defined_by = self
758            .nested_bodies_within(defining_anchor)
759            .iter()
760            .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
761        self.mk_local_def_ids_from_iter(
762            self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
763        )
764    }
765
766    type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
767    fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
768        self.arena.alloc(probe)
769    }
770    fn evaluate_root_goal_for_proof_tree_raw(
771        self,
772        canonical_goal: CanonicalInput<'tcx>,
773    ) -> (QueryResult<'tcx>, &'tcx inspect::Probe<TyCtxt<'tcx>>) {
774        self.evaluate_root_goal_for_proof_tree_raw(canonical_goal)
775    }
776}
777
778macro_rules! bidirectional_lang_item_map {
779    (
780        $solver_ty:ident, $to_solver:ident, $from_solver:ident;
781        $($name:ident),+ $(,)?
782    ) => {
783        fn $from_solver(lang_item: $solver_ty) -> LangItem {
784            match lang_item {
785                $($solver_ty::$name => LangItem::$name,)+
786            }
787        }
788
789        fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> {
790            Some(match lang_item {
791                $(LangItem::$name => $solver_ty::$name,)+
792                _ => return None,
793            })
794        }
795    }
796}
797
798bidirectional_lang_item_map! {
799    SolverLangItem, lang_item_to_solver_lang_item, solver_lang_item_to_lang_item;
800
801// tidy-alphabetical-start
802    AsyncFnKindUpvars,
803    AsyncFnOnceOutput,
804    CallOnceFuture,
805    CallRefFuture,
806    CoroutineReturn,
807    CoroutineYield,
808    DynMetadata,
809    FutureOutput,
810    Metadata,
811// tidy-alphabetical-end
812}
813
814bidirectional_lang_item_map! {
815    SolverAdtLangItem, lang_item_to_solver_adt_lang_item, solver_adt_lang_item_to_lang_item;
816
817// tidy-alphabetical-start
818    Option,
819    Poll,
820// tidy-alphabetical-end
821}
822
823bidirectional_lang_item_map! {
824    SolverTraitLangItem, lang_item_to_solver_trait_lang_item, solver_trait_lang_item_to_lang_item;
825
826// tidy-alphabetical-start
827    AsyncFn,
828    AsyncFnKindHelper,
829    AsyncFnMut,
830    AsyncFnOnce,
831    AsyncFnOnceOutput,
832    AsyncIterator,
833    BikeshedGuaranteedNoDrop,
834    Clone,
835    Copy,
836    Coroutine,
837    Destruct,
838    DiscriminantKind,
839    Drop,
840    Fn,
841    FnMut,
842    FnOnce,
843    FnPtrTrait,
844    FusedIterator,
845    Future,
846    Iterator,
847    MetaSized,
848    PointeeSized,
849    PointeeTrait,
850    Sized,
851    TransmuteTrait,
852    Tuple,
853    Unpin,
854    Unsize,
855// tidy-alphabetical-end
856}
857
858impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
859    fn is_local(self) -> bool {
860        self.is_local()
861    }
862
863    fn as_local(self) -> Option<LocalDefId> {
864        self.as_local()
865    }
866}
867
868impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
869    fn rust() -> Self {
870        ExternAbi::Rust
871    }
872
873    fn is_rust(self) -> bool {
874        matches!(self, ExternAbi::Rust)
875    }
876}
877
878impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
879    fn safe() -> Self {
880        hir::Safety::Safe
881    }
882
883    fn is_safe(self) -> bool {
884        self.is_safe()
885    }
886
887    fn prefix_str(self) -> &'static str {
888        self.prefix_str()
889    }
890}
891
892impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
893    fn generic_const_exprs(self) -> bool {
894        self.generic_const_exprs()
895    }
896
897    fn coroutine_clone(self) -> bool {
898        self.coroutine_clone()
899    }
900
901    fn associated_const_equality(self) -> bool {
902        self.associated_const_equality()
903    }
904
905    fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
906        // We don't consider feature bounds to hold in the crate when `staged_api` feature is
907        // enabled, even if it is enabled through `#[feature]`.
908        // This is to prevent accidentally leaking unstable APIs to stable.
909        !self.staged_api() && self.enabled(symbol)
910    }
911}
912
913impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
914    fn dummy() -> Self {
915        DUMMY_SP
916    }
917}
918
919type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
920
921pub struct CtxtInterners<'tcx> {
922    /// The arena that types, regions, etc. are allocated from.
923    arena: &'tcx WorkerLocal<Arena<'tcx>>,
924
925    // Specifically use a speedy hash algorithm for these hash sets, since
926    // they're accessed quite often.
927    type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
928    const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
929    args: InternedSet<'tcx, GenericArgs<'tcx>>,
930    type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
931    canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
932    region: InternedSet<'tcx, RegionKind<'tcx>>,
933    poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
934    predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
935    clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
936    projs: InternedSet<'tcx, List<ProjectionKind>>,
937    place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
938    const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
939    pat: InternedSet<'tcx, PatternKind<'tcx>>,
940    const_allocation: InternedSet<'tcx, Allocation>,
941    bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
942    layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
943    adt_def: InternedSet<'tcx, AdtDefData>,
944    external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
945    predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
946    fields: InternedSet<'tcx, List<FieldIdx>>,
947    local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
948    captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
949    offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
950    valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
951    patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
952    outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
953}
954
955impl<'tcx> CtxtInterners<'tcx> {
956    fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
957        // Default interner size - this value has been chosen empirically, and may need to be adjusted
958        // as the compiler evolves.
959        const N: usize = 2048;
960        CtxtInterners {
961            arena,
962            // The factors have been chosen by @FractalFir based on observed interner sizes, and local perf runs.
963            // To get the interner sizes, insert `eprintln` printing the size of the interner in functions like `intern_ty`.
964            // Bigger benchmarks tend to give more accurate ratios, so use something like `x perf eprintln --includes cargo`.
965            type_: InternedSet::with_capacity(N * 16),
966            const_lists: InternedSet::with_capacity(N * 4),
967            args: InternedSet::with_capacity(N * 4),
968            type_lists: InternedSet::with_capacity(N * 4),
969            region: InternedSet::with_capacity(N * 4),
970            poly_existential_predicates: InternedSet::with_capacity(N / 4),
971            canonical_var_kinds: InternedSet::with_capacity(N / 2),
972            predicate: InternedSet::with_capacity(N),
973            clauses: InternedSet::with_capacity(N),
974            projs: InternedSet::with_capacity(N * 4),
975            place_elems: InternedSet::with_capacity(N * 2),
976            const_: InternedSet::with_capacity(N * 2),
977            pat: InternedSet::with_capacity(N),
978            const_allocation: InternedSet::with_capacity(N),
979            bound_variable_kinds: InternedSet::with_capacity(N * 2),
980            layout: InternedSet::with_capacity(N),
981            adt_def: InternedSet::with_capacity(N),
982            external_constraints: InternedSet::with_capacity(N),
983            predefined_opaques_in_body: InternedSet::with_capacity(N),
984            fields: InternedSet::with_capacity(N * 4),
985            local_def_ids: InternedSet::with_capacity(N),
986            captures: InternedSet::with_capacity(N),
987            offset_of: InternedSet::with_capacity(N),
988            valtree: InternedSet::with_capacity(N),
989            patterns: InternedSet::with_capacity(N),
990            outlives: InternedSet::with_capacity(N),
991        }
992    }
993
994    /// Interns a type. (Use `mk_*` functions instead, where possible.)
995    #[allow(rustc::usage_of_ty_tykind)]
996    #[inline(never)]
997    fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
998        Ty(Interned::new_unchecked(
999            self.type_
1000                .intern(kind, |kind| {
1001                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
1002                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1003
1004                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1005                        internee: kind,
1006                        stable_hash,
1007                        flags: flags.flags,
1008                        outer_exclusive_binder: flags.outer_exclusive_binder,
1009                    }))
1010                })
1011                .0,
1012        ))
1013    }
1014
1015    /// Interns a const. (Use `mk_*` functions instead, where possible.)
1016    #[allow(rustc::usage_of_ty_tykind)]
1017    #[inline(never)]
1018    fn intern_const(
1019        &self,
1020        kind: ty::ConstKind<'tcx>,
1021        sess: &Session,
1022        untracked: &Untracked,
1023    ) -> Const<'tcx> {
1024        Const(Interned::new_unchecked(
1025            self.const_
1026                .intern(kind, |kind: ty::ConstKind<'_>| {
1027                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
1028                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1029
1030                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1031                        internee: kind,
1032                        stable_hash,
1033                        flags: flags.flags,
1034                        outer_exclusive_binder: flags.outer_exclusive_binder,
1035                    }))
1036                })
1037                .0,
1038        ))
1039    }
1040
1041    fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
1042        &self,
1043        flags: &ty::FlagComputation<TyCtxt<'tcx>>,
1044        sess: &'a Session,
1045        untracked: &'a Untracked,
1046        val: &T,
1047    ) -> Fingerprint {
1048        // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them.
1049        // Without incremental, we rarely stable-hash types, so let's not do it proactively.
1050        if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
1051            Fingerprint::ZERO
1052        } else {
1053            let mut hasher = StableHasher::new();
1054            let mut hcx = StableHashingContext::new(sess, untracked);
1055            val.hash_stable(&mut hcx, &mut hasher);
1056            hasher.finish()
1057        }
1058    }
1059
1060    /// Interns a predicate. (Use `mk_predicate` instead, where possible.)
1061    #[inline(never)]
1062    fn intern_predicate(
1063        &self,
1064        kind: Binder<'tcx, PredicateKind<'tcx>>,
1065        sess: &Session,
1066        untracked: &Untracked,
1067    ) -> Predicate<'tcx> {
1068        Predicate(Interned::new_unchecked(
1069            self.predicate
1070                .intern(kind, |kind| {
1071                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
1072
1073                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1074
1075                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1076                        internee: kind,
1077                        stable_hash,
1078                        flags: flags.flags,
1079                        outer_exclusive_binder: flags.outer_exclusive_binder,
1080                    }))
1081                })
1082                .0,
1083        ))
1084    }
1085
1086    fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
1087        if clauses.is_empty() {
1088            ListWithCachedTypeInfo::empty()
1089        } else {
1090            self.clauses
1091                .intern_ref(clauses, || {
1092                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
1093
1094                    InternedInSet(ListWithCachedTypeInfo::from_arena(
1095                        &*self.arena,
1096                        flags.into(),
1097                        clauses,
1098                    ))
1099                })
1100                .0
1101        }
1102    }
1103}
1104
1105// For these preinterned values, an alternative would be to have
1106// variable-length vectors that grow as needed. But that turned out to be
1107// slightly more complex and no faster.
1108
1109const NUM_PREINTERNED_TY_VARS: u32 = 100;
1110const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
1111const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
1112const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
1113const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
1114
1115// From general profiling of the *max vars during canonicalization* of a value:
1116// - about 90% of the time, there are no canonical vars
1117// - about 9% of the time, there is only one canonical var
1118// - there are rarely more than 3-5 canonical vars (with exceptions in particularly pathological cases)
1119// This may not match the number of bound vars found in `for`s.
1120// Given that this is all heap interned, it seems likely that interning fewer
1121// vars here won't make an appreciable difference. Though, if we were to inline the data (in an array),
1122// we may want to consider reducing the number for canonicalized vars down to 4 or so.
1123const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
1124
1125// This number may seem high, but it is reached in all but the smallest crates.
1126const NUM_PREINTERNED_RE_VARS: u32 = 500;
1127const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
1128const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
1129
1130pub struct CommonTypes<'tcx> {
1131    pub unit: Ty<'tcx>,
1132    pub bool: Ty<'tcx>,
1133    pub char: Ty<'tcx>,
1134    pub isize: Ty<'tcx>,
1135    pub i8: Ty<'tcx>,
1136    pub i16: Ty<'tcx>,
1137    pub i32: Ty<'tcx>,
1138    pub i64: Ty<'tcx>,
1139    pub i128: Ty<'tcx>,
1140    pub usize: Ty<'tcx>,
1141    pub u8: Ty<'tcx>,
1142    pub u16: Ty<'tcx>,
1143    pub u32: Ty<'tcx>,
1144    pub u64: Ty<'tcx>,
1145    pub u128: Ty<'tcx>,
1146    pub f16: Ty<'tcx>,
1147    pub f32: Ty<'tcx>,
1148    pub f64: Ty<'tcx>,
1149    pub f128: Ty<'tcx>,
1150    pub str_: Ty<'tcx>,
1151    pub never: Ty<'tcx>,
1152    pub self_param: Ty<'tcx>,
1153
1154    /// Dummy type used for the `Self` of a `TraitRef` created for converting
1155    /// a trait object, and which gets removed in `ExistentialTraitRef`.
1156    /// This type must not appear anywhere in other converted types.
1157    /// `Infer(ty::FreshTy(0))` does the job.
1158    pub trait_object_dummy_self: Ty<'tcx>,
1159
1160    /// Pre-interned `Infer(ty::TyVar(n))` for small values of `n`.
1161    pub ty_vars: Vec<Ty<'tcx>>,
1162
1163    /// Pre-interned `Infer(ty::FreshTy(n))` for small values of `n`.
1164    pub fresh_tys: Vec<Ty<'tcx>>,
1165
1166    /// Pre-interned `Infer(ty::FreshIntTy(n))` for small values of `n`.
1167    pub fresh_int_tys: Vec<Ty<'tcx>>,
1168
1169    /// Pre-interned `Infer(ty::FreshFloatTy(n))` for small values of `n`.
1170    pub fresh_float_tys: Vec<Ty<'tcx>>,
1171
1172    /// Pre-interned values of the form:
1173    /// `Bound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundTy { var: v, kind: BoundTyKind::Anon})`
1174    /// for small values of `i` and `v`.
1175    pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
1176
1177    // Pre-interned values of the form:
1178    // `Bound(BoundVarIndexKind::Canonical, BoundTy { var: v, kind: BoundTyKind::Anon })`
1179    // for small values of `v`.
1180    pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
1181}
1182
1183pub struct CommonLifetimes<'tcx> {
1184    /// `ReStatic`
1185    pub re_static: Region<'tcx>,
1186
1187    /// Erased region, used outside of type inference.
1188    pub re_erased: Region<'tcx>,
1189
1190    /// Pre-interned `ReVar(ty::RegionVar(n))` for small values of `n`.
1191    pub re_vars: Vec<Region<'tcx>>,
1192
1193    /// Pre-interned values of the form:
1194    /// `ReBound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundRegion { var: v, kind: BoundRegionKind::Anon })`
1195    /// for small values of `i` and `v`.
1196    pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
1197
1198    // Pre-interned values of the form:
1199    // `ReBound(BoundVarIndexKind::Canonical, BoundRegion { var: v, kind: BoundRegionKind::Anon })`
1200    // for small values of `v`.
1201    pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
1202}
1203
1204pub struct CommonConsts<'tcx> {
1205    pub unit: Const<'tcx>,
1206    pub true_: Const<'tcx>,
1207    pub false_: Const<'tcx>,
1208    /// Use [`ty::ValTree::zst`] instead.
1209    pub(crate) valtree_zst: ValTree<'tcx>,
1210}
1211
1212impl<'tcx> CommonTypes<'tcx> {
1213    fn new(
1214        interners: &CtxtInterners<'tcx>,
1215        sess: &Session,
1216        untracked: &Untracked,
1217    ) -> CommonTypes<'tcx> {
1218        let mk = |ty| interners.intern_ty(ty, sess, untracked);
1219
1220        let ty_vars =
1221            (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1222        let fresh_tys: Vec<_> =
1223            (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1224        let fresh_int_tys: Vec<_> =
1225            (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1226        let fresh_float_tys: Vec<_> =
1227            (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1228
1229        let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
1230            .map(|i| {
1231                (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
1232                    .map(|v| {
1233                        mk(ty::Bound(
1234                            ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
1235                            ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
1236                        ))
1237                    })
1238                    .collect()
1239            })
1240            .collect();
1241
1242        let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
1243            .map(|v| {
1244                mk(ty::Bound(
1245                    ty::BoundVarIndexKind::Canonical,
1246                    ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
1247                ))
1248            })
1249            .collect();
1250
1251        CommonTypes {
1252            unit: mk(Tuple(List::empty())),
1253            bool: mk(Bool),
1254            char: mk(Char),
1255            never: mk(Never),
1256            isize: mk(Int(ty::IntTy::Isize)),
1257            i8: mk(Int(ty::IntTy::I8)),
1258            i16: mk(Int(ty::IntTy::I16)),
1259            i32: mk(Int(ty::IntTy::I32)),
1260            i64: mk(Int(ty::IntTy::I64)),
1261            i128: mk(Int(ty::IntTy::I128)),
1262            usize: mk(Uint(ty::UintTy::Usize)),
1263            u8: mk(Uint(ty::UintTy::U8)),
1264            u16: mk(Uint(ty::UintTy::U16)),
1265            u32: mk(Uint(ty::UintTy::U32)),
1266            u64: mk(Uint(ty::UintTy::U64)),
1267            u128: mk(Uint(ty::UintTy::U128)),
1268            f16: mk(Float(ty::FloatTy::F16)),
1269            f32: mk(Float(ty::FloatTy::F32)),
1270            f64: mk(Float(ty::FloatTy::F64)),
1271            f128: mk(Float(ty::FloatTy::F128)),
1272            str_: mk(Str),
1273            self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1274
1275            trait_object_dummy_self: fresh_tys[0],
1276
1277            ty_vars,
1278            fresh_tys,
1279            fresh_int_tys,
1280            fresh_float_tys,
1281            anon_bound_tys,
1282            anon_canonical_bound_tys,
1283        }
1284    }
1285}
1286
1287impl<'tcx> CommonLifetimes<'tcx> {
1288    fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1289        let mk = |r| {
1290            Region(Interned::new_unchecked(
1291                interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1292            ))
1293        };
1294
1295        let re_vars =
1296            (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1297
1298        let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
1299            .map(|i| {
1300                (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
1301                    .map(|v| {
1302                        mk(ty::ReBound(
1303                            ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
1304                            ty::BoundRegion {
1305                                var: ty::BoundVar::from(v),
1306                                kind: ty::BoundRegionKind::Anon,
1307                            },
1308                        ))
1309                    })
1310                    .collect()
1311            })
1312            .collect();
1313
1314        let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
1315            .map(|v| {
1316                mk(ty::ReBound(
1317                    ty::BoundVarIndexKind::Canonical,
1318                    ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
1319                ))
1320            })
1321            .collect();
1322
1323        CommonLifetimes {
1324            re_static: mk(ty::ReStatic),
1325            re_erased: mk(ty::ReErased),
1326            re_vars,
1327            anon_re_bounds,
1328            anon_re_canonical_bounds,
1329        }
1330    }
1331}
1332
1333impl<'tcx> CommonConsts<'tcx> {
1334    fn new(
1335        interners: &CtxtInterners<'tcx>,
1336        types: &CommonTypes<'tcx>,
1337        sess: &Session,
1338        untracked: &Untracked,
1339    ) -> CommonConsts<'tcx> {
1340        let mk_const = |c| {
1341            interners.intern_const(
1342                c, sess, // This is only used to create a stable hashing context.
1343                untracked,
1344            )
1345        };
1346
1347        let mk_valtree = |v| {
1348            ty::ValTree(Interned::new_unchecked(
1349                interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1350            ))
1351        };
1352
1353        let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1354        let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1355        let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1356
1357        CommonConsts {
1358            unit: mk_const(ty::ConstKind::Value(ty::Value {
1359                ty: types.unit,
1360                valtree: valtree_zst,
1361            })),
1362            true_: mk_const(ty::ConstKind::Value(ty::Value {
1363                ty: types.bool,
1364                valtree: valtree_true,
1365            })),
1366            false_: mk_const(ty::ConstKind::Value(ty::Value {
1367                ty: types.bool,
1368                valtree: valtree_false,
1369            })),
1370            valtree_zst,
1371        }
1372    }
1373}
1374
1375/// This struct contains information regarding a free parameter region,
1376/// either a `ReEarlyParam` or `ReLateParam`.
1377#[derive(Debug)]
1378pub struct FreeRegionInfo {
1379    /// `LocalDefId` of the scope.
1380    pub scope: LocalDefId,
1381    /// the `DefId` of the free region.
1382    pub region_def_id: DefId,
1383    /// checks if bound region is in Impl Item
1384    pub is_impl_item: bool,
1385}
1386
1387/// This struct should only be created by `create_def`.
1388#[derive(Copy, Clone)]
1389pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1390    pub tcx: TyCtxt<'tcx>,
1391    // Do not allow direct access, as downstream code must not mutate this field.
1392    key: KEY,
1393}
1394
1395/// Never return a `Feed` from a query. Only queries that create a `DefId` are
1396/// allowed to feed queries for that `DefId`.
1397impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1398
1399/// The same as `TyCtxtFeed`, but does not contain a `TyCtxt`.
1400/// Use this to pass around when you have a `TyCtxt` elsewhere.
1401/// Just an optimization to save space and not store hundreds of
1402/// `TyCtxtFeed` in the resolver.
1403#[derive(Copy, Clone)]
1404pub struct Feed<'tcx, KEY: Copy> {
1405    _tcx: PhantomData<TyCtxt<'tcx>>,
1406    // Do not allow direct access, as downstream code must not mutate this field.
1407    key: KEY,
1408}
1409
1410/// Never return a `Feed` from a query. Only queries that create a `DefId` are
1411/// allowed to feed queries for that `DefId`.
1412impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1413
1414impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1415    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1416        self.key.fmt(f)
1417    }
1418}
1419
1420/// Some workarounds to use cases that cannot use `create_def`.
1421/// Do not add new ways to create `TyCtxtFeed` without consulting
1422/// with T-compiler and making an analysis about why your addition
1423/// does not cause incremental compilation issues.
1424impl<'tcx> TyCtxt<'tcx> {
1425    /// Can only be fed before queries are run, and is thus exempt from any
1426    /// incremental issues. Do not use except for the initial query feeding.
1427    pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1428        self.dep_graph.assert_ignored();
1429        TyCtxtFeed { tcx: self, key: () }
1430    }
1431
1432    /// Only used in the resolver to register the `CRATE_DEF_ID` `DefId` and feed
1433    /// some queries for it. It will panic if used twice.
1434    pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1435        let key = self.untracked().source_span.push(span);
1436        assert_eq!(key, CRATE_DEF_ID);
1437        TyCtxtFeed { tcx: self, key }
1438    }
1439
1440    /// In order to break cycles involving `AnonConst`, we need to set the expected type by side
1441    /// effect. However, we do not want this as a general capability, so this interface restricts
1442    /// to the only allowed case.
1443    pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1444        debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1445        TyCtxtFeed { tcx: self, key }.type_of(value)
1446    }
1447}
1448
1449impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1450    #[inline(always)]
1451    pub fn key(&self) -> KEY {
1452        self.key
1453    }
1454
1455    #[inline(always)]
1456    pub fn downgrade(self) -> Feed<'tcx, KEY> {
1457        Feed { _tcx: PhantomData, key: self.key }
1458    }
1459}
1460
1461impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1462    #[inline(always)]
1463    pub fn key(&self) -> KEY {
1464        self.key
1465    }
1466
1467    #[inline(always)]
1468    pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1469        TyCtxtFeed { tcx, key: self.key }
1470    }
1471}
1472
1473impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1474    #[inline(always)]
1475    pub fn def_id(&self) -> LocalDefId {
1476        self.key
1477    }
1478
1479    // Caller must ensure that `self.key` ID is indeed an owner.
1480    pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1481        TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1482    }
1483
1484    // Fills in all the important parts needed by HIR queries
1485    pub fn feed_hir(&self) {
1486        self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1487
1488        let node = hir::OwnerNode::Synthetic;
1489        let bodies = Default::default();
1490        let attrs = hir::AttributeMap::EMPTY;
1491
1492        let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
1493            self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
1494        let node = node.into();
1495        self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1496            opt_hash_including_bodies,
1497            nodes: IndexVec::from_elem_n(
1498                hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1499                1,
1500            ),
1501            bodies,
1502        })));
1503        self.feed_owner_id().hir_attr_map(attrs);
1504    }
1505}
1506
1507/// The central data structure of the compiler. It stores references
1508/// to the various **arenas** and also houses the results of the
1509/// various **compiler queries** that have been performed. See the
1510/// [rustc dev guide] for more details.
1511///
1512/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html
1513///
1514/// An implementation detail: `TyCtxt` is a wrapper type for [GlobalCtxt],
1515/// which is the struct that actually holds all the data. `TyCtxt` derefs to
1516/// `GlobalCtxt`, and in practice `TyCtxt` is passed around everywhere, and all
1517/// operations are done via `TyCtxt`. A `TyCtxt` is obtained for a `GlobalCtxt`
1518/// by calling `enter` with a closure `f`. That function creates both the
1519/// `TyCtxt`, and an `ImplicitCtxt` around it that is put into TLS. Within `f`:
1520/// - The `ImplicitCtxt` is available implicitly via TLS.
1521/// - The `TyCtxt` is available explicitly via the `tcx` parameter, and also
1522///   implicitly within the `ImplicitCtxt`. Explicit access is preferred when
1523///   possible.
1524#[derive(Copy, Clone)]
1525#[rustc_diagnostic_item = "TyCtxt"]
1526#[rustc_pass_by_value]
1527pub struct TyCtxt<'tcx> {
1528    gcx: &'tcx GlobalCtxt<'tcx>,
1529}
1530
1531impl<'tcx> LintEmitter for TyCtxt<'tcx> {
1532    type Id = HirId;
1533
1534    fn emit_node_span_lint(
1535        self,
1536        lint: &'static Lint,
1537        hir_id: HirId,
1538        span: impl Into<MultiSpan>,
1539        decorator: impl for<'a> LintDiagnostic<'a, ()>,
1540    ) {
1541        self.emit_node_span_lint(lint, hir_id, span, decorator);
1542    }
1543}
1544
1545// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. Its
1546// field are asserted to implement these traits below, so this is trivially safe, and it greatly
1547// speeds-up compilation of this crate and its dependents.
1548unsafe impl DynSend for TyCtxt<'_> {}
1549unsafe impl DynSync for TyCtxt<'_> {}
1550fn _assert_tcx_fields() {
1551    sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1552    sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1553}
1554
1555impl<'tcx> Deref for TyCtxt<'tcx> {
1556    type Target = &'tcx GlobalCtxt<'tcx>;
1557    #[inline(always)]
1558    fn deref(&self) -> &Self::Target {
1559        &self.gcx
1560    }
1561}
1562
1563/// See [TyCtxt] for details about this type.
1564pub struct GlobalCtxt<'tcx> {
1565    pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1566    pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1567
1568    interners: CtxtInterners<'tcx>,
1569
1570    pub sess: &'tcx Session,
1571    crate_types: Vec<CrateType>,
1572    /// The `stable_crate_id` is constructed out of the crate name and all the
1573    /// `-C metadata` arguments passed to the compiler. Its value forms a unique
1574    /// global identifier for the crate. It is used to allow multiple crates
1575    /// with the same name to coexist. See the
1576    /// `rustc_symbol_mangling` crate for more information.
1577    stable_crate_id: StableCrateId,
1578
1579    pub dep_graph: DepGraph,
1580
1581    pub prof: SelfProfilerRef,
1582
1583    /// Common types, pre-interned for your convenience.
1584    pub types: CommonTypes<'tcx>,
1585
1586    /// Common lifetimes, pre-interned for your convenience.
1587    pub lifetimes: CommonLifetimes<'tcx>,
1588
1589    /// Common consts, pre-interned for your convenience.
1590    pub consts: CommonConsts<'tcx>,
1591
1592    /// Hooks to be able to register functions in other crates that can then still
1593    /// be called from rustc_middle.
1594    pub(crate) hooks: crate::hooks::Providers,
1595
1596    untracked: Untracked,
1597
1598    pub query_system: QuerySystem<'tcx>,
1599    pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1600
1601    // Internal caches for metadata decoding. No need to track deps on this.
1602    pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1603
1604    /// Caches the results of trait selection. This cache is used
1605    /// for things that do not have to do with the parameters in scope.
1606    pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1607
1608    /// Caches the results of trait evaluation. This cache is used
1609    /// for things that do not have to do with the parameters in scope.
1610    /// Merge this with `selection_cache`?
1611    pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1612
1613    /// Caches the results of goal evaluation in the new solver.
1614    pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1615    pub new_solver_canonical_param_env_cache:
1616        Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
1617
1618    pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1619
1620    /// Caches the index of the highest bound var in clauses in a canonical binder.
1621    pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
1622    /// Caches the instantiation of a canonical binder given a set of args.
1623    pub clauses_cache:
1624        Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
1625
1626    /// Data layout specification for the current target.
1627    pub data_layout: TargetDataLayout,
1628
1629    /// Stores memory for globals (statics/consts).
1630    pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1631
1632    current_gcx: CurrentGcx,
1633
1634    /// A jobserver reference used to release then acquire a token while waiting on a query.
1635    pub jobserver_proxy: Arc<Proxy>,
1636}
1637
1638impl<'tcx> GlobalCtxt<'tcx> {
1639    /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
1640    /// `f`.
1641    pub fn enter<F, R>(&'tcx self, f: F) -> R
1642    where
1643        F: FnOnce(TyCtxt<'tcx>) -> R,
1644    {
1645        let icx = tls::ImplicitCtxt::new(self);
1646
1647        // Reset `current_gcx` to `None` when we exit.
1648        let _on_drop = defer(move || {
1649            *self.current_gcx.value.write() = None;
1650        });
1651
1652        // Set this `GlobalCtxt` as the current one.
1653        {
1654            let mut guard = self.current_gcx.value.write();
1655            assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1656            *guard = Some(self as *const _ as *const ());
1657        }
1658
1659        tls::enter_context(&icx, || f(icx.tcx))
1660    }
1661}
1662
1663/// This is used to get a reference to a `GlobalCtxt` if one is available.
1664///
1665/// This is needed to allow the deadlock handler access to `GlobalCtxt` to look for query cycles.
1666/// It cannot use the `TLV` global because that's only guaranteed to be defined on the thread
1667/// creating the `GlobalCtxt`. Other threads have access to the `TLV` only inside Rayon jobs, but
1668/// the deadlock handler is not called inside such a job.
1669#[derive(Clone)]
1670pub struct CurrentGcx {
1671    /// This stores a pointer to a `GlobalCtxt`. This is set to `Some` inside `GlobalCtxt::enter`
1672    /// and reset to `None` when that function returns or unwinds.
1673    value: Arc<RwLock<Option<*const ()>>>,
1674}
1675
1676unsafe impl DynSend for CurrentGcx {}
1677unsafe impl DynSync for CurrentGcx {}
1678
1679impl CurrentGcx {
1680    pub fn new() -> Self {
1681        Self { value: Arc::new(RwLock::new(None)) }
1682    }
1683
1684    pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1685        let read_guard = self.value.read();
1686        let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1687        // SAFETY: We hold the read lock for the `GlobalCtxt` pointer. That prevents
1688        // `GlobalCtxt::enter` from returning as it would first acquire the write lock.
1689        // This ensures the `GlobalCtxt` is live during `f`.
1690        f(unsafe { &*gcx })
1691    }
1692}
1693
1694impl<'tcx> TyCtxt<'tcx> {
1695    pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1696        // Closures' typeck results come from their outermost function,
1697        // as they are part of the same "inference environment".
1698        let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1699        if typeck_root_def_id != def_id.to_def_id() {
1700            return self.has_typeck_results(typeck_root_def_id.expect_local());
1701        }
1702
1703        self.hir_node_by_def_id(def_id).body_id().is_some()
1704    }
1705
1706    /// Expects a body and returns its codegen attributes.
1707    ///
1708    /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for
1709    /// constants.
1710    pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1711        let def_kind = self.def_kind(def_id);
1712        if def_kind.has_codegen_attrs() {
1713            self.codegen_fn_attrs(def_id)
1714        } else if matches!(
1715            def_kind,
1716            DefKind::AnonConst
1717                | DefKind::AssocConst
1718                | DefKind::Const
1719                | DefKind::InlineConst
1720                | DefKind::GlobalAsm
1721        ) {
1722            CodegenFnAttrs::EMPTY
1723        } else {
1724            bug!(
1725                "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1726                def_id,
1727                def_kind
1728            )
1729        }
1730    }
1731
1732    pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1733        self.arena.alloc(Steal::new(thir))
1734    }
1735
1736    pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1737        self.arena.alloc(Steal::new(mir))
1738    }
1739
1740    pub fn alloc_steal_promoted(
1741        self,
1742        promoted: IndexVec<Promoted, Body<'tcx>>,
1743    ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1744        self.arena.alloc(Steal::new(promoted))
1745    }
1746
1747    pub fn mk_adt_def(
1748        self,
1749        did: DefId,
1750        kind: AdtKind,
1751        variants: IndexVec<VariantIdx, ty::VariantDef>,
1752        repr: ReprOptions,
1753    ) -> ty::AdtDef<'tcx> {
1754        self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1755    }
1756
1757    /// Allocates a read-only byte or string literal for `mir::interpret` with alignment 1.
1758    /// Returns the same `AllocId` if called again with the same bytes.
1759    pub fn allocate_bytes_dedup<'a>(
1760        self,
1761        bytes: impl Into<Cow<'a, [u8]>>,
1762        salt: usize,
1763    ) -> interpret::AllocId {
1764        // Create an allocation that just contains these bytes.
1765        let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
1766        let alloc = self.mk_const_alloc(alloc);
1767        self.reserve_and_set_memory_dedup(alloc, salt)
1768    }
1769
1770    /// Traits added on all bounds by default, excluding `Sized` which is treated separately.
1771    pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1772        if self.sess.opts.unstable_opts.experimental_default_bounds {
1773            &[
1774                LangItem::DefaultTrait1,
1775                LangItem::DefaultTrait2,
1776                LangItem::DefaultTrait3,
1777                LangItem::DefaultTrait4,
1778            ]
1779        } else {
1780            &[]
1781        }
1782    }
1783
1784    pub fn is_default_trait(self, def_id: DefId) -> bool {
1785        self.default_traits()
1786            .iter()
1787            .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
1788    }
1789
1790    /// Returns a range of the start/end indices specified with the
1791    /// `rustc_layout_scalar_valid_range` attribute.
1792    // FIXME(eddyb) this is an awkward spot for this method, maybe move it?
1793    pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1794        let start = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1795        let end = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1796        (start, end)
1797    }
1798
1799    pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1800        value.lift_to_interner(self)
1801    }
1802
1803    /// Creates a type context. To use the context call `fn enter` which
1804    /// provides a `TyCtxt`.
1805    ///
1806    /// By only providing the `TyCtxt` inside of the closure we enforce that the type
1807    /// context and any interned value (types, args, etc.) can only be used while `ty::tls`
1808    /// has a valid reference to the context, to allow formatting values that need it.
1809    pub fn create_global_ctxt<T>(
1810        gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1811        s: &'tcx Session,
1812        crate_types: Vec<CrateType>,
1813        stable_crate_id: StableCrateId,
1814        arena: &'tcx WorkerLocal<Arena<'tcx>>,
1815        hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1816        untracked: Untracked,
1817        dep_graph: DepGraph,
1818        query_kinds: &'tcx [DepKindStruct<'tcx>],
1819        query_system: QuerySystem<'tcx>,
1820        hooks: crate::hooks::Providers,
1821        current_gcx: CurrentGcx,
1822        jobserver_proxy: Arc<Proxy>,
1823        f: impl FnOnce(TyCtxt<'tcx>) -> T,
1824    ) -> T {
1825        let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1826            s.dcx().emit_fatal(err);
1827        });
1828        let interners = CtxtInterners::new(arena);
1829        let common_types = CommonTypes::new(&interners, s, &untracked);
1830        let common_lifetimes = CommonLifetimes::new(&interners);
1831        let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1832
1833        let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1834            sess: s,
1835            crate_types,
1836            stable_crate_id,
1837            arena,
1838            hir_arena,
1839            interners,
1840            dep_graph,
1841            hooks,
1842            prof: s.prof.clone(),
1843            types: common_types,
1844            lifetimes: common_lifetimes,
1845            consts: common_consts,
1846            untracked,
1847            query_system,
1848            query_kinds,
1849            ty_rcache: Default::default(),
1850            selection_cache: Default::default(),
1851            evaluation_cache: Default::default(),
1852            new_solver_evaluation_cache: Default::default(),
1853            new_solver_canonical_param_env_cache: Default::default(),
1854            canonical_param_env_cache: Default::default(),
1855            highest_var_in_clauses_cache: Default::default(),
1856            clauses_cache: Default::default(),
1857            data_layout,
1858            alloc_map: interpret::AllocMap::new(),
1859            current_gcx,
1860            jobserver_proxy,
1861        });
1862
1863        // This is a separate function to work around a crash with parallel rustc (#135870)
1864        gcx.enter(f)
1865    }
1866
1867    /// Obtain all lang items of this crate and all dependencies (recursively)
1868    pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1869        self.get_lang_items(())
1870    }
1871
1872    /// Gets a `Ty` representing the [`LangItem::OrderingEnum`]
1873    #[track_caller]
1874    pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1875        let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1876        self.type_of(ordering_enum).no_bound_vars().unwrap()
1877    }
1878
1879    /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
1880    /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
1881    pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1882        self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1883    }
1884
1885    /// Obtain the diagnostic item's name
1886    pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1887        self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1888    }
1889
1890    /// Check whether the diagnostic item with the given `name` has the given `DefId`.
1891    pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1892        self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1893    }
1894
1895    pub fn is_coroutine(self, def_id: DefId) -> bool {
1896        self.coroutine_kind(def_id).is_some()
1897    }
1898
1899    pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1900        self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1901    }
1902
1903    /// Returns the movability of the coroutine of `def_id`, or panics
1904    /// if given a `def_id` that is not a coroutine.
1905    pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1906        self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1907    }
1908
1909    /// Returns `true` if the node pointed to by `def_id` is a coroutine for an async construct.
1910    pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1911        matches!(
1912            self.coroutine_kind(def_id),
1913            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1914        )
1915    }
1916
1917    // Whether the body owner is synthetic, which in this case means it does not correspond to
1918    // meaningful HIR. This is currently used to skip over MIR borrowck.
1919    pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1920        matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1921    }
1922
1923    /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`.
1924    /// This means it is neither an `async` or `gen` construct.
1925    pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1926        matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1927    }
1928
1929    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `gen` construct.
1930    pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1931        matches!(
1932            self.coroutine_kind(def_id),
1933            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1934        )
1935    }
1936
1937    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `async gen` construct.
1938    pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1939        matches!(
1940            self.coroutine_kind(def_id),
1941            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1942        )
1943    }
1944
1945    pub fn features(self) -> &'tcx rustc_feature::Features {
1946        self.features_query(())
1947    }
1948
1949    pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1950        let id = id.into_query_param();
1951        // Accessing the DefKey is ok, since it is part of DefPathHash.
1952        if let Some(id) = id.as_local() {
1953            self.definitions_untracked().def_key(id)
1954        } else {
1955            self.cstore_untracked().def_key(id)
1956        }
1957    }
1958
1959    /// Converts a `DefId` into its fully expanded `DefPath` (every
1960    /// `DefId` is really just an interned `DefPath`).
1961    ///
1962    /// Note that if `id` is not local to this crate, the result will
1963    ///  be a non-local `DefPath`.
1964    pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1965        // Accessing the DefPath is ok, since it is part of DefPathHash.
1966        if let Some(id) = id.as_local() {
1967            self.definitions_untracked().def_path(id)
1968        } else {
1969            self.cstore_untracked().def_path(id)
1970        }
1971    }
1972
1973    #[inline]
1974    pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1975        // Accessing the DefPathHash is ok, it is incr. comp. stable.
1976        if let Some(def_id) = def_id.as_local() {
1977            self.definitions_untracked().def_path_hash(def_id)
1978        } else {
1979            self.cstore_untracked().def_path_hash(def_id)
1980        }
1981    }
1982
1983    #[inline]
1984    pub fn crate_types(self) -> &'tcx [CrateType] {
1985        &self.crate_types
1986    }
1987
1988    pub fn needs_metadata(self) -> bool {
1989        self.crate_types().iter().any(|ty| match *ty {
1990            CrateType::Executable
1991            | CrateType::Staticlib
1992            | CrateType::Cdylib
1993            | CrateType::Sdylib => false,
1994            CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1995        })
1996    }
1997
1998    pub fn needs_crate_hash(self) -> bool {
1999        // Why is the crate hash needed for these configurations?
2000        // - debug_assertions: for the "fingerprint the result" check in
2001        //   `rustc_query_system::query::plumbing::execute_job`.
2002        // - incremental: for query lookups.
2003        // - needs_metadata: for putting into crate metadata.
2004        // - instrument_coverage: for putting into coverage data (see
2005        //   `hash_mir_source`).
2006        // - metrics_dir: metrics use the strict version hash in the filenames
2007        //   for dumped metrics files to prevent overwriting distinct metrics
2008        //   for similar source builds (may change in the future, this is part
2009        //   of the proof of concept impl for the metrics initiative project goal)
2010        cfg!(debug_assertions)
2011            || self.sess.opts.incremental.is_some()
2012            || self.needs_metadata()
2013            || self.sess.instrument_coverage()
2014            || self.sess.opts.unstable_opts.metrics_dir.is_some()
2015    }
2016
2017    #[inline]
2018    pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
2019        if crate_num == LOCAL_CRATE {
2020            self.stable_crate_id
2021        } else {
2022            self.cstore_untracked().stable_crate_id(crate_num)
2023        }
2024    }
2025
2026    /// Maps a StableCrateId to the corresponding CrateNum. This method assumes
2027    /// that the crate in question has already been loaded by the CrateStore.
2028    #[inline]
2029    pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
2030        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
2031            LOCAL_CRATE
2032        } else {
2033            *self
2034                .untracked()
2035                .stable_crate_ids
2036                .read()
2037                .get(&stable_crate_id)
2038                .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
2039        }
2040    }
2041
2042    /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
2043    /// session, if it still exists. This is used during incremental compilation to
2044    /// turn a deserialized `DefPathHash` into its current `DefId`.
2045    pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
2046        debug!("def_path_hash_to_def_id({:?})", hash);
2047
2048        let stable_crate_id = hash.stable_crate_id();
2049
2050        // If this is a DefPathHash from the local crate, we can look up the
2051        // DefId in the tcx's `Definitions`.
2052        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
2053            Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
2054        } else {
2055            self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
2056        }
2057    }
2058
2059    pub fn def_path_debug_str(self, def_id: DefId) -> String {
2060        // We are explicitly not going through queries here in order to get
2061        // crate name and stable crate id since this code is called from debug!()
2062        // statements within the query system and we'd run into endless
2063        // recursion otherwise.
2064        let (crate_name, stable_crate_id) = if def_id.is_local() {
2065            (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
2066        } else {
2067            let cstore = &*self.cstore_untracked();
2068            (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
2069        };
2070
2071        format!(
2072            "{}[{:04x}]{}",
2073            crate_name,
2074            // Don't print the whole stable crate id. That's just
2075            // annoying in debug output.
2076            stable_crate_id.as_u64() >> (8 * 6),
2077            self.def_path(def_id).to_string_no_crate_verbose()
2078        )
2079    }
2080
2081    pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
2082        self.sess.dcx()
2083    }
2084
2085    pub fn is_target_feature_call_safe(
2086        self,
2087        callee_features: &[TargetFeature],
2088        body_features: &[TargetFeature],
2089    ) -> bool {
2090        // If the called function has target features the calling function hasn't,
2091        // the call requires `unsafe`. Don't check this on wasm
2092        // targets, though. For more information on wasm see the
2093        // is_like_wasm check in hir_analysis/src/collect.rs
2094        self.sess.target.options.is_like_wasm
2095            || callee_features
2096                .iter()
2097                .all(|feature| body_features.iter().any(|f| f.name == feature.name))
2098    }
2099
2100    /// Returns the safe version of the signature of the given function, if calling it
2101    /// would be safe in the context of the given caller.
2102    pub fn adjust_target_feature_sig(
2103        self,
2104        fun_def: DefId,
2105        fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
2106        caller: DefId,
2107    ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
2108        let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
2109        let callee_features = &self.codegen_fn_attrs(caller).target_features;
2110        if self.is_target_feature_call_safe(&fun_features, &callee_features) {
2111            return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
2112        }
2113        None
2114    }
2115
2116    /// Helper to get a tracked environment variable via. [`TyCtxt::env_var_os`] and converting to
2117    /// UTF-8 like [`std::env::var`].
2118    pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
2119        match self.env_var_os(key.as_ref()) {
2120            Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
2121            None => Err(VarError::NotPresent),
2122        }
2123    }
2124}
2125
2126impl<'tcx> TyCtxtAt<'tcx> {
2127    /// Create a new definition within the incr. comp. engine.
2128    pub fn create_def(
2129        self,
2130        parent: LocalDefId,
2131        name: Option<Symbol>,
2132        def_kind: DefKind,
2133        override_def_path_data: Option<DefPathData>,
2134        disambiguator: &mut DisambiguatorState,
2135    ) -> TyCtxtFeed<'tcx, LocalDefId> {
2136        let feed =
2137            self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
2138
2139        feed.def_span(self.span);
2140        feed
2141    }
2142}
2143
2144impl<'tcx> TyCtxt<'tcx> {
2145    /// `tcx`-dependent operations performed for every created definition.
2146    pub fn create_def(
2147        self,
2148        parent: LocalDefId,
2149        name: Option<Symbol>,
2150        def_kind: DefKind,
2151        override_def_path_data: Option<DefPathData>,
2152        disambiguator: &mut DisambiguatorState,
2153    ) -> TyCtxtFeed<'tcx, LocalDefId> {
2154        let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2155        // The following call has the side effect of modifying the tables inside `definitions`.
2156        // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
2157        // decode the on-disk cache.
2158        //
2159        // Any LocalDefId which is used within queries, either as key or result, either:
2160        // - has been created before the construction of the TyCtxt;
2161        // - has been created by this call to `create_def`.
2162        // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
2163        // comp. engine itself.
2164        let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2165
2166        // This function modifies `self.definitions` using a side-effect.
2167        // We need to ensure that these side effects are re-run by the incr. comp. engine.
2168        // Depending on the forever-red node will tell the graph that the calling query
2169        // needs to be re-evaluated.
2170        self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2171
2172        let feed = TyCtxtFeed { tcx: self, key: def_id };
2173        feed.def_kind(def_kind);
2174        // Unique types created for closures participate in type privacy checking.
2175        // They have visibilities inherited from the module they are defined in.
2176        // Visibilities for opaque types are meaningless, but still provided
2177        // so that all items have visibilities.
2178        if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2179            let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2180            feed.visibility(ty::Visibility::Restricted(parent_mod));
2181        }
2182
2183        feed
2184    }
2185
2186    pub fn create_crate_num(
2187        self,
2188        stable_crate_id: StableCrateId,
2189    ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2190        if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2191            return Err(existing);
2192        }
2193
2194        let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2195        self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2196        Ok(TyCtxtFeed { key: num, tcx: self })
2197    }
2198
2199    pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2200        // Depend on the `analysis` query to ensure compilation if finished.
2201        self.ensure_ok().analysis(());
2202
2203        let definitions = &self.untracked.definitions;
2204        gen {
2205            let mut i = 0;
2206
2207            // Recompute the number of definitions each time, because our caller may be creating
2208            // new ones.
2209            while i < { definitions.read().num_definitions() } {
2210                let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2211                yield LocalDefId { local_def_index };
2212                i += 1;
2213            }
2214
2215            // Freeze definitions once we finish iterating on them, to prevent adding new ones.
2216            definitions.freeze();
2217        }
2218    }
2219
2220    pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2221        // Depend on the `analysis` query to ensure compilation if finished.
2222        self.ensure_ok().analysis(());
2223
2224        // Freeze definitions once we start iterating on them, to prevent adding new ones
2225        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
2226        self.untracked.definitions.freeze().def_path_table()
2227    }
2228
2229    pub fn def_path_hash_to_def_index_map(
2230        self,
2231    ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2232        // Create a dependency to the crate to be sure we re-execute this when the amount of
2233        // definitions change.
2234        self.ensure_ok().hir_crate_items(());
2235        // Freeze definitions once we start iterating on them, to prevent adding new ones
2236        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
2237        self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2238    }
2239
2240    /// Note that this is *untracked* and should only be used within the query
2241    /// system if the result is otherwise tracked through queries
2242    #[inline]
2243    pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2244        FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2245    }
2246
2247    /// Give out access to the untracked data without any sanity checks.
2248    pub fn untracked(self) -> &'tcx Untracked {
2249        &self.untracked
2250    }
2251    /// Note that this is *untracked* and should only be used within the query
2252    /// system if the result is otherwise tracked through queries
2253    #[inline]
2254    pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2255        self.untracked.definitions.read()
2256    }
2257
2258    /// Note that this is *untracked* and should only be used within the query
2259    /// system if the result is otherwise tracked through queries
2260    #[inline]
2261    pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2262        self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2263    }
2264
2265    #[inline(always)]
2266    pub fn with_stable_hashing_context<R>(
2267        self,
2268        f: impl FnOnce(StableHashingContext<'_>) -> R,
2269    ) -> R {
2270        f(StableHashingContext::new(self.sess, &self.untracked))
2271    }
2272
2273    pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2274        self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2275    }
2276
2277    #[inline]
2278    pub fn local_crate_exports_generics(self) -> bool {
2279        self.crate_types().iter().any(|crate_type| {
2280            match crate_type {
2281                CrateType::Executable
2282                | CrateType::Staticlib
2283                | CrateType::ProcMacro
2284                | CrateType::Cdylib
2285                | CrateType::Sdylib => false,
2286
2287                // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
2288                // We want to block export of generics from dylibs,
2289                // but we must fix rust-lang/rust#65890 before we can
2290                // do that robustly.
2291                CrateType::Dylib => true,
2292
2293                CrateType::Rlib => true,
2294            }
2295        })
2296    }
2297
2298    /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
2299    pub fn is_suitable_region(
2300        self,
2301        generic_param_scope: LocalDefId,
2302        mut region: Region<'tcx>,
2303    ) -> Option<FreeRegionInfo> {
2304        let (suitable_region_binding_scope, region_def_id) = loop {
2305            let def_id =
2306                region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2307            let scope = self.local_parent(def_id);
2308            if self.def_kind(scope) == DefKind::OpaqueTy {
2309                // Lifetime params of opaque types are synthetic and thus irrelevant to
2310                // diagnostics. Map them back to their origin!
2311                region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2312                continue;
2313            }
2314            break (scope, def_id.into());
2315        };
2316
2317        let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2318            Node::Item(..) | Node::TraitItem(..) => false,
2319            Node::ImplItem(impl_item) => match impl_item.impl_kind {
2320                // For now, we do not try to target impls of traits. This is
2321                // because this message is going to suggest that the user
2322                // change the fn signature, but they may not be free to do so,
2323                // since the signature must match the trait.
2324                //
2325                // FIXME(#42706) -- in some cases, we could do better here.
2326                hir::ImplItemImplKind::Trait { .. } => true,
2327                _ => false,
2328            },
2329            _ => false,
2330        };
2331
2332        Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2333    }
2334
2335    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
2336    pub fn return_type_impl_or_dyn_traits(
2337        self,
2338        scope_def_id: LocalDefId,
2339    ) -> Vec<&'tcx hir::Ty<'tcx>> {
2340        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2341        let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2342            self.hir_fn_decl_by_hir_id(hir_id)
2343        else {
2344            return vec![];
2345        };
2346
2347        let mut v = TraitObjectVisitor(vec![]);
2348        v.visit_ty_unambig(hir_output);
2349        v.0
2350    }
2351
2352    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in
2353    /// its return type, and the associated alias span when type alias is used,
2354    /// along with a span for lifetime suggestion (if there are existing generics).
2355    pub fn return_type_impl_or_dyn_traits_with_type_alias(
2356        self,
2357        scope_def_id: LocalDefId,
2358    ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2359        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2360        let mut v = TraitObjectVisitor(vec![]);
2361        // when the return type is a type alias
2362        if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2363            && let hir::TyKind::Path(hir::QPath::Resolved(
2364                None,
2365                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2366            && let Some(local_id) = def_id.as_local()
2367            && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias
2368            && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
2369        {
2370            v.visit_ty_unambig(alias_ty);
2371            if !v.0.is_empty() {
2372                return Some((
2373                    v.0,
2374                    alias_generics.span,
2375                    alias_generics.span_for_lifetime_suggestion(),
2376                ));
2377            }
2378        }
2379        None
2380    }
2381
2382    /// Determines whether identifiers in the assembly have strict naming rules.
2383    /// Currently, only NVPTX* targets need it.
2384    pub fn has_strict_asm_symbol_naming(self) -> bool {
2385        self.sess.target.arch.contains("nvptx")
2386    }
2387
2388    /// Returns `&'static core::panic::Location<'static>`.
2389    pub fn caller_location_ty(self) -> Ty<'tcx> {
2390        Ty::new_imm_ref(
2391            self,
2392            self.lifetimes.re_static,
2393            self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2394                .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2395        )
2396    }
2397
2398    /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
2399    pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2400        let kind = self.def_kind(def_id);
2401        (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2402    }
2403
2404    pub fn type_length_limit(self) -> Limit {
2405        self.limits(()).type_length_limit
2406    }
2407
2408    pub fn recursion_limit(self) -> Limit {
2409        self.limits(()).recursion_limit
2410    }
2411
2412    pub fn move_size_limit(self) -> Limit {
2413        self.limits(()).move_size_limit
2414    }
2415
2416    pub fn pattern_complexity_limit(self) -> Limit {
2417        self.limits(()).pattern_complexity_limit
2418    }
2419
2420    /// All traits in the crate graph, including those not visible to the user.
2421    pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
2422        iter::once(LOCAL_CRATE)
2423            .chain(self.crates(()).iter().copied())
2424            .flat_map(move |cnum| self.traits(cnum).iter().copied())
2425    }
2426
2427    /// All traits that are visible within the crate graph (i.e. excluding private dependencies).
2428    pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2429        let visible_crates =
2430            self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2431
2432        iter::once(LOCAL_CRATE)
2433            .chain(visible_crates)
2434            .flat_map(move |cnum| self.traits(cnum).iter().copied())
2435    }
2436
2437    #[inline]
2438    pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2439        self.visibility(def_id).expect_local()
2440    }
2441
2442    /// Returns the origin of the opaque type `def_id`.
2443    #[instrument(skip(self), level = "trace", ret)]
2444    pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2445        self.hir_expect_opaque_ty(def_id).origin
2446    }
2447
2448    pub fn finish(self) {
2449        // We assume that no queries are run past here. If there are new queries
2450        // after this point, they'll show up as "<unknown>" in self-profiling data.
2451        self.alloc_self_profile_query_strings();
2452
2453        self.save_dep_graph();
2454        self.query_key_hash_verify_all();
2455
2456        if let Err((path, error)) = self.dep_graph.finish_encoding() {
2457            self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2458        }
2459    }
2460}
2461
2462macro_rules! nop_lift {
2463    ($set:ident; $ty:ty => $lifted:ty) => {
2464        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2465            type Lifted = $lifted;
2466            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2467                // Assert that the set has the right type.
2468                // Given an argument that has an interned type, the return type has the type of
2469                // the corresponding interner set. This won't actually return anything, we're
2470                // just doing this to compute said type!
2471                fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2472                    _x: Interned<'tcx, Inner>,
2473                ) -> InternedSet<'tcx, Inner> {
2474                    unreachable!()
2475                }
2476                fn _type_eq<T>(_x: &T, _y: &T) {}
2477                fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2478                    // If `x` is a newtype around an `Interned<T>`, then `interner` is an
2479                    // interner of appropriate type. (Ideally we'd also check that `x` is a
2480                    // newtype with just that one field. Not sure how to do that.)
2481                    let interner = _intern_set_ty_from_interned_ty(x.0);
2482                    // Now check that this is the same type as `interners.$set`.
2483                    _type_eq(&interner, &tcx.interners.$set);
2484                }
2485
2486                tcx.interners
2487                    .$set
2488                    .contains_pointer_to(&InternedInSet(&*self.0.0))
2489                    // SAFETY: `self` is interned and therefore valid
2490                    // for the entire lifetime of the `TyCtxt`.
2491                    .then(|| unsafe { mem::transmute(self) })
2492            }
2493        }
2494    };
2495}
2496
2497macro_rules! nop_list_lift {
2498    ($set:ident; $ty:ty => $lifted:ty) => {
2499        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2500            type Lifted = &'tcx List<$lifted>;
2501            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2502                // Assert that the set has the right type.
2503                if false {
2504                    let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2505                }
2506
2507                if self.is_empty() {
2508                    return Some(List::empty());
2509                }
2510                tcx.interners
2511                    .$set
2512                    .contains_pointer_to(&InternedInSet(self))
2513                    .then(|| unsafe { mem::transmute(self) })
2514            }
2515        }
2516    };
2517}
2518
2519nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2520nop_lift! { region; Region<'a> => Region<'tcx> }
2521nop_lift! { const_; Const<'a> => Const<'tcx> }
2522nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2523nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2524nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2525nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2526nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2527nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2528
2529nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2530nop_list_lift! {
2531    poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2532}
2533nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2534
2535// This is the impl for `&'a GenericArgs<'a>`.
2536nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2537
2538macro_rules! sty_debug_print {
2539    ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2540        // Curious inner module to allow variant names to be used as
2541        // variable names.
2542        #[allow(non_snake_case)]
2543        mod inner {
2544            use crate::ty::{self, TyCtxt};
2545            use crate::ty::context::InternedInSet;
2546
2547            #[derive(Copy, Clone)]
2548            struct DebugStat {
2549                total: usize,
2550                lt_infer: usize,
2551                ty_infer: usize,
2552                ct_infer: usize,
2553                all_infer: usize,
2554            }
2555
2556            pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2557                let mut total = DebugStat {
2558                    total: 0,
2559                    lt_infer: 0,
2560                    ty_infer: 0,
2561                    ct_infer: 0,
2562                    all_infer: 0,
2563                };
2564                $(let mut $variant = total;)*
2565
2566                for shard in tcx.interners.type_.lock_shards() {
2567                    // It seems that ordering doesn't affect anything here.
2568                    #[allow(rustc::potential_query_instability)]
2569                    let types = shard.iter();
2570                    for &(InternedInSet(t), ()) in types {
2571                        let variant = match t.internee {
2572                            ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2573                                ty::Float(..) | ty::Str | ty::Never => continue,
2574                            ty::Error(_) => /* unimportant */ continue,
2575                            $(ty::$variant(..) => &mut $variant,)*
2576                        };
2577                        let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2578                        let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2579                        let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2580
2581                        variant.total += 1;
2582                        total.total += 1;
2583                        if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2584                        if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2585                        if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2586                        if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2587                    }
2588                }
2589                writeln!(fmt, "Ty interner             total           ty lt ct all")?;
2590                $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
2591                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2592                    stringify!($variant),
2593                    uses = $variant.total,
2594                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
2595                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
2596                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
2597                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
2598                    all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
2599                )*
2600                writeln!(fmt, "                  total {uses:6}        \
2601                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2602                    uses = total.total,
2603                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
2604                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
2605                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
2606                    all = total.all_infer as f64 * 100.0  / total.total as f64)
2607            }
2608        }
2609
2610        inner::go($fmt, $ctxt)
2611    }}
2612}
2613
2614impl<'tcx> TyCtxt<'tcx> {
2615    pub fn debug_stats(self) -> impl fmt::Debug {
2616        fmt::from_fn(move |fmt| {
2617            sty_debug_print!(
2618                fmt,
2619                self,
2620                Adt,
2621                Array,
2622                Slice,
2623                RawPtr,
2624                Ref,
2625                FnDef,
2626                FnPtr,
2627                UnsafeBinder,
2628                Placeholder,
2629                Coroutine,
2630                CoroutineWitness,
2631                Dynamic,
2632                Closure,
2633                CoroutineClosure,
2634                Tuple,
2635                Bound,
2636                Param,
2637                Infer,
2638                Alias,
2639                Pat,
2640                Foreign
2641            )?;
2642
2643            writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2644            writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2645            writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2646            writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2647
2648            Ok(())
2649        })
2650    }
2651}
2652
2653// This type holds a `T` in the interner. The `T` is stored in the arena and
2654// this type just holds a pointer to it, but it still effectively owns it. It
2655// impls `Borrow` so that it can be looked up using the original
2656// (non-arena-memory-owning) types.
2657struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2658
2659impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2660    fn clone(&self) -> Self {
2661        InternedInSet(self.0)
2662    }
2663}
2664
2665impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2666
2667impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2668    fn into_pointer(&self) -> *const () {
2669        self.0 as *const _ as *const ()
2670    }
2671}
2672
2673#[allow(rustc::usage_of_ty_tykind)]
2674impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2675    fn borrow(&self) -> &T {
2676        &self.0.internee
2677    }
2678}
2679
2680impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2681    fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2682        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2683        // `x == y`.
2684        self.0.internee == other.0.internee
2685    }
2686}
2687
2688impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2689
2690impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2691    fn hash<H: Hasher>(&self, s: &mut H) {
2692        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2693        self.0.internee.hash(s)
2694    }
2695}
2696
2697impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2698    fn borrow(&self) -> &[T] {
2699        &self.0[..]
2700    }
2701}
2702
2703impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2704    fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2705        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2706        // `x == y`.
2707        self.0[..] == other.0[..]
2708    }
2709}
2710
2711impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2712
2713impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2714    fn hash<H: Hasher>(&self, s: &mut H) {
2715        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2716        self.0[..].hash(s)
2717    }
2718}
2719
2720impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2721    fn borrow(&self) -> &[T] {
2722        &self.0[..]
2723    }
2724}
2725
2726impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2727    fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2728        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2729        // `x == y`.
2730        self.0[..] == other.0[..]
2731    }
2732}
2733
2734impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2735
2736impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2737    fn hash<H: Hasher>(&self, s: &mut H) {
2738        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2739        self.0[..].hash(s)
2740    }
2741}
2742
2743macro_rules! direct_interners {
2744    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2745        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2746            fn borrow<'a>(&'a self) -> &'a $ty {
2747                &self.0
2748            }
2749        }
2750
2751        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2752            fn eq(&self, other: &Self) -> bool {
2753                // The `Borrow` trait requires that `x.borrow() == y.borrow()`
2754                // equals `x == y`.
2755                self.0 == other.0
2756            }
2757        }
2758
2759        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2760
2761        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2762            fn hash<H: Hasher>(&self, s: &mut H) {
2763                // The `Borrow` trait requires that `x.borrow().hash(s) ==
2764                // x.hash(s)`.
2765                self.0.hash(s)
2766            }
2767        }
2768
2769        impl<'tcx> TyCtxt<'tcx> {
2770            $vis fn $method(self, v: $ty) -> $ret_ty {
2771                $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2772                    InternedInSet(self.interners.arena.alloc(v))
2773                }).0))
2774            }
2775        })+
2776    }
2777}
2778
2779// Functions with a `mk_` prefix are intended for use outside this file and
2780// crate. Functions with an `intern_` prefix are intended for use within this
2781// crate only, and have a corresponding `mk_` function.
2782direct_interners! {
2783    region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2784    valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2785    pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2786    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2787    layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2788    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2789    external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2790        ExternalConstraints -> ExternalConstraints<'tcx>,
2791}
2792
2793macro_rules! slice_interners {
2794    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2795        impl<'tcx> TyCtxt<'tcx> {
2796            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2797                if v.is_empty() {
2798                    List::empty()
2799                } else {
2800                    self.interners.$field.intern_ref(v, || {
2801                        InternedInSet(List::from_arena(&*self.arena, (), v))
2802                    }).0
2803                }
2804            })+
2805        }
2806    );
2807}
2808
2809// These functions intern slices. They all have a corresponding
2810// `mk_foo_from_iter` function that interns an iterator. The slice version
2811// should be used when possible, because it's faster.
2812slice_interners!(
2813    const_lists: pub mk_const_list(Const<'tcx>),
2814    args: pub mk_args(GenericArg<'tcx>),
2815    type_lists: pub mk_type_list(Ty<'tcx>),
2816    canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2817    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2818    projs: pub mk_projs(ProjectionKind),
2819    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2820    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2821    fields: pub mk_fields(FieldIdx),
2822    local_def_ids: intern_local_def_ids(LocalDefId),
2823    captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2824    offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2825    patterns: pub mk_patterns(Pattern<'tcx>),
2826    outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2827    predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2828);
2829
2830impl<'tcx> TyCtxt<'tcx> {
2831    /// Given a `fn` type, returns an equivalent `unsafe fn` type;
2832    /// that is, a `fn` type that is equivalent in every way for being
2833    /// unsafe.
2834    pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2835        assert!(sig.safety().is_safe());
2836        Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2837    }
2838
2839    /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
2840    /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
2841    pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2842        elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2843            self.associated_items(trait_did)
2844                .filter_by_name_unhygienic(assoc_name.name)
2845                .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2846        })
2847    }
2848
2849    /// Given a `ty`, return whether it's an `impl Future<...>`.
2850    pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2851        let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2852        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2853
2854        self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2855            let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2856                return false;
2857            };
2858            trait_predicate.trait_ref.def_id == future_trait
2859                && trait_predicate.polarity == PredicatePolarity::Positive
2860        })
2861    }
2862
2863    /// Given a closure signature, returns an equivalent fn signature. Detuples
2864    /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
2865    /// you would get a `fn(u32, i32)`.
2866    /// `unsafety` determines the unsafety of the fn signature. If you pass
2867    /// `hir::Safety::Unsafe` in the previous example, then you would get
2868    /// an `unsafe fn (u32, i32)`.
2869    /// It cannot convert a closure that requires unsafe.
2870    pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2871        sig.map_bound(|s| {
2872            let params = match s.inputs()[0].kind() {
2873                ty::Tuple(params) => *params,
2874                _ => bug!(),
2875            };
2876            self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2877        })
2878    }
2879
2880    #[inline]
2881    pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2882        self.interners.intern_predicate(
2883            binder,
2884            self.sess,
2885            // This is only used to create a stable hashing context.
2886            &self.untracked,
2887        )
2888    }
2889
2890    #[inline]
2891    pub fn reuse_or_mk_predicate(
2892        self,
2893        pred: Predicate<'tcx>,
2894        binder: Binder<'tcx, PredicateKind<'tcx>>,
2895    ) -> Predicate<'tcx> {
2896        if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2897    }
2898
2899    pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2900        self.check_args_compatible_inner(def_id, args, false)
2901    }
2902
2903    fn check_args_compatible_inner(
2904        self,
2905        def_id: DefId,
2906        args: &'tcx [ty::GenericArg<'tcx>],
2907        nested: bool,
2908    ) -> bool {
2909        let generics = self.generics_of(def_id);
2910
2911        // IATs themselves have a weird arg setup (self + own args), but nested items *in* IATs
2912        // (namely: opaques, i.e. ATPITs) do not.
2913        let own_args = if !nested
2914            && let DefKind::AssocTy = self.def_kind(def_id)
2915            && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2916        {
2917            if generics.own_params.len() + 1 != args.len() {
2918                return false;
2919            }
2920
2921            if !matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2922                return false;
2923            }
2924
2925            &args[1..]
2926        } else {
2927            if generics.count() != args.len() {
2928                return false;
2929            }
2930
2931            let (parent_args, own_args) = args.split_at(generics.parent_count);
2932
2933            if let Some(parent) = generics.parent
2934                && !self.check_args_compatible_inner(parent, parent_args, true)
2935            {
2936                return false;
2937            }
2938
2939            own_args
2940        };
2941
2942        for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2943            match (&param.kind, arg.kind()) {
2944                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2945                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2946                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2947                _ => return false,
2948            }
2949        }
2950
2951        true
2952    }
2953
2954    /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
2955    /// and print out the args if not.
2956    pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2957        if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2958            if let DefKind::AssocTy = self.def_kind(def_id)
2959                && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2960            {
2961                bug!(
2962                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2963                    self.def_path_str(def_id),
2964                    args,
2965                    // Make `[Self, GAT_ARGS...]` (this could be simplified)
2966                    self.mk_args_from_iter(
2967                        [self.types.self_param.into()].into_iter().chain(
2968                            self.generics_of(def_id)
2969                                .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2970                                .iter()
2971                                .copied()
2972                        )
2973                    )
2974                );
2975            } else {
2976                bug!(
2977                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2978                    self.def_path_str(def_id),
2979                    args,
2980                    ty::GenericArgs::identity_for_item(self, def_id)
2981                );
2982            }
2983        }
2984    }
2985
2986    #[inline(always)]
2987    pub(crate) fn check_and_mk_args(
2988        self,
2989        def_id: DefId,
2990        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2991    ) -> GenericArgsRef<'tcx> {
2992        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2993        self.debug_assert_args_compatible(def_id, args);
2994        args
2995    }
2996
2997    #[inline]
2998    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2999        self.interners.intern_const(
3000            kind,
3001            self.sess,
3002            // This is only used to create a stable hashing context.
3003            &self.untracked,
3004        )
3005    }
3006
3007    // Avoid this in favour of more specific `Ty::new_*` methods, where possible.
3008    #[allow(rustc::usage_of_ty_tykind)]
3009    #[inline]
3010    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
3011        self.interners.intern_ty(
3012            st,
3013            self.sess,
3014            // This is only used to create a stable hashing context.
3015            &self.untracked,
3016        )
3017    }
3018
3019    pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
3020        match param.kind {
3021            GenericParamDefKind::Lifetime => {
3022                ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
3023            }
3024            GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
3025            GenericParamDefKind::Const { .. } => {
3026                ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
3027                    .into()
3028            }
3029        }
3030    }
3031
3032    pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
3033        self.mk_place_elem(place, PlaceElem::Field(f, ty))
3034    }
3035
3036    pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
3037        self.mk_place_elem(place, PlaceElem::Deref)
3038    }
3039
3040    pub fn mk_place_downcast(
3041        self,
3042        place: Place<'tcx>,
3043        adt_def: AdtDef<'tcx>,
3044        variant_index: VariantIdx,
3045    ) -> Place<'tcx> {
3046        self.mk_place_elem(
3047            place,
3048            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
3049        )
3050    }
3051
3052    pub fn mk_place_downcast_unnamed(
3053        self,
3054        place: Place<'tcx>,
3055        variant_index: VariantIdx,
3056    ) -> Place<'tcx> {
3057        self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
3058    }
3059
3060    pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
3061        self.mk_place_elem(place, PlaceElem::Index(index))
3062    }
3063
3064    /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
3065    /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
3066    /// flight.
3067    pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
3068        let mut projection = place.projection.to_vec();
3069        projection.push(elem);
3070
3071        Place { local: place.local, projection: self.mk_place_elems(&projection) }
3072    }
3073
3074    pub fn mk_poly_existential_predicates(
3075        self,
3076        eps: &[PolyExistentialPredicate<'tcx>],
3077    ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
3078        assert!(!eps.is_empty());
3079        assert!(
3080            eps.array_windows()
3081                .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
3082                    != Ordering::Greater)
3083        );
3084        self.intern_poly_existential_predicates(eps)
3085    }
3086
3087    pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
3088        // FIXME consider asking the input slice to be sorted to avoid
3089        // re-interning permutations, in which case that would be asserted
3090        // here.
3091        self.interners.intern_clauses(clauses)
3092    }
3093
3094    pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
3095        // FIXME consider asking the input slice to be sorted to avoid
3096        // re-interning permutations, in which case that would be asserted
3097        // here.
3098        self.intern_local_def_ids(def_ids)
3099    }
3100
3101    pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
3102    where
3103        I: Iterator<Item = T>,
3104        T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
3105    {
3106        T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
3107    }
3108
3109    pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
3110    where
3111        I: Iterator<Item = T>,
3112        T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
3113    {
3114        T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
3115    }
3116
3117    pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
3118    where
3119        I: Iterator<Item = T>,
3120        T: CollectAndApply<
3121                &'tcx ty::CapturedPlace<'tcx>,
3122                &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
3123            >,
3124    {
3125        T::collect_and_apply(iter, |xs| self.intern_captures(xs))
3126    }
3127
3128    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
3129    where
3130        I: Iterator<Item = T>,
3131        T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
3132    {
3133        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3134    }
3135
3136    // Unlike various other `mk_*_from_iter` functions, this one uses `I:
3137    // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
3138    // variant, because of the need to combine `inputs` and `output`. This
3139    // explains the lack of `_from_iter` suffix.
3140    pub fn mk_fn_sig<I, T>(
3141        self,
3142        inputs: I,
3143        output: I::Item,
3144        c_variadic: bool,
3145        safety: hir::Safety,
3146        abi: ExternAbi,
3147    ) -> T::Output
3148    where
3149        I: IntoIterator<Item = T>,
3150        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3151    {
3152        T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3153            inputs_and_output: self.mk_type_list(xs),
3154            c_variadic,
3155            safety,
3156            abi,
3157        })
3158    }
3159
3160    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3161    where
3162        I: Iterator<Item = T>,
3163        T: CollectAndApply<
3164                PolyExistentialPredicate<'tcx>,
3165                &'tcx List<PolyExistentialPredicate<'tcx>>,
3166            >,
3167    {
3168        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3169    }
3170
3171    pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
3172    where
3173        I: Iterator<Item = T>,
3174        T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
3175    {
3176        T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
3177    }
3178
3179    pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3180    where
3181        I: Iterator<Item = T>,
3182        T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3183    {
3184        T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3185    }
3186
3187    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3188    where
3189        I: Iterator<Item = T>,
3190        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3191    {
3192        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3193    }
3194
3195    pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3196    where
3197        I: Iterator<Item = T>,
3198        T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3199    {
3200        T::collect_and_apply(iter, |xs| self.mk_args(xs))
3201    }
3202
3203    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3204    where
3205        I: Iterator<Item = T>,
3206        T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3207    {
3208        T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3209    }
3210
3211    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3212    where
3213        I: Iterator<Item = T>,
3214        T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3215    {
3216        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3217    }
3218
3219    pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3220    where
3221        I: Iterator<Item = T>,
3222        T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3223    {
3224        T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3225    }
3226
3227    pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
3228    where
3229        I: Iterator<Item = T>,
3230        T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
3231    {
3232        T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
3233    }
3234
3235    pub fn mk_args_trait(
3236        self,
3237        self_ty: Ty<'tcx>,
3238        rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3239    ) -> GenericArgsRef<'tcx> {
3240        self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3241    }
3242
3243    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3244    where
3245        I: Iterator<Item = T>,
3246        T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3247    {
3248        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3249    }
3250
3251    pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
3252    where
3253        I: Iterator<Item = T>,
3254        T: CollectAndApply<
3255                ty::ArgOutlivesPredicate<'tcx>,
3256                &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
3257            >,
3258    {
3259        T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
3260    }
3261
3262    /// Emit a lint at `span` from a lint struct (some type that implements `LintDiagnostic`,
3263    /// typically generated by `#[derive(LintDiagnostic)]`).
3264    #[track_caller]
3265    pub fn emit_node_span_lint(
3266        self,
3267        lint: &'static Lint,
3268        hir_id: HirId,
3269        span: impl Into<MultiSpan>,
3270        decorator: impl for<'a> LintDiagnostic<'a, ()>,
3271    ) {
3272        let level = self.lint_level_at_node(lint, hir_id);
3273        lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3274            decorator.decorate_lint(lint);
3275        })
3276    }
3277
3278    /// Emit a lint at the appropriate level for a hir node, with an associated span.
3279    ///
3280    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
3281    #[rustc_lint_diagnostics]
3282    #[track_caller]
3283    pub fn node_span_lint(
3284        self,
3285        lint: &'static Lint,
3286        hir_id: HirId,
3287        span: impl Into<MultiSpan>,
3288        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3289    ) {
3290        let level = self.lint_level_at_node(lint, hir_id);
3291        lint_level(self.sess, lint, level, Some(span.into()), decorate);
3292    }
3293
3294    /// Find the appropriate span where `use` and outer attributes can be inserted at.
3295    pub fn crate_level_attribute_injection_span(self) -> Span {
3296        let node = self.hir_node(hir::CRATE_HIR_ID);
3297        let hir::Node::Crate(m) = node else { bug!() };
3298        m.spans.inject_use_span.shrink_to_lo()
3299    }
3300
3301    pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3302        self,
3303        diag: &mut Diag<'_, E>,
3304        features: impl IntoIterator<Item = (String, Symbol)>,
3305    ) {
3306        if !self.sess.is_nightly_build() {
3307            return;
3308        }
3309
3310        let span = self.crate_level_attribute_injection_span();
3311        for (desc, feature) in features {
3312            // FIXME: make this string translatable
3313            let msg =
3314                format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3315            diag.span_suggestion_verbose(
3316                span,
3317                msg,
3318                format!("#![feature({feature})]\n"),
3319                Applicability::MaybeIncorrect,
3320            );
3321        }
3322    }
3323
3324    /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically
3325    /// generated by `#[derive(LintDiagnostic)]`).
3326    #[track_caller]
3327    pub fn emit_node_lint(
3328        self,
3329        lint: &'static Lint,
3330        id: HirId,
3331        decorator: impl for<'a> LintDiagnostic<'a, ()>,
3332    ) {
3333        self.node_lint(lint, id, |lint| {
3334            decorator.decorate_lint(lint);
3335        })
3336    }
3337
3338    /// Emit a lint at the appropriate level for a hir node.
3339    ///
3340    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
3341    #[rustc_lint_diagnostics]
3342    #[track_caller]
3343    pub fn node_lint(
3344        self,
3345        lint: &'static Lint,
3346        id: HirId,
3347        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3348    ) {
3349        let level = self.lint_level_at_node(lint, id);
3350        lint_level(self.sess, lint, level, None, decorate);
3351    }
3352
3353    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3354        let map = self.in_scope_traits_map(id.owner)?;
3355        let candidates = map.get(&id.local_id)?;
3356        Some(candidates)
3357    }
3358
3359    pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3360        debug!(?id, "named_region");
3361        self.named_variable_map(id.owner).get(&id.local_id).cloned()
3362    }
3363
3364    pub fn is_late_bound(self, id: HirId) -> bool {
3365        self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3366    }
3367
3368    pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3369        self.mk_bound_variable_kinds(
3370            &self
3371                .late_bound_vars_map(id.owner)
3372                .get(&id.local_id)
3373                .cloned()
3374                .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3375        )
3376    }
3377
3378    /// Given the def-id of an early-bound lifetime on an opaque corresponding to
3379    /// a duplicated captured lifetime, map it back to the early- or late-bound
3380    /// lifetime of the function from which it originally as captured. If it is
3381    /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
3382    /// of the signature.
3383    // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
3384    // re-use the generics of the opaque, this function will need to be tweaked slightly.
3385    pub fn map_opaque_lifetime_to_parent_lifetime(
3386        self,
3387        mut opaque_lifetime_param_def_id: LocalDefId,
3388    ) -> ty::Region<'tcx> {
3389        debug_assert!(
3390            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3391            "{opaque_lifetime_param_def_id:?} is a {}",
3392            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3393        );
3394
3395        loop {
3396            let parent = self.local_parent(opaque_lifetime_param_def_id);
3397            let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3398
3399            let Some((lifetime, _)) = lifetime_mapping
3400                .iter()
3401                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3402            else {
3403                bug!("duplicated lifetime param should be present");
3404            };
3405
3406            match *lifetime {
3407                resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3408                    let new_parent = self.local_parent(ebv);
3409
3410                    // If we map to another opaque, then it should be a parent
3411                    // of the opaque we mapped from. Continue mapping.
3412                    if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3413                        debug_assert_eq!(self.local_parent(parent), new_parent);
3414                        opaque_lifetime_param_def_id = ebv;
3415                        continue;
3416                    }
3417
3418                    let generics = self.generics_of(new_parent);
3419                    return ty::Region::new_early_param(
3420                        self,
3421                        ty::EarlyParamRegion {
3422                            index: generics
3423                                .param_def_id_to_index(self, ebv.to_def_id())
3424                                .expect("early-bound var should be present in fn generics"),
3425                            name: self.item_name(ebv.to_def_id()),
3426                        },
3427                    );
3428                }
3429                resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3430                    let new_parent = self.local_parent(lbv);
3431                    return ty::Region::new_late_param(
3432                        self,
3433                        new_parent.to_def_id(),
3434                        ty::LateParamRegionKind::Named(lbv.to_def_id()),
3435                    );
3436                }
3437                resolve_bound_vars::ResolvedArg::Error(guar) => {
3438                    return ty::Region::new_error(self, guar);
3439                }
3440                _ => {
3441                    return ty::Region::new_error_with_message(
3442                        self,
3443                        self.def_span(opaque_lifetime_param_def_id),
3444                        "cannot resolve lifetime",
3445                    );
3446                }
3447            }
3448        }
3449    }
3450
3451    /// Whether `def_id` is a stable const fn (i.e., doesn't need any feature gates to be called).
3452    ///
3453    /// When this is `false`, the function may still be callable as a `const fn` due to features
3454    /// being enabled!
3455    pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3456        self.is_const_fn(def_id)
3457            && match self.lookup_const_stability(def_id) {
3458                None => true, // a fn in a non-staged_api crate
3459                Some(stability) if stability.is_const_stable() => true,
3460                _ => false,
3461            }
3462    }
3463
3464    /// Whether the trait impl is marked const. This does not consider stability or feature gates.
3465    pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3466        self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3467            && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3468    }
3469
3470    pub fn is_sdylib_interface_build(self) -> bool {
3471        self.sess.opts.unstable_opts.build_sdylib_interface
3472    }
3473
3474    pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3475        match self.def_kind(def_id) {
3476            DefKind::Fn | DefKind::AssocFn => {}
3477            _ => return None,
3478        }
3479        self.intrinsic_raw(def_id)
3480    }
3481
3482    pub fn next_trait_solver_globally(self) -> bool {
3483        self.sess.opts.unstable_opts.next_solver.globally
3484    }
3485
3486    pub fn next_trait_solver_in_coherence(self) -> bool {
3487        self.sess.opts.unstable_opts.next_solver.coherence
3488    }
3489
3490    #[allow(rustc::bad_opt_access)]
3491    pub fn use_typing_mode_borrowck(self) -> bool {
3492        self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3493    }
3494
3495    pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3496        self.opt_rpitit_info(def_id).is_some()
3497    }
3498
3499    /// Named module children from all kinds of items, including imports.
3500    /// In addition to regular items this list also includes struct and variant constructors, and
3501    /// items inside `extern {}` blocks because all of them introduce names into parent module.
3502    ///
3503    /// Module here is understood in name resolution sense - it can be a `mod` item,
3504    /// or a crate root, or an enum, or a trait.
3505    ///
3506    /// This is not a query, making it a query causes perf regressions
3507    /// (probably due to hashing spans in `ModChild`ren).
3508    pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3509        self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3510    }
3511
3512    /// Return the crate imported by given use item.
3513    pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
3514        self.resolutions(()).extern_crate_map.get(&def_id).copied()
3515    }
3516
3517    pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3518        self.resolver_for_lowering_raw(()).0
3519    }
3520
3521    pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
3522        crate::dep_graph::make_metadata(self)
3523    }
3524
3525    /// Given an `impl_id`, return the trait it implements.
3526    /// Return `None` if this is an inherent impl.
3527    pub fn impl_trait_ref(
3528        self,
3529        def_id: impl IntoQueryParam<DefId>,
3530    ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3531        Some(self.impl_trait_header(def_id)?.trait_ref)
3532    }
3533
3534    pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3535        self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3536    }
3537
3538    pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3539        if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3540            self.coroutine_kind(def_id)
3541            && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3542            && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3543        {
3544            true
3545        } else {
3546            false
3547        }
3548    }
3549
3550    /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
3551    pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3552        self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3553    }
3554
3555    /// Whether this def is one of the special bin crate entrypoint functions that must have a
3556    /// monomorphization and also not be internalized in the bin crate.
3557    pub fn is_entrypoint(self, def_id: DefId) -> bool {
3558        if self.is_lang_item(def_id, LangItem::Start) {
3559            return true;
3560        }
3561        if let Some((entry_def_id, _)) = self.entry_fn(())
3562            && entry_def_id == def_id
3563        {
3564            return true;
3565        }
3566        false
3567    }
3568}
3569
3570/// Parameter attributes that can only be determined by examining the body of a function instead
3571/// of just its signature.
3572///
3573/// These can be useful for optimization purposes when a function is directly called. We compute
3574/// them and store them into the crate metadata so that downstream crates can make use of them.
3575///
3576/// Right now, we only have `read_only`, but `no_capture` and `no_alias` might be useful in the
3577/// future.
3578#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3579pub struct DeducedParamAttrs {
3580    /// The parameter is marked immutable in the function and contains no `UnsafeCell` (i.e. its
3581    /// type is freeze).
3582    pub read_only: bool,
3583}
3584
3585pub fn provide(providers: &mut Providers) {
3586    providers.is_panic_runtime =
3587        |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3588    providers.is_compiler_builtins =
3589        |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3590    providers.has_panic_handler = |tcx, LocalCrate| {
3591        // We want to check if the panic handler was defined in this crate
3592        tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3593    };
3594    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3595}
3596
3597pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3598    attrs.iter().any(|x| x.has_name(name))
3599}