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