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