Skip to main content

rustc_middle/ty/
context.rs

1//! Type context book-keeping.
2
3#![allow(rustc::usage_of_ty_tykind)]
4
5mod impl_interner;
6pub mod tls;
7
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::PointeeSized;
14use std::ops::Deref;
15use std::sync::{Arc, OnceLock};
16use std::{debug_assert_matches, fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_attr_ir::find_attr;
21use rustc_attr_ir::lang_items::LangItem;
22use rustc_crate_store::{CrateStoreDyn, Untracked};
23use rustc_data_structures::defer;
24use rustc_data_structures::fx::FxHashMap;
25use rustc_data_structures::intern::Interned;
26use rustc_data_structures::profiling::SelfProfilerRef;
27use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
28use rustc_data_structures::stable_hash::StableHash;
29use rustc_data_structures::steal::Steal;
30use rustc_data_structures::sync::{
31    self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
32};
33use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
34use rustc_hir::def::DefKind;
35use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
36use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState};
37use rustc_hir::intravisit::Visitor;
38use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate};
39use rustc_index::IndexVec;
40use rustc_lint_defs::Lint;
41use rustc_lint_defs::builtin::UNUSED_FEATURES;
42use rustc_macros::Diagnostic;
43use rustc_session::config::NextSolverConfig;
44use rustc_session::{IncrCompSession, Session};
45use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
46use rustc_span::{DUMMY_SP, Ident, Span, Symbol, bug, kw, sym};
47use rustc_structures::{CrateType, Limit};
48use rustc_type_ir::TyKind::*;
49pub use rustc_type_ir::lift::Lift;
50use rustc_type_ir::{
51    CollectAndApply, IncludeSizedImplicitBounds, PlaceholderType, WithCachedTypeInfo, elaborate,
52    search_graph,
53};
54use tracing::{debug, instrument};
55
56use crate::arena::Arena;
57use crate::dep_graph::dep_node::make_metadata;
58use crate::dep_graph::{DepGraph, DepNodeIndex};
59use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo};
60use crate::ich::StableHashState;
61use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
62use crate::lint::emit_lint_base;
63use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
64use crate::middle::resolve::{ModChild, ResolverAstLowering};
65use crate::middle::resolve_bound_vars;
66use crate::mir::interpret::{self, Allocation, ConstAllocation};
67use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
68use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
69use crate::thir::Thir;
70use crate::traits;
71use crate::traits::solve::{
72    CanonicalInput, CanonicalInputData, ExternalConstraints, ExternalConstraintsData,
73    PredefinedOpaques,
74};
75use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
76use crate::ty::{
77    self, AdtDef, AdtDefData, AdtKind, Binder, CanonicalizerState, Clause, ClausePolarity, Clauses,
78    Const, ConstKind, FnSigKind, GenericArg, GenericArgsUnsized, GenericParamDefKind, List,
79    ListWithCachedTypeInfo, ParamConst, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig,
80    Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind,
81    TyVid, ValTree, ValTreeKind, Visibility,
82};
83
84impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
85    fn is_local(self) -> bool {
86        self.is_local()
87    }
88
89    fn as_local(self) -> Option<LocalDefId> {
90        self.as_local()
91    }
92}
93
94impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
95    fn safe() -> Self {
96        hir::Safety::Safe
97    }
98
99    fn unsafe_mode() -> Self {
100        hir::Safety::Unsafe
101    }
102
103    fn is_safe(self) -> bool {
104        self.is_safe()
105    }
106
107    fn prefix_str(self) -> &'static str {
108        self.prefix_str()
109    }
110}
111
112impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
113    fn generic_const_exprs(self) -> bool {
114        self.generic_const_exprs()
115    }
116
117    fn gca_const_items(self) -> bool {
118        self.gca_const_items()
119    }
120
121    fn coroutine_clone(self) -> bool {
122        self.coroutine_clone()
123    }
124
125    fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
126        // We don't consider feature bounds to hold in the crate when `staged_api` feature is
127        // enabled, even if it is enabled through `#[feature]`.
128        // This is to prevent accidentally leaking unstable APIs to stable.
129        !self.staged_api() && self.enabled(symbol)
130    }
131}
132
133impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
134    fn dummy() -> Self {
135        DUMMY_SP
136    }
137}
138
139type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
140
141pub struct CtxtInterners<'tcx> {
142    /// The arena that types, regions, etc. are allocated from.
143    arena: &'tcx WorkerLocal<Arena<'tcx>>,
144
145    // Specifically use a speedy hash algorithm for these hash sets, since
146    // they're accessed quite often.
147    type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
148    const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
149    args: InternedSet<'tcx, GenericArgsUnsized<'tcx>>,
150    type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
151    canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
152    region: InternedSet<'tcx, RegionKind<'tcx>>,
153    poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
154    predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
155    clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
156    projs: InternedSet<'tcx, List<ProjectionKind>>,
157    place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
158    const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
159    pat: InternedSet<'tcx, PatternKind<'tcx>>,
160    const_allocation: InternedSet<'tcx, Allocation>,
161    bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
162    layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
163    adt_def: InternedSet<'tcx, AdtDefData>,
164    external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
165    predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
166    fields: InternedSet<'tcx, List<FieldIdx>>,
167    local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
168    captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
169    valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
170    patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
171    outlives: InternedSet<'tcx, List<ty::ArgOutlivesClause<'tcx>>>,
172    canonical_inputs: InternedSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>>,
173}
174
175impl<'tcx> CtxtInterners<'tcx> {
176    fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
177        // Default interner size - this value has been chosen empirically, and may need to be
178        // adjusted as the compiler evolves.
179        const N: usize = 2048;
180        CtxtInterners {
181            arena,
182            // The factors have been chosen by @FractalFir based on observed interner sizes, and
183            // local perf runs. To get the interner sizes, insert `eprintln` printing the size of
184            // the interner in functions like `intern_ty`. Bigger benchmarks tend to give more
185            // accurate ratios, so use something like `x perf eprintln --includes cargo`.
186            type_: InternedSet::with_capacity(N * 16),
187            const_lists: InternedSet::with_capacity(N * 4),
188            args: InternedSet::with_capacity(N * 4),
189            type_lists: InternedSet::with_capacity(N * 4),
190            region: InternedSet::with_capacity(N * 4),
191            poly_existential_predicates: InternedSet::with_capacity(N / 4),
192            canonical_var_kinds: InternedSet::with_capacity(N / 2),
193            predicate: InternedSet::with_capacity(N),
194            clauses: InternedSet::with_capacity(N),
195            projs: InternedSet::with_capacity(N * 4),
196            place_elems: InternedSet::with_capacity(N * 2),
197            const_: InternedSet::with_capacity(N * 2),
198            pat: InternedSet::with_capacity(N),
199            const_allocation: InternedSet::with_capacity(N),
200            bound_variable_kinds: InternedSet::with_capacity(N * 2),
201            layout: InternedSet::with_capacity(N),
202            adt_def: InternedSet::with_capacity(N),
203            external_constraints: InternedSet::with_capacity(N),
204            predefined_opaques_in_body: InternedSet::with_capacity(N),
205            fields: InternedSet::with_capacity(N * 4),
206            local_def_ids: InternedSet::with_capacity(N),
207            captures: InternedSet::with_capacity(N),
208            valtree: InternedSet::with_capacity(N),
209            patterns: InternedSet::with_capacity(N),
210            outlives: InternedSet::with_capacity(N),
211            canonical_inputs: InternedSet::with_capacity(N),
212        }
213    }
214
215    /// Interns a type. (Use `mk_*` functions instead, where possible.)
216    #[allow(rustc::usage_of_ty_tykind)]
217    #[inline(never)]
218    fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
219        Ty(Interned::new_unchecked(
220            self.type_
221                .intern(kind, |kind| {
222                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
223                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
224                        internee: kind,
225                        flags: flags.flags,
226                        outer_exclusive_binder: flags.outer_exclusive_binder,
227                    }))
228                })
229                .0,
230        ))
231    }
232
233    /// Interns a const. (Use `mk_*` functions instead, where possible.)
234    #[allow(rustc::usage_of_ty_tykind)]
235    #[inline(never)]
236    fn intern_const(&self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
237        Const(Interned::new_unchecked(
238            self.const_
239                .intern(kind, |kind: ty::ConstKind<'_>| {
240                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
241                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
242                        internee: kind,
243                        flags: flags.flags,
244                        outer_exclusive_binder: flags.outer_exclusive_binder,
245                    }))
246                })
247                .0,
248        ))
249    }
250
251    /// Interns a predicate. (Use `mk_predicate` instead, where possible.)
252    #[inline(never)]
253    fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
254        Predicate(Interned::new_unchecked(
255            self.predicate
256                .intern(kind, |kind| {
257                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
258                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
259                        internee: kind,
260                        flags: flags.flags,
261                        outer_exclusive_binder: flags.outer_exclusive_binder,
262                    }))
263                })
264                .0,
265        ))
266    }
267
268    fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
269        if clauses.is_empty() {
270            ListWithCachedTypeInfo::empty()
271        } else {
272            self.clauses
273                .intern_ref(clauses, || {
274                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
275
276                    InternedInSet(ListWithCachedTypeInfo::from_arena(
277                        &*self.arena,
278                        flags.into(),
279                        clauses,
280                    ))
281                })
282                .0
283        }
284    }
285}
286
287// For these preinterned values, an alternative would be to have
288// variable-length vectors that grow as needed. But that turned out to be
289// slightly more complex and no faster.
290//
291// All numbers have been chosen based on profiling data.
292
293const NUM_PREINTERNED_INFER_TY_VARS: u32 = 512;
294const NUM_PREINTERNED_INFER_FRESH_TYS: u32 = 20;
295const NUM_PREINTERNED_INFER_FRESH_INT_TYS: u32 = 3;
296const NUM_PREINTERNED_INFER_FRESH_FLOAT_TYS: u32 = 3;
297const NUM_PREINTERNED_BOUND_BOUND_ANONS_I: u32 = 3;
298const NUM_PREINTERNED_BOUND_BOUND_ANONS_V: u32 = 20;
299const NUM_PREINTERNED_BOUND_CANONICAL_ANONS: u32 = 128;
300const NUM_PREINTERNED_PLACEHOLDER_ROOT_ANONS: u32 = 128;
301
302const NUM_PREINTERNED_RE_VARS: u32 = 500;
303const NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_I: u32 = 3;
304const NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_V: u32 = 20;
305const NUM_PREINTERNED_RE_BOUND_CANONICAL_ANONS: u32 = 20;
306
307pub struct CommonTypes<'tcx> {
308    pub unit: Ty<'tcx>,
309    pub bool: Ty<'tcx>,
310    pub char: Ty<'tcx>,
311    pub isize: Ty<'tcx>,
312    pub i8: Ty<'tcx>,
313    pub i16: Ty<'tcx>,
314    pub i32: Ty<'tcx>,
315    pub i64: Ty<'tcx>,
316    pub i128: Ty<'tcx>,
317    pub usize: Ty<'tcx>,
318    pub u8: Ty<'tcx>,
319    pub u16: Ty<'tcx>,
320    pub u32: Ty<'tcx>,
321    pub u64: Ty<'tcx>,
322    pub u128: Ty<'tcx>,
323    pub f16: Ty<'tcx>,
324    pub f32: Ty<'tcx>,
325    pub f64: Ty<'tcx>,
326    pub f128: Ty<'tcx>,
327    pub str_: Ty<'tcx>,
328    pub never: Ty<'tcx>,
329    pub self_param: Ty<'tcx>,
330
331    /// A dummy type that can be used as the self type of trait object types outside of
332    /// [`ty::ExistentialTraitRef`], [`ty::ExistentialProjection`], etc.
333    ///
334    /// This is most useful or even necessary when you want to manipulate existential predicates
335    /// together with normal predicates or if you want to pass them to an API that only expects
336    /// normal predicates.
337    ///
338    /// Indeed, you can sometimes use the trait object type itself as the self type instead of this
339    /// dummy type. However, that's not always correct: For example, if said trait object type can
340    /// also appear "naturally" in whatever type system entity you're working with (like predicates)
341    /// but you still need to be able to identify the erased self type later on.
342    /// That's when this dummy type comes in handy.
343    ///
344    /// HIR ty lowering guarantees / has to guarantee that this dummy type doesn't appear in the
345    /// lowered types, so you can "freely" use it (see warning below).
346    ///
347    /// <div class="warning">
348    ///
349    /// Under the hood, this type is just `ty::Infer(ty::FreshTy(0))`. Consequently, you must be
350    /// sure that fresh types cannot appear by other means in whatever type system entity you're
351    /// working with.
352    ///
353    /// Keep uses of this dummy type as local as possible and try not to leak it to subsequent
354    /// passes!
355    ///
356    /// </div>
357    pub trait_object_dummy_self: Ty<'tcx>,
358
359    /// Pre-interned `Infer(ty::TyVar(n))` for small values of `n`.
360    pub infer_ty_vars: Vec<Ty<'tcx>>,
361
362    /// Pre-interned `Infer(ty::FreshTy(n))` for small values of `n`.
363    pub infer_fresh_tys: Vec<Ty<'tcx>>,
364
365    /// Pre-interned `Infer(ty::FreshIntTy(n))` for small values of `n`.
366    pub infer_fresh_int_tys: Vec<Ty<'tcx>>,
367
368    /// Pre-interned `Infer(ty::FreshFloatTy(n))` for small values of `n`.
369    pub infer_fresh_float_tys: Vec<Ty<'tcx>>,
370
371    /// Pre-interned values of the form:
372    /// `Bound(
373    ///     BoundVarIndexKind::Bound(DebruijnIndex(i)),
374    ///     BoundTy { var: v, kind: BoundTyKind::Anon }
375    /// )`
376    /// for small values of `i` and `v`.
377    pub bound_bound_anons: Vec<Vec<Ty<'tcx>>>,
378
379    /// Pre-interned values of the form:
380    /// `Bound(BoundVarIndexKind::Canonical, BoundTy { var: v, kind: BoundTyKind::Anon })`
381    /// for small values of `v`.
382    pub bound_canonical_anons: Vec<Ty<'tcx>>,
383
384    /// Pre-interned values of the form:
385    /// `Placeholder(Placeholder {
386    ///     universe: UniverseIndex::ROOT,
387    ///     bound: BoundTy { var: v, kind: BoundTyKind::Anon }
388    /// })`
389    /// for small values of `v`.
390    pub placeholder_root_anons: Vec<Ty<'tcx>>,
391}
392
393pub struct CommonLifetimes<'tcx> {
394    /// `ReStatic`
395    pub re_static: Region<'tcx>,
396
397    /// Erased region, used outside of type inference.
398    pub re_erased: Region<'tcx>,
399
400    /// Pre-interned `ReVar(ty::RegionVid(n))` for small values of `n`.
401    pub re_vars: Vec<Region<'tcx>>,
402
403    /// Pre-interned values of the form:
404    /// `ReBound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundRegion { var: v, kind: BoundRegionKind::Anon })`
405    /// for small values of `i` and `v`.
406    pub re_bound_bound_anons: Vec<Vec<Region<'tcx>>>,
407
408    /// Pre-interned values of the form:
409    /// `ReBound(BoundVarIndexKind::Canonical, BoundRegion { var: v, kind: BoundRegionKind::Anon })`
410    /// for small values of `v`.
411    pub re_bound_canonical_anons: Vec<Region<'tcx>>,
412}
413
414pub struct CommonConsts<'tcx> {
415    pub unit: Const<'tcx>,
416    pub true_: Const<'tcx>,
417    pub false_: Const<'tcx>,
418    /// Use [`ty::ValTree::zst`] instead.
419    pub(crate) valtree_zst: ValTree<'tcx>,
420}
421
422impl<'tcx> CommonTypes<'tcx> {
423    fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
424        let mk = |ty| interners.intern_ty(ty);
425
426        let infer_ty_vars = (0..NUM_PREINTERNED_INFER_TY_VARS)
427            .map(|n| mk(Infer(ty::TyVar(TyVid::from(n)))))
428            .collect();
429        let infer_fresh_tys: Vec<_> =
430            (0..NUM_PREINTERNED_INFER_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
431        let infer_fresh_int_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_INT_TYS)
432            .map(|n| mk(Infer(ty::FreshIntTy(n))))
433            .collect();
434        let infer_fresh_float_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_FLOAT_TYS)
435            .map(|n| mk(Infer(ty::FreshFloatTy(n))))
436            .collect();
437
438        let bound_bound_anons = (0..NUM_PREINTERNED_BOUND_BOUND_ANONS_I)
439            .map(|i| {
440                (0..NUM_PREINTERNED_BOUND_BOUND_ANONS_V)
441                    .map(|v| {
442                        mk(ty::Bound(
443                            ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
444                            ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
445                        ))
446                    })
447                    .collect()
448            })
449            .collect();
450
451        let bound_canonical_anons = (0..NUM_PREINTERNED_BOUND_CANONICAL_ANONS)
452            .map(|v| {
453                mk(ty::Bound(
454                    ty::BoundVarIndexKind::Canonical,
455                    ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
456                ))
457            })
458            .collect();
459
460        let placeholder_root_anons = (0..NUM_PREINTERNED_PLACEHOLDER_ROOT_ANONS)
461            .map(|v| {
462                mk(ty::Placeholder(PlaceholderType::new_anon(
463                    ty::UniverseIndex::ROOT,
464                    ty::BoundVar::from(v),
465                )))
466            })
467            .collect();
468
469        CommonTypes {
470            unit: mk(Tuple(List::empty())),
471            bool: mk(Bool),
472            char: mk(Char),
473            never: mk(Never),
474            isize: mk(Int(ty::IntTy::Isize)),
475            i8: mk(Int(ty::IntTy::I8)),
476            i16: mk(Int(ty::IntTy::I16)),
477            i32: mk(Int(ty::IntTy::I32)),
478            i64: mk(Int(ty::IntTy::I64)),
479            i128: mk(Int(ty::IntTy::I128)),
480            usize: mk(Uint(ty::UintTy::Usize)),
481            u8: mk(Uint(ty::UintTy::U8)),
482            u16: mk(Uint(ty::UintTy::U16)),
483            u32: mk(Uint(ty::UintTy::U32)),
484            u64: mk(Uint(ty::UintTy::U64)),
485            u128: mk(Uint(ty::UintTy::U128)),
486            f16: mk(Float(ty::FloatTy::F16)),
487            f32: mk(Float(ty::FloatTy::F32)),
488            f64: mk(Float(ty::FloatTy::F64)),
489            f128: mk(Float(ty::FloatTy::F128)),
490            str_: mk(Str),
491            self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
492
493            trait_object_dummy_self: infer_fresh_tys[0],
494
495            infer_ty_vars,
496            infer_fresh_tys,
497            infer_fresh_int_tys,
498            infer_fresh_float_tys,
499            bound_bound_anons,
500            bound_canonical_anons,
501            placeholder_root_anons,
502        }
503    }
504}
505
506impl<'tcx> CommonLifetimes<'tcx> {
507    fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
508        let mk = |r| {
509            Region(Interned::new_unchecked(
510                interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
511            ))
512        };
513
514        let re_vars =
515            (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
516
517        let re_bound_bound_anons = (0..NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_I)
518            .map(|i| {
519                (0..NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_V)
520                    .map(|v| {
521                        mk(ty::ReBound(
522                            ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
523                            ty::BoundRegion {
524                                var: ty::BoundVar::from(v),
525                                kind: ty::BoundRegionKind::Anon,
526                            },
527                        ))
528                    })
529                    .collect()
530            })
531            .collect();
532
533        let re_bound_canonical_anons = (0..NUM_PREINTERNED_RE_BOUND_CANONICAL_ANONS)
534            .map(|v| {
535                mk(ty::ReBound(
536                    ty::BoundVarIndexKind::Canonical,
537                    ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
538                ))
539            })
540            .collect();
541
542        CommonLifetimes {
543            re_static: mk(ty::ReStatic),
544            re_erased: mk(ty::ReErased),
545            re_vars,
546            re_bound_bound_anons,
547            re_bound_canonical_anons,
548        }
549    }
550}
551
552impl<'tcx> CommonConsts<'tcx> {
553    fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
554        let mk_const = |c| interners.intern_const(c);
555
556        let mk_valtree = |v| {
557            ty::ValTree(Interned::new_unchecked(
558                interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
559            ))
560        };
561
562        let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
563        let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
564        let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
565
566        CommonConsts {
567            unit: mk_const(ty::ConstKind::Value(ty::Value {
568                ty: types.unit,
569                valtree: valtree_zst,
570            })),
571            true_: mk_const(ty::ConstKind::Value(ty::Value {
572                ty: types.bool,
573                valtree: valtree_true,
574            })),
575            false_: mk_const(ty::ConstKind::Value(ty::Value {
576                ty: types.bool,
577                valtree: valtree_false,
578            })),
579            valtree_zst,
580        }
581    }
582}
583
584/// This struct contains information regarding a free parameter region,
585/// either a `ReEarlyParam` or `ReLateParam`.
586#[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 region_def_id is_impl_item", &self.scope,
            &self.region_def_id, &&self.is_impl_item)
    }
}Debug)]
587pub struct FreeRegionInfo {
588    /// `LocalDefId` of the scope.
589    pub scope: LocalDefId,
590    /// the `DefId` of the free region.
591    pub region_def_id: DefId,
592    /// checks if bound region is in Impl Item
593    pub is_impl_item: bool,
594}
595
596/// This struct should only be created by `create_def`.
597#[derive(#[automatically_derived]impl<'tcx, K: ::core::marker::Copy + Copy>
    ::core::marker::Copy for TyCtxtFeed<'tcx, K> {
}Copy, #[automatically_derived]impl<'tcx, K: ::core::clone::Clone + Copy>
    ::core::clone::Clone for TyCtxtFeed<'tcx, K> {
    #[inline]
    fn clone(&self) -> Self {
        TyCtxtFeed {
            tcx: ::core::clone::Clone::clone(&self.tcx),
            key: ::core::clone::Clone::clone(&self.key),
        }
    }
}Clone)]
598pub struct TyCtxtFeed<'tcx, K: Copy> {
599    pub tcx: TyCtxt<'tcx>,
600    // Do not allow direct access, as downstream code must not mutate this field.
601    key: K,
602}
603
604/// Only queries that create a `DefId` are allowed to feed queries for that `DefId`.
605impl<K: Copy> !StableHash for TyCtxtFeed<'_, K> {}
606
607/// Some workarounds to use cases that cannot use `create_def`.
608/// Do not add new ways to create `TyCtxtFeed` without consulting
609/// with T-compiler and making an analysis about why your addition
610/// does not cause incremental compilation issues.
611impl<'tcx> TyCtxt<'tcx> {
612    /// Can only be fed before queries are run, and is thus exempt from any
613    /// incremental issues. Do not use except for the initial query feeding.
614    pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
615        self.dep_graph.assert_ignored();
616        TyCtxtFeed { tcx: self, key: () }
617    }
618
619    /// Only used in the resolver to register the `CRATE_DEF_ID` `DefId` and feed
620    /// some queries for it. It will panic if used twice.
621    pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
622        let key = self.untracked().source_span.push(span);
623        {
    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);
624        TyCtxtFeed { tcx: self, key }
625    }
626
627    /// In order to break cycles involving `AnonConst`, we need to set the expected type by side
628    /// effect. However, we do not want this as a general capability, so this interface restricts
629    /// to the only allowed case.
630    pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
631        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);
632        if true {
    if !(self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline)
        {
        ::core::panicking::panic("assertion failed: self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline")
    };
};debug_assert!(self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline);
633        TyCtxtFeed { tcx: self, key }.type_of(value)
634    }
635
636    // Trait impl item visibility is inherited from its trait when not specified
637    // explicitly. In that case we cannot determine it in early resolve,
638    // but instead are feeding it in late resolve, where we don't have access to the
639    // `TyCtxtFeed` anymore.
640    // To avoid having to hash the `LocalDefId` multiple times for inserting and removing the
641    // `TyCtxtFeed` from a hash table, we add this hack to feed the visibility.
642    // Do not use outside of the resolver query.
643    pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
644        if truecfg!(debug_assertions) {
645            match self.def_kind(self.local_parent(key)) {
646                DefKind::Impl { of_trait: true } => {}
647                other => ::rustc_span::macros::bug_impl(None,
    format_args!("{0:?} is not an assoc item of a trait impl: {1:?}", key,
        other), Location::caller())bug!("{key:?} is not an assoc item of a trait impl: {other:?}"),
648            }
649        }
650        TyCtxtFeed { tcx: self, key }.visibility(vis.to_mod_id())
651    }
652}
653
654impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> {
655    #[inline(always)]
656    pub fn key(&self) -> K {
657        self.key
658    }
659}
660
661impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
662    #[inline(always)]
663    pub fn def_id(&self) -> LocalDefId {
664        self.key
665    }
666
667    // Caller must ensure that `self.key` ID is indeed an owner.
668    pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
669        TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
670    }
671
672    // Fills in all the important parts needed by HIR queries
673    pub fn feed_hir(&self) {
674        self.hir_owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo::new(
675            self.tcx.arena.alloc(hir::OwnerNodes::synthetic()),
676            self.tcx.arena.alloc(Default::default()),
677            self.tcx.arena.alloc(Default::default()),
678            self.tcx.arena.alloc(Steal::new(Default::default())),
679        )));
680
681        self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
682    }
683}
684
685/// An assortment of global caches used by various parts of the compiler.
686///
687/// The individual fields are mostly unrelated to each other, but have been grouped together to
688/// reduce the number of top-level fields in [`GlobalCtxt`].
689#[derive(#[automatically_derived]impl<'tcx> ::core::default::Default for
    GlobalCaches<'tcx> {
    #[inline]
    fn default() -> Self {
        GlobalCaches {
            ty_rcache: ::core::default::Default::default(),
            selection_cache: ::core::default::Default::default(),
            evaluation_cache: ::core::default::Default::default(),
            new_solver_evaluation_cache: ::core::default::Default::default(),
            new_solver_canonical_param_env_cache: ::core::default::Default::default(),
            canonicalizer_states: ::core::default::Default::default(),
            canonical_param_env_cache: ::core::default::Default::default(),
            highest_var_in_clauses_cache: ::core::default::Default::default(),
            clauses_cache: ::core::default::Default::default(),
        }
    }
}Default)]
690pub struct GlobalCaches<'tcx> {
691    // Internal caches for metadata decoding. No need to track deps on this.
692    pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
693
694    /// Caches the results of trait selection. This cache is used
695    /// for things that do not have to do with the parameters in scope.
696    pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
697
698    /// Caches the results of trait evaluation. This cache is used
699    /// for things that do not have to do with the parameters in scope.
700    /// Merge this with `selection_cache`?
701    pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
702
703    /// Caches the results of goal evaluation in the new solver.
704    new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
705    new_solver_canonical_param_env_cache: Lock<ty::CanonicalParamEnvCache<TyCtxt<'tcx>>>,
706
707    /// State reused by each new canonicalizer, and then cleared (but not deallocated) once the
708    /// canonicalizer is finished. A performance win, because it avoids reallocating new
709    /// vecs/hashmaps for every canonicalizer. The `Vec` is needed because there can be multiple
710    /// canonicalizers in use at once if the number of threads > 1. The `Box` avoids memcpy because
711    /// `CanonicalizerState` is moderately big.
712    pub canonicalizer_states: Lock<Vec<Box<CanonicalizerState<TyCtxt<'tcx>>>>>,
713
714    pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
715
716    /// Caches the index of the highest bound var in clauses in a canonical binder.
717    pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
718
719    /// Caches the instantiation of a canonical binder given a set of args.
720    pub clauses_cache:
721        Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
722}
723
724/// The central data structure of the compiler. It stores references
725/// to the various **arenas** and also houses the results of the
726/// various **compiler queries** that have been performed. See the
727/// [rustc dev guide] for more details.
728///
729/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html
730///
731/// An implementation detail: `TyCtxt` is a wrapper type for [GlobalCtxt],
732/// which is the struct that actually holds all the data. `TyCtxt` derefs to
733/// `GlobalCtxt`, and in practice `TyCtxt` is passed around everywhere, and all
734/// operations are done via `TyCtxt`. A `TyCtxt` is obtained for a `GlobalCtxt`
735/// by calling `enter` with a closure `f`. That function creates both the
736/// `TyCtxt`, and an `ImplicitCtxt` around it that is put into TLS. Within `f`:
737/// - The `ImplicitCtxt` is available implicitly via TLS.
738/// - The `TyCtxt` is available explicitly via the `tcx` parameter, and also
739///   implicitly within the `ImplicitCtxt`. Explicit access is preferred when
740///   possible.
741#[derive(#[automatically_derived]impl<'tcx> ::core::marker::Copy for TyCtxt<'tcx> { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl<'tcx>
    ::core::clone::TrivialClone for TyCtxt<'tcx> {
}
#[automatically_derived]impl<'tcx> ::core::clone::Clone for TyCtxt<'tcx> {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<&'tcx GlobalCtxt<'tcx>>;
        *self
    }
}Clone)]
742#[rustc_diagnostic_item = "TyCtxt"]
743#[rustc_pass_by_value]
744pub struct TyCtxt<'tcx> {
745    gcx: &'tcx GlobalCtxt<'tcx>,
746}
747
748// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. Its
749// field are asserted to implement these traits below, so this is trivially safe, and it greatly
750// speeds-up compilation of this crate and its dependents.
751unsafe impl DynSend for TyCtxt<'_> {}
752unsafe impl DynSync for TyCtxt<'_> {}
753fn _assert_tcx_fields() {
754    sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
755    sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
756}
757
758impl<'tcx> Deref for TyCtxt<'tcx> {
759    type Target = &'tcx GlobalCtxt<'tcx>;
760    #[inline(always)]
761    fn deref(&self) -> &Self::Target {
762        &self.gcx
763    }
764}
765
766/// See [TyCtxt] for details about this type.
767pub struct GlobalCtxt<'tcx> {
768    pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
769    pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
770
771    interners: CtxtInterners<'tcx>,
772
773    pub sess: &'tcx Session,
774    crate_types: Vec<CrateType>,
775    /// The `stable_crate_id` is constructed out of the crate name and all the
776    /// `-C metadata` arguments passed to the compiler. Its value forms a unique
777    /// global identifier for the crate. It is used to allow multiple crates
778    /// with the same name to coexist. See the
779    /// `rustc_symbol_mangling` crate for more information.
780    stable_crate_id: StableCrateId,
781
782    pub incr_comp_session: Option<&'tcx IncrCompSession>,
783    pub dep_graph: DepGraph,
784
785    /// This duplicates `Session::prof` because this field is hot enough that accessing it via
786    /// `self.sess.prof` is a measurable slowdown (see #161332).
787    pub prof: SelfProfilerRef,
788
789    /// Common types, pre-interned for your convenience.
790    pub types: CommonTypes<'tcx>,
791
792    /// Common lifetimes, pre-interned for your convenience.
793    pub lifetimes: CommonLifetimes<'tcx>,
794
795    /// Common consts, pre-interned for your convenience.
796    pub consts: CommonConsts<'tcx>,
797
798    /// Hooks to be able to register functions in other crates that can then still
799    /// be called from rustc_middle.
800    pub(crate) hooks: crate::hooks::Providers,
801
802    untracked: Untracked,
803
804    pub query_system: QuerySystem<'tcx>,
805
806    pub caches: GlobalCaches<'tcx>,
807
808    /// Data layout specification for the current target.
809    pub data_layout: TargetDataLayout,
810
811    /// Stores memory for globals (statics/consts).
812    pub(crate) alloc_map: interpret::AllocMap<'tcx>,
813
814    current_gcx: CurrentGcx,
815}
816
817impl<'tcx> GlobalCtxt<'tcx> {
818    /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
819    /// `f`.
820    pub fn enter<F, R>(&'tcx self, f: F) -> R
821    where
822        F: FnOnce(TyCtxt<'tcx>) -> R,
823    {
824        let icx = tls::ImplicitCtxt::new(self);
825
826        // Reset `current_gcx` to `None` when we exit.
827        let _on_drop = defer(move || {
828            *self.current_gcx.value.write() = None;
829        });
830
831        // Set this `GlobalCtxt` as the current one.
832        {
833            let mut guard = self.current_gcx.value.write();
834            if !guard.is_none() {
    {
        ::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
    }
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
835            *guard = Some(self as *const _ as *const ());
836        }
837
838        tls::enter_context(&icx, || f(icx.tcx))
839    }
840}
841
842/// This is used to get a reference to a `GlobalCtxt` if one is available.
843///
844/// This is needed to allow the deadlock handler access to `GlobalCtxt` to look for query cycles.
845/// It cannot use the `TLV` global because that's only guaranteed to be defined on the thread
846/// creating the `GlobalCtxt`. Other threads have access to the `TLV` only inside Rayon jobs, but
847/// the deadlock handler is not called inside such a job.
848#[derive(#[automatically_derived]impl ::core::clone::Clone for CurrentGcx {
    #[inline]
    fn clone(&self) -> Self {
        CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
    }
}Clone)]
849pub struct CurrentGcx {
850    /// This stores a pointer to a `GlobalCtxt`. This is set to `Some` inside `GlobalCtxt::enter`
851    /// and reset to `None` when that function returns or unwinds.
852    value: Arc<RwLock<Option<*const ()>>>,
853}
854
855unsafe impl DynSend for CurrentGcx {}
856unsafe impl DynSync for CurrentGcx {}
857
858impl CurrentGcx {
859    pub fn new() -> Self {
860        Self { value: Arc::new(RwLock::new(None)) }
861    }
862
863    pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
864        let read_guard = self.value.read();
865        let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
866        // SAFETY: We hold the read lock for the `GlobalCtxt` pointer. That prevents
867        // `GlobalCtxt::enter` from returning as it would first acquire the write lock.
868        // This ensures the `GlobalCtxt` is live during `f`.
869        f(unsafe { &*gcx })
870    }
871}
872
873impl<'tcx> TyCtxt<'tcx> {
874    pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
875        // Closures' typeck results come from their outermost function,
876        // as they are part of the same "inference environment".
877        let root = self.typeck_root_def_id_local(def_id);
878        self.hir_node_by_def_id(root).body_id().is_some()
879    }
880
881    /// Expects a body and returns its codegen attributes.
882    ///
883    /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for
884    /// constants.
885    pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
886        let def_kind = self.def_kind(def_id);
887        if def_kind.has_codegen_attrs() {
888            self.codegen_fn_attrs(def_id)
889        } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
    DefKind::AnonConst | DefKind::AssocConst | DefKind::Const |
        DefKind::GlobalAsm => true,
    _ => false,
}matches!(
890            def_kind,
891            DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::GlobalAsm
892        ) {
893            CodegenFnAttrs::EMPTY
894        } else {
895            ::rustc_span::macros::bug_impl(None,
    format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
        def_id, def_kind), Location::caller())bug!(
896                "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
897                def_id,
898                def_kind
899            )
900        }
901    }
902
903    pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
904        self.arena.alloc(Steal::new(thir))
905    }
906
907    pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
908        self.arena.alloc(Steal::new(mir))
909    }
910
911    pub fn alloc_steal_promoted(
912        self,
913        promoted: IndexVec<Promoted, Body<'tcx>>,
914    ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
915        self.arena.alloc(Steal::new(promoted))
916    }
917
918    pub fn mk_adt_def(
919        self,
920        did: DefId,
921        kind: AdtKind,
922        variants: IndexVec<VariantIdx, ty::VariantDef>,
923        repr: ReprOptions,
924    ) -> ty::AdtDef<'tcx> {
925        self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
926    }
927
928    /// Allocates a read-only byte or string literal for `mir::interpret` with alignment 1.
929    /// Returns the same `AllocId` if called again with the same bytes.
930    pub fn allocate_bytes_dedup<'a>(
931        self,
932        bytes: impl Into<Cow<'a, [u8]>>,
933        salt: usize,
934    ) -> interpret::AllocId {
935        // Create an allocation that just contains these bytes.
936        let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
937        let alloc = self.mk_const_alloc(alloc);
938        self.reserve_and_set_memory_dedup(alloc, salt)
939    }
940
941    /// Traits added on all bounds by default, excluding `Sized` which is treated separately.
942    pub fn default_traits(self) -> &'static [LangItem] {
943        if self.sess.opts.unstable_opts.experimental_default_bounds {
944            &[
945                LangItem::DefaultTrait1,
946                LangItem::DefaultTrait2,
947                LangItem::DefaultTrait3,
948                LangItem::DefaultTrait4,
949            ]
950        } else {
951            &[]
952        }
953    }
954
955    pub fn is_default_trait(self, def_id: DefId) -> bool {
956        self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
957    }
958
959    /// Returns true if a trait is an "implicit trait", which is a trait which is added
960    /// to bounds on generic types automatically by the compiler.
961    pub fn is_implicit_trait(
962        self,
963        def_id: DefId,
964        including_sized: IncludeSizedImplicitBounds,
965    ) -> bool {
966        self.is_default_trait(def_id)
967            // NOTE: add move and forget here later
968            || (#[allow(non_exhaustive_omitted_patterns)] match including_sized {
    IncludeSizedImplicitBounds::Yes => true,
    _ => false,
}matches!(including_sized, IncludeSizedImplicitBounds::Yes) && self.is_sizedness_trait(def_id))
969    }
970
971    pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
972        #[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))
973    }
974
975    pub fn is_forget_trait(self, def_id: DefId) -> bool {
976        #[allow(non_exhaustive_omitted_patterns)] match self.as_lang_item(def_id) {
    Some(LangItem::Forget) => true,
    _ => false,
}matches!(self.as_lang_item(def_id), Some(LangItem::Forget))
977    }
978
979    pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> T::Lifted {
980        value.lift_to_interner(self)
981    }
982
983    /// Creates a type context. To use the context call `fn enter` which
984    /// provides a `TyCtxt`.
985    ///
986    /// By only providing the `TyCtxt` inside of the closure we enforce that the type
987    /// context and any interned value (types, args, etc.) can only be used while `ty::tls`
988    /// has a valid reference to the context, to allow formatting values that need it.
989    pub fn create_global_ctxt<T>(
990        gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
991        sess: &'tcx Session,
992        crate_types: Vec<CrateType>,
993        stable_crate_id: StableCrateId,
994        arena: &'tcx WorkerLocal<Arena<'tcx>>,
995        hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
996        untracked: Untracked,
997        incr_comp_session: Option<&'tcx IncrCompSession>,
998        dep_graph: DepGraph,
999        query_system: QuerySystem<'tcx>,
1000        hooks: crate::hooks::Providers,
1001        current_gcx: CurrentGcx,
1002        f: impl FnOnce(TyCtxt<'tcx>) -> T,
1003    ) -> T {
1004        let data_layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
1005            sess.dcx().emit_fatal(err);
1006        });
1007        let interners = CtxtInterners::new(arena);
1008        let common_types = CommonTypes::new(&interners);
1009        let common_lifetimes = CommonLifetimes::new(&interners);
1010        let common_consts = CommonConsts::new(&interners, &common_types);
1011
1012        let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1013            sess,
1014            crate_types,
1015            stable_crate_id,
1016            arena,
1017            hir_arena,
1018            interners,
1019            incr_comp_session,
1020            dep_graph,
1021            hooks,
1022            prof: sess.prof.clone(),
1023            types: common_types,
1024            lifetimes: common_lifetimes,
1025            consts: common_consts,
1026            untracked,
1027            query_system,
1028            caches: Default::default(),
1029            data_layout,
1030            alloc_map: interpret::AllocMap::new(),
1031            current_gcx,
1032        });
1033
1034        // This is a separate function to work around a crash with parallel rustc (#135870)
1035        gcx.enter(f)
1036    }
1037
1038    /// Obtain all lang items of this crate and all dependencies (recursively)
1039    pub fn lang_items(self) -> &'tcx rustc_attr_ir::lang_items::LanguageItems {
1040        self.get_lang_items(())
1041    }
1042
1043    /// Gets a `Ty` representing the [`LangItem::OrderingEnum`]
1044    #[track_caller]
1045    pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1046        let ordering_enum = self.require_lang_item(LangItem::OrderingEnum, span);
1047        self.type_of(ordering_enum).no_bound_vars().unwrap()
1048    }
1049
1050    /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
1051    /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
1052    pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1053        self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1054    }
1055
1056    /// Obtain the diagnostic item's name
1057    pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1058        self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1059    }
1060
1061    /// Check whether the diagnostic item with the given `name` has the given `DefId`.
1062    pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1063        self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1064    }
1065
1066    pub fn is_coroutine(self, def_id: DefId) -> bool {
1067        self.coroutine_kind(def_id).is_some()
1068    }
1069
1070    pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1071        self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1072    }
1073
1074    /// Returns true if the const is guaranteed to have a directly represented RHS. This is either
1075    /// because it has a directly represented RHS, or is a trait definition that is marked as
1076    /// requiring its implementation to have a directly represented RHS.
1077    ///
1078    /// Note: Be very careful with using this method - under `gca_const_items`, a trait can
1079    /// declare a regular const, but an `impl` could implement it with a directly represented const
1080    /// (a la refinement). This method would return false in such a case.
1081    pub fn is_direct_const(self, def_id: DefId) -> bool {
1082        if true {
    {
        match self.def_kind(def_id) {
            DefKind::Const | DefKind::AssocConst => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Const | DefKind::AssocConst",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::Const | DefKind::AssocConst);
1083        self.is_always_gca(def_id) || self.const_of_item(def_id).is_some()
1084    }
1085
1086    /// Whether this is a projection const marked with `#[always_gca]`
1087    pub fn is_always_gca(self, def_id: DefId) -> bool {
1088        {
        {
            'done:
                {
                for i in ::rustc_attr_ir::HasAttrs::get_attrs(def_id, &self) {
                    #[allow(unused_imports)]
                    use ::rustc_attr_ir::AttributeKind::*;
                    let i: &::rustc_attr_ir::Attribute = i;
                    match i {
                        ::rustc_attr_ir::Attribute::Parsed(AlwaysGca) => {
                            break 'done Some(());
                        }
                        ::rustc_attr_ir::Attribute::Tool(..) |
                            ::rustc_attr_ir::Attribute::DeriveHelper(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }
    }.is_some()find_attr!(self, def_id, AlwaysGca)
1089    }
1090
1091    /// Returns the movability of the coroutine of `def_id`, or panics
1092    /// if given a `def_id` that is not a coroutine.
1093    pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1094        self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1095    }
1096
1097    /// Returns `true` if the node pointed to by `def_id` is a coroutine for an async construct.
1098    pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1099        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
        true,
    _ => false,
}matches!(
1100            self.coroutine_kind(def_id),
1101            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1102        )
1103    }
1104
1105    // Whether the body owner is synthetic, which in this case means it does not correspond to
1106    // meaningful HIR. This is currently used to skip over MIR borrowck.
1107    pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1108        let def_id = def_id.into();
1109        match self.def_kind(def_id) {
1110            DefKind::SyntheticCoroutineBody => true,
1111            DefKind::Const | DefKind::AssocConst => self.const_of_item(def_id).is_some(),
1112            _ => false,
1113        }
1114    }
1115
1116    /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`.
1117    /// This means it is neither an `async` or `gen` construct.
1118    pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1119        #[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(_)))
1120    }
1121
1122    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `gen` construct.
1123    pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1124        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
        true,
    _ => false,
}matches!(
1125            self.coroutine_kind(def_id),
1126            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1127        )
1128    }
1129
1130    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `async gen` construct.
1131    pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1132        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
        => true,
    _ => false,
}matches!(
1133            self.coroutine_kind(def_id),
1134            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1135        )
1136    }
1137
1138    pub fn features(self) -> &'tcx rustc_feature::Features {
1139        self.features_query(())
1140    }
1141
1142    pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1143        let id = id.into_query_key();
1144        // Accessing the DefKey is ok, since it is part of DefPathHash.
1145        if let Some(id) = id.as_local() {
1146            self.definitions_untracked().def_key(id)
1147        } else {
1148            self.cstore_untracked().def_key(id)
1149        }
1150    }
1151
1152    /// Converts a `DefId` into its fully expanded `DefPath` (every
1153    /// `DefId` is really just an interned `DefPath`).
1154    ///
1155    /// Note that if `id` is not local to this crate, the result will
1156    ///  be a non-local `DefPath`.
1157    pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1158        // Accessing the DefPath is ok, since it is part of DefPathHash.
1159        if let Some(id) = id.as_local() {
1160            self.definitions_untracked().def_path(id)
1161        } else {
1162            self.cstore_untracked().def_path(id)
1163        }
1164    }
1165
1166    #[inline]
1167    pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1168        // Accessing the DefPathHash is ok, it is incr. comp. stable.
1169        if let Some(def_id) = def_id.as_local() {
1170            self.definitions_untracked().def_path_hash(def_id)
1171        } else {
1172            self.cstore_untracked().def_path_hash(def_id)
1173        }
1174    }
1175
1176    /// Useful when one needs to access a lot of `DefPathHash`-es in quick succession. Stable
1177    /// sorting a collection for example.
1178    ///
1179    /// Read locks the structures containing the `DefPathHash` mappings, allowing us to skip lots of
1180    /// locking and releasing using `[Self::def_path_hash]` would do
1181    pub fn prelocked_def_path_hasher(
1182        self,
1183    ) -> impl Fn(DefId) -> rustc_hir::definitions::DefPathHash {
1184        let definitions = self.definitions_untracked();
1185        let cstore = self.cstore_untracked();
1186        move |def_id| match def_id.as_local() {
1187            Some(def_id) => definitions.def_path_hash(def_id),
1188            None => cstore.def_path_hash(def_id),
1189        }
1190    }
1191
1192    #[inline]
1193    pub fn crate_types(self) -> &'tcx [CrateType] {
1194        &self.crate_types
1195    }
1196
1197    pub fn needs_metadata(self) -> bool {
1198        self.crate_types().iter().any(|ty| match *ty {
1199            CrateType::Executable
1200            | CrateType::StaticLib
1201            | CrateType::Cdylib
1202            | CrateType::Sdylib => false,
1203            CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1204        }) && !self.sess.opts.actually_rustdoc
1205    }
1206
1207    pub fn needs_hir_hash(self) -> bool {
1208        // Why is the hir hash needed for these configurations?
1209        // - debug_assertions: for the "fingerprint the result" check in
1210        //   `rustc_query_impl::execution::execute_job`.
1211        // - incremental: for query lookups.
1212        // - needs_metadata: it is included in the crate metadata through the crate_hash query
1213        // - instrument_coverage: for putting into coverage data (see
1214        //   `hash_mir_source`).
1215        // - metrics_dir: metrics use the strict version hash in the filenames
1216        //   for dumped metrics files to prevent overwriting distinct metrics
1217        //   for similar source builds (may change in the future, this is part
1218        //   of the proof of concept impl for the metrics initiative project goal)
1219        truecfg!(debug_assertions)
1220            || self.sess.opts.incremental.is_some()
1221            || self.needs_metadata()
1222            || self.sess.instrument_coverage()
1223            || self.sess.opts.unstable_opts.metrics_dir.is_some()
1224    }
1225
1226    /// Whether the combined per-owner HIR hash (`OwnerInfo::opt_hash`, which folds `parenting`,
1227    /// `trait_map` and `children` on top of the node/attr hashes) needs to be computed during
1228    /// lowering.
1229    ///
1230    /// This is a strict subset of [`Self::needs_hir_hash`]: notably it drops the plain
1231    /// `needs_metadata` case. With metadata-based crate hashing (the default) the crate hash is
1232    /// built from the encoded metadata plus each owner's cheaper `OwnerInfo::fingerprint` (just the
1233    /// node and attr sub-hashes), so the combined hash is never read and computing it is wasted
1234    /// work. It is still required for:
1235    /// - `-Z metadata-crate-hash=no`, where `crate_hash` falls back to hashing each `OwnerInfo`;
1236    /// - incremental, where the `lower_to_hir` result is fingerprinted for red/green tracking;
1237    /// - debug assertions, where every query result is fingerprinted to catch nondeterminism.
1238    ///
1239    /// The `needs_hir_hash()` conjunct guarantees the node/attr sub-hashes it folds in are present.
1240    pub fn needs_owner_info_hash(self) -> bool {
1241        self.needs_hir_hash()
1242            && (!self.sess.opts.unstable_opts.metadata_crate_hash
1243                || self.sess.opts.incremental.is_some()
1244                || truecfg!(debug_assertions))
1245    }
1246
1247    #[inline]
1248    pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1249        if crate_num == LOCAL_CRATE {
1250            self.stable_crate_id
1251        } else {
1252            self.cstore_untracked().stable_crate_id(crate_num)
1253        }
1254    }
1255
1256    /// Maps a StableCrateId to the corresponding CrateNum. This method assumes
1257    /// that the crate in question has already been loaded by the CrateStore.
1258    #[inline]
1259    pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1260        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1261            LOCAL_CRATE
1262        } else {
1263            *self
1264                .untracked()
1265                .stable_crate_ids
1266                .read()
1267                .get(&stable_crate_id)
1268                .unwrap_or_else(|| ::rustc_span::macros::bug_impl(None,
    format_args!("uninterned StableCrateId: {0:?}", stable_crate_id),
    Location::caller())bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1269        }
1270    }
1271
1272    /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
1273    /// session, if it still exists. This is used during incremental compilation to
1274    /// turn a deserialized `DefPathHash` into its current `DefId`.
1275    pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1276        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs:1276",
                        "rustc_middle::ty::context", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs"),
                        ::tracing_core::__macro_support::Option::Some(1276u32),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("def_path_hash_to_def_id({0:?})",
                                                    hash) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("def_path_hash_to_def_id({:?})", hash);
1277
1278        let stable_crate_id = hash.stable_crate_id();
1279
1280        // If this is a DefPathHash from the local crate, we can look up the
1281        // DefId in the tcx's `Definitions`.
1282        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1283            Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1284        } else {
1285            self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1286        }
1287    }
1288
1289    pub fn def_path_debug_str(self, def_id: DefId) -> String {
1290        // We are explicitly not going through queries here in order to get
1291        // crate name and stable crate id since this code is called from debug!()
1292        // statements within the query system and we'd run into endless
1293        // recursion otherwise.
1294        let (crate_name, stable_crate_id) = if def_id.is_local() {
1295            (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1296        } else {
1297            let cstore = &*self.cstore_untracked();
1298            (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1299        };
1300
1301        ::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!(
1302            "{}[{:04x}]{}",
1303            crate_name,
1304            // Don't print the whole stable crate id. That's just
1305            // annoying in debug output.
1306            stable_crate_id.as_u64() >> (8 * 6),
1307            self.def_path(def_id).to_string_no_crate_verbose()
1308        )
1309    }
1310
1311    pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1312        self.sess.dcx()
1313    }
1314
1315    /// Checks to see if the caller (`body_features`) has all the features required by the callee
1316    /// (`callee_features`).
1317    pub fn is_target_feature_call_safe(
1318        self,
1319        callee_features: &[TargetFeature],
1320        body_features: &[TargetFeature],
1321    ) -> bool {
1322        // If the called function has target features the calling function hasn't,
1323        // the call requires `unsafe`. Don't check this on wasm
1324        // targets, though. For more information on wasm see the
1325        // is_like_wasm check in hir_analysis/src/collect.rs
1326        self.sess.target.options.is_like_wasm
1327            || callee_features
1328                .iter()
1329                .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1330    }
1331
1332    /// Returns the safe version of the signature of the given function, if calling it
1333    /// would be safe in the context of the given caller.
1334    pub fn adjust_target_feature_sig(
1335        self,
1336        fun_def: DefId,
1337        fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1338        caller: DefId,
1339    ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1340        let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1341        let caller_features = &self.body_codegen_attrs(caller).target_features;
1342        if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1343            return Some(fun_sig.map_bound(|sig| ty::FnSig {
1344                fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1345                ..sig
1346            }));
1347        }
1348        None
1349    }
1350
1351    /// Helper to get a tracked environment variable via. [`TyCtxt::env_var_os`] and converting to
1352    /// UTF-8 like [`std::env::var`].
1353    pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1354        match self.env_var_os(key.as_ref()) {
1355            Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1356            None => Err(VarError::NotPresent),
1357        }
1358    }
1359
1360    pub fn is_method(self, id: DefId) -> bool {
1361        self.opt_associated_item(id).is_some_and(|item| item.is_method())
1362    }
1363}
1364
1365impl<'tcx> TyCtxtAt<'tcx> {
1366    /// Create a new definition within the incr. comp. engine.
1367    pub fn create_def(
1368        self,
1369        parent: LocalDefId,
1370        name: Option<Symbol>,
1371        def_kind: DefKind,
1372        override_def_path_data: Option<DefPathData>,
1373        disambiguator: &mut PerParentDisambiguatorState,
1374    ) -> TyCtxtFeed<'tcx, LocalDefId> {
1375        let feed =
1376            self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1377
1378        feed.def_span(self.span);
1379        feed
1380    }
1381}
1382
1383impl<'tcx> TyCtxt<'tcx> {
1384    /// `tcx`-dependent operations performed for every created definition.
1385    pub fn create_def(
1386        self,
1387        parent: LocalDefId,
1388        name: Option<Symbol>,
1389        def_kind: DefKind,
1390        override_def_path_data: Option<DefPathData>,
1391        disambiguator: &mut PerParentDisambiguatorState,
1392    ) -> TyCtxtFeed<'tcx, LocalDefId> {
1393        let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1394        // The following call has the side effect of modifying the tables inside `definitions`.
1395        // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1396        // decode the on-disk cache.
1397        //
1398        // Any LocalDefId which is used within queries, either as key or result, either:
1399        // - has been created before the construction of the TyCtxt;
1400        // - has been created by this call to `create_def`.
1401        // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1402        // comp. engine itself.
1403        let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1404
1405        // This function modifies `self.definitions` using a side-effect.
1406        // We need to ensure that these side effects are re-run by the incr. comp. engine.
1407        // Depending on the forever-red node will tell the graph that the calling query
1408        // needs to be re-evaluated.
1409        self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1410
1411        let feed = TyCtxtFeed { tcx: self, key: def_id };
1412        feed.def_kind(def_kind);
1413        // Unique types created for closures participate in type privacy checking.
1414        // They have visibilities inherited from the module they are defined in.
1415        // Visibilities for opaque types are meaningless, but still provided
1416        // so that all items have visibilities.
1417        if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
    DefKind::Closure | DefKind::OpaqueTy => true,
    _ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1418            let parent_mod = self.parent_module_from_def_id(def_id);
1419            feed.visibility(ty::Visibility::Restricted(parent_mod.to_mod_id()));
1420        }
1421
1422        feed
1423    }
1424
1425    pub fn create_crate_num(
1426        self,
1427        stable_crate_id: StableCrateId,
1428    ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1429        let mut lock = self.untracked().stable_crate_ids.write();
1430        if let Some(&existing) = lock.get(&stable_crate_id) {
1431            return Err(existing);
1432        }
1433        let num = CrateNum::new(lock.len());
1434        lock.insert(stable_crate_id, num);
1435        Ok(TyCtxtFeed { key: num, tcx: self })
1436    }
1437
1438    pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1439        // Depend on the `analysis` query to ensure compilation if finished.
1440        self.ensure_ok().analysis(());
1441
1442        let definitions = &self.untracked.definitions;
1443        gen {
1444            let mut i = 0;
1445
1446            // Recompute the number of definitions each time, because our caller may be creating
1447            // new ones.
1448            while i < { definitions.read().num_definitions() } {
1449                let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1450                yield LocalDefId { local_def_index };
1451                i += 1;
1452            }
1453
1454            // Freeze definitions once we finish iterating on them, to prevent adding new ones.
1455            definitions.freeze();
1456        }
1457    }
1458
1459    pub fn definitions(self) -> &'tcx rustc_hir::definitions::Definitions {
1460        // Depend on the `analysis` query to ensure compilation if finished.
1461        self.ensure_ok().analysis(());
1462
1463        // Freeze definitions once we start iterating on them, to prevent adding new ones
1464        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1465        self.untracked.definitions.freeze()
1466    }
1467
1468    pub fn def_path_hash_to_def_index_map(self) -> &'tcx rustc_hir::definitions::DefPathToIndexMap {
1469        // Create a dependency to the crate to be sure we re-execute this when the amount of
1470        // definitions change.
1471        self.ensure_ok().hir_crate_items(());
1472        // Freeze definitions once we start iterating on them, to prevent adding new ones
1473        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1474        self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1475    }
1476
1477    /// Note that this is *untracked* and should only be used within the query
1478    /// system if the result is otherwise tracked through queries
1479    #[inline]
1480    pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1481        FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1482    }
1483
1484    /// Give out access to the untracked data without any sanity checks.
1485    pub fn untracked(self) -> &'tcx Untracked {
1486        &self.untracked
1487    }
1488    /// Note that this is *untracked* and should only be used within the query
1489    /// system if the result is otherwise tracked through queries
1490    #[inline]
1491    pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1492        self.untracked.definitions.read()
1493    }
1494
1495    #[inline(always)]
1496    pub fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashState<'_>) -> R) -> R {
1497        f(StableHashState::new(self.sess, &self.untracked))
1498    }
1499
1500    #[inline]
1501    pub fn local_crate_exports_generics(self) -> bool {
1502        // compiler-builtins has some special treatment in codegen, which can result in confusing
1503        // behavior if another crate ends up calling into its monomorphizations.
1504        // https://github.com/rust-lang/rust/issues/150173
1505        if self.is_compiler_builtins(LOCAL_CRATE) {
1506            return false;
1507        }
1508        self.crate_types().iter().any(|crate_type| {
1509            match crate_type {
1510                CrateType::Executable
1511                | CrateType::StaticLib
1512                | CrateType::ProcMacro
1513                | CrateType::Cdylib
1514                | CrateType::Sdylib => false,
1515
1516                // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
1517                // We want to block export of generics from dylibs,
1518                // but we must fix rust-lang/rust#65890 before we can
1519                // do that robustly.
1520                CrateType::Dylib => true,
1521
1522                CrateType::Rlib => true,
1523            }
1524        })
1525    }
1526
1527    /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
1528    pub fn is_suitable_region(
1529        self,
1530        generic_param_scope: LocalDefId,
1531        mut region: Region<'tcx>,
1532    ) -> Option<FreeRegionInfo> {
1533        let (suitable_region_binding_scope, region_def_id) = loop {
1534            let def_id =
1535                region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1536            let scope = self.local_parent(def_id);
1537            if self.def_kind(scope) == DefKind::OpaqueTy {
1538                // Lifetime params of opaque types are synthetic and thus irrelevant to
1539                // diagnostics. Map them back to their origin!
1540                region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1541                continue;
1542            }
1543            break (scope, def_id.into());
1544        };
1545
1546        let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1547            Node::Item(..) | Node::TraitItem(..) => false,
1548            Node::ImplItem(impl_item) => match impl_item.impl_kind {
1549                // For now, we do not try to target impls of traits. This is
1550                // because this message is going to suggest that the user
1551                // change the fn signature, but they may not be free to do so,
1552                // since the signature must match the trait.
1553                //
1554                // FIXME(#42706) -- in some cases, we could do better here.
1555                hir::ImplItemImplKind::Trait { .. } => true,
1556                _ => false,
1557            },
1558            _ => false,
1559        };
1560
1561        Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1562    }
1563
1564    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
1565    pub fn return_type_impl_or_dyn_traits(
1566        self,
1567        scope_def_id: LocalDefId,
1568    ) -> Vec<&'tcx hir::Ty<'tcx>> {
1569        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1570        let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1571            self.hir_fn_decl_by_hir_id(hir_id)
1572        else {
1573            return ::alloc::vec::Vec::new()vec![];
1574        };
1575
1576        let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1577        v.visit_ty_unambig(hir_output);
1578        v.0
1579    }
1580
1581    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in
1582    /// its return type, and the associated alias span when type alias is used,
1583    /// along with a span for lifetime suggestion (if there are existing generics).
1584    pub fn return_type_impl_or_dyn_traits_with_type_alias(
1585        self,
1586        scope_def_id: LocalDefId,
1587    ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1588        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1589        let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1590        // when the return type is a type alias
1591        if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1592            && let hir::TyKind::Path(hir::QPath::Resolved(
1593                None,
1594                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1595            && let Some(local_id) = def_id.as_local()
1596            && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias
1597            && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
1598        {
1599            v.visit_ty_unambig(alias_ty);
1600            if !v.0.is_empty() {
1601                return Some((
1602                    v.0,
1603                    alias_generics.span,
1604                    alias_generics.span_for_lifetime_suggestion(),
1605                ));
1606            }
1607        }
1608        None
1609    }
1610
1611    /// Determines whether identifiers in the assembly have strict naming rules.
1612    /// Currently, only NVPTX* targets need it.
1613    pub fn has_strict_asm_symbol_naming(self) -> bool {
1614        self.sess.target.llvm_target.starts_with("nvptx")
1615    }
1616
1617    /// Returns `&'static core::panic::Location<'static>`.
1618    pub fn caller_location_ty(self) -> Ty<'tcx> {
1619        Ty::new_imm_ref(
1620            self,
1621            self.lifetimes.re_static,
1622            self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1623                .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1624                .skip_norm_wip(),
1625        )
1626    }
1627
1628    /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
1629    pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1630        let kind = self.def_kind(def_id);
1631        (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1632    }
1633
1634    pub fn type_length_limit(self) -> Limit {
1635        self.limits(()).type_length_limit
1636    }
1637
1638    pub fn recursion_limit(self) -> Limit {
1639        self.limits(()).recursion_limit
1640    }
1641
1642    pub fn move_size_limit(self) -> Limit {
1643        self.limits(()).move_size_limit
1644    }
1645
1646    pub fn pattern_complexity_limit(self) -> Limit {
1647        self.limits(()).pattern_complexity_limit
1648    }
1649
1650    /// All traits in the crate graph, including those not visible to the user.
1651    pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1652        iter::once(LOCAL_CRATE)
1653            .chain(self.crates(()).iter().copied())
1654            .flat_map(move |cnum| self.traits(cnum).iter().copied())
1655    }
1656
1657    /// All traits that are visible within the crate graph (i.e. excluding private dependencies).
1658    pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1659        let visible_crates =
1660            self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1661
1662        iter::once(LOCAL_CRATE)
1663            .chain(visible_crates)
1664            .flat_map(move |cnum| self.traits(cnum).iter().copied())
1665    }
1666
1667    #[inline]
1668    pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1669        self.visibility(def_id).expect_local()
1670    }
1671
1672    /// Returns the origin of the opaque type `def_id`.
1673    {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
            ::tracing::Level::TRACE <=
                ::tracing::level_filters::LevelFilter::current() || { false }
    {
    __tracing_attr_span =
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("local_opaque_ty_origin",
                                "rustc_middle::ty::context", ::tracing::Level::TRACE,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs"),
                                ::tracing_core::__macro_support::Option::Some(1673u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("def_id")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("def_id");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::SPAN)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let mut interest = ::tracing::subscriber::Interest::never();
            if ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        { interest = __CALLSITE.interest(); !interest.is_never() }
                    &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest) {
                let meta = __CALLSITE.metadata();
                ::tracing::Span::new(meta,
                    &{
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
                                                        as &dyn ::tracing::field::Value))])
                        })
            } else {
                let span =
                    ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                {};
                span
            }
        };
    __tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return:
                                hir::OpaqueTyOrigin<LocalDefId> = loop {};
                        return __tracing_attr_fake_return;
                    }
                    { self.hir_expect_opaque_ty(def_id).origin }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs:1673",
                        "rustc_middle::ty::context", ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs"),
                        ::tracing_core::__macro_support::Option::Some(1673u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[instrument(skip(self), level = "trace", ret)]
1674    pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1675        self.hir_expect_opaque_ty(def_id).origin
1676    }
1677
1678    pub fn finish(self) {
1679        // We assume that no queries are run past here. If there are new queries
1680        // after this point, they'll show up as "<unknown>" in self-profiling data.
1681        self.alloc_self_profile_query_strings();
1682
1683        self.save_dep_graph();
1684        self.verify_query_key_hashes();
1685
1686        if let Err((path, error)) = self.dep_graph.finish_encoding() {
1687            self.sess
1688                .dcx()
1689                .emit_fatal(crate::diagnostics::FailedWritingFile { path: &path, error });
1690        }
1691    }
1692
1693    pub fn report_unused_features(self) {
1694        #[derive(const _: () =
    {
        impl<'_sess> rustc_errors::Diagnostic<'_sess> for UnusedFeature {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess> {
                match self {
                    UnusedFeature { feature: __binding_0 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("feature `{$feature}` is declared but not used")));
                        ;
                        diag.arg("feature", __binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
1695        #[diag("feature `{$feature}` is declared but not used")]
1696        struct UnusedFeature {
1697            feature: Symbol,
1698        }
1699
1700        // Collect first to avoid holding the lock while linting.
1701        let used_features = self.query_system.used_features.lock();
1702        let unused_features = self
1703            .features()
1704            .enabled_features_iter_stable_order()
1705            .filter(|(f, _)| {
1706                !used_features.contains_key(f)
1707                // FIXME: `restricted_std` is used to tell a standard library built
1708                // for a platform that it doesn't know how to support. But it
1709                // could only gate a private mod (see `__restricted_std_workaround`)
1710                // with `cfg(not(restricted_std))`, so it cannot be recorded as used
1711                // in downstream crates. It should never be linted, but should we
1712                // hack this in the linter to ignore it?
1713                && f.as_str() != "restricted_std"
1714                // `doc_cfg` affects rustdoc behavior: rustdoc checks it via
1715                // `tcx.features().doc_cfg()`, but a normal rustc compilation may
1716                // never observe that use. Do not lint it as unused here.
1717                && *f != sym::doc_cfg
1718            })
1719            .collect::<Vec<_>>();
1720
1721        for (feature, span) in unused_features {
1722            self.emit_node_span_lint(
1723                UNUSED_FEATURES,
1724                CRATE_HIR_ID,
1725                span,
1726                UnusedFeature { feature },
1727            );
1728        }
1729    }
1730}
1731
1732macro_rules! nop_lift {
1733    ($set:ident; $ty:ty => $lifted:ty) => {
1734        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1735            type Lifted = $lifted;
1736            #[track_caller]
1737            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1738                // Assert that the set has the right type.
1739                // Given an argument that has an interned type, the return type has the type of
1740                // the corresponding interner set. This won't actually return anything, we're
1741                // just doing this to compute said type!
1742                fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1743                    _x: Interned<'tcx, Inner>,
1744                ) -> InternedSet<'tcx, Inner> {
1745                    unreachable!()
1746                }
1747                fn _type_eq<T>(_x: &T, _y: &T) {}
1748                fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1749                    // If `x` is a newtype around an `Interned<T>`, then `interner` is an
1750                    // interner of appropriate type. (Ideally we'd also check that `x` is a
1751                    // newtype with just that one field. Not sure how to do that.)
1752                    let interner = _intern_set_ty_from_interned_ty(x.0);
1753                    // Now check that this is the same type as `interners.$set`.
1754                    _type_eq(&interner, &tcx.interners.$set);
1755                }
1756
1757                assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1758                // SAFETY: we just checked that `self` is interned and therefore is valid for the
1759                // entire lifetime of the `TyCtxt`.
1760                unsafe { mem::transmute(self) }
1761            }
1762        }
1763    };
1764}
1765
1766macro_rules! nop_list_lift {
1767    ($set:ident; $ty:ty => $lifted:ty) => {
1768        nop_list_lift! { $set: List; $ty => $lifted }
1769    };
1770    // Allows defining own list type
1771    ($set:ident: $list:ident; $ty:ty => $lifted:ty) => {
1772        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a $list<$ty> {
1773            type Lifted = &'tcx $list<$lifted>;
1774            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1775                // Assert that the set has the right type.
1776                if false {
1777                    let _x: &InternedSet<'tcx, $list<$lifted>> = &tcx.interners.$set;
1778                }
1779
1780                if self.is_empty() {
1781                    return $list::empty();
1782                }
1783                assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1784                // SAFETY: we just checked that `self` is interned and therefore is valid for the
1785                // entire lifetime of the `TyCtxt`.
1786                unsafe { mem::transmute(self) }
1787            }
1788        }
1789    };
1790}
1791
1792impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Ty<'a> {
    type Lifted = Ty<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        fn _intern_set_ty_from_interned_ty<'tcx,
            Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
            ::core::panicking::unreachable_default_msg()
        }
        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_);
        }
        if !tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { type_; Ty<'a> => Ty<'tcx> }
1793impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Pattern<'a> {
    type Lifted = Pattern<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        fn _intern_set_ty_from_interned_ty<'tcx,
            Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
            ::core::panicking::unreachable_default_msg()
        }
        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);
        }
        if !tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
1794impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ConstAllocation<'a> {
    type Lifted = ConstAllocation<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        fn _intern_set_ty_from_interned_ty<'tcx,
            Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
            ::core::panicking::unreachable_default_msg()
        }
        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);
        }
        if !tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
1795impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Predicate<'a> {
    type Lifted = Predicate<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        fn _intern_set_ty_from_interned_ty<'tcx,
            Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
            ::core::panicking::unreachable_default_msg()
        }
        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);
        }
        if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
1796impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Clause<'a> {
    type Lifted = Clause<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        fn _intern_set_ty_from_interned_ty<'tcx,
            Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
            ::core::panicking::unreachable_default_msg()
        }
        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);
        }
        if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
1797impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Layout<'a> {
    type Lifted = Layout<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        fn _intern_set_ty_from_interned_ty<'tcx,
            Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
            ::core::panicking::unreachable_default_msg()
        }
        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);
        }
        if !tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { layout; Layout<'a> => Layout<'tcx> }
1798impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ValTree<'a> {
    type Lifted = ValTree<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        fn _intern_set_ty_from_interned_ty<'tcx,
            Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
            ::core::panicking::unreachable_default_msg()
        }
        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);
        }
        if !tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
1799
1800impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, RegionKind<'a>> {
1801    type Lifted = Interned<'tcx, RegionKind<'tcx>>;
1802
1803    #[track_caller]
1804    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1805        if !tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0)) {
    ::core::panicking::panic("assertion failed: tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0))")
};assert!(tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0)));
1806        // SAFETY: we just checked that `self` is interned in this `TyCtxt`, so
1807        // its pointee is valid for the entire lifetime of the target `TyCtxt`.
1808        unsafe { mem::transmute(self) }
1809    }
1810}
1811
1812// FIXME: unclear why exactly the macro doesn't work.
1813impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, WithCachedTypeInfo<ConstKind<'a>>> {
1814    type Lifted = Interned<'tcx, WithCachedTypeInfo<ConstKind<'tcx>>>;
1815
1816    #[track_caller]
1817    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1818        if !tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0)) {
    ::core::panicking::panic("assertion failed: tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0))")
};assert!(tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0)));
1819        // SAFETY: we just checked that `self` is interned in this `TyCtxt`, so
1820        // its pointee is valid for the entire lifetime of the target `TyCtxt`.
1821        unsafe { mem::transmute(self) }
1822    }
1823}
1824
1825impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Ty<'a>> {
    type Lifted = &'tcx List<Ty<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<Ty<'tcx>>> =
                &tcx.interners.type_lists;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
1826impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a ListWithCachedTypeInfo<Clause<'a>> {
    type Lifted = &'tcx ListWithCachedTypeInfo<Clause<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>> =
                &tcx.interners.clauses;
        }
        if self.is_empty() { return ListWithCachedTypeInfo::empty(); }
        if !tcx.interners.clauses.contains_pointer_to(&InternedInSet(self)) {
            ::core::panicking::panic("assertion failed: tcx.interners.clauses.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { clauses: ListWithCachedTypeInfo; Clause<'a> => Clause<'tcx> }
1827impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<PolyExistentialPredicate<'a>> {
    type Lifted = &'tcx List<PolyExistentialPredicate<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>> =
                &tcx.interners.poly_existential_predicates;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! {
1828    poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1829}
1830impl<'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>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>> =
                &tcx.interners.bound_variable_kinds;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind<'a> => ty::BoundVariableKind<'tcx> }
1831impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Pattern<'a>> {
    type Lifted = &'tcx List<Pattern<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<Pattern<'tcx>>> =
                &tcx.interners.patterns;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.patterns.contains_pointer_to(&InternedInSet(self)) {
            ::core::panicking::panic("assertion failed: tcx.interners.patterns.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { patterns; Pattern<'a> => Pattern<'tcx> }
1832impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<ty::ArgOutlivesClause<'a>> {
    type Lifted = &'tcx List<ty::ArgOutlivesClause<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<ty::ArgOutlivesClause<'tcx>>> =
                &tcx.interners.outlives;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.outlives.contains_pointer_to(&InternedInSet(self)) {
            ::core::panicking::panic("assertion failed: tcx.interners.outlives.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { outlives; ty::ArgOutlivesClause<'a> => ty::ArgOutlivesClause<'tcx> }
1833
1834// This is the impl for `&'a GenericArgs<'a>`.
1835impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<GenericArg<'a>> {
    type Lifted = &'tcx List<GenericArg<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<GenericArg<'tcx>>> =
                &tcx.interners.args;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.args.contains_pointer_to(&InternedInSet(self)) {
            ::core::panicking::panic("assertion failed: tcx.interners.args.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
1836
1837macro_rules! sty_debug_print {
1838    ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1839        #[allow(non_snake_case, reason = "we're using variant names as local variables")]
1840        mod inner {
1841            use crate::ty::{self, TyCtxt};
1842            use crate::ty::context::InternedInSet;
1843
1844            #[derive(Copy, Clone)]
1845            struct DebugStat {
1846                total: usize,
1847                lt_infer: usize,
1848                ty_infer: usize,
1849                ct_infer: usize,
1850                all_infer: usize,
1851            }
1852
1853            pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1854                let mut total = DebugStat {
1855                    total: 0,
1856                    lt_infer: 0,
1857                    ty_infer: 0,
1858                    ct_infer: 0,
1859                    all_infer: 0,
1860                };
1861                $(let mut $variant = total;)*
1862
1863                for shard in tcx.interners.type_.lock_shards() {
1864                    // It seems that ordering doesn't affect anything here.
1865                    #[allow(rustc::potential_query_instability)]
1866                    let types = shard.iter();
1867                    for &(InternedInSet(t), ()) in types {
1868                        let variant = match t.internee {
1869                            ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1870                                ty::Float(..) | ty::Str | ty::Never => continue,
1871                            ty::Error(_) => /* unimportant */ continue,
1872                            $(ty::$variant(..) => &mut $variant,)*
1873                        };
1874                        let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1875                        let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1876                        let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1877
1878                        variant.total += 1;
1879                        total.total += 1;
1880                        if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1881                        if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1882                        if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1883                        if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1884                    }
1885                }
1886                writeln!(fmt, "Ty interner             total           ty lt ct all")?;
1887                $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
1888                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1889                    stringify!($variant),
1890                    uses = $variant.total,
1891                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
1892                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
1893                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
1894                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
1895                    all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
1896                )*
1897                writeln!(fmt, "                  total {uses:6}        \
1898                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1899                    uses = total.total,
1900                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
1901                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
1902                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
1903                    all = total.all_infer as f64 * 100.0  / total.total as f64)
1904            }
1905        }
1906
1907        inner::go($fmt, $ctxt)
1908    }}
1909}
1910
1911impl<'tcx> TyCtxt<'tcx> {
1912    pub fn debug_stats(self) -> impl fmt::Debug {
1913        fmt::from_fn(move |fmt| {
1914            {
    #[allow(non_snake_case, reason =
    "we're using variant names as local variables")]
    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) -> Self {
                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!(
1915                fmt,
1916                self,
1917                Adt,
1918                Array,
1919                Slice,
1920                RawPtr,
1921                Ref,
1922                FnDef,
1923                FnPtr,
1924                UnsafeBinder,
1925                Placeholder,
1926                Coroutine,
1927                CoroutineWitness,
1928                Dynamic,
1929                Closure,
1930                CoroutineClosure,
1931                Tuple,
1932                Bound,
1933                Param,
1934                Infer,
1935                Alias,
1936                Pat,
1937                Foreign
1938            )?;
1939
1940            fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
        self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1941            fmt.write_fmt(format_args!("Region interner: #{0}\n",
        self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1942            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())?;
1943            fmt.write_fmt(format_args!("Layout interner: #{0}\n",
        self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1944
1945            Ok(())
1946        })
1947    }
1948}
1949
1950// This type holds a `T` in the interner. The `T` is stored in the arena and
1951// this type just holds a pointer to it, but it still effectively owns it. It
1952// impls `Borrow` so that it can be looked up using the original
1953// (non-arena-memory-owning) types.
1954struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1955
1956impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1957    fn clone(&self) -> Self {
1958        *self
1959    }
1960}
1961
1962impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1963
1964impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1965    fn into_pointer(&self) -> *const () {
1966        self.0 as *const _ as *const ()
1967    }
1968}
1969
1970#[allow(rustc::usage_of_ty_tykind)]
1971impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1972    fn borrow(&self) -> &T {
1973        &self.0.internee
1974    }
1975}
1976
1977impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1978    fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1979        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1980        // `x == y`.
1981        self.0.internee == other.0.internee
1982    }
1983}
1984
1985impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1986
1987impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1988    fn hash<H: Hasher>(&self, s: &mut H) {
1989        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1990        self.0.internee.hash(s)
1991    }
1992}
1993
1994impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1995    fn borrow(&self) -> &[T] {
1996        &self.0[..]
1997    }
1998}
1999
2000impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2001    fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2002        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2003        // `x == y`.
2004        self.0[..] == other.0[..]
2005    }
2006}
2007
2008impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2009
2010impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2011    fn hash<H: Hasher>(&self, s: &mut H) {
2012        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2013        self.0[..].hash(s)
2014    }
2015}
2016
2017impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2018    fn borrow(&self) -> &[T] {
2019        &self.0[..]
2020    }
2021}
2022
2023impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2024    fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2025        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2026        // `x == y`.
2027        self.0[..] == other.0[..]
2028    }
2029}
2030
2031impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2032
2033impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2034    fn hash<H: Hasher>(&self, s: &mut H) {
2035        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2036        self.0[..].hash(s)
2037    }
2038}
2039
2040macro_rules! direct_interners {
2041    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2042        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2043            fn borrow<'a>(&'a self) -> &'a $ty {
2044                &self.0
2045            }
2046        }
2047
2048        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2049            fn eq(&self, other: &Self) -> bool {
2050                // The `Borrow` trait requires that `x.borrow() == y.borrow()`
2051                // equals `x == y`.
2052                self.0 == other.0
2053            }
2054        }
2055
2056        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2057
2058        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2059            fn hash<H: Hasher>(&self, s: &mut H) {
2060                // The `Borrow` trait requires that `x.borrow().hash(s) ==
2061                // x.hash(s)`.
2062                self.0.hash(s)
2063            }
2064        }
2065
2066        impl<'tcx> TyCtxt<'tcx> {
2067            $vis fn $method(self, v: $ty) -> $ret_ty {
2068                $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2069                    InternedInSet(self.interners.arena.alloc(v))
2070                }).0))
2071            }
2072        })+
2073    }
2074}
2075
2076// Functions with a `mk_` prefix are intended for use outside this file and
2077// crate. Functions with an `intern_` prefix are intended for use within this
2078// crate only, and have a corresponding `mk_` function.
2079impl<'tcx> Borrow<RegionKind<'tcx>> for InternedInSet<'tcx, RegionKind<'tcx>>
    {
    fn borrow<'a>(&'a self) -> &'a RegionKind<'tcx> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, RegionKind<'tcx>> {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, RegionKind<'tcx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, RegionKind<'tcx>> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub(crate) fn intern_region(self, v: RegionKind<'tcx>) -> Region<'tcx> {
        Region(Interned::new_unchecked(self.interners.region.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'tcx> Borrow<ValTreeKind<TyCtxt<'tcx>>> for
    InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
    fn borrow<'a>(&'a self) -> &'a ValTreeKind<TyCtxt<'tcx>> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {}
impl<'tcx> Hash for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub(crate) fn intern_valtree(self, v: ValTreeKind<TyCtxt<'tcx>>)
        -> ValTree<'tcx> {
        ValTree(Interned::new_unchecked(self.interners.valtree.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'tcx> Borrow<PatternKind<'tcx>> for
    InternedInSet<'tcx, PatternKind<'tcx>> {
    fn borrow<'a>(&'a self) -> &'a PatternKind<'tcx> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, PatternKind<'tcx>> {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, PatternKind<'tcx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, PatternKind<'tcx>> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub fn mk_pat(self, v: PatternKind<'tcx>) -> Pattern<'tcx> {
        Pattern(Interned::new_unchecked(self.interners.pat.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'tcx> Borrow<Allocation> for InternedInSet<'tcx, Allocation> {
    fn borrow<'a>(&'a self) -> &'a Allocation { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, Allocation> {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, Allocation> {}
impl<'tcx> Hash for InternedInSet<'tcx, Allocation> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub fn mk_const_alloc(self, v: Allocation) -> ConstAllocation<'tcx> {
        ConstAllocation(Interned::new_unchecked(self.interners.const_allocation.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'tcx> Borrow<LayoutData<FieldIdx, VariantIdx>> for
    InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {
    fn borrow<'a>(&'a self) -> &'a LayoutData<FieldIdx, VariantIdx> {
        &self.0
    }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>>
    {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub fn mk_layout(self, v: LayoutData<FieldIdx, VariantIdx>)
        -> Layout<'tcx> {
        Layout(Interned::new_unchecked(self.interners.layout.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'tcx> Borrow<AdtDefData> for InternedInSet<'tcx, AdtDefData> {
    fn borrow<'a>(&'a self) -> &'a AdtDefData { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, AdtDefData> {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, AdtDefData> {}
impl<'tcx> Hash for InternedInSet<'tcx, AdtDefData> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub fn mk_adt_def_from_data(self, v: AdtDefData) -> AdtDef<'tcx> {
        AdtDef(Interned::new_unchecked(self.interners.adt_def.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'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))
    }
}
impl<'tcx> Borrow<CanonicalInputData<TyCtxt<'tcx>>> for
    InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {
    fn borrow<'a>(&'a self) -> &'a CanonicalInputData<TyCtxt<'tcx>> {
        &self.0
    }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>>
    {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {}
impl<'tcx> Hash for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    fn intern_canonical_input(self, v: CanonicalInputData<TyCtxt<'tcx>>)
        -> CanonicalInput<'tcx> {
        CanonicalInput(Interned::new_unchecked(self.interners.canonical_inputs.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}direct_interners! {
2080    region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2081    valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2082    pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2083    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2084    layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2085    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2086    external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2087        ExternalConstraints -> ExternalConstraints<'tcx>,
2088    canonical_inputs: intern_canonical_input(CanonicalInputData<TyCtxt<'tcx>>): CanonicalInput -> CanonicalInput<'tcx>,
2089}
2090
2091macro_rules! slice_interners {
2092    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2093        impl<'tcx> TyCtxt<'tcx> {
2094            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2095                if v.is_empty() {
2096                    List::empty()
2097                } else {
2098                    self.interners.$field.intern_ref(v, || {
2099                        InternedInSet(List::from_arena(&*self.arena, (), v))
2100                    }).0
2101                }
2102            })+
2103        }
2104    );
2105}
2106
2107// These functions intern slices. They all have a corresponding
2108// `mk_foo_from_iter` function that interns an iterator. The slice version
2109// should be used when possible, because it's faster.
2110impl<'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_raw(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::ArgOutlivesClause<'tcx>])
        -> &'tcx List<ty::ArgOutlivesClause<'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!(
2111    const_lists: pub mk_const_list(Const<'tcx>),
2112    args: pub mk_args_raw(GenericArg<'tcx>),
2113    type_lists: pub mk_type_list(Ty<'tcx>),
2114    canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2115    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2116    projs: pub mk_projs(ProjectionKind),
2117    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2118    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2119    fields: pub mk_fields(FieldIdx),
2120    local_def_ids: intern_local_def_ids(LocalDefId),
2121    captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2122    patterns: pub mk_patterns(Pattern<'tcx>),
2123    outlives: pub mk_outlives(ty::ArgOutlivesClause<'tcx>),
2124    predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2125);
2126
2127impl<'tcx> TyCtxt<'tcx> {
2128    /// Given a `fn` sig, returns an equivalent `unsafe fn` type;
2129    /// that is, a `fn` type that is equivalent in every way for being
2130    /// unsafe.
2131    pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2132        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2133        Ty::new_fn_ptr(
2134            self,
2135            sig.map_bound(|sig| ty::FnSig {
2136                fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2137                ..sig
2138            }),
2139        )
2140    }
2141
2142    /// Given a `fn` sig, returns an equivalent `unsafe fn` sig;
2143    /// that is, a `fn` sig that is equivalent in every way for being
2144    /// unsafe.
2145    pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2146        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2147        sig.map_bound(|sig| ty::FnSig {
2148            fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2149            ..sig
2150        })
2151    }
2152
2153    /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
2154    /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
2155    pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2156        elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2157            self.associated_items(trait_did)
2158                .filter_by_name_unhygienic(assoc_name.name)
2159                .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2160        })
2161    }
2162
2163    /// Given a `ty`, return whether it's an `impl Future<...>`.
2164    pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2165        let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2166            return false;
2167        };
2168        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2169
2170        self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2171            let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2172                return false;
2173            };
2174            trait_predicate.trait_ref.def_id == future_trait
2175                && trait_predicate.polarity == ClausePolarity::Positive
2176        })
2177    }
2178
2179    /// Given a closure signature, returns an equivalent fn signature. Detuples
2180    /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
2181    /// you would get a `fn(u32, i32)`.
2182    /// `unsafety` determines the unsafety of the fn signature. If you pass
2183    /// `hir::Safety::Unsafe` in the previous example, then you would get
2184    /// an `unsafe fn (u32, i32)`.
2185    /// It cannot convert a closure that requires unsafe.
2186    pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2187        sig.map_bound(|s| {
2188            let params = match s.inputs()[0].kind() {
2189                ty::Tuple(params) => *params,
2190                _ => ::rustc_span::macros::bug_impl(None, format_args!("impossible case reached"),
    Location::caller())bug!(),
2191            };
2192            // Ignore splatting, it is unsupported on closures.
2193            if !s.splatted().is_none() {
    ::core::panicking::panic("assertion failed: s.splatted().is_none()")
};assert!(s.splatted().is_none());
2194            self.mk_fn_sig(
2195                params,
2196                s.output(),
2197                s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2198            )
2199        })
2200    }
2201
2202    #[inline]
2203    pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2204        self.interners.intern_predicate(binder)
2205    }
2206
2207    #[inline]
2208    pub fn reuse_or_mk_predicate(
2209        self,
2210        pred: Predicate<'tcx>,
2211        binder: Binder<'tcx, PredicateKind<'tcx>>,
2212    ) -> Predicate<'tcx> {
2213        if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2214    }
2215
2216    /// If you have a [`ty::Alias`], you should almost certainly be calling
2217    /// [`Self::check_alias_term_args_compatible`] instead. This method assumes that inherent alias
2218    /// consts always have `impl`-form args, and will return an invalid result if the `def_id` comes
2219    /// from a [`ty::AliasConstKind::InherentSelf`] (see the doc on that for what "impl form args"
2220    /// means).
2221    pub fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgs<'tcx>) -> bool {
2222        let is_inherent_assoc_ty = #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
    DefKind::AssocTy => true,
    _ => false,
}matches!(self.def_kind(def_id), DefKind::AssocTy)
2223            && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
    {
    DefKind::Impl { of_trait: false } => true,
    _ => false,
}matches!(self.def_kind(self.parent(def_id)), DefKind::Impl { of_trait: false });
2224        self.check_args_compatible_inner(def_id, args.as_slice(), is_inherent_assoc_ty)
2225    }
2226
2227    pub fn check_alias_term_args_compatible(
2228        self,
2229        kind: ty::AliasTermKind<'tcx>,
2230        args: ty::GenericArgs<'tcx>,
2231    ) -> bool {
2232        let (def_id, is_self_args) = match kind {
2233            ty::AliasTermKind::ProjectionTy { def_id }
2234            | ty::AliasTermKind::OpaqueTy { def_id }
2235            | ty::AliasTermKind::FreeTy { def_id }
2236            | ty::AliasTermKind::AnonConst { def_id }
2237            | ty::AliasTermKind::ProjectionConst { def_id }
2238            | ty::AliasTermKind::FreeConst { def_id }
2239            | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2240            ty::AliasTermKind::InherentTy { def_id }
2241            | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2242        };
2243        self.check_args_compatible_inner(def_id, args.as_slice(), is_self_args)
2244    }
2245
2246    fn check_args_compatible_inner(
2247        self,
2248        def_id: DefId,
2249        args: &[ty::GenericArg<'tcx>],
2250        is_self_args: bool,
2251    ) -> bool {
2252        let generics = self.generics_of(def_id);
2253        let own_args = if is_self_args {
2254            if generics.own_params.len() + 1 != args.len() {
2255                return false;
2256            }
2257
2258            if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
    ty::GenericArgKind::Type(_) => true,
    _ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2259                return false;
2260            }
2261
2262            &args[1..]
2263        } else {
2264            if generics.count() != args.len() {
2265                return false;
2266            }
2267
2268            let (parent_args, own_args) = args.split_at(generics.parent_count);
2269
2270            // In the type system, IATs and IACs (inherent associated types/consts) themselves have a
2271            // weird arg setup (self + own args), but nested items *in* IATs (namely: opaques, i.e.
2272            // ATPITs) do not. So, set `is_self_args` to false for the parent generic check.
2273            if let Some(parent) = generics.parent
2274                && !self.check_args_compatible_inner(parent, parent_args, false)
2275            {
2276                return false;
2277            }
2278
2279            own_args
2280        };
2281
2282        for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2283            match (&param.kind, arg.kind()) {
2284                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2285                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2286                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2287                _ => return false,
2288            }
2289        }
2290
2291        true
2292    }
2293
2294    /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
2295    /// and print out the args if not.
2296    ///
2297    /// If you have a [`ty::Alias`], you should use
2298    /// [`Self::debug_assert_alias_term_args_compatible`] instead. See note on
2299    /// [`Self::check_args_compatible`].
2300    pub fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgs<'tcx>) {
2301        if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2302            let is_inherent_assoc_ty = #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
    DefKind::AssocTy => true,
    _ => false,
}matches!(self.def_kind(def_id), DefKind::AssocTy)
2303                && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
    {
    DefKind::Impl { of_trait: false } => true,
    _ => false,
}matches!(self.def_kind(self.parent(def_id)), DefKind::Impl { of_trait: false });
2304            self.emit_bug_args_compatible(def_id, args, is_inherent_assoc_ty);
2305        }
2306    }
2307
2308    pub fn debug_assert_alias_term_args_compatible(
2309        self,
2310        kind: ty::AliasTermKind<'tcx>,
2311        args: ty::GenericArgs<'tcx>,
2312    ) {
2313        if truecfg!(debug_assertions) {
2314            self.debug_assert_alias_term_kind_matches_def_kind(kind);
2315            if !self.check_alias_term_args_compatible(kind, args) {
2316                let (def_id, is_self_args) = match kind {
2317                    ty::AliasTermKind::ProjectionTy { def_id }
2318                    | ty::AliasTermKind::OpaqueTy { def_id }
2319                    | ty::AliasTermKind::FreeTy { def_id }
2320                    | ty::AliasTermKind::AnonConst { def_id }
2321                    | ty::AliasTermKind::ProjectionConst { def_id }
2322                    | ty::AliasTermKind::FreeConst { def_id }
2323                    | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2324                    ty::AliasTermKind::InherentTy { def_id }
2325                    | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2326                };
2327                self.emit_bug_args_compatible(def_id, args, is_self_args);
2328            }
2329        }
2330    }
2331
2332    fn debug_assert_alias_term_kind_matches_def_kind(self, kind: ty::AliasTermKind<'tcx>) {
2333        match kind {
2334            ty::AliasTermKind::ProjectionTy { def_id } => {
2335                if true {
    {
        match self.def_kind(def_id) {
            DefKind::AssocTy => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AssocTy", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy);
2336                if true {
    {
        match self.def_kind(self.parent(def_id)) {
            DefKind::Trait | DefKind::Impl { of_trait: true } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Trait | DefKind::Impl { of_trait: true }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(
2337                    self.def_kind(self.parent(def_id)),
2338                    DefKind::Trait | DefKind::Impl { of_trait: true }
2339                );
2340            }
2341            ty::AliasTermKind::InherentTy { def_id } => {
2342                if true {
    {
        match self.def_kind(def_id) {
            DefKind::AssocTy => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AssocTy", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy);
2343                if true {
    {
        match self.def_kind(self.parent(def_id)) {
            DefKind::Impl { of_trait: false } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Impl { of_trait: false }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(
2344                    self.def_kind(self.parent(def_id)),
2345                    DefKind::Impl { of_trait: false }
2346                );
2347            }
2348            ty::AliasTermKind::OpaqueTy { def_id } => {
2349                if true {
    {
        match self.def_kind(def_id) {
            DefKind::OpaqueTy => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::OpaqueTy", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::OpaqueTy);
2350            }
2351            ty::AliasTermKind::FreeTy { def_id } => {
2352                if true {
    {
        match self.def_kind(def_id) {
            DefKind::TyAlias => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::TyAlias", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::TyAlias);
2353            }
2354            ty::AliasTermKind::AnonConst { def_id } => {
2355                if true {
    {
        match self.def_kind(def_id) {
            DefKind::AnonConst => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AnonConst", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AnonConst);
2356            }
2357            ty::AliasTermKind::ProjectionConst { def_id } => {
2358                if true {
    {
        match self.def_kind(def_id) {
            DefKind::AssocConst => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AssocConst", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocConst);
2359                if true {
    {
        match self.def_kind(self.parent(def_id)) {
            DefKind::Trait | DefKind::Impl { of_trait: true } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Trait | DefKind::Impl { of_trait: true }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(
2360                    self.def_kind(self.parent(def_id)),
2361                    DefKind::Trait | DefKind::Impl { of_trait: true }
2362                );
2363            }
2364            ty::AliasTermKind::InherentConstSelf { def_id }
2365            | ty::AliasTermKind::InherentConstImpl { def_id } => {
2366                if true {
    {
        match self.def_kind(def_id) {
            DefKind::AssocConst => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AssocConst", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocConst);
2367                if true {
    {
        match self.def_kind(self.parent(def_id)) {
            DefKind::Impl { of_trait: false } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Impl { of_trait: false }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(
2368                    self.def_kind(self.parent(def_id)),
2369                    DefKind::Impl { of_trait: false }
2370                );
2371            }
2372            ty::AliasTermKind::FreeConst { def_id } => {
2373                if true {
    {
        match self.def_kind(def_id) {
            DefKind::Const => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Const", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::Const);
2374            }
2375        }
2376    }
2377
2378    fn emit_bug_args_compatible(
2379        self,
2380        def_id: DefId,
2381        args: ty::GenericArgs<'tcx>,
2382        is_self_args: bool,
2383    ) -> ! {
2384        if is_self_args {
2385            ::rustc_span::macros::bug_impl(None,
    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).as_slice()).iter().copied()))), Location::caller());bug!(
2386                "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2387                self.def_path_str(def_id),
2388                args,
2389                // Make `[Self, GAT_ARGS...]` (this could be simplified)
2390                self.mk_args_from_iter(
2391                    [self.types.self_param.into()].into_iter().chain(
2392                        self.generics_of(def_id)
2393                            .own_args(ty::GenericArgs::identity_for_item(self, def_id).as_slice())
2394                            .iter()
2395                            .copied()
2396                    )
2397                )
2398            );
2399        } else {
2400            ::rustc_span::macros::bug_impl(None,
    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)),
    Location::caller());bug!(
2401                "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2402                self.def_path_str(def_id),
2403                args,
2404                ty::GenericArgs::identity_for_item(self, def_id)
2405            );
2406        }
2407    }
2408
2409    #[inline(always)]
2410    pub(crate) fn check_and_mk_args(
2411        self,
2412        def_id: DefId,
2413        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2414    ) -> ty::GenericArgs<'tcx> {
2415        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2416        self.debug_assert_args_compatible(def_id, args);
2417        args
2418    }
2419
2420    #[inline]
2421    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2422        self.interners.intern_const(kind)
2423    }
2424
2425    // Avoid this in favour of more specific `Ty::new_*` methods, where possible.
2426    #[allow(rustc::usage_of_ty_tykind)]
2427    #[inline]
2428    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2429        self.interners.intern_ty(st)
2430    }
2431
2432    pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2433        match param.kind {
2434            GenericParamDefKind::Lifetime => {
2435                ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2436            }
2437            GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2438            GenericParamDefKind::Const { .. } => {
2439                ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2440                    .into()
2441            }
2442        }
2443    }
2444
2445    pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2446        self.mk_place_elem(place, PlaceElem::Field(f, ty))
2447    }
2448
2449    pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2450        self.mk_place_elem(place, PlaceElem::Deref)
2451    }
2452
2453    pub fn mk_place_downcast(
2454        self,
2455        place: Place<'tcx>,
2456        adt_def: AdtDef<'tcx>,
2457        variant_index: VariantIdx,
2458    ) -> Place<'tcx> {
2459        self.mk_place_elem(
2460            place,
2461            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2462        )
2463    }
2464
2465    pub fn mk_place_downcast_unnamed(
2466        self,
2467        place: Place<'tcx>,
2468        variant_index: VariantIdx,
2469    ) -> Place<'tcx> {
2470        self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2471    }
2472
2473    pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2474        self.mk_place_elem(place, PlaceElem::Index(index))
2475    }
2476
2477    /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2478    /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2479    /// flight.
2480    pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2481        Place {
2482            local: place.local,
2483            projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2484        }
2485    }
2486
2487    pub fn mk_poly_existential_predicates(
2488        self,
2489        eps: &[PolyExistentialPredicate<'tcx>],
2490    ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2491        if !!eps.is_empty() {
    ::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2492        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!(
2493            eps.array_windows()
2494                .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2495                    != Ordering::Greater)
2496        );
2497        self.intern_poly_existential_predicates(eps)
2498    }
2499
2500    pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2501        // FIXME consider asking the input slice to be sorted to avoid
2502        // re-interning permutations, in which case that would be asserted
2503        // here.
2504        self.interners.intern_clauses(clauses)
2505    }
2506
2507    pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2508        // FIXME consider asking the input slice to be sorted to avoid
2509        // re-interning permutations, in which case that would be asserted
2510        // here.
2511        self.intern_local_def_ids(def_ids)
2512    }
2513
2514    pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2515    where
2516        I: Iterator<Item = T>,
2517        T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2518    {
2519        T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2520    }
2521
2522    pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2523    where
2524        I: Iterator<Item = T>,
2525        T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2526    {
2527        T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2528    }
2529
2530    pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2531    where
2532        I: Iterator<Item = T>,
2533        T: CollectAndApply<
2534                &'tcx ty::CapturedPlace<'tcx>,
2535                &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2536            >,
2537    {
2538        T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2539    }
2540
2541    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2542    where
2543        I: Iterator<Item = T>,
2544        T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2545    {
2546        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2547    }
2548
2549    // Unlike various other `mk_*_from_iter` functions, this one uses `I:
2550    // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
2551    // variant, because of the need to combine `inputs` and `output`. This
2552    // explains the lack of `_from_iter` suffix.
2553    pub fn mk_fn_sig<I, T>(
2554        self,
2555        inputs: I,
2556        output: I::Item,
2557        fn_sig_kind: FnSigKind<'tcx>,
2558    ) -> T::Output
2559    where
2560        I: IntoIterator<Item = T>,
2561        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2562    {
2563        T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2564            inputs_and_output: self.mk_type_list(xs),
2565            fn_sig_kind,
2566        })
2567    }
2568
2569    /// `mk_fn_sig`, but with a Rust ABI, and no C-variadic argument.
2570    pub fn mk_fn_sig_rust_abi<I, T>(
2571        self,
2572        inputs: I,
2573        output: I::Item,
2574        safety: hir::Safety,
2575    ) -> T::Output
2576    where
2577        I: IntoIterator<Item = T>,
2578        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2579    {
2580        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2581    }
2582
2583    /// `mk_fn_sig`, but with a safe Rust ABI, and no C-variadic argument.
2584    pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2585    where
2586        I: IntoIterator<Item = T>,
2587        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2588    {
2589        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2590    }
2591
2592    /// `mk_fn_sig`, but with an **un**safe Rust ABI, and no C-variadic argument.
2593    pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2594    where
2595        I: IntoIterator<Item = T>,
2596        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2597    {
2598        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2599    }
2600
2601    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2602    where
2603        I: Iterator<Item = T>,
2604        T: CollectAndApply<
2605                PolyExistentialPredicate<'tcx>,
2606                &'tcx List<PolyExistentialPredicate<'tcx>>,
2607            >,
2608    {
2609        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2610    }
2611
2612    pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2613    where
2614        I: Iterator<Item = T>,
2615        T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2616    {
2617        T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2618    }
2619
2620    pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2621    where
2622        I: Iterator<Item = T>,
2623        T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2624    {
2625        T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2626    }
2627
2628    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2629    where
2630        I: Iterator<Item = T>,
2631        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2632    {
2633        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2634    }
2635
2636    pub fn mk_args(self, args: &[GenericArg<'tcx>]) -> ty::GenericArgs<'tcx> {
2637        ty::GenericArgs::from_args(self.mk_args_raw(args))
2638    }
2639
2640    pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2641    where
2642        I: Iterator<Item = T>,
2643        T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgs<'tcx>>,
2644    {
2645        T::collect_and_apply(iter, |xs| self.mk_args(xs))
2646    }
2647
2648    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2649    where
2650        I: Iterator<Item = T>,
2651        T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2652    {
2653        T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2654    }
2655
2656    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2657    where
2658        I: Iterator<Item = T>,
2659        T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2660    {
2661        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2662    }
2663
2664    pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2665    where
2666        I: Iterator<Item = T>,
2667        T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2668    {
2669        T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2670    }
2671
2672    pub fn mk_args_trait(
2673        self,
2674        self_ty: Ty<'tcx>,
2675        rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2676    ) -> ty::GenericArgs<'tcx> {
2677        self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2678    }
2679
2680    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2681    where
2682        I: Iterator<Item = T>,
2683        T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2684    {
2685        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2686    }
2687
2688    pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2689    where
2690        I: Iterator<Item = T>,
2691        T: CollectAndApply<
2692                ty::ArgOutlivesClause<'tcx>,
2693                &'tcx ty::List<ty::ArgOutlivesClause<'tcx>>,
2694            >,
2695    {
2696        T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2697    }
2698
2699    /// Emit a lint at `span` from a lint struct (some type that implements `Diagnostic`,
2700    /// typically generated by `#[derive(Diagnostic)]`).
2701    #[track_caller]
2702    pub fn emit_node_span_lint(
2703        self,
2704        lint: &'static Lint,
2705        hir_id: HirId,
2706        span: impl Into<MultiSpan>,
2707        decorator: impl for<'a> Diagnostic<'a>,
2708    ) {
2709        let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2710        emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2711    }
2712
2713    /// Find the appropriate span where `use` and outer attributes can be inserted at.
2714    pub fn crate_level_attribute_injection_span(self) -> Span {
2715        let node = self.hir_node(hir::CRATE_HIR_ID);
2716        let hir::Node::Crate(m) = node else { ::rustc_span::macros::bug_impl(None, format_args!("impossible case reached"),
    Location::caller())bug!() };
2717        m.spans.inject_use_span.shrink_to_lo()
2718    }
2719
2720    pub fn disabled_nightly_features(
2721        self,
2722        diag: &mut Diag<'_>,
2723        features: impl IntoIterator<Item = (String, Symbol)>,
2724    ) {
2725        if !self.sess.is_nightly_build() {
2726            return;
2727        }
2728
2729        let span = self.crate_level_attribute_injection_span();
2730        for (desc, feature) in features {
2731            // FIXME: make this string translatable
2732            let msg =
2733                ::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}");
2734            diag.span_suggestion_verbose(
2735                span,
2736                msg,
2737                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
    })format!("#![feature({feature})]\n"),
2738                Applicability::MaybeIncorrect,
2739            );
2740        }
2741    }
2742
2743    /// Emit a lint from a lint struct (some type that implements `Diagnostic`, typically generated
2744    /// by `#[derive(Diagnostic)]`).
2745    #[track_caller]
2746    pub fn emit_node_lint(
2747        self,
2748        lint: &'static Lint,
2749        id: HirId,
2750        decorator: impl for<'a> Diagnostic<'a>,
2751    ) {
2752        let level_spec = self.lint_level_spec_at_node(lint, id);
2753        emit_lint_base(self.sess, lint, level_spec, None, decorator);
2754    }
2755
2756    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2757        let map = self.in_scope_traits_map(id.owner)?;
2758        let candidates = map.get(&id.local_id)?;
2759        Some(candidates)
2760    }
2761
2762    pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2763        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs:2763",
                        "rustc_middle::ty::context", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs"),
                        ::tracing_core::__macro_support::Option::Some(2763u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
                        ::tracing_core::field::FieldSet::new(&["message",
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("id")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("id");
                                            NAME.as_str()
                                        }], ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("named_region")
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&id)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(?id, "named_region");
2764        self.named_variable_map(id.owner).get(&id.local_id).cloned()
2765    }
2766
2767    pub fn is_late_bound(self, id: HirId) -> bool {
2768        self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2769    }
2770
2771    pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2772        self.mk_bound_variable_kinds(
2773            &self
2774                .late_bound_vars_map(id.owner)
2775                .get(&id.local_id)
2776                .cloned()
2777                .unwrap_or_else(|| ::rustc_span::macros::bug_impl(None,
    format_args!("No bound vars found for {0}", self.hir_id_to_string(id)),
    Location::caller())bug!("No bound vars found for {}", self.hir_id_to_string(id))),
2778        )
2779    }
2780
2781    /// Given the def-id of an early-bound lifetime on an opaque corresponding to
2782    /// a duplicated captured lifetime, map it back to the early- or late-bound
2783    /// lifetime of the function from which it originally as captured. If it is
2784    /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
2785    /// of the signature.
2786    // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
2787    // re-use the generics of the opaque, this function will need to be tweaked slightly.
2788    pub fn map_opaque_lifetime_to_parent_lifetime(
2789        self,
2790        mut opaque_lifetime_param_def_id: LocalDefId,
2791    ) -> ty::Region<'tcx> {
2792        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!(
2793            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2794            "{opaque_lifetime_param_def_id:?} is a {}",
2795            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2796        );
2797
2798        loop {
2799            let parent = self.local_parent(opaque_lifetime_param_def_id);
2800            let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2801
2802            let Some((lifetime, _)) = lifetime_mapping
2803                .iter()
2804                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2805            else {
2806                ::rustc_span::macros::bug_impl(None,
    format_args!("duplicated lifetime param should be present"),
    Location::caller());bug!("duplicated lifetime param should be present");
2807            };
2808
2809            match *lifetime {
2810                resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2811                    let new_parent = self.local_parent(ebv);
2812
2813                    // If we map to another opaque, then it should be a parent
2814                    // of the opaque we mapped from. Continue mapping.
2815                    if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
    DefKind::OpaqueTy => true,
    _ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2816                        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);
2817                        opaque_lifetime_param_def_id = ebv;
2818                        continue;
2819                    }
2820
2821                    let generics = self.generics_of(new_parent);
2822                    return ty::Region::new_early_param(
2823                        self,
2824                        ty::EarlyParamRegion {
2825                            index: generics
2826                                .param_def_id_to_index(self, ebv.to_def_id())
2827                                .expect("early-bound var should be present in fn generics"),
2828                            name: self.item_name(ebv.to_def_id()),
2829                        },
2830                    );
2831                }
2832                resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2833                    let new_parent = self.local_parent(lbv);
2834                    return ty::Region::new_late_param(
2835                        self,
2836                        new_parent.to_def_id(),
2837                        ty::LateParamRegionKind::Named(lbv.to_def_id()),
2838                    );
2839                }
2840                resolve_bound_vars::ResolvedArg::Error(guar) => {
2841                    return ty::Region::new_error(self, guar);
2842                }
2843                _ => {
2844                    return ty::Region::new_error_with_message(
2845                        self,
2846                        self.def_span(opaque_lifetime_param_def_id),
2847                        "cannot resolve lifetime",
2848                    );
2849                }
2850            }
2851        }
2852    }
2853
2854    /// Whether `def_id` is a stable const fn (i.e., doesn't need any feature gates to be called).
2855    ///
2856    /// When this is `false`, the function may still be callable as a `const fn` due to features
2857    /// being enabled!
2858    pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2859        self.is_const_fn(def_id)
2860            && match self.lookup_const_stability(def_id) {
2861                None => true, // a fn in a non-staged_api crate
2862                Some(stability) if stability.is_const_stable() => true,
2863                _ => false,
2864            }
2865    }
2866
2867    /// Whether the trait impl is marked const. This does not consider stability or feature gates.
2868    pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2869        self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2870            && #[allow(non_exhaustive_omitted_patterns)] match self.impl_trait_header(def_id).constness
    {
    hir::Constness::Const { always: false } => true,
    _ => false,
}matches!(
2871                self.impl_trait_header(def_id).constness,
2872                hir::Constness::Const { always: false }
2873            )
2874    }
2875
2876    pub fn is_sdylib_interface_build(self) -> bool {
2877        self.sess.opts.unstable_opts.build_sdylib_interface
2878    }
2879
2880    pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2881        let def_id = def_id.into_query_key();
2882        match self.def_kind(def_id) {
2883            DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2884            _ => None,
2885        }
2886    }
2887
2888    pub fn next_trait_solver_globally(self) -> bool {
2889        self.sess.opts.unstable_opts.next_solver == NextSolverConfig::Globally
2890            && !self.sess.opts.unstable_opts.higher_ranked_assumptions
2891            && !self.features().generic_const_exprs()
2892    }
2893
2894    pub fn next_solver_overflow_fcw_limit(self) -> Option<usize> {
2895        self.sess.opts.unstable_opts.next_solver_overflow_fcw_limit
2896    }
2897
2898    pub fn disable_trait_solver_fast_paths(self) -> bool {
2899        self.sess.opts.unstable_opts.disable_fast_paths
2900    }
2901
2902    pub fn disable_param_env_normalization_hack(self) -> bool {
2903        self.sess.opts.unstable_opts.disable_param_env_normalization_hack
2904    }
2905
2906    pub fn renormalize_rigid_aliases(self) -> bool {
2907        self.sess.opts.unstable_opts.renormalize_rigid_aliases
2908    }
2909
2910    #[allow(rustc::bad_opt_access)]
2911    pub fn use_typing_mode_post_typeck_through_borrowck(self) -> bool {
2912        self.next_trait_solver_globally()
2913    }
2914
2915    pub fn assumptions_on_binders(self) -> bool {
2916        self.sess.opts.unstable_opts.assumptions_on_binders
2917    }
2918
2919    pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2920        self.opt_rpitit_info(def_id).is_some()
2921    }
2922
2923    pub fn get_impl_future_output_ty(self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
2924        let (def_id, args) = match *ty.kind() {
2925            ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
2926            ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, args, .. })
2927                if self.is_impl_trait_in_trait(def_id) =>
2928            {
2929                (def_id, args)
2930            }
2931            _ => return None,
2932        };
2933
2934        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2935        let item_def_id = self.associated_item_def_ids(future_trait)[0];
2936
2937        self.explicit_item_self_bounds(def_id)
2938            .iter_instantiated_copied(self, args)
2939            .map(ty::Unnormalized::skip_norm_wip)
2940            .find_map(|(predicate, _)| {
2941                predicate
2942                    .kind()
2943                    .map_bound(|kind| match kind {
2944                        ty::ClauseKind::Projection(projection_predicate)
2945                            if projection_predicate.def_id() == item_def_id =>
2946                        {
2947                            projection_predicate.term.as_type()
2948                        }
2949                        _ => None,
2950                    })
2951                    .no_bound_vars()
2952                    .flatten()
2953            })
2954    }
2955
2956    /// Named module children from all kinds of items, including imports.
2957    /// In addition to regular items this list also includes struct and variant constructors, and
2958    /// items inside `extern {}` blocks because all of them introduce names into parent module.
2959    ///
2960    /// Module here is understood in name resolution sense - it can be a `mod` item,
2961    /// or a crate root, or an enum, or a trait.
2962    ///
2963    /// This is not a query, making it a query causes perf regressions
2964    /// (probably due to hashing spans in `ModChild`ren).
2965    pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2966        self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2967    }
2968
2969    /// Return the crate imported by given use item.
2970    pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2971        self.resolutions(()).extern_crate_map.get(&def_id).copied()
2972    }
2973
2974    pub fn resolver_for_lowering(
2975        self,
2976    ) -> (&'tcx Steal<ResolverAstLowering<'tcx>>, &'tcx Steal<ast::Crate>) {
2977        let (resolver, krate, _) = self.resolver_for_lowering_raw(());
2978        (resolver, krate)
2979    }
2980
2981    pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2982        make_metadata(self)
2983    }
2984
2985    pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2986        if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2987            self.coroutine_kind(def_id)
2988            && let ty::Coroutine(_, args) =
2989                self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2990            && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2991        {
2992            true
2993        } else {
2994            false
2995        }
2996    }
2997
2998    /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
2999    pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3000        {
        {
            'done:
                {
                for i in ::rustc_attr_ir::HasAttrs::get_attrs(def_id, &self) {
                    #[allow(unused_imports)]
                    use ::rustc_attr_ir::AttributeKind::*;
                    let i: &::rustc_attr_ir::Attribute = i;
                    match i {
                        ::rustc_attr_ir::Attribute::Parsed(DoNotRecommend) => {
                            break 'done Some(());
                        }
                        ::rustc_attr_ir::Attribute::Tool(..) |
                            ::rustc_attr_ir::Attribute::DeriveHelper(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }
    }.is_some()find_attr!(self, def_id, DoNotRecommend)
3001    }
3002
3003    pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
3004        let def_id = def_id.into_query_key();
3005        self.trivial_const(def_id).is_some()
3006    }
3007
3008    /// Whether this def is one of the special bin crate entrypoint functions that must have a
3009    /// monomorphization and also not be internalized in the bin crate.
3010    pub fn is_entrypoint(self, def_id: DefId) -> bool {
3011        if self.is_lang_item(def_id, LangItem::Start) {
3012            return true;
3013        }
3014        if let Some((entry_def_id, _)) = self.entry_fn(())
3015            && entry_def_id == def_id
3016        {
3017            return true;
3018        }
3019        false
3020    }
3021}
3022
3023pub fn provide(providers: &mut Providers) {
3024    providers.is_panic_runtime = |tcx, LocalCrate| {
        'done:
            {
            for i in tcx.hir_krate_attrs() {
                #[allow(unused_imports)]
                use ::rustc_attr_ir::AttributeKind::*;
                let i: &::rustc_attr_ir::Attribute = i;
                match i {
                    ::rustc_attr_ir::Attribute::Parsed(PanicRuntime) => {
                        break 'done Some(());
                    }
                    ::rustc_attr_ir::Attribute::Tool(..) |
                        ::rustc_attr_ir::Attribute::DeriveHelper(..) =>
                        {}
                        #[deny(unreachable_patterns)]
                        _ => {}
                }
            }
            None
        }
    }.is_some()find_attr!(tcx, crate, PanicRuntime);
3025    providers.is_compiler_builtins = |tcx, LocalCrate| {
        'done:
            {
            for i in tcx.hir_krate_attrs() {
                #[allow(unused_imports)]
                use ::rustc_attr_ir::AttributeKind::*;
                let i: &::rustc_attr_ir::Attribute = i;
                match i {
                    ::rustc_attr_ir::Attribute::Parsed(CompilerBuiltins) => {
                        break 'done Some(());
                    }
                    ::rustc_attr_ir::Attribute::Tool(..) |
                        ::rustc_attr_ir::Attribute::DeriveHelper(..) =>
                        {}
                        #[deny(unreachable_patterns)]
                        _ => {}
                }
            }
            None
        }
    }.is_some()find_attr!(tcx, crate, CompilerBuiltins);
3026    providers.has_panic_handler = |tcx, LocalCrate| {
3027        // We want to check if the panic handler was defined in this crate
3028        tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3029    };
3030    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3031}