rustc_middle/ty/
context.rs

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