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