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