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