Skip to main content

rustc_middle/ty/
context.rs

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

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

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

        #[allow(deprecated)]
        {
            {
                'done:
                    {
                    for i in self.get_all_attrs(def_id) {
                        #[allow(unused_imports)]
                        use rustc_hir::attrs::AttributeKind::*;
                        let i: &rustc_hir::Attribute = i;
                        match i {
                            rustc_hir::Attribute::Parsed(DoNotRecommend { .. }) => {
                                break 'done Some(());
                            }
                            rustc_hir::Attribute::Unparsed(..) =>
                                {}
                                #[deny(unreachable_patterns)]
                                _ => {}
                        }
                    }
                    None
                }
            }
        }
    }.is_some()find_attr!(self, def_id, DoNotRecommend { .. })
2770    }
2771
2772    pub fn is_trivial_const<P>(self, def_id: P) -> bool
2773    where
2774        P: IntoQueryParam<DefId>,
2775    {
2776        self.trivial_const(def_id).is_some()
2777    }
2778
2779    /// Whether this def is one of the special bin crate entrypoint functions that must have a
2780    /// monomorphization and also not be internalized in the bin crate.
2781    pub fn is_entrypoint(self, def_id: DefId) -> bool {
2782        if self.is_lang_item(def_id, LangItem::Start) {
2783            return true;
2784        }
2785        if let Some((entry_def_id, _)) = self.entry_fn(())
2786            && entry_def_id == def_id
2787        {
2788            return true;
2789        }
2790        false
2791    }
2792}
2793
2794pub fn provide(providers: &mut Providers) {
2795    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);
2796    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);
2797    providers.has_panic_handler = |tcx, LocalCrate| {
2798        // We want to check if the panic handler was defined in this crate
2799        tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2800    };
2801    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2802}