Skip to main content

rustc_middle/ty/
context.rs

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