Skip to main content

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