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