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