rustc_middle/ty/
context.rs

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