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