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