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