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