rustc_middle/ty/
context.rs

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