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    /// Check if the given `def_id` is a const with the `#[type_const]` attribute.
1890    pub fn is_type_const(self, def_id: DefId) -> bool {
1891        #[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)
1892            && {
    {
            'done:
                {
                for i in self.get_all_attrs(def_id) {
                    let i: &rustc_hir::Attribute = i;
                    match i {
                        rustc_hir::Attribute::Parsed(AttributeKind::TypeConst(_)) =>
                            {
                            break 'done Some(());
                        }
                        _ => {}
                    }
                }
                None
            }
        }.is_some()
}find_attr!(self.get_all_attrs(def_id), AttributeKind::TypeConst(_))
1893    }
1894
1895    /// Returns the movability of the coroutine of `def_id`, or panics
1896    /// if given a `def_id` that is not a coroutine.
1897    pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1898        self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1899    }
1900
1901    /// Returns `true` if the node pointed to by `def_id` is a coroutine for an async construct.
1902    pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1903        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
        true,
    _ => false,
}matches!(
1904            self.coroutine_kind(def_id),
1905            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1906        )
1907    }
1908
1909    // Whether the body owner is synthetic, which in this case means it does not correspond to
1910    // meaningful HIR. This is currently used to skip over MIR borrowck.
1911    pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1912        #[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)
1913    }
1914
1915    /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`.
1916    /// This means it is neither an `async` or `gen` construct.
1917    pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1918        #[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(_)))
1919    }
1920
1921    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `gen` construct.
1922    pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1923        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
        true,
    _ => false,
}matches!(
1924            self.coroutine_kind(def_id),
1925            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1926        )
1927    }
1928
1929    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `async gen` construct.
1930    pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1931        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
        => true,
    _ => false,
}matches!(
1932            self.coroutine_kind(def_id),
1933            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1934        )
1935    }
1936
1937    pub fn features(self) -> &'tcx rustc_feature::Features {
1938        self.features_query(())
1939    }
1940
1941    pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1942        let id = id.into_query_param();
1943        // Accessing the DefKey is ok, since it is part of DefPathHash.
1944        if let Some(id) = id.as_local() {
1945            self.definitions_untracked().def_key(id)
1946        } else {
1947            self.cstore_untracked().def_key(id)
1948        }
1949    }
1950
1951    /// Converts a `DefId` into its fully expanded `DefPath` (every
1952    /// `DefId` is really just an interned `DefPath`).
1953    ///
1954    /// Note that if `id` is not local to this crate, the result will
1955    ///  be a non-local `DefPath`.
1956    pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1957        // Accessing the DefPath is ok, since it is part of DefPathHash.
1958        if let Some(id) = id.as_local() {
1959            self.definitions_untracked().def_path(id)
1960        } else {
1961            self.cstore_untracked().def_path(id)
1962        }
1963    }
1964
1965    #[inline]
1966    pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1967        // Accessing the DefPathHash is ok, it is incr. comp. stable.
1968        if let Some(def_id) = def_id.as_local() {
1969            self.definitions_untracked().def_path_hash(def_id)
1970        } else {
1971            self.cstore_untracked().def_path_hash(def_id)
1972        }
1973    }
1974
1975    #[inline]
1976    pub fn crate_types(self) -> &'tcx [CrateType] {
1977        &self.crate_types
1978    }
1979
1980    pub fn needs_metadata(self) -> bool {
1981        self.crate_types().iter().any(|ty| match *ty {
1982            CrateType::Executable
1983            | CrateType::StaticLib
1984            | CrateType::Cdylib
1985            | CrateType::Sdylib => false,
1986            CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1987        })
1988    }
1989
1990    pub fn needs_crate_hash(self) -> bool {
1991        // Why is the crate hash needed for these configurations?
1992        // - debug_assertions: for the "fingerprint the result" check in
1993        //   `rustc_query_system::query::plumbing::execute_job`.
1994        // - incremental: for query lookups.
1995        // - needs_metadata: for putting into crate metadata.
1996        // - instrument_coverage: for putting into coverage data (see
1997        //   `hash_mir_source`).
1998        // - metrics_dir: metrics use the strict version hash in the filenames
1999        //   for dumped metrics files to prevent overwriting distinct metrics
2000        //   for similar source builds (may change in the future, this is part
2001        //   of the proof of concept impl for the metrics initiative project goal)
2002        truecfg!(debug_assertions)
2003            || self.sess.opts.incremental.is_some()
2004            || self.needs_metadata()
2005            || self.sess.instrument_coverage()
2006            || self.sess.opts.unstable_opts.metrics_dir.is_some()
2007    }
2008
2009    #[inline]
2010    pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
2011        if crate_num == LOCAL_CRATE {
2012            self.stable_crate_id
2013        } else {
2014            self.cstore_untracked().stable_crate_id(crate_num)
2015        }
2016    }
2017
2018    /// Maps a StableCrateId to the corresponding CrateNum. This method assumes
2019    /// that the crate in question has already been loaded by the CrateStore.
2020    #[inline]
2021    pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
2022        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
2023            LOCAL_CRATE
2024        } else {
2025            *self
2026                .untracked()
2027                .stable_crate_ids
2028                .read()
2029                .get(&stable_crate_id)
2030                .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
        stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
2031        }
2032    }
2033
2034    /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
2035    /// session, if it still exists. This is used during incremental compilation to
2036    /// turn a deserialized `DefPathHash` into its current `DefId`.
2037    pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
2038        {
    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:2038",
                        "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(2038u32),
                        ::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);
2039
2040        let stable_crate_id = hash.stable_crate_id();
2041
2042        // If this is a DefPathHash from the local crate, we can look up the
2043        // DefId in the tcx's `Definitions`.
2044        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
2045            Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
2046        } else {
2047            self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
2048        }
2049    }
2050
2051    pub fn def_path_debug_str(self, def_id: DefId) -> String {
2052        // We are explicitly not going through queries here in order to get
2053        // crate name and stable crate id since this code is called from debug!()
2054        // statements within the query system and we'd run into endless
2055        // recursion otherwise.
2056        let (crate_name, stable_crate_id) = if def_id.is_local() {
2057            (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
2058        } else {
2059            let cstore = &*self.cstore_untracked();
2060            (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
2061        };
2062
2063        ::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!(
2064            "{}[{:04x}]{}",
2065            crate_name,
2066            // Don't print the whole stable crate id. That's just
2067            // annoying in debug output.
2068            stable_crate_id.as_u64() >> (8 * 6),
2069            self.def_path(def_id).to_string_no_crate_verbose()
2070        )
2071    }
2072
2073    pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
2074        self.sess.dcx()
2075    }
2076
2077    /// Checks to see if the caller (`body_features`) has all the features required by the callee
2078    /// (`callee_features`).
2079    pub fn is_target_feature_call_safe(
2080        self,
2081        callee_features: &[TargetFeature],
2082        body_features: &[TargetFeature],
2083    ) -> bool {
2084        // If the called function has target features the calling function hasn't,
2085        // the call requires `unsafe`. Don't check this on wasm
2086        // targets, though. For more information on wasm see the
2087        // is_like_wasm check in hir_analysis/src/collect.rs
2088        self.sess.target.options.is_like_wasm
2089            || callee_features
2090                .iter()
2091                .all(|feature| body_features.iter().any(|f| f.name == feature.name))
2092    }
2093
2094    /// Returns the safe version of the signature of the given function, if calling it
2095    /// would be safe in the context of the given caller.
2096    pub fn adjust_target_feature_sig(
2097        self,
2098        fun_def: DefId,
2099        fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
2100        caller: DefId,
2101    ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
2102        let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
2103        let callee_features = &self.codegen_fn_attrs(caller).target_features;
2104        if self.is_target_feature_call_safe(&fun_features, &callee_features) {
2105            return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
2106        }
2107        None
2108    }
2109
2110    /// Helper to get a tracked environment variable via. [`TyCtxt::env_var_os`] and converting to
2111    /// UTF-8 like [`std::env::var`].
2112    pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
2113        match self.env_var_os(key.as_ref()) {
2114            Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
2115            None => Err(VarError::NotPresent),
2116        }
2117    }
2118}
2119
2120impl<'tcx> TyCtxtAt<'tcx> {
2121    /// Create a new definition within the incr. comp. engine.
2122    pub fn create_def(
2123        self,
2124        parent: LocalDefId,
2125        name: Option<Symbol>,
2126        def_kind: DefKind,
2127        override_def_path_data: Option<DefPathData>,
2128        disambiguator: &mut DisambiguatorState,
2129    ) -> TyCtxtFeed<'tcx, LocalDefId> {
2130        let feed =
2131            self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
2132
2133        feed.def_span(self.span);
2134        feed
2135    }
2136}
2137
2138impl<'tcx> TyCtxt<'tcx> {
2139    /// `tcx`-dependent operations performed for every created definition.
2140    pub fn create_def(
2141        self,
2142        parent: LocalDefId,
2143        name: Option<Symbol>,
2144        def_kind: DefKind,
2145        override_def_path_data: Option<DefPathData>,
2146        disambiguator: &mut DisambiguatorState,
2147    ) -> TyCtxtFeed<'tcx, LocalDefId> {
2148        let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2149        // The following call has the side effect of modifying the tables inside `definitions`.
2150        // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
2151        // decode the on-disk cache.
2152        //
2153        // Any LocalDefId which is used within queries, either as key or result, either:
2154        // - has been created before the construction of the TyCtxt;
2155        // - has been created by this call to `create_def`.
2156        // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
2157        // comp. engine itself.
2158        let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2159
2160        // This function modifies `self.definitions` using a side-effect.
2161        // We need to ensure that these side effects are re-run by the incr. comp. engine.
2162        // Depending on the forever-red node will tell the graph that the calling query
2163        // needs to be re-evaluated.
2164        self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2165
2166        let feed = TyCtxtFeed { tcx: self, key: def_id };
2167        feed.def_kind(def_kind);
2168        // Unique types created for closures participate in type privacy checking.
2169        // They have visibilities inherited from the module they are defined in.
2170        // Visibilities for opaque types are meaningless, but still provided
2171        // so that all items have visibilities.
2172        if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
    DefKind::Closure | DefKind::OpaqueTy => true,
    _ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2173            let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2174            feed.visibility(ty::Visibility::Restricted(parent_mod));
2175        }
2176
2177        feed
2178    }
2179
2180    pub fn create_crate_num(
2181        self,
2182        stable_crate_id: StableCrateId,
2183    ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2184        if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2185            return Err(existing);
2186        }
2187
2188        let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2189        self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2190        Ok(TyCtxtFeed { key: num, tcx: self })
2191    }
2192
2193    pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2194        // Depend on the `analysis` query to ensure compilation if finished.
2195        self.ensure_ok().analysis(());
2196
2197        let definitions = &self.untracked.definitions;
2198        gen {
2199            let mut i = 0;
2200
2201            // Recompute the number of definitions each time, because our caller may be creating
2202            // new ones.
2203            while i < { definitions.read().num_definitions() } {
2204                let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2205                yield LocalDefId { local_def_index };
2206                i += 1;
2207            }
2208
2209            // Freeze definitions once we finish iterating on them, to prevent adding new ones.
2210            definitions.freeze();
2211        }
2212    }
2213
2214    pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2215        // Depend on the `analysis` query to ensure compilation if finished.
2216        self.ensure_ok().analysis(());
2217
2218        // Freeze definitions once we start iterating on them, to prevent adding new ones
2219        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
2220        self.untracked.definitions.freeze().def_path_table()
2221    }
2222
2223    pub fn def_path_hash_to_def_index_map(
2224        self,
2225    ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2226        // Create a dependency to the crate to be sure we re-execute this when the amount of
2227        // definitions change.
2228        self.ensure_ok().hir_crate_items(());
2229        // Freeze definitions once we start iterating on them, to prevent adding new ones
2230        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
2231        self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2232    }
2233
2234    /// Note that this is *untracked* and should only be used within the query
2235    /// system if the result is otherwise tracked through queries
2236    #[inline]
2237    pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2238        FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2239    }
2240
2241    /// Give out access to the untracked data without any sanity checks.
2242    pub fn untracked(self) -> &'tcx Untracked {
2243        &self.untracked
2244    }
2245    /// Note that this is *untracked* and should only be used within the query
2246    /// system if the result is otherwise tracked through queries
2247    #[inline]
2248    pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2249        self.untracked.definitions.read()
2250    }
2251
2252    /// Note that this is *untracked* and should only be used within the query
2253    /// system if the result is otherwise tracked through queries
2254    #[inline]
2255    pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2256        self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2257    }
2258
2259    #[inline(always)]
2260    pub fn with_stable_hashing_context<R>(
2261        self,
2262        f: impl FnOnce(StableHashingContext<'_>) -> R,
2263    ) -> R {
2264        f(StableHashingContext::new(self.sess, &self.untracked))
2265    }
2266
2267    pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2268        self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2269    }
2270
2271    #[inline]
2272    pub fn local_crate_exports_generics(self) -> bool {
2273        // compiler-builtins has some special treatment in codegen, which can result in confusing
2274        // behavior if another crate ends up calling into its monomorphizations.
2275        // https://github.com/rust-lang/rust/issues/150173
2276        if self.is_compiler_builtins(LOCAL_CRATE) {
2277            return false;
2278        }
2279        self.crate_types().iter().any(|crate_type| {
2280            match crate_type {
2281                CrateType::Executable
2282                | CrateType::StaticLib
2283                | CrateType::ProcMacro
2284                | CrateType::Cdylib
2285                | CrateType::Sdylib => false,
2286
2287                // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
2288                // We want to block export of generics from dylibs,
2289                // but we must fix rust-lang/rust#65890 before we can
2290                // do that robustly.
2291                CrateType::Dylib => true,
2292
2293                CrateType::Rlib => true,
2294            }
2295        })
2296    }
2297
2298    /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
2299    pub fn is_suitable_region(
2300        self,
2301        generic_param_scope: LocalDefId,
2302        mut region: Region<'tcx>,
2303    ) -> Option<FreeRegionInfo> {
2304        let (suitable_region_binding_scope, region_def_id) = loop {
2305            let def_id =
2306                region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2307            let scope = self.local_parent(def_id);
2308            if self.def_kind(scope) == DefKind::OpaqueTy {
2309                // Lifetime params of opaque types are synthetic and thus irrelevant to
2310                // diagnostics. Map them back to their origin!
2311                region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2312                continue;
2313            }
2314            break (scope, def_id.into());
2315        };
2316
2317        let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2318            Node::Item(..) | Node::TraitItem(..) => false,
2319            Node::ImplItem(impl_item) => match impl_item.impl_kind {
2320                // For now, we do not try to target impls of traits. This is
2321                // because this message is going to suggest that the user
2322                // change the fn signature, but they may not be free to do so,
2323                // since the signature must match the trait.
2324                //
2325                // FIXME(#42706) -- in some cases, we could do better here.
2326                hir::ImplItemImplKind::Trait { .. } => true,
2327                _ => false,
2328            },
2329            _ => false,
2330        };
2331
2332        Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2333    }
2334
2335    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
2336    pub fn return_type_impl_or_dyn_traits(
2337        self,
2338        scope_def_id: LocalDefId,
2339    ) -> Vec<&'tcx hir::Ty<'tcx>> {
2340        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2341        let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2342            self.hir_fn_decl_by_hir_id(hir_id)
2343        else {
2344            return ::alloc::vec::Vec::new()vec![];
2345        };
2346
2347        let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
2348        v.visit_ty_unambig(hir_output);
2349        v.0
2350    }
2351
2352    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in
2353    /// its return type, and the associated alias span when type alias is used,
2354    /// along with a span for lifetime suggestion (if there are existing generics).
2355    pub fn return_type_impl_or_dyn_traits_with_type_alias(
2356        self,
2357        scope_def_id: LocalDefId,
2358    ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2359        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2360        let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
2361        // when the return type is a type alias
2362        if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2363            && let hir::TyKind::Path(hir::QPath::Resolved(
2364                None,
2365                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2366            && let Some(local_id) = def_id.as_local()
2367            && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias
2368            && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
2369        {
2370            v.visit_ty_unambig(alias_ty);
2371            if !v.0.is_empty() {
2372                return Some((
2373                    v.0,
2374                    alias_generics.span,
2375                    alias_generics.span_for_lifetime_suggestion(),
2376                ));
2377            }
2378        }
2379        None
2380    }
2381
2382    /// Determines whether identifiers in the assembly have strict naming rules.
2383    /// Currently, only NVPTX* targets need it.
2384    pub fn has_strict_asm_symbol_naming(self) -> bool {
2385        self.sess.target.llvm_target.starts_with("nvptx")
2386    }
2387
2388    /// Returns `&'static core::panic::Location<'static>`.
2389    pub fn caller_location_ty(self) -> Ty<'tcx> {
2390        Ty::new_imm_ref(
2391            self,
2392            self.lifetimes.re_static,
2393            self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2394                .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2395        )
2396    }
2397
2398    /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
2399    pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2400        let kind = self.def_kind(def_id);
2401        (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2402    }
2403
2404    pub fn type_length_limit(self) -> Limit {
2405        self.limits(()).type_length_limit
2406    }
2407
2408    pub fn recursion_limit(self) -> Limit {
2409        self.limits(()).recursion_limit
2410    }
2411
2412    pub fn move_size_limit(self) -> Limit {
2413        self.limits(()).move_size_limit
2414    }
2415
2416    pub fn pattern_complexity_limit(self) -> Limit {
2417        self.limits(()).pattern_complexity_limit
2418    }
2419
2420    /// All traits in the crate graph, including those not visible to the user.
2421    pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
2422        iter::once(LOCAL_CRATE)
2423            .chain(self.crates(()).iter().copied())
2424            .flat_map(move |cnum| self.traits(cnum).iter().copied())
2425    }
2426
2427    /// All traits that are visible within the crate graph (i.e. excluding private dependencies).
2428    pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2429        let visible_crates =
2430            self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2431
2432        iter::once(LOCAL_CRATE)
2433            .chain(visible_crates)
2434            .flat_map(move |cnum| self.traits(cnum).iter().copied())
2435    }
2436
2437    #[inline]
2438    pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2439        self.visibility(def_id).expect_local()
2440    }
2441
2442    /// Returns the origin of the opaque type `def_id`.
2443    x;#[instrument(skip(self), level = "trace", ret)]
2444    pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2445        self.hir_expect_opaque_ty(def_id).origin
2446    }
2447
2448    pub fn finish(self) {
2449        // We assume that no queries are run past here. If there are new queries
2450        // after this point, they'll show up as "<unknown>" in self-profiling data.
2451        self.alloc_self_profile_query_strings();
2452
2453        self.save_dep_graph();
2454        self.query_key_hash_verify_all();
2455
2456        if let Err((path, error)) = self.dep_graph.finish_encoding() {
2457            self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2458        }
2459    }
2460}
2461
2462macro_rules! nop_lift {
2463    ($set:ident; $ty:ty => $lifted:ty) => {
2464        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2465            type Lifted = $lifted;
2466            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2467                // Assert that the set has the right type.
2468                // Given an argument that has an interned type, the return type has the type of
2469                // the corresponding interner set. This won't actually return anything, we're
2470                // just doing this to compute said type!
2471                fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2472                    _x: Interned<'tcx, Inner>,
2473                ) -> InternedSet<'tcx, Inner> {
2474                    unreachable!()
2475                }
2476                fn _type_eq<T>(_x: &T, _y: &T) {}
2477                fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2478                    // If `x` is a newtype around an `Interned<T>`, then `interner` is an
2479                    // interner of appropriate type. (Ideally we'd also check that `x` is a
2480                    // newtype with just that one field. Not sure how to do that.)
2481                    let interner = _intern_set_ty_from_interned_ty(x.0);
2482                    // Now check that this is the same type as `interners.$set`.
2483                    _type_eq(&interner, &tcx.interners.$set);
2484                }
2485
2486                tcx.interners
2487                    .$set
2488                    .contains_pointer_to(&InternedInSet(&*self.0.0))
2489                    // SAFETY: `self` is interned and therefore valid
2490                    // for the entire lifetime of the `TyCtxt`.
2491                    .then(|| unsafe { mem::transmute(self) })
2492            }
2493        }
2494    };
2495}
2496
2497macro_rules! nop_list_lift {
2498    ($set:ident; $ty:ty => $lifted:ty) => {
2499        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2500            type Lifted = &'tcx List<$lifted>;
2501            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2502                // Assert that the set has the right type.
2503                if false {
2504                    let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2505                }
2506
2507                if self.is_empty() {
2508                    return Some(List::empty());
2509                }
2510                tcx.interners
2511                    .$set
2512                    .contains_pointer_to(&InternedInSet(self))
2513                    .then(|| unsafe { mem::transmute(self) })
2514            }
2515        }
2516    };
2517}
2518
2519impl<'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> }
2520impl<'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> }
2521impl<'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> }
2522impl<'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> }
2523impl<'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> }
2524impl<'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> }
2525impl<'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> }
2526impl<'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> }
2527impl<'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> }
2528
2529impl<'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> }
2530impl<'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! {
2531    poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2532}
2533impl<'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> }
2534
2535// This is the impl for `&'a GenericArgs<'a>`.
2536impl<'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> }
2537
2538macro_rules! sty_debug_print {
2539    ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2540        // Curious inner module to allow variant names to be used as
2541        // variable names.
2542        #[allow(non_snake_case)]
2543        mod inner {
2544            use crate::ty::{self, TyCtxt};
2545            use crate::ty::context::InternedInSet;
2546
2547            #[derive(Copy, Clone)]
2548            struct DebugStat {
2549                total: usize,
2550                lt_infer: usize,
2551                ty_infer: usize,
2552                ct_infer: usize,
2553                all_infer: usize,
2554            }
2555
2556            pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2557                let mut total = DebugStat {
2558                    total: 0,
2559                    lt_infer: 0,
2560                    ty_infer: 0,
2561                    ct_infer: 0,
2562                    all_infer: 0,
2563                };
2564                $(let mut $variant = total;)*
2565
2566                for shard in tcx.interners.type_.lock_shards() {
2567                    // It seems that ordering doesn't affect anything here.
2568                    #[allow(rustc::potential_query_instability)]
2569                    let types = shard.iter();
2570                    for &(InternedInSet(t), ()) in types {
2571                        let variant = match t.internee {
2572                            ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2573                                ty::Float(..) | ty::Str | ty::Never => continue,
2574                            ty::Error(_) => /* unimportant */ continue,
2575                            $(ty::$variant(..) => &mut $variant,)*
2576                        };
2577                        let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2578                        let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2579                        let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2580
2581                        variant.total += 1;
2582                        total.total += 1;
2583                        if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2584                        if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2585                        if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2586                        if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2587                    }
2588                }
2589                writeln!(fmt, "Ty interner             total           ty lt ct all")?;
2590                $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
2591                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2592                    stringify!($variant),
2593                    uses = $variant.total,
2594                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
2595                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
2596                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
2597                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
2598                    all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
2599                )*
2600                writeln!(fmt, "                  total {uses:6}        \
2601                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2602                    uses = total.total,
2603                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
2604                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
2605                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
2606                    all = total.all_infer as f64 * 100.0  / total.total as f64)
2607            }
2608        }
2609
2610        inner::go($fmt, $ctxt)
2611    }}
2612}
2613
2614impl<'tcx> TyCtxt<'tcx> {
2615    pub fn debug_stats(self) -> impl fmt::Debug {
2616        fmt::from_fn(move |fmt| {
2617            {
    #[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!(
2618                fmt,
2619                self,
2620                Adt,
2621                Array,
2622                Slice,
2623                RawPtr,
2624                Ref,
2625                FnDef,
2626                FnPtr,
2627                UnsafeBinder,
2628                Placeholder,
2629                Coroutine,
2630                CoroutineWitness,
2631                Dynamic,
2632                Closure,
2633                CoroutineClosure,
2634                Tuple,
2635                Bound,
2636                Param,
2637                Infer,
2638                Alias,
2639                Pat,
2640                Foreign
2641            )?;
2642
2643            fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
        self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2644            fmt.write_fmt(format_args!("Region interner: #{0}\n",
        self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2645            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())?;
2646            fmt.write_fmt(format_args!("Layout interner: #{0}\n",
        self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2647
2648            Ok(())
2649        })
2650    }
2651}
2652
2653// This type holds a `T` in the interner. The `T` is stored in the arena and
2654// this type just holds a pointer to it, but it still effectively owns it. It
2655// impls `Borrow` so that it can be looked up using the original
2656// (non-arena-memory-owning) types.
2657struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2658
2659impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2660    fn clone(&self) -> Self {
2661        *self
2662    }
2663}
2664
2665impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2666
2667impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2668    fn into_pointer(&self) -> *const () {
2669        self.0 as *const _ as *const ()
2670    }
2671}
2672
2673#[allow(rustc::usage_of_ty_tykind)]
2674impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2675    fn borrow(&self) -> &T {
2676        &self.0.internee
2677    }
2678}
2679
2680impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2681    fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2682        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2683        // `x == y`.
2684        self.0.internee == other.0.internee
2685    }
2686}
2687
2688impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2689
2690impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2691    fn hash<H: Hasher>(&self, s: &mut H) {
2692        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2693        self.0.internee.hash(s)
2694    }
2695}
2696
2697impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2698    fn borrow(&self) -> &[T] {
2699        &self.0[..]
2700    }
2701}
2702
2703impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2704    fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2705        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2706        // `x == y`.
2707        self.0[..] == other.0[..]
2708    }
2709}
2710
2711impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2712
2713impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2714    fn hash<H: Hasher>(&self, s: &mut H) {
2715        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2716        self.0[..].hash(s)
2717    }
2718}
2719
2720impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2721    fn borrow(&self) -> &[T] {
2722        &self.0[..]
2723    }
2724}
2725
2726impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2727    fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2728        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2729        // `x == y`.
2730        self.0[..] == other.0[..]
2731    }
2732}
2733
2734impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2735
2736impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2737    fn hash<H: Hasher>(&self, s: &mut H) {
2738        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2739        self.0[..].hash(s)
2740    }
2741}
2742
2743macro_rules! direct_interners {
2744    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2745        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2746            fn borrow<'a>(&'a self) -> &'a $ty {
2747                &self.0
2748            }
2749        }
2750
2751        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2752            fn eq(&self, other: &Self) -> bool {
2753                // The `Borrow` trait requires that `x.borrow() == y.borrow()`
2754                // equals `x == y`.
2755                self.0 == other.0
2756            }
2757        }
2758
2759        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2760
2761        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2762            fn hash<H: Hasher>(&self, s: &mut H) {
2763                // The `Borrow` trait requires that `x.borrow().hash(s) ==
2764                // x.hash(s)`.
2765                self.0.hash(s)
2766            }
2767        }
2768
2769        impl<'tcx> TyCtxt<'tcx> {
2770            $vis fn $method(self, v: $ty) -> $ret_ty {
2771                $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2772                    InternedInSet(self.interners.arena.alloc(v))
2773                }).0))
2774            }
2775        })+
2776    }
2777}
2778
2779// Functions with a `mk_` prefix are intended for use outside this file and
2780// crate. Functions with an `intern_` prefix are intended for use within this
2781// crate only, and have a corresponding `mk_` function.
2782impl<'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! {
2783    region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2784    valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2785    pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2786    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2787    layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2788    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2789    external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2790        ExternalConstraints -> ExternalConstraints<'tcx>,
2791}
2792
2793macro_rules! slice_interners {
2794    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2795        impl<'tcx> TyCtxt<'tcx> {
2796            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2797                if v.is_empty() {
2798                    List::empty()
2799                } else {
2800                    self.interners.$field.intern_ref(v, || {
2801                        InternedInSet(List::from_arena(&*self.arena, (), v))
2802                    }).0
2803                }
2804            })+
2805        }
2806    );
2807}
2808
2809// These functions intern slices. They all have a corresponding
2810// `mk_foo_from_iter` function that interns an iterator. The slice version
2811// should be used when possible, because it's faster.
2812impl<'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!(
2813    const_lists: pub mk_const_list(Const<'tcx>),
2814    args: pub mk_args(GenericArg<'tcx>),
2815    type_lists: pub mk_type_list(Ty<'tcx>),
2816    canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2817    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2818    projs: pub mk_projs(ProjectionKind),
2819    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2820    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2821    fields: pub mk_fields(FieldIdx),
2822    local_def_ids: intern_local_def_ids(LocalDefId),
2823    captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2824    patterns: pub mk_patterns(Pattern<'tcx>),
2825    outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2826    predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2827);
2828
2829impl<'tcx> TyCtxt<'tcx> {
2830    /// Given a `fn` sig, returns an equivalent `unsafe fn` type;
2831    /// that is, a `fn` type that is equivalent in every way for being
2832    /// unsafe.
2833    pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2834        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2835        Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2836    }
2837
2838    /// Given a `fn` sig, returns an equivalent `unsafe fn` sig;
2839    /// that is, a `fn` sig that is equivalent in every way for being
2840    /// unsafe.
2841    pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2842        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2843        sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig })
2844    }
2845
2846    /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
2847    /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
2848    pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2849        elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2850            self.associated_items(trait_did)
2851                .filter_by_name_unhygienic(assoc_name.name)
2852                .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2853        })
2854    }
2855
2856    /// Given a `ty`, return whether it's an `impl Future<...>`.
2857    pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2858        let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2859        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2860
2861        self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2862            let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2863                return false;
2864            };
2865            trait_predicate.trait_ref.def_id == future_trait
2866                && trait_predicate.polarity == PredicatePolarity::Positive
2867        })
2868    }
2869
2870    /// Given a closure signature, returns an equivalent fn signature. Detuples
2871    /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
2872    /// you would get a `fn(u32, i32)`.
2873    /// `unsafety` determines the unsafety of the fn signature. If you pass
2874    /// `hir::Safety::Unsafe` in the previous example, then you would get
2875    /// an `unsafe fn (u32, i32)`.
2876    /// It cannot convert a closure that requires unsafe.
2877    pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2878        sig.map_bound(|s| {
2879            let params = match s.inputs()[0].kind() {
2880                ty::Tuple(params) => *params,
2881                _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2882            };
2883            self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2884        })
2885    }
2886
2887    #[inline]
2888    pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2889        self.interners.intern_predicate(
2890            binder,
2891            self.sess,
2892            // This is only used to create a stable hashing context.
2893            &self.untracked,
2894        )
2895    }
2896
2897    #[inline]
2898    pub fn reuse_or_mk_predicate(
2899        self,
2900        pred: Predicate<'tcx>,
2901        binder: Binder<'tcx, PredicateKind<'tcx>>,
2902    ) -> Predicate<'tcx> {
2903        if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2904    }
2905
2906    pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2907        self.check_args_compatible_inner(def_id, args, false)
2908    }
2909
2910    fn check_args_compatible_inner(
2911        self,
2912        def_id: DefId,
2913        args: &'tcx [ty::GenericArg<'tcx>],
2914        nested: bool,
2915    ) -> bool {
2916        let generics = self.generics_of(def_id);
2917
2918        // IATs themselves have a weird arg setup (self + own args), but nested items *in* IATs
2919        // (namely: opaques, i.e. ATPITs) do not.
2920        let own_args = if !nested
2921            && let DefKind::AssocTy = self.def_kind(def_id)
2922            && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2923        {
2924            if generics.own_params.len() + 1 != args.len() {
2925                return false;
2926            }
2927
2928            if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
    ty::GenericArgKind::Type(_) => true,
    _ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2929                return false;
2930            }
2931
2932            &args[1..]
2933        } else {
2934            if generics.count() != args.len() {
2935                return false;
2936            }
2937
2938            let (parent_args, own_args) = args.split_at(generics.parent_count);
2939
2940            if let Some(parent) = generics.parent
2941                && !self.check_args_compatible_inner(parent, parent_args, true)
2942            {
2943                return false;
2944            }
2945
2946            own_args
2947        };
2948
2949        for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2950            match (&param.kind, arg.kind()) {
2951                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2952                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2953                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2954                _ => return false,
2955            }
2956        }
2957
2958        true
2959    }
2960
2961    /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
2962    /// and print out the args if not.
2963    pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2964        if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2965            if let DefKind::AssocTy = self.def_kind(def_id)
2966                && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2967            {
2968                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!(
2969                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2970                    self.def_path_str(def_id),
2971                    args,
2972                    // Make `[Self, GAT_ARGS...]` (this could be simplified)
2973                    self.mk_args_from_iter(
2974                        [self.types.self_param.into()].into_iter().chain(
2975                            self.generics_of(def_id)
2976                                .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2977                                .iter()
2978                                .copied()
2979                        )
2980                    )
2981                );
2982            } else {
2983                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!(
2984                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2985                    self.def_path_str(def_id),
2986                    args,
2987                    ty::GenericArgs::identity_for_item(self, def_id)
2988                );
2989            }
2990        }
2991    }
2992
2993    #[inline(always)]
2994    pub(crate) fn check_and_mk_args(
2995        self,
2996        def_id: DefId,
2997        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2998    ) -> GenericArgsRef<'tcx> {
2999        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
3000        self.debug_assert_args_compatible(def_id, args);
3001        args
3002    }
3003
3004    #[inline]
3005    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
3006        self.interners.intern_const(
3007            kind,
3008            self.sess,
3009            // This is only used to create a stable hashing context.
3010            &self.untracked,
3011        )
3012    }
3013
3014    // Avoid this in favour of more specific `Ty::new_*` methods, where possible.
3015    #[allow(rustc::usage_of_ty_tykind)]
3016    #[inline]
3017    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
3018        self.interners.intern_ty(
3019            st,
3020            self.sess,
3021            // This is only used to create a stable hashing context.
3022            &self.untracked,
3023        )
3024    }
3025
3026    pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
3027        match param.kind {
3028            GenericParamDefKind::Lifetime => {
3029                ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
3030            }
3031            GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
3032            GenericParamDefKind::Const { .. } => {
3033                ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
3034                    .into()
3035            }
3036        }
3037    }
3038
3039    pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
3040        self.mk_place_elem(place, PlaceElem::Field(f, ty))
3041    }
3042
3043    pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
3044        self.mk_place_elem(place, PlaceElem::Deref)
3045    }
3046
3047    pub fn mk_place_downcast(
3048        self,
3049        place: Place<'tcx>,
3050        adt_def: AdtDef<'tcx>,
3051        variant_index: VariantIdx,
3052    ) -> Place<'tcx> {
3053        self.mk_place_elem(
3054            place,
3055            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
3056        )
3057    }
3058
3059    pub fn mk_place_downcast_unnamed(
3060        self,
3061        place: Place<'tcx>,
3062        variant_index: VariantIdx,
3063    ) -> Place<'tcx> {
3064        self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
3065    }
3066
3067    pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
3068        self.mk_place_elem(place, PlaceElem::Index(index))
3069    }
3070
3071    /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
3072    /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
3073    /// flight.
3074    pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
3075        let mut projection = place.projection.to_vec();
3076        projection.push(elem);
3077
3078        Place { local: place.local, projection: self.mk_place_elems(&projection) }
3079    }
3080
3081    pub fn mk_poly_existential_predicates(
3082        self,
3083        eps: &[PolyExistentialPredicate<'tcx>],
3084    ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
3085        if !!eps.is_empty() {
    ::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
3086        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!(
3087            eps.array_windows()
3088                .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
3089                    != Ordering::Greater)
3090        );
3091        self.intern_poly_existential_predicates(eps)
3092    }
3093
3094    pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
3095        // FIXME consider asking the input slice to be sorted to avoid
3096        // re-interning permutations, in which case that would be asserted
3097        // here.
3098        self.interners.intern_clauses(clauses)
3099    }
3100
3101    pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
3102        // FIXME consider asking the input slice to be sorted to avoid
3103        // re-interning permutations, in which case that would be asserted
3104        // here.
3105        self.intern_local_def_ids(def_ids)
3106    }
3107
3108    pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
3109    where
3110        I: Iterator<Item = T>,
3111        T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
3112    {
3113        T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
3114    }
3115
3116    pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
3117    where
3118        I: Iterator<Item = T>,
3119        T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
3120    {
3121        T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
3122    }
3123
3124    pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
3125    where
3126        I: Iterator<Item = T>,
3127        T: CollectAndApply<
3128                &'tcx ty::CapturedPlace<'tcx>,
3129                &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
3130            >,
3131    {
3132        T::collect_and_apply(iter, |xs| self.intern_captures(xs))
3133    }
3134
3135    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
3136    where
3137        I: Iterator<Item = T>,
3138        T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
3139    {
3140        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3141    }
3142
3143    // Unlike various other `mk_*_from_iter` functions, this one uses `I:
3144    // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
3145    // variant, because of the need to combine `inputs` and `output`. This
3146    // explains the lack of `_from_iter` suffix.
3147    pub fn mk_fn_sig<I, T>(
3148        self,
3149        inputs: I,
3150        output: I::Item,
3151        c_variadic: bool,
3152        safety: hir::Safety,
3153        abi: ExternAbi,
3154    ) -> T::Output
3155    where
3156        I: IntoIterator<Item = T>,
3157        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3158    {
3159        T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3160            inputs_and_output: self.mk_type_list(xs),
3161            c_variadic,
3162            safety,
3163            abi,
3164        })
3165    }
3166
3167    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3168    where
3169        I: Iterator<Item = T>,
3170        T: CollectAndApply<
3171                PolyExistentialPredicate<'tcx>,
3172                &'tcx List<PolyExistentialPredicate<'tcx>>,
3173            >,
3174    {
3175        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3176    }
3177
3178    pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
3179    where
3180        I: Iterator<Item = T>,
3181        T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
3182    {
3183        T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
3184    }
3185
3186    pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3187    where
3188        I: Iterator<Item = T>,
3189        T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3190    {
3191        T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3192    }
3193
3194    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3195    where
3196        I: Iterator<Item = T>,
3197        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3198    {
3199        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3200    }
3201
3202    pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3203    where
3204        I: Iterator<Item = T>,
3205        T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3206    {
3207        T::collect_and_apply(iter, |xs| self.mk_args(xs))
3208    }
3209
3210    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3211    where
3212        I: Iterator<Item = T>,
3213        T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3214    {
3215        T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3216    }
3217
3218    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3219    where
3220        I: Iterator<Item = T>,
3221        T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3222    {
3223        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3224    }
3225
3226    pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3227    where
3228        I: Iterator<Item = T>,
3229        T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3230    {
3231        T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3232    }
3233
3234    pub fn mk_args_trait(
3235        self,
3236        self_ty: Ty<'tcx>,
3237        rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3238    ) -> GenericArgsRef<'tcx> {
3239        self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3240    }
3241
3242    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3243    where
3244        I: Iterator<Item = T>,
3245        T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
3246    {
3247        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3248    }
3249
3250    pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
3251    where
3252        I: Iterator<Item = T>,
3253        T: CollectAndApply<
3254                ty::ArgOutlivesPredicate<'tcx>,
3255                &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
3256            >,
3257    {
3258        T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
3259    }
3260
3261    /// Emit a lint at `span` from a lint struct (some type that implements `LintDiagnostic`,
3262    /// typically generated by `#[derive(LintDiagnostic)]`).
3263    #[track_caller]
3264    pub fn emit_node_span_lint(
3265        self,
3266        lint: &'static Lint,
3267        hir_id: HirId,
3268        span: impl Into<MultiSpan>,
3269        decorator: impl for<'a> LintDiagnostic<'a, ()>,
3270    ) {
3271        let level = self.lint_level_at_node(lint, hir_id);
3272        lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3273            decorator.decorate_lint(lint);
3274        })
3275    }
3276
3277    /// Emit a lint at the appropriate level for a hir node, with an associated span.
3278    ///
3279    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
3280    #[track_caller]
3281    pub fn node_span_lint(
3282        self,
3283        lint: &'static Lint,
3284        hir_id: HirId,
3285        span: impl Into<MultiSpan>,
3286        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3287    ) {
3288        let level = self.lint_level_at_node(lint, hir_id);
3289        lint_level(self.sess, lint, level, Some(span.into()), decorate);
3290    }
3291
3292    /// Find the appropriate span where `use` and outer attributes can be inserted at.
3293    pub fn crate_level_attribute_injection_span(self) -> Span {
3294        let node = self.hir_node(hir::CRATE_HIR_ID);
3295        let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
3296        m.spans.inject_use_span.shrink_to_lo()
3297    }
3298
3299    pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3300        self,
3301        diag: &mut Diag<'_, E>,
3302        features: impl IntoIterator<Item = (String, Symbol)>,
3303    ) {
3304        if !self.sess.is_nightly_build() {
3305            return;
3306        }
3307
3308        let span = self.crate_level_attribute_injection_span();
3309        for (desc, feature) in features {
3310            // FIXME: make this string translatable
3311            let msg =
3312                ::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}");
3313            diag.span_suggestion_verbose(
3314                span,
3315                msg,
3316                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
    })format!("#![feature({feature})]\n"),
3317                Applicability::MaybeIncorrect,
3318            );
3319        }
3320    }
3321
3322    /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically
3323    /// generated by `#[derive(LintDiagnostic)]`).
3324    #[track_caller]
3325    pub fn emit_node_lint(
3326        self,
3327        lint: &'static Lint,
3328        id: HirId,
3329        decorator: impl for<'a> LintDiagnostic<'a, ()>,
3330    ) {
3331        self.node_lint(lint, id, |lint| {
3332            decorator.decorate_lint(lint);
3333        })
3334    }
3335
3336    /// Emit a lint at the appropriate level for a hir node.
3337    ///
3338    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
3339    #[track_caller]
3340    pub fn node_lint(
3341        self,
3342        lint: &'static Lint,
3343        id: HirId,
3344        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3345    ) {
3346        let level = self.lint_level_at_node(lint, id);
3347        lint_level(self.sess, lint, level, None, decorate);
3348    }
3349
3350    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3351        let map = self.in_scope_traits_map(id.owner)?;
3352        let candidates = map.get(&id.local_id)?;
3353        Some(candidates)
3354    }
3355
3356    pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3357        {
    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:3357",
                        "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(3357u32),
                        ::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");
3358        self.named_variable_map(id.owner).get(&id.local_id).cloned()
3359    }
3360
3361    pub fn is_late_bound(self, id: HirId) -> bool {
3362        self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3363    }
3364
3365    pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
3366        self.mk_bound_variable_kinds(
3367            &self
3368                .late_bound_vars_map(id.owner)
3369                .get(&id.local_id)
3370                .cloned()
3371                .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))),
3372        )
3373    }
3374
3375    /// Given the def-id of an early-bound lifetime on an opaque corresponding to
3376    /// a duplicated captured lifetime, map it back to the early- or late-bound
3377    /// lifetime of the function from which it originally as captured. If it is
3378    /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
3379    /// of the signature.
3380    // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
3381    // re-use the generics of the opaque, this function will need to be tweaked slightly.
3382    pub fn map_opaque_lifetime_to_parent_lifetime(
3383        self,
3384        mut opaque_lifetime_param_def_id: LocalDefId,
3385    ) -> ty::Region<'tcx> {
3386        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!(
3387            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3388            "{opaque_lifetime_param_def_id:?} is a {}",
3389            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3390        );
3391
3392        loop {
3393            let parent = self.local_parent(opaque_lifetime_param_def_id);
3394            let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3395
3396            let Some((lifetime, _)) = lifetime_mapping
3397                .iter()
3398                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3399            else {
3400                crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
3401            };
3402
3403            match *lifetime {
3404                resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3405                    let new_parent = self.local_parent(ebv);
3406
3407                    // If we map to another opaque, then it should be a parent
3408                    // of the opaque we mapped from. Continue mapping.
3409                    if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
    DefKind::OpaqueTy => true,
    _ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3410                        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);
3411                        opaque_lifetime_param_def_id = ebv;
3412                        continue;
3413                    }
3414
3415                    let generics = self.generics_of(new_parent);
3416                    return ty::Region::new_early_param(
3417                        self,
3418                        ty::EarlyParamRegion {
3419                            index: generics
3420                                .param_def_id_to_index(self, ebv.to_def_id())
3421                                .expect("early-bound var should be present in fn generics"),
3422                            name: self.item_name(ebv.to_def_id()),
3423                        },
3424                    );
3425                }
3426                resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3427                    let new_parent = self.local_parent(lbv);
3428                    return ty::Region::new_late_param(
3429                        self,
3430                        new_parent.to_def_id(),
3431                        ty::LateParamRegionKind::Named(lbv.to_def_id()),
3432                    );
3433                }
3434                resolve_bound_vars::ResolvedArg::Error(guar) => {
3435                    return ty::Region::new_error(self, guar);
3436                }
3437                _ => {
3438                    return ty::Region::new_error_with_message(
3439                        self,
3440                        self.def_span(opaque_lifetime_param_def_id),
3441                        "cannot resolve lifetime",
3442                    );
3443                }
3444            }
3445        }
3446    }
3447
3448    /// Whether `def_id` is a stable const fn (i.e., doesn't need any feature gates to be called).
3449    ///
3450    /// When this is `false`, the function may still be callable as a `const fn` due to features
3451    /// being enabled!
3452    pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3453        self.is_const_fn(def_id)
3454            && match self.lookup_const_stability(def_id) {
3455                None => true, // a fn in a non-staged_api crate
3456                Some(stability) if stability.is_const_stable() => true,
3457                _ => false,
3458            }
3459    }
3460
3461    /// Whether the trait impl is marked const. This does not consider stability or feature gates.
3462    pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3463        self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3464            && self.impl_trait_header(def_id).constness == hir::Constness::Const
3465    }
3466
3467    pub fn is_sdylib_interface_build(self) -> bool {
3468        self.sess.opts.unstable_opts.build_sdylib_interface
3469    }
3470
3471    pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3472        match self.def_kind(def_id) {
3473            DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
3474            _ => None,
3475        }
3476    }
3477
3478    pub fn next_trait_solver_globally(self) -> bool {
3479        self.sess.opts.unstable_opts.next_solver.globally
3480    }
3481
3482    pub fn next_trait_solver_in_coherence(self) -> bool {
3483        self.sess.opts.unstable_opts.next_solver.coherence
3484    }
3485
3486    #[allow(rustc::bad_opt_access)]
3487    pub fn use_typing_mode_borrowck(self) -> bool {
3488        self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3489    }
3490
3491    pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3492        self.opt_rpitit_info(def_id).is_some()
3493    }
3494
3495    /// Named module children from all kinds of items, including imports.
3496    /// In addition to regular items this list also includes struct and variant constructors, and
3497    /// items inside `extern {}` blocks because all of them introduce names into parent module.
3498    ///
3499    /// Module here is understood in name resolution sense - it can be a `mod` item,
3500    /// or a crate root, or an enum, or a trait.
3501    ///
3502    /// This is not a query, making it a query causes perf regressions
3503    /// (probably due to hashing spans in `ModChild`ren).
3504    pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3505        self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3506    }
3507
3508    /// Return the crate imported by given use item.
3509    pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
3510        self.resolutions(()).extern_crate_map.get(&def_id).copied()
3511    }
3512
3513    pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3514        self.resolver_for_lowering_raw(()).0
3515    }
3516
3517    pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
3518        crate::dep_graph::make_metadata(self)
3519    }
3520
3521    pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3522        if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3523            self.coroutine_kind(def_id)
3524            && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3525            && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3526        {
3527            true
3528        } else {
3529            false
3530        }
3531    }
3532
3533    /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
3534    pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3535        {
    {
            '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 { .. })
3536    }
3537
3538    pub fn is_trivial_const<P>(self, def_id: P) -> bool
3539    where
3540        P: IntoQueryParam<DefId>,
3541    {
3542        self.trivial_const(def_id).is_some()
3543    }
3544
3545    /// Whether this def is one of the special bin crate entrypoint functions that must have a
3546    /// monomorphization and also not be internalized in the bin crate.
3547    pub fn is_entrypoint(self, def_id: DefId) -> bool {
3548        if self.is_lang_item(def_id, LangItem::Start) {
3549            return true;
3550        }
3551        if let Some((entry_def_id, _)) = self.entry_fn(())
3552            && entry_def_id == def_id
3553        {
3554            return true;
3555        }
3556        false
3557    }
3558}
3559
3560pub fn provide(providers: &mut Providers) {
3561    providers.is_panic_runtime =
3562        |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);
3563    providers.is_compiler_builtins =
3564        |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);
3565    providers.has_panic_handler = |tcx, LocalCrate| {
3566        // We want to check if the panic handler was defined in this crate
3567        tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3568    };
3569    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3570}