Skip to main content

rustc_middle/ty/
context.rs

1//! Type context book-keeping.
2
3#![allow(rustc::usage_of_ty_tykind)]
4
5mod impl_interner;
6pub mod tls;
7
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::{PhantomData, PointeeSized};
14use std::ops::{Bound, Deref};
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::fingerprint::Fingerprint;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::jobserver::Proxy;
25use rustc_data_structures::profiling::SelfProfilerRef;
26use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
27use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
28use rustc_data_structures::steal::Steal;
29use rustc_data_structures::sync::{
30    self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
31};
32use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
33use rustc_hir::def::DefKind;
34use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
35use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
36use rustc_hir::intravisit::VisitorExt;
37use rustc_hir::lang_items::LangItem;
38use rustc_hir::limit::Limit;
39use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr};
40use rustc_index::IndexVec;
41use rustc_macros::Diagnostic;
42use rustc_session::Session;
43use rustc_session::config::CrateType;
44use rustc_session::cstore::{CrateStoreDyn, Untracked};
45use rustc_session::lint::Lint;
46use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
47use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw};
48use rustc_type_ir::TyKind::*;
49pub use rustc_type_ir::lift::Lift;
50use rustc_type_ir::{CollectAndApply, TypeFlags, WithCachedTypeInfo, elaborate, search_graph};
51use tracing::{debug, instrument};
52
53use crate::arena::Arena;
54use crate::dep_graph::dep_node::make_metadata;
55use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
56use crate::ich::StableHashingContext;
57use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
58use crate::lint::{diag_lint_level, lint_level};
59use crate::metadata::ModChild;
60use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
61use crate::middle::resolve_bound_vars;
62use crate::mir::interpret::{self, Allocation, ConstAllocation};
63use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
64use crate::query::plumbing::QuerySystem;
65use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
66use crate::thir::Thir;
67use crate::traits;
68use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
69use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
70use crate::ty::{
71    self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
72    GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, Pattern,
73    PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity,
74    Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, ValTree, ValTreeKind,
75    Visibility,
76};
77
78impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
79    fn is_local(self) -> bool {
80        self.is_local()
81    }
82
83    fn as_local(self) -> Option<LocalDefId> {
84        self.as_local()
85    }
86}
87
88impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
89    fn rust() -> Self {
90        ExternAbi::Rust
91    }
92
93    fn is_rust(self) -> bool {
94        #[allow(non_exhaustive_omitted_patterns)] match self {
    ExternAbi::Rust => true,
    _ => false,
}matches!(self, ExternAbi::Rust)
95    }
96}
97
98impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
99    fn safe() -> Self {
100        hir::Safety::Safe
101    }
102
103    fn is_safe(self) -> bool {
104        self.is_safe()
105    }
106
107    fn prefix_str(self) -> &'static str {
108        self.prefix_str()
109    }
110}
111
112impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
113    fn generic_const_exprs(self) -> bool {
114        self.generic_const_exprs()
115    }
116
117    fn coroutine_clone(self) -> bool {
118        self.coroutine_clone()
119    }
120
121    fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
122        // We don't consider feature bounds to hold in the crate when `staged_api` feature is
123        // enabled, even if it is enabled through `#[feature]`.
124        // This is to prevent accidentally leaking unstable APIs to stable.
125        !self.staged_api() && self.enabled(symbol)
126    }
127}
128
129impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
130    fn dummy() -> Self {
131        DUMMY_SP
132    }
133}
134
135type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
136
137pub struct CtxtInterners<'tcx> {
138    /// The arena that types, regions, etc. are allocated from.
139    arena: &'tcx WorkerLocal<Arena<'tcx>>,
140
141    // Specifically use a speedy hash algorithm for these hash sets, since
142    // they're accessed quite often.
143    type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
144    const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
145    args: InternedSet<'tcx, GenericArgs<'tcx>>,
146    type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
147    canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
148    region: InternedSet<'tcx, RegionKind<'tcx>>,
149    poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
150    predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
151    clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
152    projs: InternedSet<'tcx, List<ProjectionKind>>,
153    place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
154    const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
155    pat: InternedSet<'tcx, PatternKind<'tcx>>,
156    const_allocation: InternedSet<'tcx, Allocation>,
157    bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
158    layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
159    adt_def: InternedSet<'tcx, AdtDefData>,
160    external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
161    predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
162    fields: InternedSet<'tcx, List<FieldIdx>>,
163    local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
164    captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
165    valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
166    patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
167    outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
168}
169
170impl<'tcx> CtxtInterners<'tcx> {
171    fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
172        // Default interner size - this value has been chosen empirically, and may need to be adjusted
173        // as the compiler evolves.
174        const N: usize = 2048;
175        CtxtInterners {
176            arena,
177            // The factors have been chosen by @FractalFir based on observed interner sizes, and local perf runs.
178            // To get the interner sizes, insert `eprintln` printing the size of the interner in functions like `intern_ty`.
179            // Bigger benchmarks tend to give more accurate ratios, so use something like `x perf eprintln --includes cargo`.
180            type_: InternedSet::with_capacity(N * 16),
181            const_lists: InternedSet::with_capacity(N * 4),
182            args: InternedSet::with_capacity(N * 4),
183            type_lists: InternedSet::with_capacity(N * 4),
184            region: InternedSet::with_capacity(N * 4),
185            poly_existential_predicates: InternedSet::with_capacity(N / 4),
186            canonical_var_kinds: InternedSet::with_capacity(N / 2),
187            predicate: InternedSet::with_capacity(N),
188            clauses: InternedSet::with_capacity(N),
189            projs: InternedSet::with_capacity(N * 4),
190            place_elems: InternedSet::with_capacity(N * 2),
191            const_: InternedSet::with_capacity(N * 2),
192            pat: InternedSet::with_capacity(N),
193            const_allocation: InternedSet::with_capacity(N),
194            bound_variable_kinds: InternedSet::with_capacity(N * 2),
195            layout: InternedSet::with_capacity(N),
196            adt_def: InternedSet::with_capacity(N),
197            external_constraints: InternedSet::with_capacity(N),
198            predefined_opaques_in_body: InternedSet::with_capacity(N),
199            fields: InternedSet::with_capacity(N * 4),
200            local_def_ids: InternedSet::with_capacity(N),
201            captures: InternedSet::with_capacity(N),
202            valtree: InternedSet::with_capacity(N),
203            patterns: InternedSet::with_capacity(N),
204            outlives: InternedSet::with_capacity(N),
205        }
206    }
207
208    /// Interns a type. (Use `mk_*` functions instead, where possible.)
209    #[allow(rustc::usage_of_ty_tykind)]
210    #[inline(never)]
211    fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
212        Ty(Interned::new_unchecked(
213            self.type_
214                .intern(kind, |kind| {
215                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
216                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
217
218                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
219                        internee: kind,
220                        stable_hash,
221                        flags: flags.flags,
222                        outer_exclusive_binder: flags.outer_exclusive_binder,
223                    }))
224                })
225                .0,
226        ))
227    }
228
229    /// Interns a const. (Use `mk_*` functions instead, where possible.)
230    #[allow(rustc::usage_of_ty_tykind)]
231    #[inline(never)]
232    fn intern_const(
233        &self,
234        kind: ty::ConstKind<'tcx>,
235        sess: &Session,
236        untracked: &Untracked,
237    ) -> Const<'tcx> {
238        Const(Interned::new_unchecked(
239            self.const_
240                .intern(kind, |kind: ty::ConstKind<'_>| {
241                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
242                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
243
244                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
245                        internee: kind,
246                        stable_hash,
247                        flags: flags.flags,
248                        outer_exclusive_binder: flags.outer_exclusive_binder,
249                    }))
250                })
251                .0,
252        ))
253    }
254
255    fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
256        &self,
257        flags: &ty::FlagComputation<TyCtxt<'tcx>>,
258        sess: &'a Session,
259        untracked: &'a Untracked,
260        val: &T,
261    ) -> Fingerprint {
262        // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them.
263        // Without incremental, we rarely stable-hash types, so let's not do it proactively.
264        if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
265            Fingerprint::ZERO
266        } else {
267            let mut hasher = StableHasher::new();
268            let mut hcx = StableHashingContext::new(sess, untracked);
269            val.hash_stable(&mut hcx, &mut hasher);
270            hasher.finish()
271        }
272    }
273
274    /// Interns a predicate. (Use `mk_predicate` instead, where possible.)
275    #[inline(never)]
276    fn intern_predicate(
277        &self,
278        kind: Binder<'tcx, PredicateKind<'tcx>>,
279        sess: &Session,
280        untracked: &Untracked,
281    ) -> Predicate<'tcx> {
282        Predicate(Interned::new_unchecked(
283            self.predicate
284                .intern(kind, |kind| {
285                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
286
287                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
288
289                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
290                        internee: kind,
291                        stable_hash,
292                        flags: flags.flags,
293                        outer_exclusive_binder: flags.outer_exclusive_binder,
294                    }))
295                })
296                .0,
297        ))
298    }
299
300    fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
301        if clauses.is_empty() {
302            ListWithCachedTypeInfo::empty()
303        } else {
304            self.clauses
305                .intern_ref(clauses, || {
306                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
307
308                    InternedInSet(ListWithCachedTypeInfo::from_arena(
309                        &*self.arena,
310                        flags.into(),
311                        clauses,
312                    ))
313                })
314                .0
315        }
316    }
317}
318
319// For these preinterned values, an alternative would be to have
320// variable-length vectors that grow as needed. But that turned out to be
321// slightly more complex and no faster.
322
323const NUM_PREINTERNED_TY_VARS: u32 = 100;
324const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
325const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
326const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
327const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
328
329// From general profiling of the *max vars during canonicalization* of a value:
330// - about 90% of the time, there are no canonical vars
331// - about 9% of the time, there is only one canonical var
332// - there are rarely more than 3-5 canonical vars (with exceptions in particularly pathological cases)
333// This may not match the number of bound vars found in `for`s.
334// Given that this is all heap interned, it seems likely that interning fewer
335// vars here won't make an appreciable difference. Though, if we were to inline the data (in an array),
336// we may want to consider reducing the number for canonicalized vars down to 4 or so.
337const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
338
339// This number may seem high, but it is reached in all but the smallest crates.
340const NUM_PREINTERNED_RE_VARS: u32 = 500;
341const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
342const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
343
344pub struct CommonTypes<'tcx> {
345    pub unit: Ty<'tcx>,
346    pub bool: Ty<'tcx>,
347    pub char: Ty<'tcx>,
348    pub isize: Ty<'tcx>,
349    pub i8: Ty<'tcx>,
350    pub i16: Ty<'tcx>,
351    pub i32: Ty<'tcx>,
352    pub i64: Ty<'tcx>,
353    pub i128: Ty<'tcx>,
354    pub usize: Ty<'tcx>,
355    pub u8: Ty<'tcx>,
356    pub u16: Ty<'tcx>,
357    pub u32: Ty<'tcx>,
358    pub u64: Ty<'tcx>,
359    pub u128: Ty<'tcx>,
360    pub f16: Ty<'tcx>,
361    pub f32: Ty<'tcx>,
362    pub f64: Ty<'tcx>,
363    pub f128: Ty<'tcx>,
364    pub str_: Ty<'tcx>,
365    pub never: Ty<'tcx>,
366    pub self_param: Ty<'tcx>,
367
368    /// Dummy type used for the `Self` of a `TraitRef` created for converting
369    /// a trait object, and which gets removed in `ExistentialTraitRef`.
370    /// This type must not appear anywhere in other converted types.
371    /// `Infer(ty::FreshTy(0))` does the job.
372    pub trait_object_dummy_self: Ty<'tcx>,
373
374    /// Pre-interned `Infer(ty::TyVar(n))` for small values of `n`.
375    pub ty_vars: Vec<Ty<'tcx>>,
376
377    /// Pre-interned `Infer(ty::FreshTy(n))` for small values of `n`.
378    pub fresh_tys: Vec<Ty<'tcx>>,
379
380    /// Pre-interned `Infer(ty::FreshIntTy(n))` for small values of `n`.
381    pub fresh_int_tys: Vec<Ty<'tcx>>,
382
383    /// Pre-interned `Infer(ty::FreshFloatTy(n))` for small values of `n`.
384    pub fresh_float_tys: Vec<Ty<'tcx>>,
385
386    /// Pre-interned values of the form:
387    /// `Bound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundTy { var: v, kind: BoundTyKind::Anon})`
388    /// for small values of `i` and `v`.
389    pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
390
391    // Pre-interned values of the form:
392    // `Bound(BoundVarIndexKind::Canonical, BoundTy { var: v, kind: BoundTyKind::Anon })`
393    // for small values of `v`.
394    pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
395}
396
397pub struct CommonLifetimes<'tcx> {
398    /// `ReStatic`
399    pub re_static: Region<'tcx>,
400
401    /// Erased region, used outside of type inference.
402    pub re_erased: Region<'tcx>,
403
404    /// Pre-interned `ReVar(ty::RegionVar(n))` for small values of `n`.
405    pub re_vars: Vec<Region<'tcx>>,
406
407    /// Pre-interned values of the form:
408    /// `ReBound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundRegion { var: v, kind: BoundRegionKind::Anon })`
409    /// for small values of `i` and `v`.
410    pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
411
412    // Pre-interned values of the form:
413    // `ReBound(BoundVarIndexKind::Canonical, BoundRegion { var: v, kind: BoundRegionKind::Anon })`
414    // for small values of `v`.
415    pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
416}
417
418pub struct CommonConsts<'tcx> {
419    pub unit: Const<'tcx>,
420    pub true_: Const<'tcx>,
421    pub false_: Const<'tcx>,
422    /// Use [`ty::ValTree::zst`] instead.
423    pub(crate) valtree_zst: ValTree<'tcx>,
424}
425
426impl<'tcx> CommonTypes<'tcx> {
427    fn new(
428        interners: &CtxtInterners<'tcx>,
429        sess: &Session,
430        untracked: &Untracked,
431    ) -> CommonTypes<'tcx> {
432        let mk = |ty| interners.intern_ty(ty, sess, untracked);
433
434        let ty_vars =
435            (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
436        let fresh_tys: Vec<_> =
437            (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
438        let fresh_int_tys: Vec<_> =
439            (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
440        let fresh_float_tys: Vec<_> =
441            (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
442
443        let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
444            .map(|i| {
445                (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
446                    .map(|v| {
447                        mk(ty::Bound(
448                            ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
449                            ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
450                        ))
451                    })
452                    .collect()
453            })
454            .collect();
455
456        let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
457            .map(|v| {
458                mk(ty::Bound(
459                    ty::BoundVarIndexKind::Canonical,
460                    ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
461                ))
462            })
463            .collect();
464
465        CommonTypes {
466            unit: mk(Tuple(List::empty())),
467            bool: mk(Bool),
468            char: mk(Char),
469            never: mk(Never),
470            isize: mk(Int(ty::IntTy::Isize)),
471            i8: mk(Int(ty::IntTy::I8)),
472            i16: mk(Int(ty::IntTy::I16)),
473            i32: mk(Int(ty::IntTy::I32)),
474            i64: mk(Int(ty::IntTy::I64)),
475            i128: mk(Int(ty::IntTy::I128)),
476            usize: mk(Uint(ty::UintTy::Usize)),
477            u8: mk(Uint(ty::UintTy::U8)),
478            u16: mk(Uint(ty::UintTy::U16)),
479            u32: mk(Uint(ty::UintTy::U32)),
480            u64: mk(Uint(ty::UintTy::U64)),
481            u128: mk(Uint(ty::UintTy::U128)),
482            f16: mk(Float(ty::FloatTy::F16)),
483            f32: mk(Float(ty::FloatTy::F32)),
484            f64: mk(Float(ty::FloatTy::F64)),
485            f128: mk(Float(ty::FloatTy::F128)),
486            str_: mk(Str),
487            self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
488
489            trait_object_dummy_self: fresh_tys[0],
490
491            ty_vars,
492            fresh_tys,
493            fresh_int_tys,
494            fresh_float_tys,
495            anon_bound_tys,
496            anon_canonical_bound_tys,
497        }
498    }
499}
500
501impl<'tcx> CommonLifetimes<'tcx> {
502    fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
503        let mk = |r| {
504            Region(Interned::new_unchecked(
505                interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
506            ))
507        };
508
509        let re_vars =
510            (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
511
512        let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
513            .map(|i| {
514                (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
515                    .map(|v| {
516                        mk(ty::ReBound(
517                            ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
518                            ty::BoundRegion {
519                                var: ty::BoundVar::from(v),
520                                kind: ty::BoundRegionKind::Anon,
521                            },
522                        ))
523                    })
524                    .collect()
525            })
526            .collect();
527
528        let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
529            .map(|v| {
530                mk(ty::ReBound(
531                    ty::BoundVarIndexKind::Canonical,
532                    ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
533                ))
534            })
535            .collect();
536
537        CommonLifetimes {
538            re_static: mk(ty::ReStatic),
539            re_erased: mk(ty::ReErased),
540            re_vars,
541            anon_re_bounds,
542            anon_re_canonical_bounds,
543        }
544    }
545}
546
547impl<'tcx> CommonConsts<'tcx> {
548    fn new(
549        interners: &CtxtInterners<'tcx>,
550        types: &CommonTypes<'tcx>,
551        sess: &Session,
552        untracked: &Untracked,
553    ) -> CommonConsts<'tcx> {
554        let mk_const = |c| {
555            interners.intern_const(
556                c, sess, // This is only used to create a stable hashing context.
557                untracked,
558            )
559        };
560
561        let mk_valtree = |v| {
562            ty::ValTree(Interned::new_unchecked(
563                interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
564            ))
565        };
566
567        let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
568        let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
569        let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
570
571        CommonConsts {
572            unit: mk_const(ty::ConstKind::Value(ty::Value {
573                ty: types.unit,
574                valtree: valtree_zst,
575            })),
576            true_: mk_const(ty::ConstKind::Value(ty::Value {
577                ty: types.bool,
578                valtree: valtree_true,
579            })),
580            false_: mk_const(ty::ConstKind::Value(ty::Value {
581                ty: types.bool,
582                valtree: valtree_false,
583            })),
584            valtree_zst,
585        }
586    }
587}
588
589/// This struct contains information regarding a free parameter region,
590/// either a `ReEarlyParam` or `ReLateParam`.
591#[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)]
592pub struct FreeRegionInfo {
593    /// `LocalDefId` of the scope.
594    pub scope: LocalDefId,
595    /// the `DefId` of the free region.
596    pub region_def_id: DefId,
597    /// checks if bound region is in Impl Item
598    pub is_impl_item: bool,
599}
600
601/// This struct should only be created by `create_def`.
602#[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)]
603pub struct TyCtxtFeed<'tcx, KEY: Copy> {
604    pub tcx: TyCtxt<'tcx>,
605    // Do not allow direct access, as downstream code must not mutate this field.
606    key: KEY,
607}
608
609/// Never return a `Feed` from a query. Only queries that create a `DefId` are
610/// allowed to feed queries for that `DefId`.
611impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
612
613/// The same as `TyCtxtFeed`, but does not contain a `TyCtxt`.
614/// Use this to pass around when you have a `TyCtxt` elsewhere.
615/// Just an optimization to save space and not store hundreds of
616/// `TyCtxtFeed` in the resolver.
617#[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)]
618pub struct Feed<'tcx, KEY: Copy> {
619    _tcx: PhantomData<TyCtxt<'tcx>>,
620    // Do not allow direct access, as downstream code must not mutate this field.
621    key: KEY,
622}
623
624/// Never return a `Feed` from a query. Only queries that create a `DefId` are
625/// allowed to feed queries for that `DefId`.
626impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
627
628impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
629    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
630        self.key.fmt(f)
631    }
632}
633
634/// Some workarounds to use cases that cannot use `create_def`.
635/// Do not add new ways to create `TyCtxtFeed` without consulting
636/// with T-compiler and making an analysis about why your addition
637/// does not cause incremental compilation issues.
638impl<'tcx> TyCtxt<'tcx> {
639    /// Can only be fed before queries are run, and is thus exempt from any
640    /// incremental issues. Do not use except for the initial query feeding.
641    pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
642        self.dep_graph.assert_ignored();
643        TyCtxtFeed { tcx: self, key: () }
644    }
645
646    /// Only used in the resolver to register the `CRATE_DEF_ID` `DefId` and feed
647    /// some queries for it. It will panic if used twice.
648    pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
649        let key = self.untracked().source_span.push(span);
650        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);
651        TyCtxtFeed { tcx: self, key }
652    }
653
654    /// In order to break cycles involving `AnonConst`, we need to set the expected type by side
655    /// effect. However, we do not want this as a general capability, so this interface restricts
656    /// to the only allowed case.
657    pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
658        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);
659        TyCtxtFeed { tcx: self, key }.type_of(value)
660    }
661}
662
663impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
664    #[inline(always)]
665    pub fn key(&self) -> KEY {
666        self.key
667    }
668
669    #[inline(always)]
670    pub fn downgrade(self) -> Feed<'tcx, KEY> {
671        Feed { _tcx: PhantomData, key: self.key }
672    }
673}
674
675impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
676    #[inline(always)]
677    pub fn key(&self) -> KEY {
678        self.key
679    }
680
681    #[inline(always)]
682    pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
683        TyCtxtFeed { tcx, key: self.key }
684    }
685}
686
687impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
688    #[inline(always)]
689    pub fn def_id(&self) -> LocalDefId {
690        self.key
691    }
692
693    // Caller must ensure that `self.key` ID is indeed an owner.
694    pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
695        TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
696    }
697
698    // Fills in all the important parts needed by HIR queries
699    pub fn feed_hir(&self) {
700        self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
701
702        let node = hir::OwnerNode::Synthetic;
703        let bodies = Default::default();
704        let attrs = hir::AttributeMap::EMPTY;
705
706        let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
707            self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
708        let node = node.into();
709        self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
710            opt_hash_including_bodies,
711            nodes: IndexVec::from_elem_n(
712                hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
713                1,
714            ),
715            bodies,
716        })));
717        self.feed_owner_id().hir_attr_map(attrs);
718    }
719}
720
721/// The central data structure of the compiler. It stores references
722/// to the various **arenas** and also houses the results of the
723/// various **compiler queries** that have been performed. See the
724/// [rustc dev guide] for more details.
725///
726/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html
727///
728/// An implementation detail: `TyCtxt` is a wrapper type for [GlobalCtxt],
729/// which is the struct that actually holds all the data. `TyCtxt` derefs to
730/// `GlobalCtxt`, and in practice `TyCtxt` is passed around everywhere, and all
731/// operations are done via `TyCtxt`. A `TyCtxt` is obtained for a `GlobalCtxt`
732/// by calling `enter` with a closure `f`. That function creates both the
733/// `TyCtxt`, and an `ImplicitCtxt` around it that is put into TLS. Within `f`:
734/// - The `ImplicitCtxt` is available implicitly via TLS.
735/// - The `TyCtxt` is available explicitly via the `tcx` parameter, and also
736///   implicitly within the `ImplicitCtxt`. Explicit access is preferred when
737///   possible.
738#[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)]
739#[rustc_diagnostic_item = "TyCtxt"]
740#[rustc_pass_by_value]
741pub struct TyCtxt<'tcx> {
742    gcx: &'tcx GlobalCtxt<'tcx>,
743}
744
745// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. Its
746// field are asserted to implement these traits below, so this is trivially safe, and it greatly
747// speeds-up compilation of this crate and its dependents.
748unsafe impl DynSend for TyCtxt<'_> {}
749unsafe impl DynSync for TyCtxt<'_> {}
750fn _assert_tcx_fields() {
751    sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
752    sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
753}
754
755impl<'tcx> Deref for TyCtxt<'tcx> {
756    type Target = &'tcx GlobalCtxt<'tcx>;
757    #[inline(always)]
758    fn deref(&self) -> &Self::Target {
759        &self.gcx
760    }
761}
762
763/// See [TyCtxt] for details about this type.
764pub struct GlobalCtxt<'tcx> {
765    pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
766    pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
767
768    interners: CtxtInterners<'tcx>,
769
770    pub sess: &'tcx Session,
771    crate_types: Vec<CrateType>,
772    /// The `stable_crate_id` is constructed out of the crate name and all the
773    /// `-C metadata` arguments passed to the compiler. Its value forms a unique
774    /// global identifier for the crate. It is used to allow multiple crates
775    /// with the same name to coexist. See the
776    /// `rustc_symbol_mangling` crate for more information.
777    stable_crate_id: StableCrateId,
778
779    pub dep_graph: DepGraph,
780
781    pub prof: SelfProfilerRef,
782
783    /// Common types, pre-interned for your convenience.
784    pub types: CommonTypes<'tcx>,
785
786    /// Common lifetimes, pre-interned for your convenience.
787    pub lifetimes: CommonLifetimes<'tcx>,
788
789    /// Common consts, pre-interned for your convenience.
790    pub consts: CommonConsts<'tcx>,
791
792    /// Hooks to be able to register functions in other crates that can then still
793    /// be called from rustc_middle.
794    pub(crate) hooks: crate::hooks::Providers,
795
796    untracked: Untracked,
797
798    pub query_system: QuerySystem<'tcx>,
799    pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
800
801    // Internal caches for metadata decoding. No need to track deps on this.
802    pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
803
804    /// Caches the results of trait selection. This cache is used
805    /// for things that do not have to do with the parameters in scope.
806    pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
807
808    /// Caches the results of trait evaluation. This cache is used
809    /// for things that do not have to do with the parameters in scope.
810    /// Merge this with `selection_cache`?
811    pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
812
813    /// Caches the results of goal evaluation in the new solver.
814    pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
815    pub new_solver_canonical_param_env_cache:
816        Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
817
818    pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
819
820    /// Caches the index of the highest bound var in clauses in a canonical binder.
821    pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
822    /// Caches the instantiation of a canonical binder given a set of args.
823    pub clauses_cache:
824        Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
825
826    /// Data layout specification for the current target.
827    pub data_layout: TargetDataLayout,
828
829    /// Stores memory for globals (statics/consts).
830    pub(crate) alloc_map: interpret::AllocMap<'tcx>,
831
832    current_gcx: CurrentGcx,
833
834    /// A jobserver reference used to release then acquire a token while waiting on a query.
835    pub jobserver_proxy: Arc<Proxy>,
836}
837
838impl<'tcx> GlobalCtxt<'tcx> {
839    /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
840    /// `f`.
841    pub fn enter<F, R>(&'tcx self, f: F) -> R
842    where
843        F: FnOnce(TyCtxt<'tcx>) -> R,
844    {
845        let icx = tls::ImplicitCtxt::new(self);
846
847        // Reset `current_gcx` to `None` when we exit.
848        let _on_drop = defer(move || {
849            *self.current_gcx.value.write() = None;
850        });
851
852        // Set this `GlobalCtxt` as the current one.
853        {
854            let mut guard = self.current_gcx.value.write();
855            if !guard.is_none() {
    {
        ::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
    }
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
856            *guard = Some(self as *const _ as *const ());
857        }
858
859        tls::enter_context(&icx, || f(icx.tcx))
860    }
861}
862
863/// This is used to get a reference to a `GlobalCtxt` if one is available.
864///
865/// This is needed to allow the deadlock handler access to `GlobalCtxt` to look for query cycles.
866/// It cannot use the `TLV` global because that's only guaranteed to be defined on the thread
867/// creating the `GlobalCtxt`. Other threads have access to the `TLV` only inside Rayon jobs, but
868/// the deadlock handler is not called inside such a job.
869#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
    #[inline]
    fn clone(&self) -> CurrentGcx {
        CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
    }
}Clone)]
870pub struct CurrentGcx {
871    /// This stores a pointer to a `GlobalCtxt`. This is set to `Some` inside `GlobalCtxt::enter`
872    /// and reset to `None` when that function returns or unwinds.
873    value: Arc<RwLock<Option<*const ()>>>,
874}
875
876unsafe impl DynSend for CurrentGcx {}
877unsafe impl DynSync for CurrentGcx {}
878
879impl CurrentGcx {
880    pub fn new() -> Self {
881        Self { value: Arc::new(RwLock::new(None)) }
882    }
883
884    pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
885        let read_guard = self.value.read();
886        let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
887        // SAFETY: We hold the read lock for the `GlobalCtxt` pointer. That prevents
888        // `GlobalCtxt::enter` from returning as it would first acquire the write lock.
889        // This ensures the `GlobalCtxt` is live during `f`.
890        f(unsafe { &*gcx })
891    }
892}
893
894impl<'tcx> TyCtxt<'tcx> {
895    pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
896        // Closures' typeck results come from their outermost function,
897        // as they are part of the same "inference environment".
898        let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
899        if typeck_root_def_id != def_id.to_def_id() {
900            return self.has_typeck_results(typeck_root_def_id.expect_local());
901        }
902
903        self.hir_node_by_def_id(def_id).body_id().is_some()
904    }
905
906    /// Expects a body and returns its codegen attributes.
907    ///
908    /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for
909    /// constants.
910    pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
911        let def_kind = self.def_kind(def_id);
912        if def_kind.has_codegen_attrs() {
913            self.codegen_fn_attrs(def_id)
914        } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
    DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
        DefKind::InlineConst | DefKind::GlobalAsm => true,
    _ => false,
}matches!(
915            def_kind,
916            DefKind::AnonConst
917                | DefKind::AssocConst { .. }
918                | DefKind::Const { .. }
919                | DefKind::InlineConst
920                | DefKind::GlobalAsm
921        ) {
922            CodegenFnAttrs::EMPTY
923        } else {
924            crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
        def_id, def_kind))bug!(
925                "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
926                def_id,
927                def_kind
928            )
929        }
930    }
931
932    pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
933        self.arena.alloc(Steal::new(thir))
934    }
935
936    pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
937        self.arena.alloc(Steal::new(mir))
938    }
939
940    pub fn alloc_steal_promoted(
941        self,
942        promoted: IndexVec<Promoted, Body<'tcx>>,
943    ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
944        self.arena.alloc(Steal::new(promoted))
945    }
946
947    pub fn mk_adt_def(
948        self,
949        did: DefId,
950        kind: AdtKind,
951        variants: IndexVec<VariantIdx, ty::VariantDef>,
952        repr: ReprOptions,
953    ) -> ty::AdtDef<'tcx> {
954        self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
955    }
956
957    /// Allocates a read-only byte or string literal for `mir::interpret` with alignment 1.
958    /// Returns the same `AllocId` if called again with the same bytes.
959    pub fn allocate_bytes_dedup<'a>(
960        self,
961        bytes: impl Into<Cow<'a, [u8]>>,
962        salt: usize,
963    ) -> interpret::AllocId {
964        // Create an allocation that just contains these bytes.
965        let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
966        let alloc = self.mk_const_alloc(alloc);
967        self.reserve_and_set_memory_dedup(alloc, salt)
968    }
969
970    /// Traits added on all bounds by default, excluding `Sized` which is treated separately.
971    pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
972        if self.sess.opts.unstable_opts.experimental_default_bounds {
973            &[
974                LangItem::DefaultTrait1,
975                LangItem::DefaultTrait2,
976                LangItem::DefaultTrait3,
977                LangItem::DefaultTrait4,
978            ]
979        } else {
980            &[]
981        }
982    }
983
984    pub fn is_default_trait(self, def_id: DefId) -> bool {
985        self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
986    }
987
988    pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
989        #[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))
990    }
991
992    /// Returns a range of the start/end indices specified with the
993    /// `rustc_layout_scalar_valid_range` attribute.
994    // FIXME(eddyb) this is an awkward spot for this method, maybe move it?
995    pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
996        let start = {

    #[allow(deprecated)]
    {
        {
            'done:
                {
                for i in self.get_all_attrs(def_id) {
                    #[allow(unused_imports)]
                    use rustc_hir::attrs::AttributeKind::*;
                    let i: &rustc_hir::Attribute = i;
                    match i {
                        rustc_hir::Attribute::Parsed(RustcLayoutScalarValidRangeStart(n,
                            _)) => {
                            break 'done Some(Bound::Included(**n));
                        }
                        rustc_hir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }
    }
}find_attr!(self, def_id, RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
997        let end =
998            {

    #[allow(deprecated)]
    {
        {
            'done:
                {
                for i in self.get_all_attrs(def_id) {
                    #[allow(unused_imports)]
                    use rustc_hir::attrs::AttributeKind::*;
                    let i: &rustc_hir::Attribute = i;
                    match i {
                        rustc_hir::Attribute::Parsed(RustcLayoutScalarValidRangeEnd(n,
                            _)) => {
                            break 'done Some(Bound::Included(**n));
                        }
                        rustc_hir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }
    }
}find_attr!(self, def_id, RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n))
999                .unwrap_or(Bound::Unbounded);
1000        (start, end)
1001    }
1002
1003    pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1004        value.lift_to_interner(self)
1005    }
1006
1007    /// Creates a type context. To use the context call `fn enter` which
1008    /// provides a `TyCtxt`.
1009    ///
1010    /// By only providing the `TyCtxt` inside of the closure we enforce that the type
1011    /// context and any interned value (types, args, etc.) can only be used while `ty::tls`
1012    /// has a valid reference to the context, to allow formatting values that need it.
1013    pub fn create_global_ctxt<T>(
1014        gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1015        s: &'tcx Session,
1016        crate_types: Vec<CrateType>,
1017        stable_crate_id: StableCrateId,
1018        arena: &'tcx WorkerLocal<Arena<'tcx>>,
1019        hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1020        untracked: Untracked,
1021        dep_graph: DepGraph,
1022        dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
1023        query_system: QuerySystem<'tcx>,
1024        hooks: crate::hooks::Providers,
1025        current_gcx: CurrentGcx,
1026        jobserver_proxy: Arc<Proxy>,
1027        f: impl FnOnce(TyCtxt<'tcx>) -> T,
1028    ) -> T {
1029        let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1030            s.dcx().emit_fatal(err);
1031        });
1032        let interners = CtxtInterners::new(arena);
1033        let common_types = CommonTypes::new(&interners, s, &untracked);
1034        let common_lifetimes = CommonLifetimes::new(&interners);
1035        let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1036
1037        let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1038            sess: s,
1039            crate_types,
1040            stable_crate_id,
1041            arena,
1042            hir_arena,
1043            interners,
1044            dep_graph,
1045            hooks,
1046            prof: s.prof.clone(),
1047            types: common_types,
1048            lifetimes: common_lifetimes,
1049            consts: common_consts,
1050            untracked,
1051            query_system,
1052            dep_kind_vtables,
1053            ty_rcache: Default::default(),
1054            selection_cache: Default::default(),
1055            evaluation_cache: Default::default(),
1056            new_solver_evaluation_cache: Default::default(),
1057            new_solver_canonical_param_env_cache: Default::default(),
1058            canonical_param_env_cache: Default::default(),
1059            highest_var_in_clauses_cache: Default::default(),
1060            clauses_cache: Default::default(),
1061            data_layout,
1062            alloc_map: interpret::AllocMap::new(),
1063            current_gcx,
1064            jobserver_proxy,
1065        });
1066
1067        // This is a separate function to work around a crash with parallel rustc (#135870)
1068        gcx.enter(f)
1069    }
1070
1071    /// Obtain all lang items of this crate and all dependencies (recursively)
1072    pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1073        self.get_lang_items(())
1074    }
1075
1076    /// Gets a `Ty` representing the [`LangItem::OrderingEnum`]
1077    #[track_caller]
1078    pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1079        let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1080        self.type_of(ordering_enum).no_bound_vars().unwrap()
1081    }
1082
1083    /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
1084    /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
1085    pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1086        self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1087    }
1088
1089    /// Obtain the diagnostic item's name
1090    pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1091        self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1092    }
1093
1094    /// Check whether the diagnostic item with the given `name` has the given `DefId`.
1095    pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1096        self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1097    }
1098
1099    pub fn is_coroutine(self, def_id: DefId) -> bool {
1100        self.coroutine_kind(def_id).is_some()
1101    }
1102
1103    pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1104        self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1105    }
1106
1107    pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1108        if !self.is_type_const(def_id) {
1109            return None;
1110        }
1111        Some(self.def_span(def_id))
1112    }
1113
1114    /// Check if the given `def_id` is a `type const` (mgca)
1115    pub fn is_type_const<I: Copy + IntoQueryParam<DefId>>(self, def_id: I) -> bool {
1116        // No need to call the query directly in this case always false.
1117        let def_kind = self.def_kind(def_id.into_query_param());
1118        match def_kind {
1119            DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1120                is_type_const
1121            }
1122            _ => false,
1123        }
1124    }
1125
1126    /// Returns the movability of the coroutine of `def_id`, or panics
1127    /// if given a `def_id` that is not a coroutine.
1128    pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1129        self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1130    }
1131
1132    /// Returns `true` if the node pointed to by `def_id` is a coroutine for an async construct.
1133    pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1134        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
        true,
    _ => false,
}matches!(
1135            self.coroutine_kind(def_id),
1136            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1137        )
1138    }
1139
1140    // Whether the body owner is synthetic, which in this case means it does not correspond to
1141    // meaningful HIR. This is currently used to skip over MIR borrowck.
1142    pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1143        #[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)
1144    }
1145
1146    /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`.
1147    /// This means it is neither an `async` or `gen` construct.
1148    pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1149        #[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(_)))
1150    }
1151
1152    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `gen` construct.
1153    pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1154        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
        true,
    _ => false,
}matches!(
1155            self.coroutine_kind(def_id),
1156            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1157        )
1158    }
1159
1160    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `async gen` construct.
1161    pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1162        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
        => true,
    _ => false,
}matches!(
1163            self.coroutine_kind(def_id),
1164            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1165        )
1166    }
1167
1168    pub fn features(self) -> &'tcx rustc_feature::Features {
1169        self.features_query(())
1170    }
1171
1172    pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1173        let id = id.into_query_param();
1174        // Accessing the DefKey is ok, since it is part of DefPathHash.
1175        if let Some(id) = id.as_local() {
1176            self.definitions_untracked().def_key(id)
1177        } else {
1178            self.cstore_untracked().def_key(id)
1179        }
1180    }
1181
1182    /// Converts a `DefId` into its fully expanded `DefPath` (every
1183    /// `DefId` is really just an interned `DefPath`).
1184    ///
1185    /// Note that if `id` is not local to this crate, the result will
1186    ///  be a non-local `DefPath`.
1187    pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1188        // Accessing the DefPath is ok, since it is part of DefPathHash.
1189        if let Some(id) = id.as_local() {
1190            self.definitions_untracked().def_path(id)
1191        } else {
1192            self.cstore_untracked().def_path(id)
1193        }
1194    }
1195
1196    #[inline]
1197    pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1198        // Accessing the DefPathHash is ok, it is incr. comp. stable.
1199        if let Some(def_id) = def_id.as_local() {
1200            self.definitions_untracked().def_path_hash(def_id)
1201        } else {
1202            self.cstore_untracked().def_path_hash(def_id)
1203        }
1204    }
1205
1206    #[inline]
1207    pub fn crate_types(self) -> &'tcx [CrateType] {
1208        &self.crate_types
1209    }
1210
1211    pub fn needs_metadata(self) -> bool {
1212        self.crate_types().iter().any(|ty| match *ty {
1213            CrateType::Executable
1214            | CrateType::StaticLib
1215            | CrateType::Cdylib
1216            | CrateType::Sdylib => false,
1217            CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1218        })
1219    }
1220
1221    pub fn needs_crate_hash(self) -> bool {
1222        // Why is the crate hash needed for these configurations?
1223        // - debug_assertions: for the "fingerprint the result" check in
1224        //   `rustc_query_impl::execution::execute_job`.
1225        // - incremental: for query lookups.
1226        // - needs_metadata: for putting into crate metadata.
1227        // - instrument_coverage: for putting into coverage data (see
1228        //   `hash_mir_source`).
1229        // - metrics_dir: metrics use the strict version hash in the filenames
1230        //   for dumped metrics files to prevent overwriting distinct metrics
1231        //   for similar source builds (may change in the future, this is part
1232        //   of the proof of concept impl for the metrics initiative project goal)
1233        truecfg!(debug_assertions)
1234            || self.sess.opts.incremental.is_some()
1235            || self.needs_metadata()
1236            || self.sess.instrument_coverage()
1237            || self.sess.opts.unstable_opts.metrics_dir.is_some()
1238    }
1239
1240    #[inline]
1241    pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1242        if crate_num == LOCAL_CRATE {
1243            self.stable_crate_id
1244        } else {
1245            self.cstore_untracked().stable_crate_id(crate_num)
1246        }
1247    }
1248
1249    /// Maps a StableCrateId to the corresponding CrateNum. This method assumes
1250    /// that the crate in question has already been loaded by the CrateStore.
1251    #[inline]
1252    pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1253        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1254            LOCAL_CRATE
1255        } else {
1256            *self
1257                .untracked()
1258                .stable_crate_ids
1259                .read()
1260                .get(&stable_crate_id)
1261                .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
        stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1262        }
1263    }
1264
1265    /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
1266    /// session, if it still exists. This is used during incremental compilation to
1267    /// turn a deserialized `DefPathHash` into its current `DefId`.
1268    pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1269        {
    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:1269",
                        "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(1269u32),
                        ::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);
1270
1271        let stable_crate_id = hash.stable_crate_id();
1272
1273        // If this is a DefPathHash from the local crate, we can look up the
1274        // DefId in the tcx's `Definitions`.
1275        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1276            Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1277        } else {
1278            self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1279        }
1280    }
1281
1282    pub fn def_path_debug_str(self, def_id: DefId) -> String {
1283        // We are explicitly not going through queries here in order to get
1284        // crate name and stable crate id since this code is called from debug!()
1285        // statements within the query system and we'd run into endless
1286        // recursion otherwise.
1287        let (crate_name, stable_crate_id) = if def_id.is_local() {
1288            (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1289        } else {
1290            let cstore = &*self.cstore_untracked();
1291            (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1292        };
1293
1294        ::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!(
1295            "{}[{:04x}]{}",
1296            crate_name,
1297            // Don't print the whole stable crate id. That's just
1298            // annoying in debug output.
1299            stable_crate_id.as_u64() >> (8 * 6),
1300            self.def_path(def_id).to_string_no_crate_verbose()
1301        )
1302    }
1303
1304    pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1305        self.sess.dcx()
1306    }
1307
1308    /// Checks to see if the caller (`body_features`) has all the features required by the callee
1309    /// (`callee_features`).
1310    pub fn is_target_feature_call_safe(
1311        self,
1312        callee_features: &[TargetFeature],
1313        body_features: &[TargetFeature],
1314    ) -> bool {
1315        // If the called function has target features the calling function hasn't,
1316        // the call requires `unsafe`. Don't check this on wasm
1317        // targets, though. For more information on wasm see the
1318        // is_like_wasm check in hir_analysis/src/collect.rs
1319        self.sess.target.options.is_like_wasm
1320            || callee_features
1321                .iter()
1322                .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1323    }
1324
1325    /// Returns the safe version of the signature of the given function, if calling it
1326    /// would be safe in the context of the given caller.
1327    pub fn adjust_target_feature_sig(
1328        self,
1329        fun_def: DefId,
1330        fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1331        caller: DefId,
1332    ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1333        let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1334        let caller_features = &self.body_codegen_attrs(caller).target_features;
1335        if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1336            return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
1337        }
1338        None
1339    }
1340
1341    /// Helper to get a tracked environment variable via. [`TyCtxt::env_var_os`] and converting to
1342    /// UTF-8 like [`std::env::var`].
1343    pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1344        match self.env_var_os(key.as_ref()) {
1345            Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1346            None => Err(VarError::NotPresent),
1347        }
1348    }
1349}
1350
1351impl<'tcx> TyCtxtAt<'tcx> {
1352    /// Create a new definition within the incr. comp. engine.
1353    pub fn create_def(
1354        self,
1355        parent: LocalDefId,
1356        name: Option<Symbol>,
1357        def_kind: DefKind,
1358        override_def_path_data: Option<DefPathData>,
1359        disambiguator: &mut DisambiguatorState,
1360    ) -> TyCtxtFeed<'tcx, LocalDefId> {
1361        let feed =
1362            self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1363
1364        feed.def_span(self.span);
1365        feed
1366    }
1367}
1368
1369impl<'tcx> TyCtxt<'tcx> {
1370    /// `tcx`-dependent operations performed for every created definition.
1371    pub fn create_def(
1372        self,
1373        parent: LocalDefId,
1374        name: Option<Symbol>,
1375        def_kind: DefKind,
1376        override_def_path_data: Option<DefPathData>,
1377        disambiguator: &mut DisambiguatorState,
1378    ) -> TyCtxtFeed<'tcx, LocalDefId> {
1379        let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1380        // The following call has the side effect of modifying the tables inside `definitions`.
1381        // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1382        // decode the on-disk cache.
1383        //
1384        // Any LocalDefId which is used within queries, either as key or result, either:
1385        // - has been created before the construction of the TyCtxt;
1386        // - has been created by this call to `create_def`.
1387        // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1388        // comp. engine itself.
1389        let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1390
1391        // This function modifies `self.definitions` using a side-effect.
1392        // We need to ensure that these side effects are re-run by the incr. comp. engine.
1393        // Depending on the forever-red node will tell the graph that the calling query
1394        // needs to be re-evaluated.
1395        self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1396
1397        let feed = TyCtxtFeed { tcx: self, key: def_id };
1398        feed.def_kind(def_kind);
1399        // Unique types created for closures participate in type privacy checking.
1400        // They have visibilities inherited from the module they are defined in.
1401        // Visibilities for opaque types are meaningless, but still provided
1402        // so that all items have visibilities.
1403        if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
    DefKind::Closure | DefKind::OpaqueTy => true,
    _ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1404            let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1405            feed.visibility(ty::Visibility::Restricted(parent_mod));
1406        }
1407
1408        feed
1409    }
1410
1411    pub fn create_crate_num(
1412        self,
1413        stable_crate_id: StableCrateId,
1414    ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1415        if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
1416            return Err(existing);
1417        }
1418
1419        let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
1420        self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
1421        Ok(TyCtxtFeed { key: num, tcx: self })
1422    }
1423
1424    pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1425        // Depend on the `analysis` query to ensure compilation if finished.
1426        self.ensure_ok().analysis(());
1427
1428        let definitions = &self.untracked.definitions;
1429        gen {
1430            let mut i = 0;
1431
1432            // Recompute the number of definitions each time, because our caller may be creating
1433            // new ones.
1434            while i < { definitions.read().num_definitions() } {
1435                let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1436                yield LocalDefId { local_def_index };
1437                i += 1;
1438            }
1439
1440            // Freeze definitions once we finish iterating on them, to prevent adding new ones.
1441            definitions.freeze();
1442        }
1443    }
1444
1445    pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1446        // Depend on the `analysis` query to ensure compilation if finished.
1447        self.ensure_ok().analysis(());
1448
1449        // Freeze definitions once we start iterating on them, to prevent adding new ones
1450        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1451        self.untracked.definitions.freeze().def_path_table()
1452    }
1453
1454    pub fn def_path_hash_to_def_index_map(
1455        self,
1456    ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1457        // Create a dependency to the crate to be sure we re-execute this when the amount of
1458        // definitions change.
1459        self.ensure_ok().hir_crate_items(());
1460        // Freeze definitions once we start iterating on them, to prevent adding new ones
1461        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1462        self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1463    }
1464
1465    /// Note that this is *untracked* and should only be used within the query
1466    /// system if the result is otherwise tracked through queries
1467    #[inline]
1468    pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1469        FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1470    }
1471
1472    /// Give out access to the untracked data without any sanity checks.
1473    pub fn untracked(self) -> &'tcx Untracked {
1474        &self.untracked
1475    }
1476    /// Note that this is *untracked* and should only be used within the query
1477    /// system if the result is otherwise tracked through queries
1478    #[inline]
1479    pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1480        self.untracked.definitions.read()
1481    }
1482
1483    /// Note that this is *untracked* and should only be used within the query
1484    /// system if the result is otherwise tracked through queries
1485    #[inline]
1486    pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1487        self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1488    }
1489
1490    #[inline(always)]
1491    pub fn with_stable_hashing_context<R>(
1492        self,
1493        f: impl FnOnce(StableHashingContext<'_>) -> R,
1494    ) -> R {
1495        f(StableHashingContext::new(self.sess, &self.untracked))
1496    }
1497
1498    #[inline]
1499    pub fn local_crate_exports_generics(self) -> bool {
1500        // compiler-builtins has some special treatment in codegen, which can result in confusing
1501        // behavior if another crate ends up calling into its monomorphizations.
1502        // https://github.com/rust-lang/rust/issues/150173
1503        if self.is_compiler_builtins(LOCAL_CRATE) {
1504            return false;
1505        }
1506        self.crate_types().iter().any(|crate_type| {
1507            match crate_type {
1508                CrateType::Executable
1509                | CrateType::StaticLib
1510                | CrateType::ProcMacro
1511                | CrateType::Cdylib
1512                | CrateType::Sdylib => false,
1513
1514                // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
1515                // We want to block export of generics from dylibs,
1516                // but we must fix rust-lang/rust#65890 before we can
1517                // do that robustly.
1518                CrateType::Dylib => true,
1519
1520                CrateType::Rlib => true,
1521            }
1522        })
1523    }
1524
1525    /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
1526    pub fn is_suitable_region(
1527        self,
1528        generic_param_scope: LocalDefId,
1529        mut region: Region<'tcx>,
1530    ) -> Option<FreeRegionInfo> {
1531        let (suitable_region_binding_scope, region_def_id) = loop {
1532            let def_id =
1533                region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1534            let scope = self.local_parent(def_id);
1535            if self.def_kind(scope) == DefKind::OpaqueTy {
1536                // Lifetime params of opaque types are synthetic and thus irrelevant to
1537                // diagnostics. Map them back to their origin!
1538                region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1539                continue;
1540            }
1541            break (scope, def_id.into());
1542        };
1543
1544        let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1545            Node::Item(..) | Node::TraitItem(..) => false,
1546            Node::ImplItem(impl_item) => match impl_item.impl_kind {
1547                // For now, we do not try to target impls of traits. This is
1548                // because this message is going to suggest that the user
1549                // change the fn signature, but they may not be free to do so,
1550                // since the signature must match the trait.
1551                //
1552                // FIXME(#42706) -- in some cases, we could do better here.
1553                hir::ImplItemImplKind::Trait { .. } => true,
1554                _ => false,
1555            },
1556            _ => false,
1557        };
1558
1559        Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1560    }
1561
1562    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
1563    pub fn return_type_impl_or_dyn_traits(
1564        self,
1565        scope_def_id: LocalDefId,
1566    ) -> Vec<&'tcx hir::Ty<'tcx>> {
1567        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1568        let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1569            self.hir_fn_decl_by_hir_id(hir_id)
1570        else {
1571            return ::alloc::vec::Vec::new()vec![];
1572        };
1573
1574        let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1575        v.visit_ty_unambig(hir_output);
1576        v.0
1577    }
1578
1579    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in
1580    /// its return type, and the associated alias span when type alias is used,
1581    /// along with a span for lifetime suggestion (if there are existing generics).
1582    pub fn return_type_impl_or_dyn_traits_with_type_alias(
1583        self,
1584        scope_def_id: LocalDefId,
1585    ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1586        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1587        let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1588        // when the return type is a type alias
1589        if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1590            && let hir::TyKind::Path(hir::QPath::Resolved(
1591                None,
1592                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1593            && let Some(local_id) = def_id.as_local()
1594            && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias
1595            && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
1596        {
1597            v.visit_ty_unambig(alias_ty);
1598            if !v.0.is_empty() {
1599                return Some((
1600                    v.0,
1601                    alias_generics.span,
1602                    alias_generics.span_for_lifetime_suggestion(),
1603                ));
1604            }
1605        }
1606        None
1607    }
1608
1609    /// Determines whether identifiers in the assembly have strict naming rules.
1610    /// Currently, only NVPTX* targets need it.
1611    pub fn has_strict_asm_symbol_naming(self) -> bool {
1612        self.sess.target.llvm_target.starts_with("nvptx")
1613    }
1614
1615    /// Returns `&'static core::panic::Location<'static>`.
1616    pub fn caller_location_ty(self) -> Ty<'tcx> {
1617        Ty::new_imm_ref(
1618            self,
1619            self.lifetimes.re_static,
1620            self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1621                .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
1622        )
1623    }
1624
1625    /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
1626    pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1627        let kind = self.def_kind(def_id);
1628        (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1629    }
1630
1631    pub fn type_length_limit(self) -> Limit {
1632        self.limits(()).type_length_limit
1633    }
1634
1635    pub fn recursion_limit(self) -> Limit {
1636        self.limits(()).recursion_limit
1637    }
1638
1639    pub fn move_size_limit(self) -> Limit {
1640        self.limits(()).move_size_limit
1641    }
1642
1643    pub fn pattern_complexity_limit(self) -> Limit {
1644        self.limits(()).pattern_complexity_limit
1645    }
1646
1647    /// All traits in the crate graph, including those not visible to the user.
1648    pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1649        iter::once(LOCAL_CRATE)
1650            .chain(self.crates(()).iter().copied())
1651            .flat_map(move |cnum| self.traits(cnum).iter().copied())
1652    }
1653
1654    /// All traits that are visible within the crate graph (i.e. excluding private dependencies).
1655    pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1656        let visible_crates =
1657            self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1658
1659        iter::once(LOCAL_CRATE)
1660            .chain(visible_crates)
1661            .flat_map(move |cnum| self.traits(cnum).iter().copied())
1662    }
1663
1664    #[inline]
1665    pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1666        self.visibility(def_id).expect_local()
1667    }
1668
1669    /// Returns the origin of the opaque type `def_id`.
1670    x;#[instrument(skip(self), level = "trace", ret)]
1671    pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1672        self.hir_expect_opaque_ty(def_id).origin
1673    }
1674
1675    pub fn finish(self) {
1676        // We assume that no queries are run past here. If there are new queries
1677        // after this point, they'll show up as "<unknown>" in self-profiling data.
1678        self.alloc_self_profile_query_strings();
1679
1680        self.save_dep_graph();
1681        self.query_key_hash_verify_all();
1682
1683        if let Err((path, error)) = self.dep_graph.finish_encoding() {
1684            self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
1685        }
1686    }
1687
1688    pub fn report_unused_features(self) {
1689        #[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for UnusedFeature
            where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnusedFeature { feature: __binding_0 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("feature `{$feature}` is declared but not used")));
                        ;
                        diag.arg("feature", __binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
1690        #[diag("feature `{$feature}` is declared but not used")]
1691        struct UnusedFeature {
1692            feature: Symbol,
1693        }
1694
1695        // Collect first to avoid holding the lock while linting.
1696        let used_features = self.sess.used_features.lock();
1697        let unused_features = self
1698            .features()
1699            .enabled_features_iter_stable_order()
1700            .filter(|(f, _)| {
1701                !used_features.contains_key(f)
1702                // FIXME: `restricted_std` is used to tell a standard library built
1703                // for a platform that it doesn't know how to support. But it
1704                // could only gate a private mod (see `__restricted_std_workaround`)
1705                // with `cfg(not(restricted_std))`, so it cannot be recorded as used
1706                // in downstream crates. It should never be linted, but should we
1707                // hack this in the linter to ignore it?
1708                && f.as_str() != "restricted_std"
1709            })
1710            .collect::<Vec<_>>();
1711
1712        for (feature, span) in unused_features {
1713            self.emit_node_span_lint(
1714                rustc_session::lint::builtin::UNUSED_FEATURES,
1715                CRATE_HIR_ID,
1716                span,
1717                UnusedFeature { feature },
1718            );
1719        }
1720    }
1721}
1722
1723macro_rules! nop_lift {
1724    ($set:ident; $ty:ty => $lifted:ty) => {
1725        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1726            type Lifted = $lifted;
1727            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1728                // Assert that the set has the right type.
1729                // Given an argument that has an interned type, the return type has the type of
1730                // the corresponding interner set. This won't actually return anything, we're
1731                // just doing this to compute said type!
1732                fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1733                    _x: Interned<'tcx, Inner>,
1734                ) -> InternedSet<'tcx, Inner> {
1735                    unreachable!()
1736                }
1737                fn _type_eq<T>(_x: &T, _y: &T) {}
1738                fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1739                    // If `x` is a newtype around an `Interned<T>`, then `interner` is an
1740                    // interner of appropriate type. (Ideally we'd also check that `x` is a
1741                    // newtype with just that one field. Not sure how to do that.)
1742                    let interner = _intern_set_ty_from_interned_ty(x.0);
1743                    // Now check that this is the same type as `interners.$set`.
1744                    _type_eq(&interner, &tcx.interners.$set);
1745                }
1746
1747                tcx.interners
1748                    .$set
1749                    .contains_pointer_to(&InternedInSet(&*self.0.0))
1750                    // SAFETY: `self` is interned and therefore valid
1751                    // for the entire lifetime of the `TyCtxt`.
1752                    .then(|| unsafe { mem::transmute(self) })
1753            }
1754        }
1755    };
1756}
1757
1758macro_rules! nop_list_lift {
1759    ($set:ident; $ty:ty => $lifted:ty) => {
1760        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
1761            type Lifted = &'tcx List<$lifted>;
1762            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1763                // Assert that the set has the right type.
1764                if false {
1765                    let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
1766                }
1767
1768                if self.is_empty() {
1769                    return Some(List::empty());
1770                }
1771                tcx.interners
1772                    .$set
1773                    .contains_pointer_to(&InternedInSet(self))
1774                    .then(|| unsafe { mem::transmute(self) })
1775            }
1776        }
1777    };
1778}
1779
1780impl<'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> }
1781impl<'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> }
1782impl<'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> }
1783impl<'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> }
1784impl<'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> }
1785impl<'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> }
1786impl<'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> }
1787impl<'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> }
1788impl<'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> }
1789
1790impl<'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> }
1791impl<'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! {
1792    poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1793}
1794impl<'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> }
1795
1796// This is the impl for `&'a GenericArgs<'a>`.
1797impl<'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> }
1798
1799macro_rules! sty_debug_print {
1800    ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1801        // Curious inner module to allow variant names to be used as
1802        // variable names.
1803        #[allow(non_snake_case)]
1804        mod inner {
1805            use crate::ty::{self, TyCtxt};
1806            use crate::ty::context::InternedInSet;
1807
1808            #[derive(Copy, Clone)]
1809            struct DebugStat {
1810                total: usize,
1811                lt_infer: usize,
1812                ty_infer: usize,
1813                ct_infer: usize,
1814                all_infer: usize,
1815            }
1816
1817            pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1818                let mut total = DebugStat {
1819                    total: 0,
1820                    lt_infer: 0,
1821                    ty_infer: 0,
1822                    ct_infer: 0,
1823                    all_infer: 0,
1824                };
1825                $(let mut $variant = total;)*
1826
1827                for shard in tcx.interners.type_.lock_shards() {
1828                    // It seems that ordering doesn't affect anything here.
1829                    #[allow(rustc::potential_query_instability)]
1830                    let types = shard.iter();
1831                    for &(InternedInSet(t), ()) in types {
1832                        let variant = match t.internee {
1833                            ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1834                                ty::Float(..) | ty::Str | ty::Never => continue,
1835                            ty::Error(_) => /* unimportant */ continue,
1836                            $(ty::$variant(..) => &mut $variant,)*
1837                        };
1838                        let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1839                        let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1840                        let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1841
1842                        variant.total += 1;
1843                        total.total += 1;
1844                        if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1845                        if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1846                        if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1847                        if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1848                    }
1849                }
1850                writeln!(fmt, "Ty interner             total           ty lt ct all")?;
1851                $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
1852                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1853                    stringify!($variant),
1854                    uses = $variant.total,
1855                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
1856                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
1857                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
1858                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
1859                    all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
1860                )*
1861                writeln!(fmt, "                  total {uses:6}        \
1862                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1863                    uses = total.total,
1864                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
1865                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
1866                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
1867                    all = total.all_infer as f64 * 100.0  / total.total as f64)
1868            }
1869        }
1870
1871        inner::go($fmt, $ctxt)
1872    }}
1873}
1874
1875impl<'tcx> TyCtxt<'tcx> {
1876    pub fn debug_stats(self) -> impl fmt::Debug {
1877        fmt::from_fn(move |fmt| {
1878            {
    #[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!(
1879                fmt,
1880                self,
1881                Adt,
1882                Array,
1883                Slice,
1884                RawPtr,
1885                Ref,
1886                FnDef,
1887                FnPtr,
1888                UnsafeBinder,
1889                Placeholder,
1890                Coroutine,
1891                CoroutineWitness,
1892                Dynamic,
1893                Closure,
1894                CoroutineClosure,
1895                Tuple,
1896                Bound,
1897                Param,
1898                Infer,
1899                Alias,
1900                Pat,
1901                Foreign
1902            )?;
1903
1904            fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
        self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1905            fmt.write_fmt(format_args!("Region interner: #{0}\n",
        self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1906            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())?;
1907            fmt.write_fmt(format_args!("Layout interner: #{0}\n",
        self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1908
1909            Ok(())
1910        })
1911    }
1912}
1913
1914// This type holds a `T` in the interner. The `T` is stored in the arena and
1915// this type just holds a pointer to it, but it still effectively owns it. It
1916// impls `Borrow` so that it can be looked up using the original
1917// (non-arena-memory-owning) types.
1918struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1919
1920impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1921    fn clone(&self) -> Self {
1922        *self
1923    }
1924}
1925
1926impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1927
1928impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1929    fn into_pointer(&self) -> *const () {
1930        self.0 as *const _ as *const ()
1931    }
1932}
1933
1934#[allow(rustc::usage_of_ty_tykind)]
1935impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1936    fn borrow(&self) -> &T {
1937        &self.0.internee
1938    }
1939}
1940
1941impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1942    fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1943        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1944        // `x == y`.
1945        self.0.internee == other.0.internee
1946    }
1947}
1948
1949impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1950
1951impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1952    fn hash<H: Hasher>(&self, s: &mut H) {
1953        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1954        self.0.internee.hash(s)
1955    }
1956}
1957
1958impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1959    fn borrow(&self) -> &[T] {
1960        &self.0[..]
1961    }
1962}
1963
1964impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1965    fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1966        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1967        // `x == y`.
1968        self.0[..] == other.0[..]
1969    }
1970}
1971
1972impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1973
1974impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1975    fn hash<H: Hasher>(&self, s: &mut H) {
1976        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1977        self.0[..].hash(s)
1978    }
1979}
1980
1981impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1982    fn borrow(&self) -> &[T] {
1983        &self.0[..]
1984    }
1985}
1986
1987impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1988    fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1989        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1990        // `x == y`.
1991        self.0[..] == other.0[..]
1992    }
1993}
1994
1995impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1996
1997impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1998    fn hash<H: Hasher>(&self, s: &mut H) {
1999        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2000        self.0[..].hash(s)
2001    }
2002}
2003
2004macro_rules! direct_interners {
2005    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2006        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2007            fn borrow<'a>(&'a self) -> &'a $ty {
2008                &self.0
2009            }
2010        }
2011
2012        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2013            fn eq(&self, other: &Self) -> bool {
2014                // The `Borrow` trait requires that `x.borrow() == y.borrow()`
2015                // equals `x == y`.
2016                self.0 == other.0
2017            }
2018        }
2019
2020        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2021
2022        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2023            fn hash<H: Hasher>(&self, s: &mut H) {
2024                // The `Borrow` trait requires that `x.borrow().hash(s) ==
2025                // x.hash(s)`.
2026                self.0.hash(s)
2027            }
2028        }
2029
2030        impl<'tcx> TyCtxt<'tcx> {
2031            $vis fn $method(self, v: $ty) -> $ret_ty {
2032                $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2033                    InternedInSet(self.interners.arena.alloc(v))
2034                }).0))
2035            }
2036        })+
2037    }
2038}
2039
2040// Functions with a `mk_` prefix are intended for use outside this file and
2041// crate. Functions with an `intern_` prefix are intended for use within this
2042// crate only, and have a corresponding `mk_` function.
2043impl<'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! {
2044    region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2045    valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2046    pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2047    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2048    layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2049    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2050    external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2051        ExternalConstraints -> ExternalConstraints<'tcx>,
2052}
2053
2054macro_rules! slice_interners {
2055    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2056        impl<'tcx> TyCtxt<'tcx> {
2057            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2058                if v.is_empty() {
2059                    List::empty()
2060                } else {
2061                    self.interners.$field.intern_ref(v, || {
2062                        InternedInSet(List::from_arena(&*self.arena, (), v))
2063                    }).0
2064                }
2065            })+
2066        }
2067    );
2068}
2069
2070// These functions intern slices. They all have a corresponding
2071// `mk_foo_from_iter` function that interns an iterator. The slice version
2072// should be used when possible, because it's faster.
2073impl<'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!(
2074    const_lists: pub mk_const_list(Const<'tcx>),
2075    args: pub mk_args(GenericArg<'tcx>),
2076    type_lists: pub mk_type_list(Ty<'tcx>),
2077    canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2078    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2079    projs: pub mk_projs(ProjectionKind),
2080    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2081    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2082    fields: pub mk_fields(FieldIdx),
2083    local_def_ids: intern_local_def_ids(LocalDefId),
2084    captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2085    patterns: pub mk_patterns(Pattern<'tcx>),
2086    outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2087    predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2088);
2089
2090impl<'tcx> TyCtxt<'tcx> {
2091    /// Given a `fn` sig, returns an equivalent `unsafe fn` type;
2092    /// that is, a `fn` type that is equivalent in every way for being
2093    /// unsafe.
2094    pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2095        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2096        Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2097    }
2098
2099    /// Given a `fn` sig, returns an equivalent `unsafe fn` sig;
2100    /// that is, a `fn` sig that is equivalent in every way for being
2101    /// unsafe.
2102    pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2103        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2104        sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig })
2105    }
2106
2107    /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
2108    /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
2109    pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2110        elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2111            self.associated_items(trait_did)
2112                .filter_by_name_unhygienic(assoc_name.name)
2113                .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2114        })
2115    }
2116
2117    /// Given a `ty`, return whether it's an `impl Future<...>`.
2118    pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2119        let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *ty.kind() else { return false };
2120        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2121
2122        self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2123            let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2124                return false;
2125            };
2126            trait_predicate.trait_ref.def_id == future_trait
2127                && trait_predicate.polarity == PredicatePolarity::Positive
2128        })
2129    }
2130
2131    /// Given a closure signature, returns an equivalent fn signature. Detuples
2132    /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
2133    /// you would get a `fn(u32, i32)`.
2134    /// `unsafety` determines the unsafety of the fn signature. If you pass
2135    /// `hir::Safety::Unsafe` in the previous example, then you would get
2136    /// an `unsafe fn (u32, i32)`.
2137    /// It cannot convert a closure that requires unsafe.
2138    pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2139        sig.map_bound(|s| {
2140            let params = match s.inputs()[0].kind() {
2141                ty::Tuple(params) => *params,
2142                _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2143            };
2144            self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2145        })
2146    }
2147
2148    #[inline]
2149    pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2150        self.interners.intern_predicate(
2151            binder,
2152            self.sess,
2153            // This is only used to create a stable hashing context.
2154            &self.untracked,
2155        )
2156    }
2157
2158    #[inline]
2159    pub fn reuse_or_mk_predicate(
2160        self,
2161        pred: Predicate<'tcx>,
2162        binder: Binder<'tcx, PredicateKind<'tcx>>,
2163    ) -> Predicate<'tcx> {
2164        if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2165    }
2166
2167    pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2168        self.check_args_compatible_inner(def_id, args, false)
2169    }
2170
2171    fn check_args_compatible_inner(
2172        self,
2173        def_id: DefId,
2174        args: &'tcx [ty::GenericArg<'tcx>],
2175        nested: bool,
2176    ) -> bool {
2177        let generics = self.generics_of(def_id);
2178
2179        // IATs and IACs (inherent associated types/consts with `type const`) themselves have a
2180        // weird arg setup (self + own args), but nested items *in* IATs (namely: opaques, i.e.
2181        // ATPITs) do not.
2182        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)
2183            && #[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 });
2184        let is_inherent_assoc_type_const =
2185            #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
    DefKind::AssocConst { is_type_const: true } => true,
    _ => false,
}matches!(self.def_kind(def_id), DefKind::AssocConst { is_type_const: true })
2186                && #[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 });
2187        let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2188            if generics.own_params.len() + 1 != args.len() {
2189                return false;
2190            }
2191
2192            if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
    ty::GenericArgKind::Type(_) => true,
    _ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2193                return false;
2194            }
2195
2196            &args[1..]
2197        } else {
2198            if generics.count() != args.len() {
2199                return false;
2200            }
2201
2202            let (parent_args, own_args) = args.split_at(generics.parent_count);
2203
2204            if let Some(parent) = generics.parent
2205                && !self.check_args_compatible_inner(parent, parent_args, true)
2206            {
2207                return false;
2208            }
2209
2210            own_args
2211        };
2212
2213        for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2214            match (&param.kind, arg.kind()) {
2215                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2216                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2217                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2218                _ => return false,
2219            }
2220        }
2221
2222        true
2223    }
2224
2225    /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
2226    /// and print out the args if not.
2227    pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2228        if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2229            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)
2230                && #[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 });
2231            let is_inherent_assoc_type_const =
2232                #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
    DefKind::AssocConst { is_type_const: true } => true,
    _ => false,
}matches!(self.def_kind(def_id), DefKind::AssocConst { is_type_const: true })
2233                    && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
    {
    DefKind::Impl { of_trait: false } => true,
    _ => false,
}matches!(
2234                        self.def_kind(self.parent(def_id)),
2235                        DefKind::Impl { of_trait: false }
2236                    );
2237            if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2238                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!(
2239                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2240                    self.def_path_str(def_id),
2241                    args,
2242                    // Make `[Self, GAT_ARGS...]` (this could be simplified)
2243                    self.mk_args_from_iter(
2244                        [self.types.self_param.into()].into_iter().chain(
2245                            self.generics_of(def_id)
2246                                .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2247                                .iter()
2248                                .copied()
2249                        )
2250                    )
2251                );
2252            } else {
2253                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!(
2254                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2255                    self.def_path_str(def_id),
2256                    args,
2257                    ty::GenericArgs::identity_for_item(self, def_id)
2258                );
2259            }
2260        }
2261    }
2262
2263    #[inline(always)]
2264    pub(crate) fn check_and_mk_args(
2265        self,
2266        def_id: DefId,
2267        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2268    ) -> GenericArgsRef<'tcx> {
2269        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2270        self.debug_assert_args_compatible(def_id, args);
2271        args
2272    }
2273
2274    #[inline]
2275    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2276        self.interners.intern_const(
2277            kind,
2278            self.sess,
2279            // This is only used to create a stable hashing context.
2280            &self.untracked,
2281        )
2282    }
2283
2284    // Avoid this in favour of more specific `Ty::new_*` methods, where possible.
2285    #[allow(rustc::usage_of_ty_tykind)]
2286    #[inline]
2287    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2288        self.interners.intern_ty(
2289            st,
2290            self.sess,
2291            // This is only used to create a stable hashing context.
2292            &self.untracked,
2293        )
2294    }
2295
2296    pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2297        match param.kind {
2298            GenericParamDefKind::Lifetime => {
2299                ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2300            }
2301            GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2302            GenericParamDefKind::Const { .. } => {
2303                ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2304                    .into()
2305            }
2306        }
2307    }
2308
2309    pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2310        self.mk_place_elem(place, PlaceElem::Field(f, ty))
2311    }
2312
2313    pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2314        self.mk_place_elem(place, PlaceElem::Deref)
2315    }
2316
2317    pub fn mk_place_downcast(
2318        self,
2319        place: Place<'tcx>,
2320        adt_def: AdtDef<'tcx>,
2321        variant_index: VariantIdx,
2322    ) -> Place<'tcx> {
2323        self.mk_place_elem(
2324            place,
2325            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2326        )
2327    }
2328
2329    pub fn mk_place_downcast_unnamed(
2330        self,
2331        place: Place<'tcx>,
2332        variant_index: VariantIdx,
2333    ) -> Place<'tcx> {
2334        self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2335    }
2336
2337    pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2338        self.mk_place_elem(place, PlaceElem::Index(index))
2339    }
2340
2341    /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2342    /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2343    /// flight.
2344    pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2345        let mut projection = place.projection.to_vec();
2346        projection.push(elem);
2347
2348        Place { local: place.local, projection: self.mk_place_elems(&projection) }
2349    }
2350
2351    pub fn mk_poly_existential_predicates(
2352        self,
2353        eps: &[PolyExistentialPredicate<'tcx>],
2354    ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2355        if !!eps.is_empty() {
    ::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2356        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!(
2357            eps.array_windows()
2358                .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2359                    != Ordering::Greater)
2360        );
2361        self.intern_poly_existential_predicates(eps)
2362    }
2363
2364    pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2365        // FIXME consider asking the input slice to be sorted to avoid
2366        // re-interning permutations, in which case that would be asserted
2367        // here.
2368        self.interners.intern_clauses(clauses)
2369    }
2370
2371    pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2372        // FIXME consider asking the input slice to be sorted to avoid
2373        // re-interning permutations, in which case that would be asserted
2374        // here.
2375        self.intern_local_def_ids(def_ids)
2376    }
2377
2378    pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2379    where
2380        I: Iterator<Item = T>,
2381        T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2382    {
2383        T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2384    }
2385
2386    pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2387    where
2388        I: Iterator<Item = T>,
2389        T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2390    {
2391        T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2392    }
2393
2394    pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2395    where
2396        I: Iterator<Item = T>,
2397        T: CollectAndApply<
2398                &'tcx ty::CapturedPlace<'tcx>,
2399                &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2400            >,
2401    {
2402        T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2403    }
2404
2405    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2406    where
2407        I: Iterator<Item = T>,
2408        T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2409    {
2410        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2411    }
2412
2413    // Unlike various other `mk_*_from_iter` functions, this one uses `I:
2414    // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
2415    // variant, because of the need to combine `inputs` and `output`. This
2416    // explains the lack of `_from_iter` suffix.
2417    pub fn mk_fn_sig<I, T>(
2418        self,
2419        inputs: I,
2420        output: I::Item,
2421        c_variadic: bool,
2422        safety: hir::Safety,
2423        abi: ExternAbi,
2424    ) -> T::Output
2425    where
2426        I: IntoIterator<Item = T>,
2427        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2428    {
2429        T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2430            inputs_and_output: self.mk_type_list(xs),
2431            c_variadic,
2432            safety,
2433            abi,
2434        })
2435    }
2436
2437    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2438    where
2439        I: Iterator<Item = T>,
2440        T: CollectAndApply<
2441                PolyExistentialPredicate<'tcx>,
2442                &'tcx List<PolyExistentialPredicate<'tcx>>,
2443            >,
2444    {
2445        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2446    }
2447
2448    pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2449    where
2450        I: Iterator<Item = T>,
2451        T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2452    {
2453        T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2454    }
2455
2456    pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2457    where
2458        I: Iterator<Item = T>,
2459        T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2460    {
2461        T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2462    }
2463
2464    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2465    where
2466        I: Iterator<Item = T>,
2467        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2468    {
2469        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2470    }
2471
2472    pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2473    where
2474        I: Iterator<Item = T>,
2475        T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2476    {
2477        T::collect_and_apply(iter, |xs| self.mk_args(xs))
2478    }
2479
2480    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2481    where
2482        I: Iterator<Item = T>,
2483        T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2484    {
2485        T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2486    }
2487
2488    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2489    where
2490        I: Iterator<Item = T>,
2491        T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2492    {
2493        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2494    }
2495
2496    pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2497    where
2498        I: Iterator<Item = T>,
2499        T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2500    {
2501        T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2502    }
2503
2504    pub fn mk_args_trait(
2505        self,
2506        self_ty: Ty<'tcx>,
2507        rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2508    ) -> GenericArgsRef<'tcx> {
2509        self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2510    }
2511
2512    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2513    where
2514        I: Iterator<Item = T>,
2515        T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2516    {
2517        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2518    }
2519
2520    pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2521    where
2522        I: Iterator<Item = T>,
2523        T: CollectAndApply<
2524                ty::ArgOutlivesPredicate<'tcx>,
2525                &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2526            >,
2527    {
2528        T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2529    }
2530
2531    /// Emit a lint at `span` from a lint struct (some type that implements `Diagnostic`,
2532    /// typically generated by `#[derive(Diagnostic)]`).
2533    #[track_caller]
2534    pub fn emit_node_span_lint(
2535        self,
2536        lint: &'static Lint,
2537        hir_id: HirId,
2538        span: impl Into<MultiSpan>,
2539        decorator: impl for<'a> Diagnostic<'a, ()>,
2540    ) {
2541        let level = self.lint_level_at_node(lint, hir_id);
2542        diag_lint_level(self.sess, lint, level, Some(span.into()), decorator)
2543    }
2544
2545    /// Emit a lint at the appropriate level for a hir node, with an associated span.
2546    ///
2547    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
2548    #[track_caller]
2549    pub fn node_span_lint(
2550        self,
2551        lint: &'static Lint,
2552        hir_id: HirId,
2553        span: impl Into<MultiSpan>,
2554        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
2555    ) {
2556        let level = self.lint_level_at_node(lint, hir_id);
2557        lint_level(self.sess, lint, level, Some(span.into()), decorate);
2558    }
2559
2560    /// Find the appropriate span where `use` and outer attributes can be inserted at.
2561    pub fn crate_level_attribute_injection_span(self) -> Span {
2562        let node = self.hir_node(hir::CRATE_HIR_ID);
2563        let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2564        m.spans.inject_use_span.shrink_to_lo()
2565    }
2566
2567    pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2568        self,
2569        diag: &mut Diag<'_, E>,
2570        features: impl IntoIterator<Item = (String, Symbol)>,
2571    ) {
2572        if !self.sess.is_nightly_build() {
2573            return;
2574        }
2575
2576        let span = self.crate_level_attribute_injection_span();
2577        for (desc, feature) in features {
2578            // FIXME: make this string translatable
2579            let msg =
2580                ::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}");
2581            diag.span_suggestion_verbose(
2582                span,
2583                msg,
2584                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
    })format!("#![feature({feature})]\n"),
2585                Applicability::MaybeIncorrect,
2586            );
2587        }
2588    }
2589
2590    /// Emit a lint from a lint struct (some type that implements `Diagnostic`, typically generated
2591    /// by `#[derive(Diagnostic)]`).
2592    #[track_caller]
2593    pub fn emit_node_lint(
2594        self,
2595        lint: &'static Lint,
2596        id: HirId,
2597        decorator: impl for<'a> Diagnostic<'a, ()>,
2598    ) {
2599        let level = self.lint_level_at_node(lint, id);
2600        diag_lint_level(self.sess, lint, level, None, decorator);
2601    }
2602
2603    /// Emit a lint at the appropriate level for a hir node.
2604    ///
2605    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
2606    #[track_caller]
2607    pub fn node_lint(
2608        self,
2609        lint: &'static Lint,
2610        id: HirId,
2611        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
2612    ) {
2613        let level = self.lint_level_at_node(lint, id);
2614        lint_level(self.sess, lint, level, None, decorate);
2615    }
2616
2617    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2618        let map = self.in_scope_traits_map(id.owner)?;
2619        let candidates = map.get(&id.local_id)?;
2620        Some(candidates)
2621    }
2622
2623    pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2624        {
    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:2624",
                        "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(2624u32),
                        ::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");
2625        self.named_variable_map(id.owner).get(&id.local_id).cloned()
2626    }
2627
2628    pub fn is_late_bound(self, id: HirId) -> bool {
2629        self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2630    }
2631
2632    pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2633        self.mk_bound_variable_kinds(
2634            &self
2635                .late_bound_vars_map(id.owner)
2636                .get(&id.local_id)
2637                .cloned()
2638                .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))),
2639        )
2640    }
2641
2642    /// Given the def-id of an early-bound lifetime on an opaque corresponding to
2643    /// a duplicated captured lifetime, map it back to the early- or late-bound
2644    /// lifetime of the function from which it originally as captured. If it is
2645    /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
2646    /// of the signature.
2647    // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
2648    // re-use the generics of the opaque, this function will need to be tweaked slightly.
2649    pub fn map_opaque_lifetime_to_parent_lifetime(
2650        self,
2651        mut opaque_lifetime_param_def_id: LocalDefId,
2652    ) -> ty::Region<'tcx> {
2653        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!(
2654            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2655            "{opaque_lifetime_param_def_id:?} is a {}",
2656            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2657        );
2658
2659        loop {
2660            let parent = self.local_parent(opaque_lifetime_param_def_id);
2661            let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2662
2663            let Some((lifetime, _)) = lifetime_mapping
2664                .iter()
2665                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2666            else {
2667                crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2668            };
2669
2670            match *lifetime {
2671                resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2672                    let new_parent = self.local_parent(ebv);
2673
2674                    // If we map to another opaque, then it should be a parent
2675                    // of the opaque we mapped from. Continue mapping.
2676                    if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
    DefKind::OpaqueTy => true,
    _ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2677                        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);
2678                        opaque_lifetime_param_def_id = ebv;
2679                        continue;
2680                    }
2681
2682                    let generics = self.generics_of(new_parent);
2683                    return ty::Region::new_early_param(
2684                        self,
2685                        ty::EarlyParamRegion {
2686                            index: generics
2687                                .param_def_id_to_index(self, ebv.to_def_id())
2688                                .expect("early-bound var should be present in fn generics"),
2689                            name: self.item_name(ebv.to_def_id()),
2690                        },
2691                    );
2692                }
2693                resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2694                    let new_parent = self.local_parent(lbv);
2695                    return ty::Region::new_late_param(
2696                        self,
2697                        new_parent.to_def_id(),
2698                        ty::LateParamRegionKind::Named(lbv.to_def_id()),
2699                    );
2700                }
2701                resolve_bound_vars::ResolvedArg::Error(guar) => {
2702                    return ty::Region::new_error(self, guar);
2703                }
2704                _ => {
2705                    return ty::Region::new_error_with_message(
2706                        self,
2707                        self.def_span(opaque_lifetime_param_def_id),
2708                        "cannot resolve lifetime",
2709                    );
2710                }
2711            }
2712        }
2713    }
2714
2715    /// Whether `def_id` is a stable const fn (i.e., doesn't need any feature gates to be called).
2716    ///
2717    /// When this is `false`, the function may still be callable as a `const fn` due to features
2718    /// being enabled!
2719    pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2720        self.is_const_fn(def_id)
2721            && match self.lookup_const_stability(def_id) {
2722                None => true, // a fn in a non-staged_api crate
2723                Some(stability) if stability.is_const_stable() => true,
2724                _ => false,
2725            }
2726    }
2727
2728    /// Whether the trait impl is marked const. This does not consider stability or feature gates.
2729    pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2730        self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2731            && self.impl_trait_header(def_id).constness == hir::Constness::Const
2732    }
2733
2734    pub fn is_sdylib_interface_build(self) -> bool {
2735        self.sess.opts.unstable_opts.build_sdylib_interface
2736    }
2737
2738    pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
2739        match self.def_kind(def_id) {
2740            DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2741            _ => None,
2742        }
2743    }
2744
2745    pub fn next_trait_solver_globally(self) -> bool {
2746        self.sess.opts.unstable_opts.next_solver.globally
2747    }
2748
2749    pub fn next_trait_solver_in_coherence(self) -> bool {
2750        self.sess.opts.unstable_opts.next_solver.coherence
2751    }
2752
2753    #[allow(rustc::bad_opt_access)]
2754    pub fn use_typing_mode_borrowck(self) -> bool {
2755        self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
2756    }
2757
2758    pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2759        self.opt_rpitit_info(def_id).is_some()
2760    }
2761
2762    /// Named module children from all kinds of items, including imports.
2763    /// In addition to regular items this list also includes struct and variant constructors, and
2764    /// items inside `extern {}` blocks because all of them introduce names into parent module.
2765    ///
2766    /// Module here is understood in name resolution sense - it can be a `mod` item,
2767    /// or a crate root, or an enum, or a trait.
2768    ///
2769    /// This is not a query, making it a query causes perf regressions
2770    /// (probably due to hashing spans in `ModChild`ren).
2771    pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2772        self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2773    }
2774
2775    /// Return the crate imported by given use item.
2776    pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2777        self.resolutions(()).extern_crate_map.get(&def_id).copied()
2778    }
2779
2780    pub fn resolver_for_lowering(
2781        self,
2782    ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc<ast::Crate>)> {
2783        self.resolver_for_lowering_raw(()).0
2784    }
2785
2786    pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2787        make_metadata(self)
2788    }
2789
2790    pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2791        if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2792            self.coroutine_kind(def_id)
2793            && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
2794            && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2795        {
2796            true
2797        } else {
2798            false
2799        }
2800    }
2801
2802    /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
2803    pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2804        {

        #[allow(deprecated)]
        {
            {
                'done:
                    {
                    for i in self.get_all_attrs(def_id) {
                        #[allow(unused_imports)]
                        use rustc_hir::attrs::AttributeKind::*;
                        let i: &rustc_hir::Attribute = i;
                        match i {
                            rustc_hir::Attribute::Parsed(DoNotRecommend { .. }) => {
                                break 'done Some(());
                            }
                            rustc_hir::Attribute::Unparsed(..) =>
                                {}
                                #[deny(unreachable_patterns)]
                                _ => {}
                        }
                    }
                    None
                }
            }
        }
    }.is_some()find_attr!(self, def_id, DoNotRecommend { .. })
2805    }
2806
2807    pub fn is_trivial_const<P>(self, def_id: P) -> bool
2808    where
2809        P: IntoQueryParam<DefId>,
2810    {
2811        self.trivial_const(def_id).is_some()
2812    }
2813
2814    /// Whether this def is one of the special bin crate entrypoint functions that must have a
2815    /// monomorphization and also not be internalized in the bin crate.
2816    pub fn is_entrypoint(self, def_id: DefId) -> bool {
2817        if self.is_lang_item(def_id, LangItem::Start) {
2818            return true;
2819        }
2820        if let Some((entry_def_id, _)) = self.entry_fn(())
2821            && entry_def_id == def_id
2822        {
2823            return true;
2824        }
2825        false
2826    }
2827}
2828
2829pub fn provide(providers: &mut Providers) {
2830    providers.is_panic_runtime = |tcx, LocalCrate| {
        'done:
            {
            for i in tcx.hir_krate_attrs() {
                #[allow(unused_imports)]
                use rustc_hir::attrs::AttributeKind::*;
                let i: &rustc_hir::Attribute = i;
                match i {
                    rustc_hir::Attribute::Parsed(PanicRuntime) => {
                        break 'done Some(());
                    }
                    rustc_hir::Attribute::Unparsed(..) =>
                        {}
                        #[deny(unreachable_patterns)]
                        _ => {}
                }
            }
            None
        }
    }.is_some()find_attr!(tcx, crate, PanicRuntime);
2831    providers.is_compiler_builtins = |tcx, LocalCrate| {
        'done:
            {
            for i in tcx.hir_krate_attrs() {
                #[allow(unused_imports)]
                use rustc_hir::attrs::AttributeKind::*;
                let i: &rustc_hir::Attribute = i;
                match i {
                    rustc_hir::Attribute::Parsed(CompilerBuiltins) => {
                        break 'done Some(());
                    }
                    rustc_hir::Attribute::Unparsed(..) =>
                        {}
                        #[deny(unreachable_patterns)]
                        _ => {}
                }
            }
            None
        }
    }.is_some()find_attr!(tcx, crate, CompilerBuiltins);
2832    providers.has_panic_handler = |tcx, LocalCrate| {
2833        // We want to check if the panic handler was defined in this crate
2834        tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2835    };
2836    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2837}