1#![allow(rustc::usage_of_ty_tykind)]
4
5pub mod tls;
6
7use std::assert_matches::debug_assert_matches;
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::{PhantomData, PointeeSized};
14use std::ops::{Bound, Deref};
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::fingerprint::Fingerprint;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::jobserver::Proxy;
25use rustc_data_structures::profiling::SelfProfilerRef;
26use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
27use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
28use rustc_data_structures::steal::Steal;
29use rustc_data_structures::sync::{
30    self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
31};
32use rustc_errors::{
33    Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, LintEmitter, MultiSpan,
34};
35use rustc_hir::attrs::AttributeKind;
36use rustc_hir::def::{CtorKind, CtorOf, DefKind};
37use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
38use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
39use rustc_hir::intravisit::VisitorExt;
40use rustc_hir::lang_items::LangItem;
41use rustc_hir::limit::Limit;
42use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate, find_attr};
43use rustc_index::IndexVec;
44use rustc_macros::{HashStable, TyDecodable, TyEncodable};
45use rustc_query_system::cache::WithDepNode;
46use rustc_query_system::dep_graph::DepNodeIndex;
47use rustc_query_system::ich::StableHashingContext;
48use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
49use rustc_session::Session;
50use rustc_session::config::CrateType;
51use rustc_session::cstore::{CrateStoreDyn, Untracked};
52use rustc_session::lint::Lint;
53use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
54use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
55use rustc_type_ir::TyKind::*;
56use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem};
57pub use rustc_type_ir::lift::Lift;
58use rustc_type_ir::{
59    CollectAndApply, Interner, TypeFlags, TypeFoldable, WithCachedTypeInfo, elaborate, search_graph,
60};
61use tracing::{debug, instrument};
62
63use crate::arena::Arena;
64use crate::dep_graph::{DepGraph, DepKindStruct};
65use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind, CanonicalVarKinds};
66use crate::lint::lint_level;
67use crate::metadata::ModChild;
68use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
69use crate::middle::resolve_bound_vars;
70use crate::mir::interpret::{self, Allocation, ConstAllocation};
71use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
72use crate::query::plumbing::QuerySystem;
73use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
74use crate::thir::Thir;
75use crate::traits;
76use crate::traits::solve::{
77    self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, PredefinedOpaques,
78    PredefinedOpaquesData, QueryResult, inspect,
79};
80use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
81use crate::ty::{
82    self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
83    GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, ParamTy,
84    Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
85    PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
86    ValTree, ValTreeKind, Visibility,
87};
88
89#[allow(rustc::usage_of_ty_tykind)]
90impl<'tcx> Interner for TyCtxt<'tcx> {
91    fn next_trait_solver_globally(self) -> bool {
92        self.next_trait_solver_globally()
93    }
94
95    type DefId = DefId;
96    type LocalDefId = LocalDefId;
97    type TraitId = DefId;
98    type ForeignId = DefId;
99    type FunctionId = DefId;
100    type ClosureId = DefId;
101    type CoroutineClosureId = DefId;
102    type CoroutineId = DefId;
103    type AdtId = DefId;
104    type ImplId = DefId;
105    type Span = Span;
106
107    type GenericArgs = ty::GenericArgsRef<'tcx>;
108
109    type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
110    type GenericArg = ty::GenericArg<'tcx>;
111    type Term = ty::Term<'tcx>;
112    type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
113
114    type BoundVarKind = ty::BoundVariableKind;
115    type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
116
117    fn mk_predefined_opaques_in_body(
118        self,
119        data: PredefinedOpaquesData<Self>,
120    ) -> Self::PredefinedOpaques {
121        self.mk_predefined_opaques_in_body(data)
122    }
123    type LocalDefIds = &'tcx ty::List<LocalDefId>;
124    type CanonicalVarKinds = CanonicalVarKinds<'tcx>;
125    fn mk_canonical_var_kinds(
126        self,
127        kinds: &[ty::CanonicalVarKind<Self>],
128    ) -> Self::CanonicalVarKinds {
129        self.mk_canonical_var_kinds(kinds)
130    }
131
132    type ExternalConstraints = ExternalConstraints<'tcx>;
133    fn mk_external_constraints(
134        self,
135        data: ExternalConstraintsData<Self>,
136    ) -> ExternalConstraints<'tcx> {
137        self.mk_external_constraints(data)
138    }
139    type DepNodeIndex = DepNodeIndex;
140    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
141        self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
142    }
143    type Ty = Ty<'tcx>;
144    type Tys = &'tcx List<Ty<'tcx>>;
145
146    type FnInputTys = &'tcx [Ty<'tcx>];
147    type ParamTy = ParamTy;
148    type BoundTy = ty::BoundTy;
149    type Symbol = Symbol;
150
151    type PlaceholderTy = ty::PlaceholderType;
152    type ErrorGuaranteed = ErrorGuaranteed;
153    type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
154
155    type AllocId = crate::mir::interpret::AllocId;
156    type Pat = Pattern<'tcx>;
157    type PatList = &'tcx List<Pattern<'tcx>>;
158    type Safety = hir::Safety;
159    type Abi = ExternAbi;
160    type Const = ty::Const<'tcx>;
161    type PlaceholderConst = ty::PlaceholderConst;
162
163    type ParamConst = ty::ParamConst;
164    type BoundConst = ty::BoundConst;
165    type ValueConst = ty::Value<'tcx>;
166    type ExprConst = ty::Expr<'tcx>;
167    type ValTree = ty::ValTree<'tcx>;
168
169    type Region = Region<'tcx>;
170    type EarlyParamRegion = ty::EarlyParamRegion;
171    type LateParamRegion = ty::LateParamRegion;
172    type BoundRegion = ty::BoundRegion;
173    type PlaceholderRegion = ty::PlaceholderRegion;
174
175    type RegionAssumptions = &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>;
176
177    type ParamEnv = ty::ParamEnv<'tcx>;
178    type Predicate = Predicate<'tcx>;
179
180    type Clause = Clause<'tcx>;
181    type Clauses = ty::Clauses<'tcx>;
182
183    type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
184    fn mk_tracked<T: fmt::Debug + Clone>(
185        self,
186        data: T,
187        dep_node: DepNodeIndex,
188    ) -> Self::Tracked<T> {
189        WithDepNode::new(dep_node, data)
190    }
191    fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
192        tracked.get(self)
193    }
194
195    fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
196        f(&mut *self.new_solver_evaluation_cache.lock())
197    }
198
199    fn canonical_param_env_cache_get_or_insert<R>(
200        self,
201        param_env: ty::ParamEnv<'tcx>,
202        f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry<Self>,
203        from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry<Self>) -> R,
204    ) -> R {
205        let mut cache = self.new_solver_canonical_param_env_cache.lock();
206        let entry = cache.entry(param_env).or_insert_with(f);
207        from_entry(entry)
208    }
209
210    fn evaluation_is_concurrent(&self) -> bool {
211        self.sess.threads() > 1
212    }
213
214    fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
215        self.expand_abstract_consts(t)
216    }
217
218    type GenericsOf = &'tcx ty::Generics;
219
220    fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
221        self.generics_of(def_id)
222    }
223
224    type VariancesOf = &'tcx [ty::Variance];
225
226    fn variances_of(self, def_id: DefId) -> Self::VariancesOf {
227        self.variances_of(def_id)
228    }
229
230    fn opt_alias_variances(
231        self,
232        kind: impl Into<ty::AliasTermKind>,
233        def_id: DefId,
234    ) -> Option<&'tcx [ty::Variance]> {
235        self.opt_alias_variances(kind, def_id)
236    }
237
238    fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
239        self.type_of(def_id)
240    }
241    fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
242        self.type_of_opaque_hir_typeck(def_id)
243    }
244
245    type AdtDef = ty::AdtDef<'tcx>;
246    fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
247        self.adt_def(adt_def_id)
248    }
249
250    fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
251        match self.def_kind(alias.def_id) {
252            DefKind::AssocTy => {
253                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
254                {
255                    ty::Inherent
256                } else {
257                    ty::Projection
258                }
259            }
260            DefKind::OpaqueTy => ty::Opaque,
261            DefKind::TyAlias => ty::Free,
262            kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
263        }
264    }
265
266    fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind {
267        match self.def_kind(alias.def_id) {
268            DefKind::AssocTy => {
269                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
270                {
271                    ty::AliasTermKind::InherentTy
272                } else {
273                    ty::AliasTermKind::ProjectionTy
274                }
275            }
276            DefKind::AssocConst => {
277                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
278                {
279                    ty::AliasTermKind::InherentConst
280                } else {
281                    ty::AliasTermKind::ProjectionConst
282                }
283            }
284            DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
285            DefKind::TyAlias => ty::AliasTermKind::FreeTy,
286            DefKind::Const => ty::AliasTermKind::FreeConst,
287            DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
288                ty::AliasTermKind::UnevaluatedConst
289            }
290            kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
291        }
292    }
293
294    fn trait_ref_and_own_args_for_alias(
295        self,
296        def_id: DefId,
297        args: ty::GenericArgsRef<'tcx>,
298    ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
299        debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
300        let trait_def_id = self.parent(def_id);
301        debug_assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
302        let trait_ref = ty::TraitRef::from_assoc(self, trait_def_id, args);
303        (trait_ref, &args[trait_ref.args.len()..])
304    }
305
306    fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
307        self.mk_args(args)
308    }
309
310    fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
311    where
312        I: Iterator<Item = T>,
313        T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
314    {
315        self.mk_args_from_iter(args)
316    }
317
318    fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
319        self.check_args_compatible(def_id, args)
320    }
321
322    fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
323        self.debug_assert_args_compatible(def_id, args);
324    }
325
326    fn debug_assert_existential_args_compatible(
330        self,
331        def_id: Self::DefId,
332        args: Self::GenericArgs,
333    ) {
334        if cfg!(debug_assertions) {
337            self.debug_assert_args_compatible(
338                def_id,
339                self.mk_args_from_iter(
340                    [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
341                ),
342            );
343        }
344    }
345
346    fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
347    where
348        I: Iterator<Item = T>,
349        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
350    {
351        self.mk_type_list_from_iter(args)
352    }
353
354    fn parent(self, def_id: DefId) -> DefId {
355        self.parent(def_id)
356    }
357
358    fn recursion_limit(self) -> usize {
359        self.recursion_limit().0
360    }
361
362    type Features = &'tcx rustc_feature::Features;
363
364    fn features(self) -> Self::Features {
365        self.features()
366    }
367
368    fn coroutine_hidden_types(
369        self,
370        def_id: DefId,
371    ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> {
372        self.coroutine_hidden_types(def_id)
373    }
374
375    fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
376        self.fn_sig(def_id)
377    }
378
379    fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
380        self.coroutine_movability(def_id)
381    }
382
383    fn coroutine_for_closure(self, def_id: DefId) -> DefId {
384        self.coroutine_for_closure(def_id)
385    }
386
387    fn generics_require_sized_self(self, def_id: DefId) -> bool {
388        self.generics_require_sized_self(def_id)
389    }
390
391    fn item_bounds(
392        self,
393        def_id: DefId,
394    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
395        self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
396    }
397
398    fn item_self_bounds(
399        self,
400        def_id: DefId,
401    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
402        self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
403    }
404
405    fn item_non_self_bounds(
406        self,
407        def_id: DefId,
408    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
409        self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
410    }
411
412    fn predicates_of(
413        self,
414        def_id: DefId,
415    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
416        ty::EarlyBinder::bind(
417            self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
418        )
419    }
420
421    fn own_predicates_of(
422        self,
423        def_id: DefId,
424    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
425        ty::EarlyBinder::bind(
426            self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
427        )
428    }
429
430    fn explicit_super_predicates_of(
431        self,
432        def_id: DefId,
433    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
434        self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
435    }
436
437    fn explicit_implied_predicates_of(
438        self,
439        def_id: DefId,
440    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
441        self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
442    }
443
444    fn impl_super_outlives(
445        self,
446        impl_def_id: DefId,
447    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
448        self.impl_super_outlives(impl_def_id)
449    }
450
451    fn impl_is_const(self, def_id: DefId) -> bool {
452        debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
453        self.is_conditionally_const(def_id)
454    }
455
456    fn fn_is_const(self, def_id: DefId) -> bool {
457        debug_assert_matches!(
458            self.def_kind(def_id),
459            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
460        );
461        self.is_conditionally_const(def_id)
462    }
463
464    fn alias_has_const_conditions(self, def_id: DefId) -> bool {
465        debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
466        self.is_conditionally_const(def_id)
467    }
468
469    fn const_conditions(
470        self,
471        def_id: DefId,
472    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
473        ty::EarlyBinder::bind(
474            self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
475        )
476    }
477
478    fn explicit_implied_const_bounds(
479        self,
480        def_id: DefId,
481    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
482        ty::EarlyBinder::bind(
483            self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
484        )
485    }
486
487    fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
488        self.impl_self_is_guaranteed_unsized(impl_def_id)
489    }
490
491    fn has_target_features(self, def_id: DefId) -> bool {
492        !self.codegen_fn_attrs(def_id).target_features.is_empty()
493    }
494
495    fn require_lang_item(self, lang_item: SolverLangItem) -> DefId {
496        self.require_lang_item(solver_lang_item_to_lang_item(lang_item), DUMMY_SP)
497    }
498
499    fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> DefId {
500        self.require_lang_item(solver_trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
501    }
502
503    fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> DefId {
504        self.require_lang_item(solver_adt_lang_item_to_lang_item(lang_item), DUMMY_SP)
505    }
506
507    fn is_lang_item(self, def_id: DefId, lang_item: SolverLangItem) -> bool {
508        self.is_lang_item(def_id, solver_lang_item_to_lang_item(lang_item))
509    }
510
511    fn is_trait_lang_item(self, def_id: DefId, lang_item: SolverTraitLangItem) -> bool {
512        self.is_lang_item(def_id, solver_trait_lang_item_to_lang_item(lang_item))
513    }
514
515    fn is_adt_lang_item(self, def_id: DefId, lang_item: SolverAdtLangItem) -> bool {
516        self.is_lang_item(def_id, solver_adt_lang_item_to_lang_item(lang_item))
517    }
518
519    fn is_default_trait(self, def_id: DefId) -> bool {
520        self.is_default_trait(def_id)
521    }
522
523    fn as_lang_item(self, def_id: DefId) -> Option<SolverLangItem> {
524        lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?)
525    }
526
527    fn as_trait_lang_item(self, def_id: DefId) -> Option<SolverTraitLangItem> {
528        lang_item_to_solver_trait_lang_item(self.lang_items().from_def_id(def_id)?)
529    }
530
531    fn as_adt_lang_item(self, def_id: DefId) -> Option<SolverAdtLangItem> {
532        lang_item_to_solver_adt_lang_item(self.lang_items().from_def_id(def_id)?)
533    }
534
535    fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
536        self.associated_items(def_id)
537            .in_definition_order()
538            .filter(|assoc_item| assoc_item.is_type())
539            .map(|assoc_item| assoc_item.def_id)
540    }
541
542    fn for_each_relevant_impl(
546        self,
547        trait_def_id: DefId,
548        self_ty: Ty<'tcx>,
549        mut f: impl FnMut(DefId),
550    ) {
551        let tcx = self;
552        let trait_impls = tcx.trait_impls_of(trait_def_id);
553        let mut consider_impls_for_simplified_type = |simp| {
554            if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
555                for &impl_def_id in impls_for_type {
556                    f(impl_def_id);
557                }
558            }
559        };
560
561        match self_ty.kind() {
562            ty::Bool
563            | ty::Char
564            | ty::Int(_)
565            | ty::Uint(_)
566            | ty::Float(_)
567            | ty::Adt(_, _)
568            | ty::Foreign(_)
569            | ty::Str
570            | ty::Array(_, _)
571            | ty::Pat(_, _)
572            | ty::Slice(_)
573            | ty::RawPtr(_, _)
574            | ty::Ref(_, _, _)
575            | ty::FnDef(_, _)
576            | ty::FnPtr(..)
577            | ty::Dynamic(_, _, _)
578            | ty::Closure(..)
579            | ty::CoroutineClosure(..)
580            | ty::Coroutine(_, _)
581            | ty::Never
582            | ty::Tuple(_)
583            | ty::UnsafeBinder(_) => {
584                let simp = ty::fast_reject::simplify_type(
585                    tcx,
586                    self_ty,
587                    ty::fast_reject::TreatParams::AsRigid,
588                )
589                .unwrap();
590                consider_impls_for_simplified_type(simp);
591            }
592
593            ty::Infer(ty::IntVar(_)) => {
596                use ty::IntTy::*;
597                use ty::UintTy::*;
598                let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
600                let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
601                let possible_integers = [
602                    ty::SimplifiedType::Int(I8),
604                    ty::SimplifiedType::Int(I16),
605                    ty::SimplifiedType::Int(I32),
606                    ty::SimplifiedType::Int(I64),
607                    ty::SimplifiedType::Int(I128),
608                    ty::SimplifiedType::Int(Isize),
609                    ty::SimplifiedType::Uint(U8),
611                    ty::SimplifiedType::Uint(U16),
612                    ty::SimplifiedType::Uint(U32),
613                    ty::SimplifiedType::Uint(U64),
614                    ty::SimplifiedType::Uint(U128),
615                    ty::SimplifiedType::Uint(Usize),
616                ];
617                for simp in possible_integers {
618                    consider_impls_for_simplified_type(simp);
619                }
620            }
621
622            ty::Infer(ty::FloatVar(_)) => {
623                let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
625                let possible_floats = [
626                    ty::SimplifiedType::Float(ty::FloatTy::F16),
627                    ty::SimplifiedType::Float(ty::FloatTy::F32),
628                    ty::SimplifiedType::Float(ty::FloatTy::F64),
629                    ty::SimplifiedType::Float(ty::FloatTy::F128),
630                ];
631
632                for simp in possible_floats {
633                    consider_impls_for_simplified_type(simp);
634                }
635            }
636
637            ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
642
643            ty::CoroutineWitness(..) => (),
647
648            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
650            | ty::Param(_)
651            | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
652        }
653
654        #[allow(rustc::usage_of_type_ir_traits)]
655        self.for_each_blanket_impl(trait_def_id, f)
656    }
657    fn for_each_blanket_impl(self, trait_def_id: DefId, mut f: impl FnMut(DefId)) {
658        let trait_impls = self.trait_impls_of(trait_def_id);
659        for &impl_def_id in trait_impls.blanket_impls() {
660            f(impl_def_id);
661        }
662    }
663
664    fn has_item_definition(self, def_id: DefId) -> bool {
665        self.defaultness(def_id).has_value()
666    }
667
668    fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
669        self.specializes((impl_def_id, victim_def_id))
670    }
671
672    fn impl_is_default(self, impl_def_id: DefId) -> bool {
673        self.defaultness(impl_def_id).is_default()
674    }
675
676    fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
677        self.impl_trait_ref(impl_def_id).unwrap()
678    }
679
680    fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
681        self.impl_polarity(impl_def_id)
682    }
683
684    fn trait_is_auto(self, trait_def_id: DefId) -> bool {
685        self.trait_is_auto(trait_def_id)
686    }
687
688    fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
689        self.trait_is_coinductive(trait_def_id)
690    }
691
692    fn trait_is_alias(self, trait_def_id: DefId) -> bool {
693        self.trait_is_alias(trait_def_id)
694    }
695
696    fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
697        self.is_dyn_compatible(trait_def_id)
698    }
699
700    fn trait_is_fundamental(self, def_id: DefId) -> bool {
701        self.trait_def(def_id).is_fundamental
702    }
703
704    fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
705        self.trait_def(trait_def_id).implement_via_object
706    }
707
708    fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
709        self.trait_def(trait_def_id).safety.is_unsafe()
710    }
711
712    fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
713        self.is_impl_trait_in_trait(def_id)
714    }
715
716    fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
717        self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
718    }
719
720    fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
721        self.is_general_coroutine(coroutine_def_id)
722    }
723
724    fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
725        self.coroutine_is_async(coroutine_def_id)
726    }
727
728    fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
729        self.coroutine_is_gen(coroutine_def_id)
730    }
731
732    fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
733        self.coroutine_is_async_gen(coroutine_def_id)
734    }
735
736    type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
737    fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
738        self.unsizing_params_for_adt(adt_def_id)
739    }
740
741    fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
742        self,
743        binder: ty::Binder<'tcx, T>,
744    ) -> ty::Binder<'tcx, T> {
745        self.anonymize_bound_vars(binder)
746    }
747
748    fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
749        self.opaque_types_defined_by(defining_anchor)
750    }
751
752    fn opaque_types_and_coroutines_defined_by(
753        self,
754        defining_anchor: Self::LocalDefId,
755    ) -> Self::LocalDefIds {
756        let coroutines_defined_by = self
757            .nested_bodies_within(defining_anchor)
758            .iter()
759            .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
760        self.mk_local_def_ids_from_iter(
761            self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
762        )
763    }
764
765    type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
766    fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
767        self.arena.alloc(probe)
768    }
769    fn evaluate_root_goal_for_proof_tree_raw(
770        self,
771        canonical_goal: CanonicalInput<'tcx>,
772    ) -> (QueryResult<'tcx>, &'tcx inspect::Probe<TyCtxt<'tcx>>) {
773        self.evaluate_root_goal_for_proof_tree_raw(canonical_goal)
774    }
775}
776
777macro_rules! bidirectional_lang_item_map {
778    (
779        $solver_ty:ident, $to_solver:ident, $from_solver:ident;
780        $($name:ident),+ $(,)?
781    ) => {
782        fn $from_solver(lang_item: $solver_ty) -> LangItem {
783            match lang_item {
784                $($solver_ty::$name => LangItem::$name,)+
785            }
786        }
787
788        fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> {
789            Some(match lang_item {
790                $(LangItem::$name => $solver_ty::$name,)+
791                _ => return None,
792            })
793        }
794    }
795}
796
797bidirectional_lang_item_map! {
798    SolverLangItem, lang_item_to_solver_lang_item, solver_lang_item_to_lang_item;
799
800AsyncFnKindUpvars,
802    AsyncFnOnceOutput,
803    CallOnceFuture,
804    CallRefFuture,
805    CoroutineReturn,
806    CoroutineYield,
807    DynMetadata,
808    FutureOutput,
809    Metadata,
810}
812
813bidirectional_lang_item_map! {
814    SolverAdtLangItem, lang_item_to_solver_adt_lang_item, solver_adt_lang_item_to_lang_item;
815
816Option,
818    Poll,
819}
821
822bidirectional_lang_item_map! {
823    SolverTraitLangItem, lang_item_to_solver_trait_lang_item, solver_trait_lang_item_to_lang_item;
824
825AsyncFn,
827    AsyncFnKindHelper,
828    AsyncFnMut,
829    AsyncFnOnce,
830    AsyncFnOnceOutput,
831    AsyncIterator,
832    BikeshedGuaranteedNoDrop,
833    Clone,
834    Copy,
835    Coroutine,
836    Destruct,
837    DiscriminantKind,
838    Drop,
839    Fn,
840    FnMut,
841    FnOnce,
842    FnPtrTrait,
843    FusedIterator,
844    Future,
845    Iterator,
846    MetaSized,
847    PointeeSized,
848    PointeeTrait,
849    Sized,
850    TransmuteTrait,
851    Tuple,
852    Unpin,
853    Unsize,
854}
856
857impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
858    fn is_local(self) -> bool {
859        self.is_local()
860    }
861
862    fn as_local(self) -> Option<LocalDefId> {
863        self.as_local()
864    }
865}
866
867impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
868    fn rust() -> Self {
869        ExternAbi::Rust
870    }
871
872    fn is_rust(self) -> bool {
873        matches!(self, ExternAbi::Rust)
874    }
875}
876
877impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
878    fn safe() -> Self {
879        hir::Safety::Safe
880    }
881
882    fn is_safe(self) -> bool {
883        self.is_safe()
884    }
885
886    fn prefix_str(self) -> &'static str {
887        self.prefix_str()
888    }
889}
890
891impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
892    fn generic_const_exprs(self) -> bool {
893        self.generic_const_exprs()
894    }
895
896    fn coroutine_clone(self) -> bool {
897        self.coroutine_clone()
898    }
899
900    fn associated_const_equality(self) -> bool {
901        self.associated_const_equality()
902    }
903
904    fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
905        !self.staged_api() && self.enabled(symbol)
909    }
910}
911
912impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
913    fn dummy() -> Self {
914        DUMMY_SP
915    }
916}
917
918type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
919
920pub struct CtxtInterners<'tcx> {
921    arena: &'tcx WorkerLocal<Arena<'tcx>>,
923
924    type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
927    const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
928    args: InternedSet<'tcx, GenericArgs<'tcx>>,
929    type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
930    canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
931    region: InternedSet<'tcx, RegionKind<'tcx>>,
932    poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
933    predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
934    clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
935    projs: InternedSet<'tcx, List<ProjectionKind>>,
936    place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
937    const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
938    pat: InternedSet<'tcx, PatternKind<'tcx>>,
939    const_allocation: InternedSet<'tcx, Allocation>,
940    bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
941    layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
942    adt_def: InternedSet<'tcx, AdtDefData>,
943    external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
944    predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
945    fields: InternedSet<'tcx, List<FieldIdx>>,
946    local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
947    captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
948    offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
949    valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
950    patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
951    outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
952}
953
954impl<'tcx> CtxtInterners<'tcx> {
955    fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
956        const N: usize = 2048;
959        CtxtInterners {
960            arena,
961            type_: InternedSet::with_capacity(N * 16),
965            const_lists: InternedSet::with_capacity(N * 4),
966            args: InternedSet::with_capacity(N * 4),
967            type_lists: InternedSet::with_capacity(N * 4),
968            region: InternedSet::with_capacity(N * 4),
969            poly_existential_predicates: InternedSet::with_capacity(N / 4),
970            canonical_var_kinds: InternedSet::with_capacity(N / 2),
971            predicate: InternedSet::with_capacity(N),
972            clauses: InternedSet::with_capacity(N),
973            projs: InternedSet::with_capacity(N * 4),
974            place_elems: InternedSet::with_capacity(N * 2),
975            const_: InternedSet::with_capacity(N * 2),
976            pat: InternedSet::with_capacity(N),
977            const_allocation: InternedSet::with_capacity(N),
978            bound_variable_kinds: InternedSet::with_capacity(N * 2),
979            layout: InternedSet::with_capacity(N),
980            adt_def: InternedSet::with_capacity(N),
981            external_constraints: InternedSet::with_capacity(N),
982            predefined_opaques_in_body: InternedSet::with_capacity(N),
983            fields: InternedSet::with_capacity(N * 4),
984            local_def_ids: InternedSet::with_capacity(N),
985            captures: InternedSet::with_capacity(N),
986            offset_of: InternedSet::with_capacity(N),
987            valtree: InternedSet::with_capacity(N),
988            patterns: InternedSet::with_capacity(N),
989            outlives: InternedSet::with_capacity(N),
990        }
991    }
992
993    #[allow(rustc::usage_of_ty_tykind)]
995    #[inline(never)]
996    fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
997        Ty(Interned::new_unchecked(
998            self.type_
999                .intern(kind, |kind| {
1000                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
1001                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1002
1003                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1004                        internee: kind,
1005                        stable_hash,
1006                        flags: flags.flags,
1007                        outer_exclusive_binder: flags.outer_exclusive_binder,
1008                    }))
1009                })
1010                .0,
1011        ))
1012    }
1013
1014    #[allow(rustc::usage_of_ty_tykind)]
1016    #[inline(never)]
1017    fn intern_const(
1018        &self,
1019        kind: ty::ConstKind<'tcx>,
1020        sess: &Session,
1021        untracked: &Untracked,
1022    ) -> Const<'tcx> {
1023        Const(Interned::new_unchecked(
1024            self.const_
1025                .intern(kind, |kind: ty::ConstKind<'_>| {
1026                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
1027                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1028
1029                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1030                        internee: kind,
1031                        stable_hash,
1032                        flags: flags.flags,
1033                        outer_exclusive_binder: flags.outer_exclusive_binder,
1034                    }))
1035                })
1036                .0,
1037        ))
1038    }
1039
1040    fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
1041        &self,
1042        flags: &ty::FlagComputation<TyCtxt<'tcx>>,
1043        sess: &'a Session,
1044        untracked: &'a Untracked,
1045        val: &T,
1046    ) -> Fingerprint {
1047        if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
1050            Fingerprint::ZERO
1051        } else {
1052            let mut hasher = StableHasher::new();
1053            let mut hcx = StableHashingContext::new(sess, untracked);
1054            val.hash_stable(&mut hcx, &mut hasher);
1055            hasher.finish()
1056        }
1057    }
1058
1059    #[inline(never)]
1061    fn intern_predicate(
1062        &self,
1063        kind: Binder<'tcx, PredicateKind<'tcx>>,
1064        sess: &Session,
1065        untracked: &Untracked,
1066    ) -> Predicate<'tcx> {
1067        Predicate(Interned::new_unchecked(
1068            self.predicate
1069                .intern(kind, |kind| {
1070                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
1071
1072                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1073
1074                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1075                        internee: kind,
1076                        stable_hash,
1077                        flags: flags.flags,
1078                        outer_exclusive_binder: flags.outer_exclusive_binder,
1079                    }))
1080                })
1081                .0,
1082        ))
1083    }
1084
1085    fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
1086        if clauses.is_empty() {
1087            ListWithCachedTypeInfo::empty()
1088        } else {
1089            self.clauses
1090                .intern_ref(clauses, || {
1091                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
1092
1093                    InternedInSet(ListWithCachedTypeInfo::from_arena(
1094                        &*self.arena,
1095                        flags.into(),
1096                        clauses,
1097                    ))
1098                })
1099                .0
1100        }
1101    }
1102}
1103
1104const NUM_PREINTERNED_TY_VARS: u32 = 100;
1109const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
1110const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
1111const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
1112const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
1113const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
1114
1115const NUM_PREINTERNED_RE_VARS: u32 = 500;
1117const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
1118const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
1119
1120pub struct CommonTypes<'tcx> {
1121    pub unit: Ty<'tcx>,
1122    pub bool: Ty<'tcx>,
1123    pub char: Ty<'tcx>,
1124    pub isize: Ty<'tcx>,
1125    pub i8: Ty<'tcx>,
1126    pub i16: Ty<'tcx>,
1127    pub i32: Ty<'tcx>,
1128    pub i64: Ty<'tcx>,
1129    pub i128: Ty<'tcx>,
1130    pub usize: Ty<'tcx>,
1131    pub u8: Ty<'tcx>,
1132    pub u16: Ty<'tcx>,
1133    pub u32: Ty<'tcx>,
1134    pub u64: Ty<'tcx>,
1135    pub u128: Ty<'tcx>,
1136    pub f16: Ty<'tcx>,
1137    pub f32: Ty<'tcx>,
1138    pub f64: Ty<'tcx>,
1139    pub f128: Ty<'tcx>,
1140    pub str_: Ty<'tcx>,
1141    pub never: Ty<'tcx>,
1142    pub self_param: Ty<'tcx>,
1143
1144    pub trait_object_dummy_self: Ty<'tcx>,
1149
1150    pub ty_vars: Vec<Ty<'tcx>>,
1152
1153    pub fresh_tys: Vec<Ty<'tcx>>,
1155
1156    pub fresh_int_tys: Vec<Ty<'tcx>>,
1158
1159    pub fresh_float_tys: Vec<Ty<'tcx>>,
1161
1162    pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
1166}
1167
1168pub struct CommonLifetimes<'tcx> {
1169    pub re_static: Region<'tcx>,
1171
1172    pub re_erased: Region<'tcx>,
1174
1175    pub re_vars: Vec<Region<'tcx>>,
1177
1178    pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
1182}
1183
1184pub struct CommonConsts<'tcx> {
1185    pub unit: Const<'tcx>,
1186    pub true_: Const<'tcx>,
1187    pub false_: Const<'tcx>,
1188    pub(crate) valtree_zst: ValTree<'tcx>,
1190}
1191
1192impl<'tcx> CommonTypes<'tcx> {
1193    fn new(
1194        interners: &CtxtInterners<'tcx>,
1195        sess: &Session,
1196        untracked: &Untracked,
1197    ) -> CommonTypes<'tcx> {
1198        let mk = |ty| interners.intern_ty(ty, sess, untracked);
1199
1200        let ty_vars =
1201            (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1202        let fresh_tys: Vec<_> =
1203            (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1204        let fresh_int_tys: Vec<_> =
1205            (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1206        let fresh_float_tys: Vec<_> =
1207            (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1208
1209        let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
1210            .map(|i| {
1211                (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
1212                    .map(|v| {
1213                        mk(ty::Bound(
1214                            ty::DebruijnIndex::from(i),
1215                            ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
1216                        ))
1217                    })
1218                    .collect()
1219            })
1220            .collect();
1221
1222        CommonTypes {
1223            unit: mk(Tuple(List::empty())),
1224            bool: mk(Bool),
1225            char: mk(Char),
1226            never: mk(Never),
1227            isize: mk(Int(ty::IntTy::Isize)),
1228            i8: mk(Int(ty::IntTy::I8)),
1229            i16: mk(Int(ty::IntTy::I16)),
1230            i32: mk(Int(ty::IntTy::I32)),
1231            i64: mk(Int(ty::IntTy::I64)),
1232            i128: mk(Int(ty::IntTy::I128)),
1233            usize: mk(Uint(ty::UintTy::Usize)),
1234            u8: mk(Uint(ty::UintTy::U8)),
1235            u16: mk(Uint(ty::UintTy::U16)),
1236            u32: mk(Uint(ty::UintTy::U32)),
1237            u64: mk(Uint(ty::UintTy::U64)),
1238            u128: mk(Uint(ty::UintTy::U128)),
1239            f16: mk(Float(ty::FloatTy::F16)),
1240            f32: mk(Float(ty::FloatTy::F32)),
1241            f64: mk(Float(ty::FloatTy::F64)),
1242            f128: mk(Float(ty::FloatTy::F128)),
1243            str_: mk(Str),
1244            self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1245
1246            trait_object_dummy_self: fresh_tys[0],
1247
1248            ty_vars,
1249            fresh_tys,
1250            fresh_int_tys,
1251            fresh_float_tys,
1252            anon_bound_tys,
1253        }
1254    }
1255}
1256
1257impl<'tcx> CommonLifetimes<'tcx> {
1258    fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1259        let mk = |r| {
1260            Region(Interned::new_unchecked(
1261                interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1262            ))
1263        };
1264
1265        let re_vars =
1266            (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1267
1268        let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
1269            .map(|i| {
1270                (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
1271                    .map(|v| {
1272                        mk(ty::ReBound(
1273                            ty::DebruijnIndex::from(i),
1274                            ty::BoundRegion {
1275                                var: ty::BoundVar::from(v),
1276                                kind: ty::BoundRegionKind::Anon,
1277                            },
1278                        ))
1279                    })
1280                    .collect()
1281            })
1282            .collect();
1283
1284        CommonLifetimes {
1285            re_static: mk(ty::ReStatic),
1286            re_erased: mk(ty::ReErased),
1287            re_vars,
1288            anon_re_bounds,
1289        }
1290    }
1291}
1292
1293impl<'tcx> CommonConsts<'tcx> {
1294    fn new(
1295        interners: &CtxtInterners<'tcx>,
1296        types: &CommonTypes<'tcx>,
1297        sess: &Session,
1298        untracked: &Untracked,
1299    ) -> CommonConsts<'tcx> {
1300        let mk_const = |c| {
1301            interners.intern_const(
1302                c, sess, untracked,
1304            )
1305        };
1306
1307        let mk_valtree = |v| {
1308            ty::ValTree(Interned::new_unchecked(
1309                interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1310            ))
1311        };
1312
1313        let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1314        let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1315        let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1316
1317        CommonConsts {
1318            unit: mk_const(ty::ConstKind::Value(ty::Value {
1319                ty: types.unit,
1320                valtree: valtree_zst,
1321            })),
1322            true_: mk_const(ty::ConstKind::Value(ty::Value {
1323                ty: types.bool,
1324                valtree: valtree_true,
1325            })),
1326            false_: mk_const(ty::ConstKind::Value(ty::Value {
1327                ty: types.bool,
1328                valtree: valtree_false,
1329            })),
1330            valtree_zst,
1331        }
1332    }
1333}
1334
1335#[derive(Debug)]
1338pub struct FreeRegionInfo {
1339    pub scope: LocalDefId,
1341    pub region_def_id: DefId,
1343    pub is_impl_item: bool,
1345}
1346
1347#[derive(Copy, Clone)]
1349pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1350    pub tcx: TyCtxt<'tcx>,
1351    key: KEY,
1353}
1354
1355impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1358
1359#[derive(Copy, Clone)]
1364pub struct Feed<'tcx, KEY: Copy> {
1365    _tcx: PhantomData<TyCtxt<'tcx>>,
1366    key: KEY,
1368}
1369
1370impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1373
1374impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1375    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1376        self.key.fmt(f)
1377    }
1378}
1379
1380impl<'tcx> TyCtxt<'tcx> {
1385    pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1388        self.dep_graph.assert_ignored();
1389        TyCtxtFeed { tcx: self, key: () }
1390    }
1391
1392    pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1395        let key = self.untracked().source_span.push(span);
1396        assert_eq!(key, CRATE_DEF_ID);
1397        TyCtxtFeed { tcx: self, key }
1398    }
1399
1400    pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1404        debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1405        TyCtxtFeed { tcx: self, key }.type_of(value)
1406    }
1407}
1408
1409impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1410    #[inline(always)]
1411    pub fn key(&self) -> KEY {
1412        self.key
1413    }
1414
1415    #[inline(always)]
1416    pub fn downgrade(self) -> Feed<'tcx, KEY> {
1417        Feed { _tcx: PhantomData, key: self.key }
1418    }
1419}
1420
1421impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1422    #[inline(always)]
1423    pub fn key(&self) -> KEY {
1424        self.key
1425    }
1426
1427    #[inline(always)]
1428    pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1429        TyCtxtFeed { tcx, key: self.key }
1430    }
1431}
1432
1433impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1434    #[inline(always)]
1435    pub fn def_id(&self) -> LocalDefId {
1436        self.key
1437    }
1438
1439    pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1441        TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1442    }
1443
1444    pub fn feed_hir(&self) {
1446        self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1447
1448        let node = hir::OwnerNode::Synthetic;
1449        let bodies = Default::default();
1450        let attrs = hir::AttributeMap::EMPTY;
1451
1452        let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
1453            self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
1454        let node = node.into();
1455        self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1456            opt_hash_including_bodies,
1457            nodes: IndexVec::from_elem_n(
1458                hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1459                1,
1460            ),
1461            bodies,
1462        })));
1463        self.feed_owner_id().hir_attr_map(attrs);
1464    }
1465}
1466
1467#[derive(Copy, Clone)]
1485#[rustc_diagnostic_item = "TyCtxt"]
1486#[rustc_pass_by_value]
1487pub struct TyCtxt<'tcx> {
1488    gcx: &'tcx GlobalCtxt<'tcx>,
1489}
1490
1491impl<'tcx> LintEmitter for TyCtxt<'tcx> {
1492    type Id = HirId;
1493
1494    fn emit_node_span_lint(
1495        self,
1496        lint: &'static Lint,
1497        hir_id: HirId,
1498        span: impl Into<MultiSpan>,
1499        decorator: impl for<'a> LintDiagnostic<'a, ()>,
1500    ) {
1501        self.emit_node_span_lint(lint, hir_id, span, decorator);
1502    }
1503}
1504
1505unsafe impl DynSend for TyCtxt<'_> {}
1509unsafe impl DynSync for TyCtxt<'_> {}
1510fn _assert_tcx_fields() {
1511    sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1512    sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1513}
1514
1515impl<'tcx> Deref for TyCtxt<'tcx> {
1516    type Target = &'tcx GlobalCtxt<'tcx>;
1517    #[inline(always)]
1518    fn deref(&self) -> &Self::Target {
1519        &self.gcx
1520    }
1521}
1522
1523pub struct GlobalCtxt<'tcx> {
1525    pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1526    pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1527
1528    interners: CtxtInterners<'tcx>,
1529
1530    pub sess: &'tcx Session,
1531    crate_types: Vec<CrateType>,
1532    stable_crate_id: StableCrateId,
1538
1539    pub dep_graph: DepGraph,
1540
1541    pub prof: SelfProfilerRef,
1542
1543    pub types: CommonTypes<'tcx>,
1545
1546    pub lifetimes: CommonLifetimes<'tcx>,
1548
1549    pub consts: CommonConsts<'tcx>,
1551
1552    pub(crate) hooks: crate::hooks::Providers,
1555
1556    untracked: Untracked,
1557
1558    pub query_system: QuerySystem<'tcx>,
1559    pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1560
1561    pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1563
1564    pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1567
1568    pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1572
1573    pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1575    pub new_solver_canonical_param_env_cache:
1576        Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
1577
1578    pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1579
1580    pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
1582    pub clauses_cache:
1584        Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
1585
1586    pub data_layout: TargetDataLayout,
1588
1589    pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1591
1592    current_gcx: CurrentGcx,
1593
1594    pub jobserver_proxy: Arc<Proxy>,
1596}
1597
1598impl<'tcx> GlobalCtxt<'tcx> {
1599    pub fn enter<F, R>(&'tcx self, f: F) -> R
1602    where
1603        F: FnOnce(TyCtxt<'tcx>) -> R,
1604    {
1605        let icx = tls::ImplicitCtxt::new(self);
1606
1607        let _on_drop = defer(move || {
1609            *self.current_gcx.value.write() = None;
1610        });
1611
1612        {
1614            let mut guard = self.current_gcx.value.write();
1615            assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1616            *guard = Some(self as *const _ as *const ());
1617        }
1618
1619        tls::enter_context(&icx, || f(icx.tcx))
1620    }
1621}
1622
1623#[derive(Clone)]
1630pub struct CurrentGcx {
1631    value: Arc<RwLock<Option<*const ()>>>,
1634}
1635
1636unsafe impl DynSend for CurrentGcx {}
1637unsafe impl DynSync for CurrentGcx {}
1638
1639impl CurrentGcx {
1640    pub fn new() -> Self {
1641        Self { value: Arc::new(RwLock::new(None)) }
1642    }
1643
1644    pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1645        let read_guard = self.value.read();
1646        let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1647        f(unsafe { &*gcx })
1651    }
1652}
1653
1654impl<'tcx> TyCtxt<'tcx> {
1655    pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1656        let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1659        if typeck_root_def_id != def_id.to_def_id() {
1660            return self.has_typeck_results(typeck_root_def_id.expect_local());
1661        }
1662
1663        self.hir_node_by_def_id(def_id).body_id().is_some()
1664    }
1665
1666    pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1671        let def_kind = self.def_kind(def_id);
1672        if def_kind.has_codegen_attrs() {
1673            self.codegen_fn_attrs(def_id)
1674        } else if matches!(
1675            def_kind,
1676            DefKind::AnonConst
1677                | DefKind::AssocConst
1678                | DefKind::Const
1679                | DefKind::InlineConst
1680                | DefKind::GlobalAsm
1681        ) {
1682            CodegenFnAttrs::EMPTY
1683        } else {
1684            bug!(
1685                "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1686                def_id,
1687                def_kind
1688            )
1689        }
1690    }
1691
1692    pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1693        self.arena.alloc(Steal::new(thir))
1694    }
1695
1696    pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1697        self.arena.alloc(Steal::new(mir))
1698    }
1699
1700    pub fn alloc_steal_promoted(
1701        self,
1702        promoted: IndexVec<Promoted, Body<'tcx>>,
1703    ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1704        self.arena.alloc(Steal::new(promoted))
1705    }
1706
1707    pub fn mk_adt_def(
1708        self,
1709        did: DefId,
1710        kind: AdtKind,
1711        variants: IndexVec<VariantIdx, ty::VariantDef>,
1712        repr: ReprOptions,
1713    ) -> ty::AdtDef<'tcx> {
1714        self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1715    }
1716
1717    pub fn allocate_bytes_dedup<'a>(
1720        self,
1721        bytes: impl Into<Cow<'a, [u8]>>,
1722        salt: usize,
1723    ) -> interpret::AllocId {
1724        let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
1726        let alloc = self.mk_const_alloc(alloc);
1727        self.reserve_and_set_memory_dedup(alloc, salt)
1728    }
1729
1730    pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1732        if self.sess.opts.unstable_opts.experimental_default_bounds {
1733            &[
1734                LangItem::DefaultTrait1,
1735                LangItem::DefaultTrait2,
1736                LangItem::DefaultTrait3,
1737                LangItem::DefaultTrait4,
1738            ]
1739        } else {
1740            &[]
1741        }
1742    }
1743
1744    pub fn is_default_trait(self, def_id: DefId) -> bool {
1745        self.default_traits()
1746            .iter()
1747            .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
1748    }
1749
1750    pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1754        let start = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1755        let end = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1756        (start, end)
1757    }
1758
1759    pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1760        value.lift_to_interner(self)
1761    }
1762
1763    pub fn create_global_ctxt<T>(
1770        gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1771        s: &'tcx Session,
1772        crate_types: Vec<CrateType>,
1773        stable_crate_id: StableCrateId,
1774        arena: &'tcx WorkerLocal<Arena<'tcx>>,
1775        hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1776        untracked: Untracked,
1777        dep_graph: DepGraph,
1778        query_kinds: &'tcx [DepKindStruct<'tcx>],
1779        query_system: QuerySystem<'tcx>,
1780        hooks: crate::hooks::Providers,
1781        current_gcx: CurrentGcx,
1782        jobserver_proxy: Arc<Proxy>,
1783        f: impl FnOnce(TyCtxt<'tcx>) -> T,
1784    ) -> T {
1785        let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1786            s.dcx().emit_fatal(err);
1787        });
1788        let interners = CtxtInterners::new(arena);
1789        let common_types = CommonTypes::new(&interners, s, &untracked);
1790        let common_lifetimes = CommonLifetimes::new(&interners);
1791        let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1792
1793        let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1794            sess: s,
1795            crate_types,
1796            stable_crate_id,
1797            arena,
1798            hir_arena,
1799            interners,
1800            dep_graph,
1801            hooks,
1802            prof: s.prof.clone(),
1803            types: common_types,
1804            lifetimes: common_lifetimes,
1805            consts: common_consts,
1806            untracked,
1807            query_system,
1808            query_kinds,
1809            ty_rcache: Default::default(),
1810            selection_cache: Default::default(),
1811            evaluation_cache: Default::default(),
1812            new_solver_evaluation_cache: Default::default(),
1813            new_solver_canonical_param_env_cache: Default::default(),
1814            canonical_param_env_cache: Default::default(),
1815            highest_var_in_clauses_cache: Default::default(),
1816            clauses_cache: Default::default(),
1817            data_layout,
1818            alloc_map: interpret::AllocMap::new(),
1819            current_gcx,
1820            jobserver_proxy,
1821        });
1822
1823        gcx.enter(f)
1825    }
1826
1827    pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1829        self.get_lang_items(())
1830    }
1831
1832    #[track_caller]
1834    pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1835        let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1836        self.type_of(ordering_enum).no_bound_vars().unwrap()
1837    }
1838
1839    pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1842        self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1843    }
1844
1845    pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1847        self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1848    }
1849
1850    pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1852        self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1853    }
1854
1855    pub fn is_coroutine(self, def_id: DefId) -> bool {
1856        self.coroutine_kind(def_id).is_some()
1857    }
1858
1859    pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1860        self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1861    }
1862
1863    pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1866        self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1867    }
1868
1869    pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1871        matches!(
1872            self.coroutine_kind(def_id),
1873            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1874        )
1875    }
1876
1877    pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1880        matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1881    }
1882
1883    pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1886        matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1887    }
1888
1889    pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1891        matches!(
1892            self.coroutine_kind(def_id),
1893            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1894        )
1895    }
1896
1897    pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1899        matches!(
1900            self.coroutine_kind(def_id),
1901            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1902        )
1903    }
1904
1905    pub fn features(self) -> &'tcx rustc_feature::Features {
1906        self.features_query(())
1907    }
1908
1909    pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1910        let id = id.into_query_param();
1911        if let Some(id) = id.as_local() {
1913            self.definitions_untracked().def_key(id)
1914        } else {
1915            self.cstore_untracked().def_key(id)
1916        }
1917    }
1918
1919    pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1925        if let Some(id) = id.as_local() {
1927            self.definitions_untracked().def_path(id)
1928        } else {
1929            self.cstore_untracked().def_path(id)
1930        }
1931    }
1932
1933    #[inline]
1934    pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1935        if let Some(def_id) = def_id.as_local() {
1937            self.definitions_untracked().def_path_hash(def_id)
1938        } else {
1939            self.cstore_untracked().def_path_hash(def_id)
1940        }
1941    }
1942
1943    #[inline]
1944    pub fn crate_types(self) -> &'tcx [CrateType] {
1945        &self.crate_types
1946    }
1947
1948    pub fn needs_metadata(self) -> bool {
1949        self.crate_types().iter().any(|ty| match *ty {
1950            CrateType::Executable
1951            | CrateType::Staticlib
1952            | CrateType::Cdylib
1953            | CrateType::Sdylib => false,
1954            CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1955        })
1956    }
1957
1958    pub fn needs_crate_hash(self) -> bool {
1959        cfg!(debug_assertions)
1971            || self.sess.opts.incremental.is_some()
1972            || self.needs_metadata()
1973            || self.sess.instrument_coverage()
1974            || self.sess.opts.unstable_opts.metrics_dir.is_some()
1975    }
1976
1977    #[inline]
1978    pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1979        if crate_num == LOCAL_CRATE {
1980            self.stable_crate_id
1981        } else {
1982            self.cstore_untracked().stable_crate_id(crate_num)
1983        }
1984    }
1985
1986    #[inline]
1989    pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1990        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1991            LOCAL_CRATE
1992        } else {
1993            *self
1994                .untracked()
1995                .stable_crate_ids
1996                .read()
1997                .get(&stable_crate_id)
1998                .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1999        }
2000    }
2001
2002    pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
2006        debug!("def_path_hash_to_def_id({:?})", hash);
2007
2008        let stable_crate_id = hash.stable_crate_id();
2009
2010        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
2013            Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
2014        } else {
2015            Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
2016        }
2017    }
2018
2019    pub fn def_path_debug_str(self, def_id: DefId) -> String {
2020        let (crate_name, stable_crate_id) = if def_id.is_local() {
2025            (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
2026        } else {
2027            let cstore = &*self.cstore_untracked();
2028            (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
2029        };
2030
2031        format!(
2032            "{}[{:04x}]{}",
2033            crate_name,
2034            stable_crate_id.as_u64() >> (8 * 6),
2037            self.def_path(def_id).to_string_no_crate_verbose()
2038        )
2039    }
2040
2041    pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
2042        self.sess.dcx()
2043    }
2044
2045    pub fn is_target_feature_call_safe(
2046        self,
2047        callee_features: &[TargetFeature],
2048        body_features: &[TargetFeature],
2049    ) -> bool {
2050        self.sess.target.options.is_like_wasm
2055            || callee_features
2056                .iter()
2057                .all(|feature| body_features.iter().any(|f| f.name == feature.name))
2058    }
2059
2060    pub fn adjust_target_feature_sig(
2063        self,
2064        fun_def: DefId,
2065        fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
2066        caller: DefId,
2067    ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
2068        let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
2069        let callee_features = &self.codegen_fn_attrs(caller).target_features;
2070        if self.is_target_feature_call_safe(&fun_features, &callee_features) {
2071            return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
2072        }
2073        None
2074    }
2075
2076    pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
2079        match self.env_var_os(key.as_ref()) {
2080            Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
2081            None => Err(VarError::NotPresent),
2082        }
2083    }
2084}
2085
2086impl<'tcx> TyCtxtAt<'tcx> {
2087    pub fn create_def(
2089        self,
2090        parent: LocalDefId,
2091        name: Option<Symbol>,
2092        def_kind: DefKind,
2093        override_def_path_data: Option<DefPathData>,
2094        disambiguator: &mut DisambiguatorState,
2095    ) -> TyCtxtFeed<'tcx, LocalDefId> {
2096        let feed =
2097            self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
2098
2099        feed.def_span(self.span);
2100        feed
2101    }
2102}
2103
2104impl<'tcx> TyCtxt<'tcx> {
2105    pub fn create_def(
2107        self,
2108        parent: LocalDefId,
2109        name: Option<Symbol>,
2110        def_kind: DefKind,
2111        override_def_path_data: Option<DefPathData>,
2112        disambiguator: &mut DisambiguatorState,
2113    ) -> TyCtxtFeed<'tcx, LocalDefId> {
2114        let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2115        let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2125
2126        self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2131
2132        let feed = TyCtxtFeed { tcx: self, key: def_id };
2133        feed.def_kind(def_kind);
2134        if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2139            let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2140            feed.visibility(ty::Visibility::Restricted(parent_mod));
2141        }
2142
2143        feed
2144    }
2145
2146    pub fn create_crate_num(
2147        self,
2148        stable_crate_id: StableCrateId,
2149    ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2150        if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2151            return Err(existing);
2152        }
2153
2154        let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2155        self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2156        Ok(TyCtxtFeed { key: num, tcx: self })
2157    }
2158
2159    pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2160        self.ensure_ok().analysis(());
2162
2163        let definitions = &self.untracked.definitions;
2164        gen {
2165            let mut i = 0;
2166
2167            while i < { definitions.read().num_definitions() } {
2170                let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2171                yield LocalDefId { local_def_index };
2172                i += 1;
2173            }
2174
2175            definitions.freeze();
2177        }
2178    }
2179
2180    pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2181        self.ensure_ok().analysis(());
2183
2184        self.untracked.definitions.freeze().def_path_table()
2187    }
2188
2189    pub fn def_path_hash_to_def_index_map(
2190        self,
2191    ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2192        self.ensure_ok().hir_crate_items(());
2195        self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2198    }
2199
2200    #[inline]
2203    pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2204        FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2205    }
2206
2207    pub fn untracked(self) -> &'tcx Untracked {
2209        &self.untracked
2210    }
2211    #[inline]
2214    pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2215        self.untracked.definitions.read()
2216    }
2217
2218    #[inline]
2221    pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2222        self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2223    }
2224
2225    #[inline(always)]
2226    pub fn with_stable_hashing_context<R>(
2227        self,
2228        f: impl FnOnce(StableHashingContext<'_>) -> R,
2229    ) -> R {
2230        f(StableHashingContext::new(self.sess, &self.untracked))
2231    }
2232
2233    pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2234        self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2235    }
2236
2237    #[inline]
2238    pub fn local_crate_exports_generics(self) -> bool {
2239        self.crate_types().iter().any(|crate_type| {
2240            match crate_type {
2241                CrateType::Executable
2242                | CrateType::Staticlib
2243                | CrateType::ProcMacro
2244                | CrateType::Cdylib
2245                | CrateType::Sdylib => false,
2246
2247                CrateType::Dylib => true,
2252
2253                CrateType::Rlib => true,
2254            }
2255        })
2256    }
2257
2258    pub fn is_suitable_region(
2260        self,
2261        generic_param_scope: LocalDefId,
2262        mut region: Region<'tcx>,
2263    ) -> Option<FreeRegionInfo> {
2264        let (suitable_region_binding_scope, region_def_id) = loop {
2265            let def_id =
2266                region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2267            let scope = self.local_parent(def_id);
2268            if self.def_kind(scope) == DefKind::OpaqueTy {
2269                region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2272                continue;
2273            }
2274            break (scope, def_id.into());
2275        };
2276
2277        let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2278            Node::Item(..) | Node::TraitItem(..) => false,
2279            Node::ImplItem(impl_item) => match impl_item.impl_kind {
2280                hir::ImplItemImplKind::Trait { .. } => true,
2287                _ => false,
2288            },
2289            _ => false,
2290        };
2291
2292        Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2293    }
2294
2295    pub fn return_type_impl_or_dyn_traits(
2297        self,
2298        scope_def_id: LocalDefId,
2299    ) -> Vec<&'tcx hir::Ty<'tcx>> {
2300        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2301        let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2302            self.hir_fn_decl_by_hir_id(hir_id)
2303        else {
2304            return vec![];
2305        };
2306
2307        let mut v = TraitObjectVisitor(vec![]);
2308        v.visit_ty_unambig(hir_output);
2309        v.0
2310    }
2311
2312    pub fn return_type_impl_or_dyn_traits_with_type_alias(
2316        self,
2317        scope_def_id: LocalDefId,
2318    ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2319        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2320        let mut v = TraitObjectVisitor(vec![]);
2321        if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2323            && let hir::TyKind::Path(hir::QPath::Resolved(
2324                None,
2325                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2326            && let Some(local_id) = def_id.as_local()
2327            && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
2329        {
2330            v.visit_ty_unambig(alias_ty);
2331            if !v.0.is_empty() {
2332                return Some((
2333                    v.0,
2334                    alias_generics.span,
2335                    alias_generics.span_for_lifetime_suggestion(),
2336                ));
2337            }
2338        }
2339        None
2340    }
2341
2342    pub fn has_strict_asm_symbol_naming(self) -> bool {
2345        self.sess.target.arch.contains("nvptx")
2346    }
2347
2348    pub fn caller_location_ty(self) -> Ty<'tcx> {
2350        Ty::new_imm_ref(
2351            self,
2352            self.lifetimes.re_static,
2353            self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2354                .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2355        )
2356    }
2357
2358    pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2360        let kind = self.def_kind(def_id);
2361        (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2362    }
2363
2364    pub fn type_length_limit(self) -> Limit {
2365        self.limits(()).type_length_limit
2366    }
2367
2368    pub fn recursion_limit(self) -> Limit {
2369        self.limits(()).recursion_limit
2370    }
2371
2372    pub fn move_size_limit(self) -> Limit {
2373        self.limits(()).move_size_limit
2374    }
2375
2376    pub fn pattern_complexity_limit(self) -> Limit {
2377        self.limits(()).pattern_complexity_limit
2378    }
2379
2380    pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
2382        iter::once(LOCAL_CRATE)
2383            .chain(self.crates(()).iter().copied())
2384            .flat_map(move |cnum| self.traits(cnum).iter().copied())
2385    }
2386
2387    pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2389        let visible_crates =
2390            self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2391
2392        iter::once(LOCAL_CRATE)
2393            .chain(visible_crates)
2394            .flat_map(move |cnum| self.traits(cnum).iter().copied())
2395    }
2396
2397    #[inline]
2398    pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2399        self.visibility(def_id).expect_local()
2400    }
2401
2402    #[instrument(skip(self), level = "trace", ret)]
2404    pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2405        self.hir_expect_opaque_ty(def_id).origin
2406    }
2407
2408    pub fn finish(self) {
2409        self.alloc_self_profile_query_strings();
2412
2413        self.save_dep_graph();
2414        self.query_key_hash_verify_all();
2415
2416        if let Err((path, error)) = self.dep_graph.finish_encoding() {
2417            self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2418        }
2419    }
2420}
2421
2422macro_rules! nop_lift {
2423    ($set:ident; $ty:ty => $lifted:ty) => {
2424        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2425            type Lifted = $lifted;
2426            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2427                fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2432                    _x: Interned<'tcx, Inner>,
2433                ) -> InternedSet<'tcx, Inner> {
2434                    unreachable!()
2435                }
2436                fn _type_eq<T>(_x: &T, _y: &T) {}
2437                fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2438                    let interner = _intern_set_ty_from_interned_ty(x.0);
2442                    _type_eq(&interner, &tcx.interners.$set);
2444                }
2445
2446                tcx.interners
2447                    .$set
2448                    .contains_pointer_to(&InternedInSet(&*self.0.0))
2449                    .then(|| unsafe { mem::transmute(self) })
2452            }
2453        }
2454    };
2455}
2456
2457macro_rules! nop_list_lift {
2458    ($set:ident; $ty:ty => $lifted:ty) => {
2459        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2460            type Lifted = &'tcx List<$lifted>;
2461            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2462                if false {
2464                    let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2465                }
2466
2467                if self.is_empty() {
2468                    return Some(List::empty());
2469                }
2470                tcx.interners
2471                    .$set
2472                    .contains_pointer_to(&InternedInSet(self))
2473                    .then(|| unsafe { mem::transmute(self) })
2474            }
2475        }
2476    };
2477}
2478
2479nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2480nop_lift! { region; Region<'a> => Region<'tcx> }
2481nop_lift! { const_; Const<'a> => Const<'tcx> }
2482nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2483nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2484nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2485nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2486nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2487nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2488
2489nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2490nop_list_lift! {
2491    poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2492}
2493nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2494
2495nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2497
2498macro_rules! sty_debug_print {
2499    ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2500        #[allow(non_snake_case)]
2503        mod inner {
2504            use crate::ty::{self, TyCtxt};
2505            use crate::ty::context::InternedInSet;
2506
2507            #[derive(Copy, Clone)]
2508            struct DebugStat {
2509                total: usize,
2510                lt_infer: usize,
2511                ty_infer: usize,
2512                ct_infer: usize,
2513                all_infer: usize,
2514            }
2515
2516            pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2517                let mut total = DebugStat {
2518                    total: 0,
2519                    lt_infer: 0,
2520                    ty_infer: 0,
2521                    ct_infer: 0,
2522                    all_infer: 0,
2523                };
2524                $(let mut $variant = total;)*
2525
2526                for shard in tcx.interners.type_.lock_shards() {
2527                    #[allow(rustc::potential_query_instability)]
2529                    let types = shard.iter();
2530                    for &(InternedInSet(t), ()) in types {
2531                        let variant = match t.internee {
2532                            ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2533                                ty::Float(..) | ty::Str | ty::Never => continue,
2534                            ty::Error(_) => continue,
2535                            $(ty::$variant(..) => &mut $variant,)*
2536                        };
2537                        let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2538                        let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2539                        let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2540
2541                        variant.total += 1;
2542                        total.total += 1;
2543                        if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2544                        if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2545                        if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2546                        if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2547                    }
2548                }
2549                writeln!(fmt, "Ty interner             total           ty lt ct all")?;
2550                $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
2551                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2552                    stringify!($variant),
2553                    uses = $variant.total,
2554                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
2555                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
2556                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
2557                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
2558                    all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
2559                )*
2560                writeln!(fmt, "                  total {uses:6}        \
2561                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2562                    uses = total.total,
2563                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
2564                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
2565                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
2566                    all = total.all_infer as f64 * 100.0  / total.total as f64)
2567            }
2568        }
2569
2570        inner::go($fmt, $ctxt)
2571    }}
2572}
2573
2574impl<'tcx> TyCtxt<'tcx> {
2575    pub fn debug_stats(self) -> impl fmt::Debug {
2576        fmt::from_fn(move |fmt| {
2577            sty_debug_print!(
2578                fmt,
2579                self,
2580                Adt,
2581                Array,
2582                Slice,
2583                RawPtr,
2584                Ref,
2585                FnDef,
2586                FnPtr,
2587                UnsafeBinder,
2588                Placeholder,
2589                Coroutine,
2590                CoroutineWitness,
2591                Dynamic,
2592                Closure,
2593                CoroutineClosure,
2594                Tuple,
2595                Bound,
2596                Param,
2597                Infer,
2598                Alias,
2599                Pat,
2600                Foreign
2601            )?;
2602
2603            writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2604            writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2605            writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2606            writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2607
2608            Ok(())
2609        })
2610    }
2611}
2612
2613struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2618
2619impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2620    fn clone(&self) -> Self {
2621        InternedInSet(self.0)
2622    }
2623}
2624
2625impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2626
2627impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2628    fn into_pointer(&self) -> *const () {
2629        self.0 as *const _ as *const ()
2630    }
2631}
2632
2633#[allow(rustc::usage_of_ty_tykind)]
2634impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2635    fn borrow(&self) -> &T {
2636        &self.0.internee
2637    }
2638}
2639
2640impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2641    fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2642        self.0.internee == other.0.internee
2645    }
2646}
2647
2648impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2649
2650impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2651    fn hash<H: Hasher>(&self, s: &mut H) {
2652        self.0.internee.hash(s)
2654    }
2655}
2656
2657impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2658    fn borrow(&self) -> &[T] {
2659        &self.0[..]
2660    }
2661}
2662
2663impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2664    fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2665        self.0[..] == other.0[..]
2668    }
2669}
2670
2671impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2672
2673impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2674    fn hash<H: Hasher>(&self, s: &mut H) {
2675        self.0[..].hash(s)
2677    }
2678}
2679
2680impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2681    fn borrow(&self) -> &[T] {
2682        &self.0[..]
2683    }
2684}
2685
2686impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2687    fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2688        self.0[..] == other.0[..]
2691    }
2692}
2693
2694impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2695
2696impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2697    fn hash<H: Hasher>(&self, s: &mut H) {
2698        self.0[..].hash(s)
2700    }
2701}
2702
2703macro_rules! direct_interners {
2704    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2705        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2706            fn borrow<'a>(&'a self) -> &'a $ty {
2707                &self.0
2708            }
2709        }
2710
2711        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2712            fn eq(&self, other: &Self) -> bool {
2713                self.0 == other.0
2716            }
2717        }
2718
2719        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2720
2721        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2722            fn hash<H: Hasher>(&self, s: &mut H) {
2723                self.0.hash(s)
2726            }
2727        }
2728
2729        impl<'tcx> TyCtxt<'tcx> {
2730            $vis fn $method(self, v: $ty) -> $ret_ty {
2731                $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2732                    InternedInSet(self.interners.arena.alloc(v))
2733                }).0))
2734            }
2735        })+
2736    }
2737}
2738
2739direct_interners! {
2743    region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2744    valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2745    pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2746    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2747    layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2748    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2749    external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2750        ExternalConstraints -> ExternalConstraints<'tcx>,
2751    predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2752        PredefinedOpaques -> PredefinedOpaques<'tcx>,
2753}
2754
2755macro_rules! slice_interners {
2756    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2757        impl<'tcx> TyCtxt<'tcx> {
2758            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2759                if v.is_empty() {
2760                    List::empty()
2761                } else {
2762                    self.interners.$field.intern_ref(v, || {
2763                        InternedInSet(List::from_arena(&*self.arena, (), v))
2764                    }).0
2765                }
2766            })+
2767        }
2768    );
2769}
2770
2771slice_interners!(
2775    const_lists: pub mk_const_list(Const<'tcx>),
2776    args: pub mk_args(GenericArg<'tcx>),
2777    type_lists: pub mk_type_list(Ty<'tcx>),
2778    canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2779    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2780    projs: pub mk_projs(ProjectionKind),
2781    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2782    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2783    fields: pub mk_fields(FieldIdx),
2784    local_def_ids: intern_local_def_ids(LocalDefId),
2785    captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2786    offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2787    patterns: pub mk_patterns(Pattern<'tcx>),
2788    outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2789);
2790
2791impl<'tcx> TyCtxt<'tcx> {
2792    pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2796        assert!(sig.safety().is_safe());
2797        Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2798    }
2799
2800    pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2803        elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2804            self.associated_items(trait_did)
2805                .filter_by_name_unhygienic(assoc_name.name)
2806                .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2807        })
2808    }
2809
2810    pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2812        let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2813        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2814
2815        self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2816            let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2817                return false;
2818            };
2819            trait_predicate.trait_ref.def_id == future_trait
2820                && trait_predicate.polarity == PredicatePolarity::Positive
2821        })
2822    }
2823
2824    pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2832        sig.map_bound(|s| {
2833            let params = match s.inputs()[0].kind() {
2834                ty::Tuple(params) => *params,
2835                _ => bug!(),
2836            };
2837            self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2838        })
2839    }
2840
2841    #[inline]
2842    pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2843        self.interners.intern_predicate(
2844            binder,
2845            self.sess,
2846            &self.untracked,
2848        )
2849    }
2850
2851    #[inline]
2852    pub fn reuse_or_mk_predicate(
2853        self,
2854        pred: Predicate<'tcx>,
2855        binder: Binder<'tcx, PredicateKind<'tcx>>,
2856    ) -> Predicate<'tcx> {
2857        if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2858    }
2859
2860    pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2861        self.check_args_compatible_inner(def_id, args, false)
2862    }
2863
2864    fn check_args_compatible_inner(
2865        self,
2866        def_id: DefId,
2867        args: &'tcx [ty::GenericArg<'tcx>],
2868        nested: bool,
2869    ) -> bool {
2870        let generics = self.generics_of(def_id);
2871
2872        let own_args = if !nested
2875            && let DefKind::AssocTy = self.def_kind(def_id)
2876            && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2877        {
2878            if generics.own_params.len() + 1 != args.len() {
2879                return false;
2880            }
2881
2882            if !matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2883                return false;
2884            }
2885
2886            &args[1..]
2887        } else {
2888            if generics.count() != args.len() {
2889                return false;
2890            }
2891
2892            let (parent_args, own_args) = args.split_at(generics.parent_count);
2893
2894            if let Some(parent) = generics.parent
2895                && !self.check_args_compatible_inner(parent, parent_args, true)
2896            {
2897                return false;
2898            }
2899
2900            own_args
2901        };
2902
2903        for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2904            match (¶m.kind, arg.kind()) {
2905                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2906                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2907                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2908                _ => return false,
2909            }
2910        }
2911
2912        true
2913    }
2914
2915    pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2918        if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2919            if let DefKind::AssocTy = self.def_kind(def_id)
2920                && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2921            {
2922                bug!(
2923                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2924                    self.def_path_str(def_id),
2925                    args,
2926                    self.mk_args_from_iter(
2928                        [self.types.self_param.into()].into_iter().chain(
2929                            self.generics_of(def_id)
2930                                .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2931                                .iter()
2932                                .copied()
2933                        )
2934                    )
2935                );
2936            } else {
2937                bug!(
2938                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2939                    self.def_path_str(def_id),
2940                    args,
2941                    ty::GenericArgs::identity_for_item(self, def_id)
2942                );
2943            }
2944        }
2945    }
2946
2947    #[inline(always)]
2948    pub(crate) fn check_and_mk_args(
2949        self,
2950        def_id: DefId,
2951        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2952    ) -> GenericArgsRef<'tcx> {
2953        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2954        self.debug_assert_args_compatible(def_id, args);
2955        args
2956    }
2957
2958    #[inline]
2959    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2960        self.interners.intern_const(
2961            kind,
2962            self.sess,
2963            &self.untracked,
2965        )
2966    }
2967
2968    #[allow(rustc::usage_of_ty_tykind)]
2970    #[inline]
2971    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2972        self.interners.intern_ty(
2973            st,
2974            self.sess,
2975            &self.untracked,
2977        )
2978    }
2979
2980    pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2981        match param.kind {
2982            GenericParamDefKind::Lifetime => {
2983                ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2984            }
2985            GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2986            GenericParamDefKind::Const { .. } => {
2987                ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2988                    .into()
2989            }
2990        }
2991    }
2992
2993    pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2994        self.mk_place_elem(place, PlaceElem::Field(f, ty))
2995    }
2996
2997    pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2998        self.mk_place_elem(place, PlaceElem::Deref)
2999    }
3000
3001    pub fn mk_place_downcast(
3002        self,
3003        place: Place<'tcx>,
3004        adt_def: AdtDef<'tcx>,
3005        variant_index: VariantIdx,
3006    ) -> Place<'tcx> {
3007        self.mk_place_elem(
3008            place,
3009            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
3010        )
3011    }
3012
3013    pub fn mk_place_downcast_unnamed(
3014        self,
3015        place: Place<'tcx>,
3016        variant_index: VariantIdx,
3017    ) -> Place<'tcx> {
3018        self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
3019    }
3020
3021    pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
3022        self.mk_place_elem(place, PlaceElem::Index(index))
3023    }
3024
3025    pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
3029        let mut projection = place.projection.to_vec();
3030        projection.push(elem);
3031
3032        Place { local: place.local, projection: self.mk_place_elems(&projection) }
3033    }
3034
3035    pub fn mk_poly_existential_predicates(
3036        self,
3037        eps: &[PolyExistentialPredicate<'tcx>],
3038    ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
3039        assert!(!eps.is_empty());
3040        assert!(
3041            eps.array_windows()
3042                .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
3043                    != Ordering::Greater)
3044        );
3045        self.intern_poly_existential_predicates(eps)
3046    }
3047
3048    pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
3049        self.interners.intern_clauses(clauses)
3053    }
3054
3055    pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
3056        self.intern_local_def_ids(def_ids)
3060    }
3061
3062    pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
3063    where
3064        I: Iterator<Item = T>,
3065        T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
3066    {
3067        T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
3068    }
3069
3070    pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
3071    where
3072        I: Iterator<Item = T>,
3073        T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
3074    {
3075        T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
3076    }
3077
3078    pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
3079    where
3080        I: Iterator<Item = T>,
3081        T: CollectAndApply<
3082                &'tcx ty::CapturedPlace<'tcx>,
3083                &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
3084            >,
3085    {
3086        T::collect_and_apply(iter, |xs| self.intern_captures(xs))
3087    }
3088
3089    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
3090    where
3091        I: Iterator<Item = T>,
3092        T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
3093    {
3094        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3095    }
3096
3097    pub fn mk_fn_sig<I, T>(
3102        self,
3103        inputs: I,
3104        output: I::Item,
3105        c_variadic: bool,
3106        safety: hir::Safety,
3107        abi: ExternAbi,
3108    ) -> T::Output
3109    where
3110        I: IntoIterator<Item = T>,
3111        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3112    {
3113        T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3114            inputs_and_output: self.mk_type_list(xs),
3115            c_variadic,
3116            safety,
3117            abi,
3118        })
3119    }
3120
3121    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3122    where
3123        I: Iterator<Item = T>,
3124        T: CollectAndApply<
3125                PolyExistentialPredicate<'tcx>,
3126                &'tcx List<PolyExistentialPredicate<'tcx>>,
3127            >,
3128    {
3129        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3130    }
3131
3132    pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3133    where
3134        I: Iterator<Item = T>,
3135        T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3136    {
3137        T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3138    }
3139
3140    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3141    where
3142        I: Iterator<Item = T>,
3143        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3144    {
3145        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3146    }
3147
3148    pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3149    where
3150        I: Iterator<Item = T>,
3151        T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3152    {
3153        T::collect_and_apply(iter, |xs| self.mk_args(xs))
3154    }
3155
3156    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3157    where
3158        I: Iterator<Item = T>,
3159        T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3160    {
3161        T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3162    }
3163
3164    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3165    where
3166        I: Iterator<Item = T>,
3167        T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3168    {
3169        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3170    }
3171
3172    pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3173    where
3174        I: Iterator<Item = T>,
3175        T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3176    {
3177        T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3178    }
3179
3180    pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
3181    where
3182        I: Iterator<Item = T>,
3183        T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
3184    {
3185        T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
3186    }
3187
3188    pub fn mk_args_trait(
3189        self,
3190        self_ty: Ty<'tcx>,
3191        rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3192    ) -> GenericArgsRef<'tcx> {
3193        self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3194    }
3195
3196    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3197    where
3198        I: Iterator<Item = T>,
3199        T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3200    {
3201        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3202    }
3203
3204    pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
3205    where
3206        I: Iterator<Item = T>,
3207        T: CollectAndApply<
3208                ty::ArgOutlivesPredicate<'tcx>,
3209                &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
3210            >,
3211    {
3212        T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
3213    }
3214
3215    #[track_caller]
3218    pub fn emit_node_span_lint(
3219        self,
3220        lint: &'static Lint,
3221        hir_id: HirId,
3222        span: impl Into<MultiSpan>,
3223        decorator: impl for<'a> LintDiagnostic<'a, ()>,
3224    ) {
3225        let level = self.lint_level_at_node(lint, hir_id);
3226        lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3227            decorator.decorate_lint(lint);
3228        })
3229    }
3230
3231    #[rustc_lint_diagnostics]
3235    #[track_caller]
3236    pub fn node_span_lint(
3237        self,
3238        lint: &'static Lint,
3239        hir_id: HirId,
3240        span: impl Into<MultiSpan>,
3241        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3242    ) {
3243        let level = self.lint_level_at_node(lint, hir_id);
3244        lint_level(self.sess, lint, level, Some(span.into()), decorate);
3245    }
3246
3247    pub fn crate_level_attribute_injection_span(self) -> Span {
3249        let node = self.hir_node(hir::CRATE_HIR_ID);
3250        let hir::Node::Crate(m) = node else { bug!() };
3251        m.spans.inject_use_span.shrink_to_lo()
3252    }
3253
3254    pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3255        self,
3256        diag: &mut Diag<'_, E>,
3257        features: impl IntoIterator<Item = (String, Symbol)>,
3258    ) {
3259        if !self.sess.is_nightly_build() {
3260            return;
3261        }
3262
3263        let span = self.crate_level_attribute_injection_span();
3264        for (desc, feature) in features {
3265            let msg =
3267                format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3268            diag.span_suggestion_verbose(
3269                span,
3270                msg,
3271                format!("#![feature({feature})]\n"),
3272                Applicability::MaybeIncorrect,
3273            );
3274        }
3275    }
3276
3277    #[track_caller]
3280    pub fn emit_node_lint(
3281        self,
3282        lint: &'static Lint,
3283        id: HirId,
3284        decorator: impl for<'a> LintDiagnostic<'a, ()>,
3285    ) {
3286        self.node_lint(lint, id, |lint| {
3287            decorator.decorate_lint(lint);
3288        })
3289    }
3290
3291    #[rustc_lint_diagnostics]
3295    #[track_caller]
3296    pub fn node_lint(
3297        self,
3298        lint: &'static Lint,
3299        id: HirId,
3300        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3301    ) {
3302        let level = self.lint_level_at_node(lint, id);
3303        lint_level(self.sess, lint, level, None, decorate);
3304    }
3305
3306    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3307        let map = self.in_scope_traits_map(id.owner)?;
3308        let candidates = map.get(&id.local_id)?;
3309        Some(candidates)
3310    }
3311
3312    pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3313        debug!(?id, "named_region");
3314        self.named_variable_map(id.owner).get(&id.local_id).cloned()
3315    }
3316
3317    pub fn is_late_bound(self, id: HirId) -> bool {
3318        self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3319    }
3320
3321    pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3322        self.mk_bound_variable_kinds(
3323            &self
3324                .late_bound_vars_map(id.owner)
3325                .get(&id.local_id)
3326                .cloned()
3327                .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3328        )
3329    }
3330
3331    pub fn map_opaque_lifetime_to_parent_lifetime(
3339        self,
3340        mut opaque_lifetime_param_def_id: LocalDefId,
3341    ) -> ty::Region<'tcx> {
3342        debug_assert!(
3343            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3344            "{opaque_lifetime_param_def_id:?} is a {}",
3345            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3346        );
3347
3348        loop {
3349            let parent = self.local_parent(opaque_lifetime_param_def_id);
3350            let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3351
3352            let Some((lifetime, _)) = lifetime_mapping
3353                .iter()
3354                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3355            else {
3356                bug!("duplicated lifetime param should be present");
3357            };
3358
3359            match *lifetime {
3360                resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3361                    let new_parent = self.local_parent(ebv);
3362
3363                    if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3366                        debug_assert_eq!(self.local_parent(parent), new_parent);
3367                        opaque_lifetime_param_def_id = ebv;
3368                        continue;
3369                    }
3370
3371                    let generics = self.generics_of(new_parent);
3372                    return ty::Region::new_early_param(
3373                        self,
3374                        ty::EarlyParamRegion {
3375                            index: generics
3376                                .param_def_id_to_index(self, ebv.to_def_id())
3377                                .expect("early-bound var should be present in fn generics"),
3378                            name: self.item_name(ebv.to_def_id()),
3379                        },
3380                    );
3381                }
3382                resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3383                    let new_parent = self.local_parent(lbv);
3384                    return ty::Region::new_late_param(
3385                        self,
3386                        new_parent.to_def_id(),
3387                        ty::LateParamRegionKind::Named(lbv.to_def_id()),
3388                    );
3389                }
3390                resolve_bound_vars::ResolvedArg::Error(guar) => {
3391                    return ty::Region::new_error(self, guar);
3392                }
3393                _ => {
3394                    return ty::Region::new_error_with_message(
3395                        self,
3396                        self.def_span(opaque_lifetime_param_def_id),
3397                        "cannot resolve lifetime",
3398                    );
3399                }
3400            }
3401        }
3402    }
3403
3404    pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3409        self.is_const_fn(def_id)
3410            && match self.lookup_const_stability(def_id) {
3411                None => true, Some(stability) if stability.is_const_stable() => true,
3413                _ => false,
3414            }
3415    }
3416
3417    pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3419        self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3420            && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3421    }
3422
3423    pub fn is_sdylib_interface_build(self) -> bool {
3424        self.sess.opts.unstable_opts.build_sdylib_interface
3425    }
3426
3427    pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3428        match self.def_kind(def_id) {
3429            DefKind::Fn | DefKind::AssocFn => {}
3430            _ => return None,
3431        }
3432        self.intrinsic_raw(def_id)
3433    }
3434
3435    pub fn next_trait_solver_globally(self) -> bool {
3436        self.sess.opts.unstable_opts.next_solver.globally
3437    }
3438
3439    pub fn next_trait_solver_in_coherence(self) -> bool {
3440        self.sess.opts.unstable_opts.next_solver.coherence
3441    }
3442
3443    #[allow(rustc::bad_opt_access)]
3444    pub fn use_typing_mode_borrowck(self) -> bool {
3445        self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3446    }
3447
3448    pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3449        self.opt_rpitit_info(def_id).is_some()
3450    }
3451
3452    pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3462        self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3463    }
3464
3465    pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
3467        self.resolutions(()).extern_crate_map.get(&def_id).copied()
3468    }
3469
3470    pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3471        self.resolver_for_lowering_raw(()).0
3472    }
3473
3474    pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
3475        crate::dep_graph::make_metadata(self)
3476    }
3477
3478    pub fn impl_trait_ref(
3481        self,
3482        def_id: impl IntoQueryParam<DefId>,
3483    ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3484        Some(self.impl_trait_header(def_id)?.trait_ref)
3485    }
3486
3487    pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3488        self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3489    }
3490
3491    pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3492        if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3493            self.coroutine_kind(def_id)
3494            && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3495            && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3496        {
3497            true
3498        } else {
3499            false
3500        }
3501    }
3502
3503    pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3505        self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3506    }
3507
3508    pub fn is_entrypoint(self, def_id: DefId) -> bool {
3511        if self.is_lang_item(def_id, LangItem::Start) {
3512            return true;
3513        }
3514        if let Some((entry_def_id, _)) = self.entry_fn(())
3515            && entry_def_id == def_id
3516        {
3517            return true;
3518        }
3519        false
3520    }
3521}
3522
3523#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3532pub struct DeducedParamAttrs {
3533    pub read_only: bool,
3536}
3537
3538pub fn provide(providers: &mut Providers) {
3539    providers.is_panic_runtime =
3540        |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3541    providers.is_compiler_builtins =
3542        |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3543    providers.has_panic_handler = |tcx, LocalCrate| {
3544        tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3546    };
3547    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3548}
3549
3550pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3551    attrs.iter().any(|x| x.has_name(name))
3552}