rustc_middle/ty/
context.rs

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