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