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