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::PointeeSized;
14use std::ops::Deref;
15use std::sync::{Arc, OnceLock};
16use std::{debug_assert_matches, fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_attr_ir::find_attr;
21use rustc_attr_ir::lang_items::LangItem;
22use rustc_crate_store::{CrateStoreDyn, Untracked};
23use rustc_data_structures::defer;
24use rustc_data_structures::fx::FxHashMap;
25use rustc_data_structures::intern::Interned;
26use rustc_data_structures::profiling::SelfProfilerRef;
27use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
28use rustc_data_structures::stable_hash::StableHash;
29use rustc_data_structures::steal::Steal;
30use rustc_data_structures::sync::{
31    self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
32};
33use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
34use rustc_hir::def::DefKind;
35use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
36use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState};
37use rustc_hir::intravisit::Visitor;
38use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate};
39use rustc_index::IndexVec;
40use rustc_lint_defs::Lint;
41use rustc_lint_defs::builtin::UNUSED_FEATURES;
42use rustc_macros::Diagnostic;
43use rustc_session::{IncrCompSession, Session};
44use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
45use rustc_span::{DUMMY_SP, Ident, Span, Symbol, bug, kw, sym};
46use rustc_structures::{CrateType, Limit};
47use rustc_type_ir::TyKind::*;
48pub use rustc_type_ir::lift::Lift;
49use rustc_type_ir::{CollectAndApply, WithCachedTypeInfo, elaborate, search_graph};
50use tracing::{debug, instrument};
51
52use crate::arena::Arena;
53use crate::dep_graph::dep_node::make_metadata;
54use crate::dep_graph::{DepGraph, DepNodeIndex};
55use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo};
56use crate::ich::StableHashState;
57use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
58use crate::lint::emit_lint_base;
59use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
60use crate::middle::resolve::{ModChild, ResolverAstLowering};
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::{
68    CanonicalInput, CanonicalInputData, ExternalConstraints, ExternalConstraintsData,
69    PredefinedOpaques,
70};
71use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
72use crate::ty::{
73    self, AdtDef, AdtDefData, AdtKind, Binder, Clause, ClausePolarity, Clauses, Const, ConstKind,
74    FnSigKind, GenericArg, GenericArgs, GenericArgsRef, GenericParamDefKind, List,
75    ListWithCachedTypeInfo, ParamConst, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig,
76    Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind,
77    TyVid, ValTree, ValTreeKind, Visibility,
78};
79
80impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
81    fn is_local(self) -> bool {
82        self.is_local()
83    }
84
85    fn as_local(self) -> Option<LocalDefId> {
86        self.as_local()
87    }
88}
89
90impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
91    fn safe() -> Self {
92        hir::Safety::Safe
93    }
94
95    fn unsafe_mode() -> Self {
96        hir::Safety::Unsafe
97    }
98
99    fn is_safe(self) -> bool {
100        self.is_safe()
101    }
102
103    fn prefix_str(self) -> &'static str {
104        self.prefix_str()
105    }
106}
107
108impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
109    fn generic_const_exprs(self) -> bool {
110        self.generic_const_exprs()
111    }
112
113    fn gca_const_items(self) -> bool {
114        self.gca_const_items()
115    }
116
117    fn coroutine_clone(self) -> bool {
118        self.coroutine_clone()
119    }
120
121    fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
122        // We don't consider feature bounds to hold in the crate when `staged_api` feature is
123        // enabled, even if it is enabled through `#[feature]`.
124        // This is to prevent accidentally leaking unstable APIs to stable.
125        !self.staged_api() && self.enabled(symbol)
126    }
127}
128
129impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
130    fn dummy() -> Self {
131        DUMMY_SP
132    }
133}
134
135type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
136
137pub struct CtxtInterners<'tcx> {
138    /// The arena that types, regions, etc. are allocated from.
139    arena: &'tcx WorkerLocal<Arena<'tcx>>,
140
141    // Specifically use a speedy hash algorithm for these hash sets, since
142    // they're accessed quite often.
143    type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
144    const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
145    args: InternedSet<'tcx, GenericArgs<'tcx>>,
146    type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
147    canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
148    region: InternedSet<'tcx, RegionKind<'tcx>>,
149    poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
150    predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
151    clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
152    projs: InternedSet<'tcx, List<ProjectionKind>>,
153    place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
154    const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
155    pat: InternedSet<'tcx, PatternKind<'tcx>>,
156    const_allocation: InternedSet<'tcx, Allocation>,
157    bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
158    layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
159    adt_def: InternedSet<'tcx, AdtDefData>,
160    external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
161    predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
162    fields: InternedSet<'tcx, List<FieldIdx>>,
163    local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
164    captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
165    valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
166    patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
167    outlives: InternedSet<'tcx, List<ty::ArgOutlivesClause<'tcx>>>,
168    canonical_inputs: InternedSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>>,
169}
170
171impl<'tcx> CtxtInterners<'tcx> {
172    fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
173        // Default interner size - this value has been chosen empirically, and may need to be
174        // adjusted as the compiler evolves.
175        const N: usize = 2048;
176        CtxtInterners {
177            arena,
178            // The factors have been chosen by @FractalFir based on observed interner sizes, and
179            // local perf runs. To get the interner sizes, insert `eprintln` printing the size of
180            // the interner in functions like `intern_ty`. Bigger benchmarks tend to give more
181            // accurate ratios, so use something like `x perf eprintln --includes cargo`.
182            type_: InternedSet::with_capacity(N * 16),
183            const_lists: InternedSet::with_capacity(N * 4),
184            args: InternedSet::with_capacity(N * 4),
185            type_lists: InternedSet::with_capacity(N * 4),
186            region: InternedSet::with_capacity(N * 4),
187            poly_existential_predicates: InternedSet::with_capacity(N / 4),
188            canonical_var_kinds: InternedSet::with_capacity(N / 2),
189            predicate: InternedSet::with_capacity(N),
190            clauses: InternedSet::with_capacity(N),
191            projs: InternedSet::with_capacity(N * 4),
192            place_elems: InternedSet::with_capacity(N * 2),
193            const_: InternedSet::with_capacity(N * 2),
194            pat: InternedSet::with_capacity(N),
195            const_allocation: InternedSet::with_capacity(N),
196            bound_variable_kinds: InternedSet::with_capacity(N * 2),
197            layout: InternedSet::with_capacity(N),
198            adt_def: InternedSet::with_capacity(N),
199            external_constraints: InternedSet::with_capacity(N),
200            predefined_opaques_in_body: InternedSet::with_capacity(N),
201            fields: InternedSet::with_capacity(N * 4),
202            local_def_ids: InternedSet::with_capacity(N),
203            captures: InternedSet::with_capacity(N),
204            valtree: InternedSet::with_capacity(N),
205            patterns: InternedSet::with_capacity(N),
206            outlives: InternedSet::with_capacity(N),
207            canonical_inputs: InternedSet::with_capacity(N),
208        }
209    }
210
211    /// Interns a type. (Use `mk_*` functions instead, where possible.)
212    #[allow(rustc::usage_of_ty_tykind)]
213    #[inline(never)]
214    fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
215        Ty(Interned::new_unchecked(
216            self.type_
217                .intern(kind, |kind| {
218                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
219                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
220                        internee: kind,
221                        flags: flags.flags,
222                        outer_exclusive_binder: flags.outer_exclusive_binder,
223                    }))
224                })
225                .0,
226        ))
227    }
228
229    /// Interns a const. (Use `mk_*` functions instead, where possible.)
230    #[allow(rustc::usage_of_ty_tykind)]
231    #[inline(never)]
232    fn intern_const(&self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
233        Const(Interned::new_unchecked(
234            self.const_
235                .intern(kind, |kind: ty::ConstKind<'_>| {
236                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
237                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
238                        internee: kind,
239                        flags: flags.flags,
240                        outer_exclusive_binder: flags.outer_exclusive_binder,
241                    }))
242                })
243                .0,
244        ))
245    }
246
247    /// Interns a predicate. (Use `mk_predicate` instead, where possible.)
248    #[inline(never)]
249    fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
250        Predicate(Interned::new_unchecked(
251            self.predicate
252                .intern(kind, |kind| {
253                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
254                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
255                        internee: kind,
256                        flags: flags.flags,
257                        outer_exclusive_binder: flags.outer_exclusive_binder,
258                    }))
259                })
260                .0,
261        ))
262    }
263
264    fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
265        if clauses.is_empty() {
266            ListWithCachedTypeInfo::empty()
267        } else {
268            self.clauses
269                .intern_ref(clauses, || {
270                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
271
272                    InternedInSet(ListWithCachedTypeInfo::from_arena(
273                        &*self.arena,
274                        flags.into(),
275                        clauses,
276                    ))
277                })
278                .0
279        }
280    }
281}
282
283// For these preinterned values, an alternative would be to have
284// variable-length vectors that grow as needed. But that turned out to be
285// slightly more complex and no faster.
286
287const NUM_PREINTERNED_TY_VARS: u32 = 100;
288const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
289const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
290const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
291const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
292
293// From general profiling of the *max vars during canonicalization* of a value:
294// - about 90% of the time, there are no canonical vars
295// - about 9% of the time, there is only one canonical var
296// - there are rarely more than 3-5 canonical vars (with exceptions in particularly pathological
297//   cases)
298// This may not match the number of bound vars found in `for`s.
299// Given that this is all heap interned, it seems likely that interning fewer
300// vars here won't make an appreciable difference. Though, if we were to inline the data (in an
301// array), we may want to consider reducing the number for canonicalized vars down to 4 or so.
302const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
303
304// This number may seem high, but it is reached in all but the smallest crates.
305const NUM_PREINTERNED_RE_VARS: u32 = 500;
306const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
307const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
308
309pub struct CommonTypes<'tcx> {
310    pub unit: Ty<'tcx>,
311    pub bool: Ty<'tcx>,
312    pub char: Ty<'tcx>,
313    pub isize: Ty<'tcx>,
314    pub i8: Ty<'tcx>,
315    pub i16: Ty<'tcx>,
316    pub i32: Ty<'tcx>,
317    pub i64: Ty<'tcx>,
318    pub i128: Ty<'tcx>,
319    pub usize: Ty<'tcx>,
320    pub u8: Ty<'tcx>,
321    pub u16: Ty<'tcx>,
322    pub u32: Ty<'tcx>,
323    pub u64: Ty<'tcx>,
324    pub u128: Ty<'tcx>,
325    pub f16: Ty<'tcx>,
326    pub f32: Ty<'tcx>,
327    pub f64: Ty<'tcx>,
328    pub f128: Ty<'tcx>,
329    pub str_: Ty<'tcx>,
330    pub never: Ty<'tcx>,
331    pub self_param: Ty<'tcx>,
332
333    /// A dummy type that can be used as the self type of trait object types outside of
334    /// [`ty::ExistentialTraitRef`], [`ty::ExistentialProjection`], etc.
335    ///
336    /// This is most useful or even necessary when you want to manipulate existential predicates
337    /// together with normal predicates or if you want to pass them to an API that only expects
338    /// normal predicates.
339    ///
340    /// Indeed, you can sometimes use the trait object type itself as the self type instead of this
341    /// dummy type. However, that's not always correct: For example, if said trait object type can
342    /// also appear "naturally" in whatever type system entity you're working with (like predicates)
343    /// but you still need to be able to identify the erased self type later on.
344    /// That's when this dummy type comes in handy.
345    ///
346    /// HIR ty lowering guarantees / has to guarantee that this dummy type doesn't appear in the
347    /// lowered types, so you can "freely" use it (see warning below).
348    ///
349    /// <div class="warning">
350    ///
351    /// Under the hood, this type is just `ty::Infer(ty::FreshTy(0))`. Consequently, you must be
352    /// sure that fresh types cannot appear by other means in whatever type system entity you're
353    /// working with.
354    ///
355    /// Keep uses of this dummy type as local as possible and try not to leak it to subsequent
356    /// passes!
357    ///
358    /// </div>
359    pub trait_object_dummy_self: Ty<'tcx>,
360
361    /// Pre-interned `Infer(ty::TyVar(n))` for small values of `n`.
362    pub ty_vars: Vec<Ty<'tcx>>,
363
364    /// Pre-interned `Infer(ty::FreshTy(n))` for small values of `n`.
365    pub fresh_tys: Vec<Ty<'tcx>>,
366
367    /// Pre-interned `Infer(ty::FreshIntTy(n))` for small values of `n`.
368    pub fresh_int_tys: Vec<Ty<'tcx>>,
369
370    /// Pre-interned `Infer(ty::FreshFloatTy(n))` for small values of `n`.
371    pub fresh_float_tys: Vec<Ty<'tcx>>,
372
373    /// Pre-interned values of the form:
374    /// `Bound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundTy { var: v, kind:
375    /// BoundTyKind::Anon})` for small values of `i` and `v`.
376    pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
377
378    // Pre-interned values of the form:
379    // `Bound(BoundVarIndexKind::Canonical, BoundTy { var: v, kind: BoundTyKind::Anon })`
380    // for small values of `v`.
381    pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
382}
383
384pub struct CommonLifetimes<'tcx> {
385    /// `ReStatic`
386    pub re_static: Region<'tcx>,
387
388    /// Erased region, used outside of type inference.
389    pub re_erased: Region<'tcx>,
390
391    /// Pre-interned `ReVar(ty::RegionVar(n))` for small values of `n`.
392    pub re_vars: Vec<Region<'tcx>>,
393
394    /// Pre-interned values of the form:
395    /// `ReBound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundRegion { var: v, kind: BoundRegionKind::Anon })`
396    /// for small values of `i` and `v`.
397    pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
398
399    // Pre-interned values of the form:
400    // `ReBound(BoundVarIndexKind::Canonical, BoundRegion { var: v, kind: BoundRegionKind::Anon })`
401    // for small values of `v`.
402    pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
403}
404
405pub struct CommonConsts<'tcx> {
406    pub unit: Const<'tcx>,
407    pub true_: Const<'tcx>,
408    pub false_: Const<'tcx>,
409    /// Use [`ty::ValTree::zst`] instead.
410    pub(crate) valtree_zst: ValTree<'tcx>,
411}
412
413impl<'tcx> CommonTypes<'tcx> {
414    fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
415        let mk = |ty| interners.intern_ty(ty);
416
417        let ty_vars =
418            (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
419        let fresh_tys: Vec<_> =
420            (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
421        let fresh_int_tys: Vec<_> =
422            (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
423        let fresh_float_tys: Vec<_> =
424            (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
425
426        let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
427            .map(|i| {
428                (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
429                    .map(|v| {
430                        mk(ty::Bound(
431                            ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
432                            ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
433                        ))
434                    })
435                    .collect()
436            })
437            .collect();
438
439        let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
440            .map(|v| {
441                mk(ty::Bound(
442                    ty::BoundVarIndexKind::Canonical,
443                    ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
444                ))
445            })
446            .collect();
447
448        CommonTypes {
449            unit: mk(Tuple(List::empty())),
450            bool: mk(Bool),
451            char: mk(Char),
452            never: mk(Never),
453            isize: mk(Int(ty::IntTy::Isize)),
454            i8: mk(Int(ty::IntTy::I8)),
455            i16: mk(Int(ty::IntTy::I16)),
456            i32: mk(Int(ty::IntTy::I32)),
457            i64: mk(Int(ty::IntTy::I64)),
458            i128: mk(Int(ty::IntTy::I128)),
459            usize: mk(Uint(ty::UintTy::Usize)),
460            u8: mk(Uint(ty::UintTy::U8)),
461            u16: mk(Uint(ty::UintTy::U16)),
462            u32: mk(Uint(ty::UintTy::U32)),
463            u64: mk(Uint(ty::UintTy::U64)),
464            u128: mk(Uint(ty::UintTy::U128)),
465            f16: mk(Float(ty::FloatTy::F16)),
466            f32: mk(Float(ty::FloatTy::F32)),
467            f64: mk(Float(ty::FloatTy::F64)),
468            f128: mk(Float(ty::FloatTy::F128)),
469            str_: mk(Str),
470            self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
471
472            trait_object_dummy_self: fresh_tys[0],
473
474            ty_vars,
475            fresh_tys,
476            fresh_int_tys,
477            fresh_float_tys,
478            anon_bound_tys,
479            anon_canonical_bound_tys,
480        }
481    }
482}
483
484impl<'tcx> CommonLifetimes<'tcx> {
485    fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
486        let mk = |r| {
487            Region(Interned::new_unchecked(
488                interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
489            ))
490        };
491
492        let re_vars =
493            (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
494
495        let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
496            .map(|i| {
497                (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
498                    .map(|v| {
499                        mk(ty::ReBound(
500                            ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
501                            ty::BoundRegion {
502                                var: ty::BoundVar::from(v),
503                                kind: ty::BoundRegionKind::Anon,
504                            },
505                        ))
506                    })
507                    .collect()
508            })
509            .collect();
510
511        let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
512            .map(|v| {
513                mk(ty::ReBound(
514                    ty::BoundVarIndexKind::Canonical,
515                    ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
516                ))
517            })
518            .collect();
519
520        CommonLifetimes {
521            re_static: mk(ty::ReStatic),
522            re_erased: mk(ty::ReErased),
523            re_vars,
524            anon_re_bounds,
525            anon_re_canonical_bounds,
526        }
527    }
528}
529
530impl<'tcx> CommonConsts<'tcx> {
531    fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
532        let mk_const = |c| interners.intern_const(c);
533
534        let mk_valtree = |v| {
535            ty::ValTree(Interned::new_unchecked(
536                interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
537            ))
538        };
539
540        let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
541        let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
542        let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
543
544        CommonConsts {
545            unit: mk_const(ty::ConstKind::Value(ty::Value {
546                ty: types.unit,
547                valtree: valtree_zst,
548            })),
549            true_: mk_const(ty::ConstKind::Value(ty::Value {
550                ty: types.bool,
551                valtree: valtree_true,
552            })),
553            false_: mk_const(ty::ConstKind::Value(ty::Value {
554                ty: types.bool,
555                valtree: valtree_false,
556            })),
557            valtree_zst,
558        }
559    }
560}
561
562/// This struct contains information regarding a free parameter region,
563/// either a `ReEarlyParam` or `ReLateParam`.
564#[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)]
565pub struct FreeRegionInfo {
566    /// `LocalDefId` of the scope.
567    pub scope: LocalDefId,
568    /// the `DefId` of the free region.
569    pub region_def_id: DefId,
570    /// checks if bound region is in Impl Item
571    pub is_impl_item: bool,
572}
573
574/// This struct should only be created by `create_def`.
575#[derive(#[automatically_derived]
impl<'tcx, K: ::core::marker::Copy + Copy> ::core::marker::Copy for
    TyCtxtFeed<'tcx, K> {
}Copy, #[automatically_derived]
impl<'tcx, K: ::core::clone::Clone + Copy> ::core::clone::Clone for
    TyCtxtFeed<'tcx, K> {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            tcx: ::core::clone::Clone::clone(&self.tcx),
            key: ::core::clone::Clone::clone(&self.key),
        }
    }
}Clone)]
576pub struct TyCtxtFeed<'tcx, K: Copy> {
577    pub tcx: TyCtxt<'tcx>,
578    // Do not allow direct access, as downstream code must not mutate this field.
579    key: K,
580}
581
582/// Only queries that create a `DefId` are allowed to feed queries for that `DefId`.
583impl<K: Copy> !StableHash for TyCtxtFeed<'_, K> {}
584
585/// Some workarounds to use cases that cannot use `create_def`.
586/// Do not add new ways to create `TyCtxtFeed` without consulting
587/// with T-compiler and making an analysis about why your addition
588/// does not cause incremental compilation issues.
589impl<'tcx> TyCtxt<'tcx> {
590    /// Can only be fed before queries are run, and is thus exempt from any
591    /// incremental issues. Do not use except for the initial query feeding.
592    pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
593        self.dep_graph.assert_ignored();
594        TyCtxtFeed { tcx: self, key: () }
595    }
596
597    /// Only used in the resolver to register the `CRATE_DEF_ID` `DefId` and feed
598    /// some queries for it. It will panic if used twice.
599    pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
600        let key = self.untracked().source_span.push(span);
601        {
    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);
602        TyCtxtFeed { tcx: self, key }
603    }
604
605    /// In order to break cycles involving `AnonConst`, we need to set the expected type by side
606    /// effect. However, we do not want this as a general capability, so this interface restricts
607    /// to the only allowed case.
608    pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
609        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);
610        if true {
    if !(self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline)
        {
        ::core::panicking::panic("assertion failed: self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline")
    };
};debug_assert!(self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline);
611        TyCtxtFeed { tcx: self, key }.type_of(value)
612    }
613
614    // Trait impl item visibility is inherited from its trait when not specified
615    // explicitly. In that case we cannot determine it in early resolve,
616    // but instead are feeding it in late resolve, where we don't have access to the
617    // `TyCtxtFeed` anymore.
618    // To avoid having to hash the `LocalDefId` multiple times for inserting and removing the
619    // `TyCtxtFeed` from a hash table, we add this hack to feed the visibility.
620    // Do not use outside of the resolver query.
621    pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
622        if truecfg!(debug_assertions) {
623            match self.def_kind(self.local_parent(key)) {
624                DefKind::Impl { of_trait: true } => {}
625                other => ::rustc_span::macros::bug_impl(None,
    format_args!("{0:?} is not an assoc item of a trait impl: {1:?}", key,
        other), Location::caller())bug!("{key:?} is not an assoc item of a trait impl: {other:?}"),
626            }
627        }
628        TyCtxtFeed { tcx: self, key }.visibility(vis.to_mod_id())
629    }
630}
631
632impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> {
633    #[inline(always)]
634    pub fn key(&self) -> K {
635        self.key
636    }
637}
638
639impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
640    #[inline(always)]
641    pub fn def_id(&self) -> LocalDefId {
642        self.key
643    }
644
645    // Caller must ensure that `self.key` ID is indeed an owner.
646    pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
647        TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
648    }
649
650    // Fills in all the important parts needed by HIR queries
651    pub fn feed_hir(&self) {
652        self.hir_owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo::new(
653            self.tcx.arena.alloc(hir::OwnerNodes::synthetic()),
654            self.tcx.arena.alloc(Default::default()),
655            self.tcx.arena.alloc(Default::default()),
656            self.tcx.arena.alloc(Steal::new(Default::default())),
657        )));
658
659        self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
660    }
661}
662
663/// An assortment of global caches used by various parts of the compiler.
664///
665/// The individual fields are mostly unrelated to each other, but have been grouped together to
666/// reduce the number of top-level fields in [`GlobalCtxt`].
667#[derive(#[automatically_derived]
impl<'tcx> ::core::default::Default for GlobalCaches<'tcx> {
    #[inline]
    fn default() -> Self {
        Self {
            ty_rcache: ::core::default::Default::default(),
            selection_cache: ::core::default::Default::default(),
            evaluation_cache: ::core::default::Default::default(),
            new_solver_evaluation_cache: ::core::default::Default::default(),
            new_solver_canonical_param_env_cache: ::core::default::Default::default(),
            canonical_param_env_cache: ::core::default::Default::default(),
            highest_var_in_clauses_cache: ::core::default::Default::default(),
            clauses_cache: ::core::default::Default::default(),
        }
    }
}Default)]
668pub struct GlobalCaches<'tcx> {
669    // Internal caches for metadata decoding. No need to track deps on this.
670    pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
671
672    /// Caches the results of trait selection. This cache is used
673    /// for things that do not have to do with the parameters in scope.
674    pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
675
676    /// Caches the results of trait evaluation. This cache is used
677    /// for things that do not have to do with the parameters in scope.
678    /// Merge this with `selection_cache`?
679    pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
680
681    /// Caches the results of goal evaluation in the new solver.
682    new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
683    new_solver_canonical_param_env_cache: Lock<ty::CanonicalParamEnvCache<TyCtxt<'tcx>>>,
684
685    pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
686
687    /// Caches the index of the highest bound var in clauses in a canonical binder.
688    pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
689
690    /// Caches the instantiation of a canonical binder given a set of args.
691    pub clauses_cache:
692        Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
693}
694
695/// The central data structure of the compiler. It stores references
696/// to the various **arenas** and also houses the results of the
697/// various **compiler queries** that have been performed. See the
698/// [rustc dev guide] for more details.
699///
700/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html
701///
702/// An implementation detail: `TyCtxt` is a wrapper type for [GlobalCtxt],
703/// which is the struct that actually holds all the data. `TyCtxt` derefs to
704/// `GlobalCtxt`, and in practice `TyCtxt` is passed around everywhere, and all
705/// operations are done via `TyCtxt`. A `TyCtxt` is obtained for a `GlobalCtxt`
706/// by calling `enter` with a closure `f`. That function creates both the
707/// `TyCtxt`, and an `ImplicitCtxt` around it that is put into TLS. Within `f`:
708/// - The `ImplicitCtxt` is available implicitly via TLS.
709/// - The `TyCtxt` is available explicitly via the `tcx` parameter, and also
710///   implicitly within the `ImplicitCtxt`. Explicit access is preferred when
711///   possible.
712#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for TyCtxt<'tcx> { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for TyCtxt<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for TyCtxt<'tcx> {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<&'tcx GlobalCtxt<'tcx>>;
        *self
    }
}Clone)]
713#[rustc_diagnostic_item = "TyCtxt"]
714#[rustc_pass_by_value]
715pub struct TyCtxt<'tcx> {
716    gcx: &'tcx GlobalCtxt<'tcx>,
717}
718
719// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. Its
720// field are asserted to implement these traits below, so this is trivially safe, and it greatly
721// speeds-up compilation of this crate and its dependents.
722unsafe impl DynSend for TyCtxt<'_> {}
723unsafe impl DynSync for TyCtxt<'_> {}
724fn _assert_tcx_fields() {
725    sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
726    sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
727}
728
729impl<'tcx> Deref for TyCtxt<'tcx> {
730    type Target = &'tcx GlobalCtxt<'tcx>;
731    #[inline(always)]
732    fn deref(&self) -> &Self::Target {
733        &self.gcx
734    }
735}
736
737/// See [TyCtxt] for details about this type.
738pub struct GlobalCtxt<'tcx> {
739    pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
740    pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
741
742    interners: CtxtInterners<'tcx>,
743
744    pub sess: &'tcx Session,
745    crate_types: Vec<CrateType>,
746    /// The `stable_crate_id` is constructed out of the crate name and all the
747    /// `-C metadata` arguments passed to the compiler. Its value forms a unique
748    /// global identifier for the crate. It is used to allow multiple crates
749    /// with the same name to coexist. See the
750    /// `rustc_symbol_mangling` crate for more information.
751    stable_crate_id: StableCrateId,
752
753    pub incr_comp_session: Option<&'tcx IncrCompSession>,
754    pub dep_graph: DepGraph,
755
756    /// This duplicates `Session::prof` because this field is hot enough that accessing it via
757    /// `self.sess.prof` is a measurable slowdown (see #161332).
758    pub prof: SelfProfilerRef,
759
760    /// Common types, pre-interned for your convenience.
761    pub types: CommonTypes<'tcx>,
762
763    /// Common lifetimes, pre-interned for your convenience.
764    pub lifetimes: CommonLifetimes<'tcx>,
765
766    /// Common consts, pre-interned for your convenience.
767    pub consts: CommonConsts<'tcx>,
768
769    /// Hooks to be able to register functions in other crates that can then still
770    /// be called from rustc_middle.
771    pub(crate) hooks: crate::hooks::Providers,
772
773    untracked: Untracked,
774
775    pub query_system: QuerySystem<'tcx>,
776
777    pub caches: GlobalCaches<'tcx>,
778
779    /// Data layout specification for the current target.
780    pub data_layout: TargetDataLayout,
781
782    /// Stores memory for globals (statics/consts).
783    pub(crate) alloc_map: interpret::AllocMap<'tcx>,
784
785    current_gcx: CurrentGcx,
786}
787
788impl<'tcx> GlobalCtxt<'tcx> {
789    /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
790    /// `f`.
791    pub fn enter<F, R>(&'tcx self, f: F) -> R
792    where
793        F: FnOnce(TyCtxt<'tcx>) -> R,
794    {
795        let icx = tls::ImplicitCtxt::new(self);
796
797        // Reset `current_gcx` to `None` when we exit.
798        let _on_drop = defer(move || {
799            *self.current_gcx.value.write() = None;
800        });
801
802        // Set this `GlobalCtxt` as the current one.
803        {
804            let mut guard = self.current_gcx.value.write();
805            if !guard.is_none() {
    {
        ::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
    }
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
806            *guard = Some(self as *const _ as *const ());
807        }
808
809        tls::enter_context(&icx, || f(icx.tcx))
810    }
811}
812
813/// This is used to get a reference to a `GlobalCtxt` if one is available.
814///
815/// This is needed to allow the deadlock handler access to `GlobalCtxt` to look for query cycles.
816/// It cannot use the `TLV` global because that's only guaranteed to be defined on the thread
817/// creating the `GlobalCtxt`. Other threads have access to the `TLV` only inside Rayon jobs, but
818/// the deadlock handler is not called inside such a job.
819#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
    #[inline]
    fn clone(&self) -> Self {
        Self { value: ::core::clone::Clone::clone(&self.value) }
    }
}Clone)]
820pub struct CurrentGcx {
821    /// This stores a pointer to a `GlobalCtxt`. This is set to `Some` inside `GlobalCtxt::enter`
822    /// and reset to `None` when that function returns or unwinds.
823    value: Arc<RwLock<Option<*const ()>>>,
824}
825
826unsafe impl DynSend for CurrentGcx {}
827unsafe impl DynSync for CurrentGcx {}
828
829impl CurrentGcx {
830    pub fn new() -> Self {
831        Self { value: Arc::new(RwLock::new(None)) }
832    }
833
834    pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
835        let read_guard = self.value.read();
836        let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
837        // SAFETY: We hold the read lock for the `GlobalCtxt` pointer. That prevents
838        // `GlobalCtxt::enter` from returning as it would first acquire the write lock.
839        // This ensures the `GlobalCtxt` is live during `f`.
840        f(unsafe { &*gcx })
841    }
842}
843
844impl<'tcx> TyCtxt<'tcx> {
845    pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
846        // Closures' typeck results come from their outermost function,
847        // as they are part of the same "inference environment".
848        let root = self.typeck_root_def_id_local(def_id);
849        self.hir_node_by_def_id(root).body_id().is_some()
850    }
851
852    /// Expects a body and returns its codegen attributes.
853    ///
854    /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for
855    /// constants.
856    pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
857        let def_kind = self.def_kind(def_id);
858        if def_kind.has_codegen_attrs() {
859            self.codegen_fn_attrs(def_id)
860        } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
    DefKind::AnonConst | DefKind::AssocConst | DefKind::Const |
        DefKind::GlobalAsm => true,
    _ => false,
}matches!(
861            def_kind,
862            DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::GlobalAsm
863        ) {
864            CodegenFnAttrs::EMPTY
865        } else {
866            ::rustc_span::macros::bug_impl(None,
    format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
        def_id, def_kind), Location::caller())bug!(
867                "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
868                def_id,
869                def_kind
870            )
871        }
872    }
873
874    pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
875        self.arena.alloc(Steal::new(thir))
876    }
877
878    pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
879        self.arena.alloc(Steal::new(mir))
880    }
881
882    pub fn alloc_steal_promoted(
883        self,
884        promoted: IndexVec<Promoted, Body<'tcx>>,
885    ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
886        self.arena.alloc(Steal::new(promoted))
887    }
888
889    pub fn mk_adt_def(
890        self,
891        did: DefId,
892        kind: AdtKind,
893        variants: IndexVec<VariantIdx, ty::VariantDef>,
894        repr: ReprOptions,
895    ) -> ty::AdtDef<'tcx> {
896        self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
897    }
898
899    /// Allocates a read-only byte or string literal for `mir::interpret` with alignment 1.
900    /// Returns the same `AllocId` if called again with the same bytes.
901    pub fn allocate_bytes_dedup<'a>(
902        self,
903        bytes: impl Into<Cow<'a, [u8]>>,
904        salt: usize,
905    ) -> interpret::AllocId {
906        // Create an allocation that just contains these bytes.
907        let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
908        let alloc = self.mk_const_alloc(alloc);
909        self.reserve_and_set_memory_dedup(alloc, salt)
910    }
911
912    /// Traits added on all bounds by default, excluding `Sized` which is treated separately.
913    pub fn default_traits(self) -> &'static [LangItem] {
914        if self.sess.opts.unstable_opts.experimental_default_bounds {
915            &[
916                LangItem::DefaultTrait1,
917                LangItem::DefaultTrait2,
918                LangItem::DefaultTrait3,
919                LangItem::DefaultTrait4,
920            ]
921        } else {
922            &[]
923        }
924    }
925
926    pub fn is_default_trait(self, def_id: DefId) -> bool {
927        self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
928    }
929
930    pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
931        #[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))
932    }
933
934    pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> T::Lifted {
935        value.lift_to_interner(self)
936    }
937
938    /// Creates a type context. To use the context call `fn enter` which
939    /// provides a `TyCtxt`.
940    ///
941    /// By only providing the `TyCtxt` inside of the closure we enforce that the type
942    /// context and any interned value (types, args, etc.) can only be used while `ty::tls`
943    /// has a valid reference to the context, to allow formatting values that need it.
944    pub fn create_global_ctxt<T>(
945        gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
946        sess: &'tcx Session,
947        crate_types: Vec<CrateType>,
948        stable_crate_id: StableCrateId,
949        arena: &'tcx WorkerLocal<Arena<'tcx>>,
950        hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
951        untracked: Untracked,
952        incr_comp_session: Option<&'tcx IncrCompSession>,
953        dep_graph: DepGraph,
954        query_system: QuerySystem<'tcx>,
955        hooks: crate::hooks::Providers,
956        current_gcx: CurrentGcx,
957        f: impl FnOnce(TyCtxt<'tcx>) -> T,
958    ) -> T {
959        let data_layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
960            sess.dcx().emit_fatal(err);
961        });
962        let interners = CtxtInterners::new(arena);
963        let common_types = CommonTypes::new(&interners);
964        let common_lifetimes = CommonLifetimes::new(&interners);
965        let common_consts = CommonConsts::new(&interners, &common_types);
966
967        let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
968            sess,
969            crate_types,
970            stable_crate_id,
971            arena,
972            hir_arena,
973            interners,
974            incr_comp_session,
975            dep_graph,
976            hooks,
977            prof: sess.prof.clone(),
978            types: common_types,
979            lifetimes: common_lifetimes,
980            consts: common_consts,
981            untracked,
982            query_system,
983            caches: Default::default(),
984            data_layout,
985            alloc_map: interpret::AllocMap::new(),
986            current_gcx,
987        });
988
989        // This is a separate function to work around a crash with parallel rustc (#135870)
990        gcx.enter(f)
991    }
992
993    /// Obtain all lang items of this crate and all dependencies (recursively)
994    pub fn lang_items(self) -> &'tcx rustc_attr_ir::lang_items::LanguageItems {
995        self.get_lang_items(())
996    }
997
998    /// Gets a `Ty` representing the [`LangItem::OrderingEnum`]
999    #[track_caller]
1000    pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1001        let ordering_enum = self.require_lang_item(LangItem::OrderingEnum, span);
1002        self.type_of(ordering_enum).no_bound_vars().unwrap()
1003    }
1004
1005    /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
1006    /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
1007    pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1008        self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1009    }
1010
1011    /// Obtain the diagnostic item's name
1012    pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1013        self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1014    }
1015
1016    /// Check whether the diagnostic item with the given `name` has the given `DefId`.
1017    pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1018        self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1019    }
1020
1021    pub fn is_coroutine(self, def_id: DefId) -> bool {
1022        self.coroutine_kind(def_id).is_some()
1023    }
1024
1025    pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1026        self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1027    }
1028
1029    /// Returns true if the const is guaranteed to have a directly represented RHS. This is either
1030    /// because it has a directly represented RHS, or is a trait definition that is marked as
1031    /// requiring its implementation to have a directly represented RHS.
1032    ///
1033    /// Note: Be very careful with using this method - under `gca_const_items`, a trait can
1034    /// declare a regular const, but an `impl` could implement it with a directly represented const
1035    /// (a la refinement). This method would return false in such a case.
1036    pub fn is_direct_const(self, def_id: DefId) -> bool {
1037        if true {
    {
        match self.def_kind(def_id) {
            DefKind::Const | DefKind::AssocConst => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Const | DefKind::AssocConst",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::Const | DefKind::AssocConst);
1038        self.is_always_gca(def_id) || self.const_of_item(def_id).is_some()
1039    }
1040
1041    /// Whether this is a projection const marked with `#[always_gca]`
1042    pub fn is_always_gca(self, def_id: DefId) -> bool {
1043        {
        {
            'done:
                {
                for i in ::rustc_attr_ir::HasAttrs::get_attrs(def_id, &self) {
                    #[allow(unused_imports)]
                    use ::rustc_attr_ir::AttributeKind::*;
                    let i: &::rustc_attr_ir::Attribute = i;
                    match i {
                        ::rustc_attr_ir::Attribute::Parsed(AlwaysGca) => {
                            break 'done Some(());
                        }
                        ::rustc_attr_ir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }
    }.is_some()find_attr!(self, def_id, AlwaysGca)
1044    }
1045
1046    /// Returns the movability of the coroutine of `def_id`, or panics
1047    /// if given a `def_id` that is not a coroutine.
1048    pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1049        self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1050    }
1051
1052    /// Returns `true` if the node pointed to by `def_id` is a coroutine for an async construct.
1053    pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1054        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
        true,
    _ => false,
}matches!(
1055            self.coroutine_kind(def_id),
1056            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1057        )
1058    }
1059
1060    // Whether the body owner is synthetic, which in this case means it does not correspond to
1061    // meaningful HIR. This is currently used to skip over MIR borrowck.
1062    pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1063        #[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)
1064    }
1065
1066    /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`.
1067    /// This means it is neither an `async` or `gen` construct.
1068    pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1069        #[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(_)))
1070    }
1071
1072    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `gen` construct.
1073    pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1074        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
        true,
    _ => false,
}matches!(
1075            self.coroutine_kind(def_id),
1076            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1077        )
1078    }
1079
1080    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `async gen` construct.
1081    pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1082        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
        => true,
    _ => false,
}matches!(
1083            self.coroutine_kind(def_id),
1084            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1085        )
1086    }
1087
1088    pub fn features(self) -> &'tcx rustc_feature::Features {
1089        self.features_query(())
1090    }
1091
1092    pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1093        let id = id.into_query_key();
1094        // Accessing the DefKey is ok, since it is part of DefPathHash.
1095        if let Some(id) = id.as_local() {
1096            self.definitions_untracked().def_key(id)
1097        } else {
1098            self.cstore_untracked().def_key(id)
1099        }
1100    }
1101
1102    /// Converts a `DefId` into its fully expanded `DefPath` (every
1103    /// `DefId` is really just an interned `DefPath`).
1104    ///
1105    /// Note that if `id` is not local to this crate, the result will
1106    ///  be a non-local `DefPath`.
1107    pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1108        // Accessing the DefPath is ok, since it is part of DefPathHash.
1109        if let Some(id) = id.as_local() {
1110            self.definitions_untracked().def_path(id)
1111        } else {
1112            self.cstore_untracked().def_path(id)
1113        }
1114    }
1115
1116    #[inline]
1117    pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1118        // Accessing the DefPathHash is ok, it is incr. comp. stable.
1119        if let Some(def_id) = def_id.as_local() {
1120            self.definitions_untracked().def_path_hash(def_id)
1121        } else {
1122            self.cstore_untracked().def_path_hash(def_id)
1123        }
1124    }
1125
1126    #[inline]
1127    pub fn crate_types(self) -> &'tcx [CrateType] {
1128        &self.crate_types
1129    }
1130
1131    pub fn needs_metadata(self) -> bool {
1132        self.crate_types().iter().any(|ty| match *ty {
1133            CrateType::Executable
1134            | CrateType::StaticLib
1135            | CrateType::Cdylib
1136            | CrateType::Sdylib => false,
1137            CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1138        })
1139    }
1140
1141    pub fn needs_hir_hash(self) -> bool {
1142        // Why is the hir hash needed for these configurations?
1143        // - debug_assertions: for the "fingerprint the result" check in
1144        //   `rustc_query_impl::execution::execute_job`.
1145        // - incremental: for query lookups.
1146        // - needs_metadata: it is included in the crate metadata through the crate_hash query
1147        // - instrument_coverage: for putting into coverage data (see
1148        //   `hash_mir_source`).
1149        // - metrics_dir: metrics use the strict version hash in the filenames
1150        //   for dumped metrics files to prevent overwriting distinct metrics
1151        //   for similar source builds (may change in the future, this is part
1152        //   of the proof of concept impl for the metrics initiative project goal)
1153        truecfg!(debug_assertions)
1154            || self.sess.opts.incremental.is_some()
1155            || self.needs_metadata()
1156            || self.sess.instrument_coverage()
1157            || self.sess.opts.unstable_opts.metrics_dir.is_some()
1158    }
1159
1160    /// Whether the combined per-owner HIR hash (`OwnerInfo::opt_hash`, which folds `parenting`,
1161    /// `trait_map` and `children` on top of the node/attr hashes) needs to be computed during
1162    /// lowering.
1163    ///
1164    /// This is a strict subset of [`Self::needs_hir_hash`]: notably it drops the plain
1165    /// `needs_metadata` case. With metadata-based crate hashing (the default) the crate hash is
1166    /// built from the encoded metadata plus each owner's cheaper `OwnerInfo::fingerprint` (just the
1167    /// node and attr sub-hashes), so the combined hash is never read and computing it is wasted
1168    /// work. It is still required for:
1169    /// - `-Z metadata-crate-hash=no`, where `crate_hash` falls back to hashing each `OwnerInfo`;
1170    /// - incremental, where the `lower_to_hir` result is fingerprinted for red/green tracking;
1171    /// - debug assertions, where every query result is fingerprinted to catch nondeterminism.
1172    ///
1173    /// The `needs_hir_hash()` conjunct guarantees the node/attr sub-hashes it folds in are present.
1174    pub fn needs_owner_info_hash(self) -> bool {
1175        self.needs_hir_hash()
1176            && (!self.sess.opts.unstable_opts.metadata_crate_hash
1177                || self.sess.opts.incremental.is_some()
1178                || truecfg!(debug_assertions))
1179    }
1180
1181    #[inline]
1182    pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1183        if crate_num == LOCAL_CRATE {
1184            self.stable_crate_id
1185        } else {
1186            self.cstore_untracked().stable_crate_id(crate_num)
1187        }
1188    }
1189
1190    /// Maps a StableCrateId to the corresponding CrateNum. This method assumes
1191    /// that the crate in question has already been loaded by the CrateStore.
1192    #[inline]
1193    pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1194        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1195            LOCAL_CRATE
1196        } else {
1197            *self
1198                .untracked()
1199                .stable_crate_ids
1200                .read()
1201                .get(&stable_crate_id)
1202                .unwrap_or_else(|| ::rustc_span::macros::bug_impl(None,
    format_args!("uninterned StableCrateId: {0:?}", stable_crate_id),
    Location::caller())bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1203        }
1204    }
1205
1206    /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
1207    /// session, if it still exists. This is used during incremental compilation to
1208    /// turn a deserialized `DefPathHash` into its current `DefId`.
1209    pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1210        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_middle/src/ty/context.rs:1210",
                        "rustc_middle::ty::context", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_middle/src/ty/context.rs"),
                        ::tracing_core::__macro_support::Option::Some(1210u32),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("def_path_hash_to_def_id({0:?})",
                                                    hash) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("def_path_hash_to_def_id({:?})", hash);
1211
1212        let stable_crate_id = hash.stable_crate_id();
1213
1214        // If this is a DefPathHash from the local crate, we can look up the
1215        // DefId in the tcx's `Definitions`.
1216        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1217            Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1218        } else {
1219            self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1220        }
1221    }
1222
1223    pub fn def_path_debug_str(self, def_id: DefId) -> String {
1224        // We are explicitly not going through queries here in order to get
1225        // crate name and stable crate id since this code is called from debug!()
1226        // statements within the query system and we'd run into endless
1227        // recursion otherwise.
1228        let (crate_name, stable_crate_id) = if def_id.is_local() {
1229            (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1230        } else {
1231            let cstore = &*self.cstore_untracked();
1232            (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1233        };
1234
1235        ::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!(
1236            "{}[{:04x}]{}",
1237            crate_name,
1238            // Don't print the whole stable crate id. That's just
1239            // annoying in debug output.
1240            stable_crate_id.as_u64() >> (8 * 6),
1241            self.def_path(def_id).to_string_no_crate_verbose()
1242        )
1243    }
1244
1245    pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1246        self.sess.dcx()
1247    }
1248
1249    /// Checks to see if the caller (`body_features`) has all the features required by the callee
1250    /// (`callee_features`).
1251    pub fn is_target_feature_call_safe(
1252        self,
1253        callee_features: &[TargetFeature],
1254        body_features: &[TargetFeature],
1255    ) -> bool {
1256        // If the called function has target features the calling function hasn't,
1257        // the call requires `unsafe`. Don't check this on wasm
1258        // targets, though. For more information on wasm see the
1259        // is_like_wasm check in hir_analysis/src/collect.rs
1260        self.sess.target.options.is_like_wasm
1261            || callee_features
1262                .iter()
1263                .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1264    }
1265
1266    /// Returns the safe version of the signature of the given function, if calling it
1267    /// would be safe in the context of the given caller.
1268    pub fn adjust_target_feature_sig(
1269        self,
1270        fun_def: DefId,
1271        fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1272        caller: DefId,
1273    ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1274        let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1275        let caller_features = &self.body_codegen_attrs(caller).target_features;
1276        if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1277            return Some(fun_sig.map_bound(|sig| ty::FnSig {
1278                fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1279                ..sig
1280            }));
1281        }
1282        None
1283    }
1284
1285    /// Helper to get a tracked environment variable via. [`TyCtxt::env_var_os`] and converting to
1286    /// UTF-8 like [`std::env::var`].
1287    pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1288        match self.env_var_os(key.as_ref()) {
1289            Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1290            None => Err(VarError::NotPresent),
1291        }
1292    }
1293
1294    pub fn is_method(self, id: DefId) -> bool {
1295        self.opt_associated_item(id).is_some_and(|item| item.is_method())
1296    }
1297}
1298
1299impl<'tcx> TyCtxtAt<'tcx> {
1300    /// Create a new definition within the incr. comp. engine.
1301    pub fn create_def(
1302        self,
1303        parent: LocalDefId,
1304        name: Option<Symbol>,
1305        def_kind: DefKind,
1306        override_def_path_data: Option<DefPathData>,
1307        disambiguator: &mut PerParentDisambiguatorState,
1308    ) -> TyCtxtFeed<'tcx, LocalDefId> {
1309        let feed =
1310            self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1311
1312        feed.def_span(self.span);
1313        feed
1314    }
1315}
1316
1317impl<'tcx> TyCtxt<'tcx> {
1318    /// `tcx`-dependent operations performed for every created definition.
1319    pub fn create_def(
1320        self,
1321        parent: LocalDefId,
1322        name: Option<Symbol>,
1323        def_kind: DefKind,
1324        override_def_path_data: Option<DefPathData>,
1325        disambiguator: &mut PerParentDisambiguatorState,
1326    ) -> TyCtxtFeed<'tcx, LocalDefId> {
1327        let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1328        // The following call has the side effect of modifying the tables inside `definitions`.
1329        // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1330        // decode the on-disk cache.
1331        //
1332        // Any LocalDefId which is used within queries, either as key or result, either:
1333        // - has been created before the construction of the TyCtxt;
1334        // - has been created by this call to `create_def`.
1335        // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1336        // comp. engine itself.
1337        let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1338
1339        // This function modifies `self.definitions` using a side-effect.
1340        // We need to ensure that these side effects are re-run by the incr. comp. engine.
1341        // Depending on the forever-red node will tell the graph that the calling query
1342        // needs to be re-evaluated.
1343        self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1344
1345        let feed = TyCtxtFeed { tcx: self, key: def_id };
1346        feed.def_kind(def_kind);
1347        // Unique types created for closures participate in type privacy checking.
1348        // They have visibilities inherited from the module they are defined in.
1349        // Visibilities for opaque types are meaningless, but still provided
1350        // so that all items have visibilities.
1351        if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
    DefKind::Closure | DefKind::OpaqueTy => true,
    _ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1352            let parent_mod = self.parent_module_from_def_id(def_id);
1353            feed.visibility(ty::Visibility::Restricted(parent_mod.to_mod_id()));
1354        }
1355
1356        feed
1357    }
1358
1359    pub fn create_crate_num(
1360        self,
1361        stable_crate_id: StableCrateId,
1362    ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1363        let mut lock = self.untracked().stable_crate_ids.write();
1364        if let Some(&existing) = lock.get(&stable_crate_id) {
1365            return Err(existing);
1366        }
1367        let num = CrateNum::new(lock.len());
1368        lock.insert(stable_crate_id, num);
1369        Ok(TyCtxtFeed { key: num, tcx: self })
1370    }
1371
1372    pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1373        // Depend on the `analysis` query to ensure compilation if finished.
1374        self.ensure_ok().analysis(());
1375
1376        let definitions = &self.untracked.definitions;
1377        gen {
1378            let mut i = 0;
1379
1380            // Recompute the number of definitions each time, because our caller may be creating
1381            // new ones.
1382            while i < { definitions.read().num_definitions() } {
1383                let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1384                yield LocalDefId { local_def_index };
1385                i += 1;
1386            }
1387
1388            // Freeze definitions once we finish iterating on them, to prevent adding new ones.
1389            definitions.freeze();
1390        }
1391    }
1392
1393    pub fn definitions(self) -> &'tcx rustc_hir::definitions::Definitions {
1394        // Depend on the `analysis` query to ensure compilation if finished.
1395        self.ensure_ok().analysis(());
1396
1397        // Freeze definitions once we start iterating on them, to prevent adding new ones
1398        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1399        self.untracked.definitions.freeze()
1400    }
1401
1402    pub fn def_path_hash_to_def_index_map(
1403        self,
1404    ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1405        // Create a dependency to the crate to be sure we re-execute this when the amount of
1406        // definitions change.
1407        self.ensure_ok().hir_crate_items(());
1408        // Freeze definitions once we start iterating on them, to prevent adding new ones
1409        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1410        self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1411    }
1412
1413    /// Note that this is *untracked* and should only be used within the query
1414    /// system if the result is otherwise tracked through queries
1415    #[inline]
1416    pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1417        FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1418    }
1419
1420    /// Give out access to the untracked data without any sanity checks.
1421    pub fn untracked(self) -> &'tcx Untracked {
1422        &self.untracked
1423    }
1424    /// Note that this is *untracked* and should only be used within the query
1425    /// system if the result is otherwise tracked through queries
1426    #[inline]
1427    pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1428        self.untracked.definitions.read()
1429    }
1430
1431    /// Note that this is *untracked* and should only be used within the query
1432    /// system if the result is otherwise tracked through queries
1433    #[inline]
1434    pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1435        self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1436    }
1437
1438    #[inline(always)]
1439    pub fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashState<'_>) -> R) -> R {
1440        f(StableHashState::new(self.sess, &self.untracked))
1441    }
1442
1443    #[inline]
1444    pub fn local_crate_exports_generics(self) -> bool {
1445        // compiler-builtins has some special treatment in codegen, which can result in confusing
1446        // behavior if another crate ends up calling into its monomorphizations.
1447        // https://github.com/rust-lang/rust/issues/150173
1448        if self.is_compiler_builtins(LOCAL_CRATE) {
1449            return false;
1450        }
1451        self.crate_types().iter().any(|crate_type| {
1452            match crate_type {
1453                CrateType::Executable
1454                | CrateType::StaticLib
1455                | CrateType::ProcMacro
1456                | CrateType::Cdylib
1457                | CrateType::Sdylib => false,
1458
1459                // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
1460                // We want to block export of generics from dylibs,
1461                // but we must fix rust-lang/rust#65890 before we can
1462                // do that robustly.
1463                CrateType::Dylib => true,
1464
1465                CrateType::Rlib => true,
1466            }
1467        })
1468    }
1469
1470    /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
1471    pub fn is_suitable_region(
1472        self,
1473        generic_param_scope: LocalDefId,
1474        mut region: Region<'tcx>,
1475    ) -> Option<FreeRegionInfo> {
1476        let (suitable_region_binding_scope, region_def_id) = loop {
1477            let def_id =
1478                region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1479            let scope = self.local_parent(def_id);
1480            if self.def_kind(scope) == DefKind::OpaqueTy {
1481                // Lifetime params of opaque types are synthetic and thus irrelevant to
1482                // diagnostics. Map them back to their origin!
1483                region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1484                continue;
1485            }
1486            break (scope, def_id.into());
1487        };
1488
1489        let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1490            Node::Item(..) | Node::TraitItem(..) => false,
1491            Node::ImplItem(impl_item) => match impl_item.impl_kind {
1492                // For now, we do not try to target impls of traits. This is
1493                // because this message is going to suggest that the user
1494                // change the fn signature, but they may not be free to do so,
1495                // since the signature must match the trait.
1496                //
1497                // FIXME(#42706) -- in some cases, we could do better here.
1498                hir::ImplItemImplKind::Trait { .. } => true,
1499                _ => false,
1500            },
1501            _ => false,
1502        };
1503
1504        Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1505    }
1506
1507    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
1508    pub fn return_type_impl_or_dyn_traits(
1509        self,
1510        scope_def_id: LocalDefId,
1511    ) -> Vec<&'tcx hir::Ty<'tcx>> {
1512        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1513        let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1514            self.hir_fn_decl_by_hir_id(hir_id)
1515        else {
1516            return ::alloc::vec::Vec::new()vec![];
1517        };
1518
1519        let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1520        v.visit_ty_unambig(hir_output);
1521        v.0
1522    }
1523
1524    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in
1525    /// its return type, and the associated alias span when type alias is used,
1526    /// along with a span for lifetime suggestion (if there are existing generics).
1527    pub fn return_type_impl_or_dyn_traits_with_type_alias(
1528        self,
1529        scope_def_id: LocalDefId,
1530    ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1531        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1532        let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1533        // when the return type is a type alias
1534        if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1535            && let hir::TyKind::Path(hir::QPath::Resolved(
1536                None,
1537                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1538            && let Some(local_id) = def_id.as_local()
1539            && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias
1540            && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
1541        {
1542            v.visit_ty_unambig(alias_ty);
1543            if !v.0.is_empty() {
1544                return Some((
1545                    v.0,
1546                    alias_generics.span,
1547                    alias_generics.span_for_lifetime_suggestion(),
1548                ));
1549            }
1550        }
1551        None
1552    }
1553
1554    /// Determines whether identifiers in the assembly have strict naming rules.
1555    /// Currently, only NVPTX* targets need it.
1556    pub fn has_strict_asm_symbol_naming(self) -> bool {
1557        self.sess.target.llvm_target.starts_with("nvptx")
1558    }
1559
1560    /// Returns `&'static core::panic::Location<'static>`.
1561    pub fn caller_location_ty(self) -> Ty<'tcx> {
1562        Ty::new_imm_ref(
1563            self,
1564            self.lifetimes.re_static,
1565            self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1566                .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1567                .skip_norm_wip(),
1568        )
1569    }
1570
1571    /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
1572    pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1573        let kind = self.def_kind(def_id);
1574        (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1575    }
1576
1577    pub fn type_length_limit(self) -> Limit {
1578        self.limits(()).type_length_limit
1579    }
1580
1581    pub fn recursion_limit(self) -> Limit {
1582        self.limits(()).recursion_limit
1583    }
1584
1585    pub fn move_size_limit(self) -> Limit {
1586        self.limits(()).move_size_limit
1587    }
1588
1589    pub fn pattern_complexity_limit(self) -> Limit {
1590        self.limits(()).pattern_complexity_limit
1591    }
1592
1593    /// All traits in the crate graph, including those not visible to the user.
1594    pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1595        iter::once(LOCAL_CRATE)
1596            .chain(self.crates(()).iter().copied())
1597            .flat_map(move |cnum| self.traits(cnum).iter().copied())
1598    }
1599
1600    /// All traits that are visible within the crate graph (i.e. excluding private dependencies).
1601    pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1602        let visible_crates =
1603            self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1604
1605        iter::once(LOCAL_CRATE)
1606            .chain(visible_crates)
1607            .flat_map(move |cnum| self.traits(cnum).iter().copied())
1608    }
1609
1610    #[inline]
1611    pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1612        self.visibility(def_id).expect_local()
1613    }
1614
1615    /// Returns the origin of the opaque type `def_id`.
1616    {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
            ::tracing::Level::TRACE <=
                ::tracing::level_filters::LevelFilter::current() || { false }
    {
    __tracing_attr_span =
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("local_opaque_ty_origin",
                                "rustc_middle::ty::context", ::tracing::Level::TRACE,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_middle/src/ty/context.rs"),
                                ::tracing_core::__macro_support::Option::Some(1616u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("def_id")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("def_id");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::SPAN)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let mut interest = ::tracing::subscriber::Interest::never();
            if ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        { interest = __CALLSITE.interest(); !interest.is_never() }
                    &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest) {
                let meta = __CALLSITE.metadata();
                ::tracing::Span::new(meta,
                    &{
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
                                                        as &dyn ::tracing::field::Value))])
                        })
            } else {
                let span =
                    ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                {};
                span
            }
        };
    __tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return:
                                hir::OpaqueTyOrigin<LocalDefId> = loop {};
                        return __tracing_attr_fake_return;
                    }
                    { self.hir_expect_opaque_ty(def_id).origin }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_middle/src/ty/context.rs:1616",
                        "rustc_middle::ty::context", ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_middle/src/ty/context.rs"),
                        ::tracing_core::__macro_support::Option::Some(1616u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[instrument(skip(self), level = "trace", ret)]
1617    pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1618        self.hir_expect_opaque_ty(def_id).origin
1619    }
1620
1621    pub fn finish(self) {
1622        // We assume that no queries are run past here. If there are new queries
1623        // after this point, they'll show up as "<unknown>" in self-profiling data.
1624        self.alloc_self_profile_query_strings();
1625
1626        self.save_dep_graph();
1627        self.verify_query_key_hashes();
1628
1629        if let Err((path, error)) = self.dep_graph.finish_encoding() {
1630            self.sess
1631                .dcx()
1632                .emit_fatal(crate::diagnostics::FailedWritingFile { path: &path, error });
1633        }
1634    }
1635
1636    pub fn report_unused_features(self) {
1637        #[derive(const _: () =
    {
        impl<'_sess> rustc_errors::Diagnostic<'_sess> for UnusedFeature {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess> {
                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)]
1638        #[diag("feature `{$feature}` is declared but not used")]
1639        struct UnusedFeature {
1640            feature: Symbol,
1641        }
1642
1643        // Collect first to avoid holding the lock while linting.
1644        let used_features = self.query_system.used_features.lock();
1645        let unused_features = self
1646            .features()
1647            .enabled_features_iter_stable_order()
1648            .filter(|(f, _)| {
1649                !used_features.contains_key(f)
1650                // FIXME: `restricted_std` is used to tell a standard library built
1651                // for a platform that it doesn't know how to support. But it
1652                // could only gate a private mod (see `__restricted_std_workaround`)
1653                // with `cfg(not(restricted_std))`, so it cannot be recorded as used
1654                // in downstream crates. It should never be linted, but should we
1655                // hack this in the linter to ignore it?
1656                && f.as_str() != "restricted_std"
1657                // `doc_cfg` affects rustdoc behavior: rustdoc checks it via
1658                // `tcx.features().doc_cfg()`, but a normal rustc compilation may
1659                // never observe that use. Do not lint it as unused here.
1660                && *f != sym::doc_cfg
1661            })
1662            .collect::<Vec<_>>();
1663
1664        for (feature, span) in unused_features {
1665            self.emit_node_span_lint(
1666                UNUSED_FEATURES,
1667                CRATE_HIR_ID,
1668                span,
1669                UnusedFeature { feature },
1670            );
1671        }
1672    }
1673}
1674
1675macro_rules! nop_lift {
1676    ($set:ident; $ty:ty => $lifted:ty) => {
1677        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1678            type Lifted = $lifted;
1679            #[track_caller]
1680            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1681                // Assert that the set has the right type.
1682                // Given an argument that has an interned type, the return type has the type of
1683                // the corresponding interner set. This won't actually return anything, we're
1684                // just doing this to compute said type!
1685                fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1686                    _x: Interned<'tcx, Inner>,
1687                ) -> InternedSet<'tcx, Inner> {
1688                    unreachable!()
1689                }
1690                fn _type_eq<T>(_x: &T, _y: &T) {}
1691                fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1692                    // If `x` is a newtype around an `Interned<T>`, then `interner` is an
1693                    // interner of appropriate type. (Ideally we'd also check that `x` is a
1694                    // newtype with just that one field. Not sure how to do that.)
1695                    let interner = _intern_set_ty_from_interned_ty(x.0);
1696                    // Now check that this is the same type as `interners.$set`.
1697                    _type_eq(&interner, &tcx.interners.$set);
1698                }
1699
1700                assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1701                // SAFETY: we just checked that `self` is interned and therefore is valid for the
1702                // entire lifetime of the `TyCtxt`.
1703                unsafe { mem::transmute(self) }
1704            }
1705        }
1706    };
1707}
1708
1709macro_rules! nop_list_lift {
1710    ($set:ident; $ty:ty => $lifted:ty) => {
1711        nop_list_lift! { $set: List; $ty => $lifted }
1712    };
1713    // Allows defining own list type
1714    ($set:ident: $list:ident; $ty:ty => $lifted:ty) => {
1715        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a $list<$ty> {
1716            type Lifted = &'tcx $list<$lifted>;
1717            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1718                // Assert that the set has the right type.
1719                if false {
1720                    let _x: &InternedSet<'tcx, $list<$lifted>> = &tcx.interners.$set;
1721                }
1722
1723                if self.is_empty() {
1724                    return $list::empty();
1725                }
1726                assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1727                // SAFETY: we just checked that `self` is interned and therefore is valid for the
1728                // entire lifetime of the `TyCtxt`.
1729                unsafe { mem::transmute(self) }
1730            }
1731        }
1732    };
1733}
1734
1735impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Ty<'a> {
    type Lifted = Ty<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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_);
        }
        if !tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { type_; Ty<'a> => Ty<'tcx> }
1736impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Pattern<'a> {
    type Lifted = Pattern<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
        }
        if !tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
1737impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ConstAllocation<'a> {
    type Lifted = ConstAllocation<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
        }
        if !tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
1738impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Predicate<'a> {
    type Lifted = Predicate<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
        }
        if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
1739impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Clause<'a> {
    type Lifted = Clause<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
        }
        if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
1740impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Layout<'a> {
    type Lifted = Layout<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
        }
        if !tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { layout; Layout<'a> => Layout<'tcx> }
1741impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ValTree<'a> {
    type Lifted = ValTree<'tcx>;
    #[track_caller]
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
        }
        if !tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
1742
1743impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, RegionKind<'a>> {
1744    type Lifted = Interned<'tcx, RegionKind<'tcx>>;
1745
1746    #[track_caller]
1747    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1748        if !tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0)) {
    ::core::panicking::panic("assertion failed: tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0))")
};assert!(tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0)));
1749        // SAFETY: we just checked that `self` is interned in this `TyCtxt`, so
1750        // its pointee is valid for the entire lifetime of the target `TyCtxt`.
1751        unsafe { mem::transmute(self) }
1752    }
1753}
1754
1755// FIXME: unclear why exactly the macro doesn't work.
1756impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, WithCachedTypeInfo<ConstKind<'a>>> {
1757    type Lifted = Interned<'tcx, WithCachedTypeInfo<ConstKind<'tcx>>>;
1758
1759    #[track_caller]
1760    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1761        if !tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0)) {
    ::core::panicking::panic("assertion failed: tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0))")
};assert!(tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0)));
1762        // SAFETY: we just checked that `self` is interned in this `TyCtxt`, so
1763        // its pointee is valid for the entire lifetime of the target `TyCtxt`.
1764        unsafe { mem::transmute(self) }
1765    }
1766}
1767
1768impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Ty<'a>> {
    type Lifted = &'tcx List<Ty<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<Ty<'tcx>>> =
                &tcx.interners.type_lists;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
1769impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a ListWithCachedTypeInfo<Clause<'a>> {
    type Lifted = &'tcx ListWithCachedTypeInfo<Clause<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>> =
                &tcx.interners.clauses;
        }
        if self.is_empty() { return ListWithCachedTypeInfo::empty(); }
        if !tcx.interners.clauses.contains_pointer_to(&InternedInSet(self)) {
            ::core::panicking::panic("assertion failed: tcx.interners.clauses.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { clauses: ListWithCachedTypeInfo; Clause<'a> => Clause<'tcx> }
1770impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<PolyExistentialPredicate<'a>> {
    type Lifted = &'tcx List<PolyExistentialPredicate<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>> =
                &tcx.interners.poly_existential_predicates;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! {
1771    poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1772}
1773impl<'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>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>> =
                &tcx.interners.bound_variable_kinds;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self))
            {
            ::core::panicking::panic("assertion failed: tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind<'a> => ty::BoundVariableKind<'tcx> }
1774impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Pattern<'a>> {
    type Lifted = &'tcx List<Pattern<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<Pattern<'tcx>>> =
                &tcx.interners.patterns;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.patterns.contains_pointer_to(&InternedInSet(self)) {
            ::core::panicking::panic("assertion failed: tcx.interners.patterns.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { patterns; Pattern<'a> => Pattern<'tcx> }
1775impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<ty::ArgOutlivesClause<'a>> {
    type Lifted = &'tcx List<ty::ArgOutlivesClause<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<ty::ArgOutlivesClause<'tcx>>> =
                &tcx.interners.outlives;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.outlives.contains_pointer_to(&InternedInSet(self)) {
            ::core::panicking::panic("assertion failed: tcx.interners.outlives.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { outlives; ty::ArgOutlivesClause<'a> => ty::ArgOutlivesClause<'tcx> }
1776
1777// This is the impl for `&'a GenericArgs<'a>`.
1778impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<GenericArg<'a>> {
    type Lifted = &'tcx List<GenericArg<'tcx>>;
    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
        if false {
            let _x: &InternedSet<'tcx, List<GenericArg<'tcx>>> =
                &tcx.interners.args;
        }
        if self.is_empty() { return List::empty(); }
        if !tcx.interners.args.contains_pointer_to(&InternedInSet(self)) {
            ::core::panicking::panic("assertion failed: tcx.interners.args.contains_pointer_to(&InternedInSet(self))")
        };
        unsafe { mem::transmute(self) }
    }
}nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
1779
1780macro_rules! sty_debug_print {
1781    ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1782        #[allow(non_snake_case, reason = "we're using variant names as local variables")]
1783        mod inner {
1784            use crate::ty::{self, TyCtxt};
1785            use crate::ty::context::InternedInSet;
1786
1787            #[derive(Copy, Clone)]
1788            struct DebugStat {
1789                total: usize,
1790                lt_infer: usize,
1791                ty_infer: usize,
1792                ct_infer: usize,
1793                all_infer: usize,
1794            }
1795
1796            pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1797                let mut total = DebugStat {
1798                    total: 0,
1799                    lt_infer: 0,
1800                    ty_infer: 0,
1801                    ct_infer: 0,
1802                    all_infer: 0,
1803                };
1804                $(let mut $variant = total;)*
1805
1806                for shard in tcx.interners.type_.lock_shards() {
1807                    // It seems that ordering doesn't affect anything here.
1808                    #[allow(rustc::potential_query_instability)]
1809                    let types = shard.iter();
1810                    for &(InternedInSet(t), ()) in types {
1811                        let variant = match t.internee {
1812                            ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1813                                ty::Float(..) | ty::Str | ty::Never => continue,
1814                            ty::Error(_) => /* unimportant */ continue,
1815                            $(ty::$variant(..) => &mut $variant,)*
1816                        };
1817                        let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1818                        let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1819                        let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1820
1821                        variant.total += 1;
1822                        total.total += 1;
1823                        if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1824                        if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1825                        if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1826                        if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1827                    }
1828                }
1829                writeln!(fmt, "Ty interner             total           ty lt ct all")?;
1830                $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
1831                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1832                    stringify!($variant),
1833                    uses = $variant.total,
1834                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
1835                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
1836                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
1837                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
1838                    all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
1839                )*
1840                writeln!(fmt, "                  total {uses:6}        \
1841                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1842                    uses = total.total,
1843                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
1844                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
1845                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
1846                    all = total.all_infer as f64 * 100.0  / total.total as f64)
1847            }
1848        }
1849
1850        inner::go($fmt, $ctxt)
1851    }}
1852}
1853
1854impl<'tcx> TyCtxt<'tcx> {
1855    pub fn debug_stats(self) -> impl fmt::Debug {
1856        fmt::from_fn(move |fmt| {
1857            {
    #[allow(non_snake_case, reason =
    "we're using variant names as local variables")]
    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) -> Self {
                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!(
1858                fmt,
1859                self,
1860                Adt,
1861                Array,
1862                Slice,
1863                RawPtr,
1864                Ref,
1865                FnDef,
1866                FnPtr,
1867                UnsafeBinder,
1868                Placeholder,
1869                Coroutine,
1870                CoroutineWitness,
1871                Dynamic,
1872                Closure,
1873                CoroutineClosure,
1874                Tuple,
1875                Bound,
1876                Param,
1877                Infer,
1878                Alias,
1879                Pat,
1880                Foreign
1881            )?;
1882
1883            fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
        self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1884            fmt.write_fmt(format_args!("Region interner: #{0}\n",
        self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1885            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())?;
1886            fmt.write_fmt(format_args!("Layout interner: #{0}\n",
        self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1887
1888            Ok(())
1889        })
1890    }
1891}
1892
1893// This type holds a `T` in the interner. The `T` is stored in the arena and
1894// this type just holds a pointer to it, but it still effectively owns it. It
1895// impls `Borrow` so that it can be looked up using the original
1896// (non-arena-memory-owning) types.
1897struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1898
1899impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1900    fn clone(&self) -> Self {
1901        *self
1902    }
1903}
1904
1905impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1906
1907impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1908    fn into_pointer(&self) -> *const () {
1909        self.0 as *const _ as *const ()
1910    }
1911}
1912
1913#[allow(rustc::usage_of_ty_tykind)]
1914impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1915    fn borrow(&self) -> &T {
1916        &self.0.internee
1917    }
1918}
1919
1920impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1921    fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1922        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1923        // `x == y`.
1924        self.0.internee == other.0.internee
1925    }
1926}
1927
1928impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1929
1930impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1931    fn hash<H: Hasher>(&self, s: &mut H) {
1932        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1933        self.0.internee.hash(s)
1934    }
1935}
1936
1937impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1938    fn borrow(&self) -> &[T] {
1939        &self.0[..]
1940    }
1941}
1942
1943impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1944    fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1945        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1946        // `x == y`.
1947        self.0[..] == other.0[..]
1948    }
1949}
1950
1951impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1952
1953impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1954    fn hash<H: Hasher>(&self, s: &mut H) {
1955        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1956        self.0[..].hash(s)
1957    }
1958}
1959
1960impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1961    fn borrow(&self) -> &[T] {
1962        &self.0[..]
1963    }
1964}
1965
1966impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1967    fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1968        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1969        // `x == y`.
1970        self.0[..] == other.0[..]
1971    }
1972}
1973
1974impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1975
1976impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1977    fn hash<H: Hasher>(&self, s: &mut H) {
1978        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1979        self.0[..].hash(s)
1980    }
1981}
1982
1983macro_rules! direct_interners {
1984    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1985        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1986            fn borrow<'a>(&'a self) -> &'a $ty {
1987                &self.0
1988            }
1989        }
1990
1991        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1992            fn eq(&self, other: &Self) -> bool {
1993                // The `Borrow` trait requires that `x.borrow() == y.borrow()`
1994                // equals `x == y`.
1995                self.0 == other.0
1996            }
1997        }
1998
1999        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2000
2001        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2002            fn hash<H: Hasher>(&self, s: &mut H) {
2003                // The `Borrow` trait requires that `x.borrow().hash(s) ==
2004                // x.hash(s)`.
2005                self.0.hash(s)
2006            }
2007        }
2008
2009        impl<'tcx> TyCtxt<'tcx> {
2010            $vis fn $method(self, v: $ty) -> $ret_ty {
2011                $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2012                    InternedInSet(self.interners.arena.alloc(v))
2013                }).0))
2014            }
2015        })+
2016    }
2017}
2018
2019// Functions with a `mk_` prefix are intended for use outside this file and
2020// crate. Functions with an `intern_` prefix are intended for use within this
2021// crate only, and have a corresponding `mk_` function.
2022impl<'tcx> Borrow<RegionKind<'tcx>> for InternedInSet<'tcx, RegionKind<'tcx>>
    {
    fn borrow<'a>(&'a self) -> &'a RegionKind<'tcx> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, RegionKind<'tcx>> {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, RegionKind<'tcx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, RegionKind<'tcx>> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub(crate) fn intern_region(self, v: RegionKind<'tcx>) -> Region<'tcx> {
        Region(Interned::new_unchecked(self.interners.region.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'tcx> Borrow<ValTreeKind<TyCtxt<'tcx>>> for
    InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
    fn borrow<'a>(&'a self) -> &'a ValTreeKind<TyCtxt<'tcx>> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {}
impl<'tcx> Hash for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub(crate) fn intern_valtree(self, v: ValTreeKind<TyCtxt<'tcx>>)
        -> ValTree<'tcx> {
        ValTree(Interned::new_unchecked(self.interners.valtree.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'tcx> Borrow<PatternKind<'tcx>> for
    InternedInSet<'tcx, PatternKind<'tcx>> {
    fn borrow<'a>(&'a self) -> &'a PatternKind<'tcx> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, PatternKind<'tcx>> {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, PatternKind<'tcx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, PatternKind<'tcx>> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub fn mk_pat(self, v: PatternKind<'tcx>) -> Pattern<'tcx> {
        Pattern(Interned::new_unchecked(self.interners.pat.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'tcx> Borrow<Allocation> for InternedInSet<'tcx, Allocation> {
    fn borrow<'a>(&'a self) -> &'a Allocation { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, Allocation> {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, Allocation> {}
impl<'tcx> Hash for InternedInSet<'tcx, Allocation> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub fn mk_const_alloc(self, v: Allocation) -> ConstAllocation<'tcx> {
        ConstAllocation(Interned::new_unchecked(self.interners.const_allocation.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'tcx> Borrow<LayoutData<FieldIdx, VariantIdx>> for
    InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {
    fn borrow<'a>(&'a self) -> &'a LayoutData<FieldIdx, VariantIdx> {
        &self.0
    }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>>
    {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub fn mk_layout(self, v: LayoutData<FieldIdx, VariantIdx>)
        -> Layout<'tcx> {
        Layout(Interned::new_unchecked(self.interners.layout.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'tcx> Borrow<AdtDefData> for InternedInSet<'tcx, AdtDefData> {
    fn borrow<'a>(&'a self) -> &'a AdtDefData { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, AdtDefData> {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, AdtDefData> {}
impl<'tcx> Hash for InternedInSet<'tcx, AdtDefData> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    pub fn mk_adt_def_from_data(self, v: AdtDefData) -> AdtDef<'tcx> {
        AdtDef(Interned::new_unchecked(self.interners.adt_def.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}
impl<'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))
    }
}
impl<'tcx> Borrow<CanonicalInputData<TyCtxt<'tcx>>> for
    InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {
    fn borrow<'a>(&'a self) -> &'a CanonicalInputData<TyCtxt<'tcx>> {
        &self.0
    }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>>
    {
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {}
impl<'tcx> Hash for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {
    fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
    fn intern_canonical_input(self, v: CanonicalInputData<TyCtxt<'tcx>>)
        -> CanonicalInput<'tcx> {
        CanonicalInput(Interned::new_unchecked(self.interners.canonical_inputs.intern(v,
                        |v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
    }
}direct_interners! {
2023    region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2024    valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2025    pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2026    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2027    layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2028    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2029    external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2030        ExternalConstraints -> ExternalConstraints<'tcx>,
2031    canonical_inputs: intern_canonical_input(CanonicalInputData<TyCtxt<'tcx>>): CanonicalInput -> CanonicalInput<'tcx>,
2032}
2033
2034macro_rules! slice_interners {
2035    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2036        impl<'tcx> TyCtxt<'tcx> {
2037            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2038                if v.is_empty() {
2039                    List::empty()
2040                } else {
2041                    self.interners.$field.intern_ref(v, || {
2042                        InternedInSet(List::from_arena(&*self.arena, (), v))
2043                    }).0
2044                }
2045            })+
2046        }
2047    );
2048}
2049
2050// These functions intern slices. They all have a corresponding
2051// `mk_foo_from_iter` function that interns an iterator. The slice version
2052// should be used when possible, because it's faster.
2053impl<'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::ArgOutlivesClause<'tcx>])
        -> &'tcx List<ty::ArgOutlivesClause<'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!(
2054    const_lists: pub mk_const_list(Const<'tcx>),
2055    args: pub mk_args(GenericArg<'tcx>),
2056    type_lists: pub mk_type_list(Ty<'tcx>),
2057    canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2058    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2059    projs: pub mk_projs(ProjectionKind),
2060    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2061    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2062    fields: pub mk_fields(FieldIdx),
2063    local_def_ids: intern_local_def_ids(LocalDefId),
2064    captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2065    patterns: pub mk_patterns(Pattern<'tcx>),
2066    outlives: pub mk_outlives(ty::ArgOutlivesClause<'tcx>),
2067    predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2068);
2069
2070impl<'tcx> TyCtxt<'tcx> {
2071    /// Given a `fn` sig, returns an equivalent `unsafe fn` type;
2072    /// that is, a `fn` type that is equivalent in every way for being
2073    /// unsafe.
2074    pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2075        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2076        Ty::new_fn_ptr(
2077            self,
2078            sig.map_bound(|sig| ty::FnSig {
2079                fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2080                ..sig
2081            }),
2082        )
2083    }
2084
2085    /// Given a `fn` sig, returns an equivalent `unsafe fn` sig;
2086    /// that is, a `fn` sig that is equivalent in every way for being
2087    /// unsafe.
2088    pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2089        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2090        sig.map_bound(|sig| ty::FnSig {
2091            fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2092            ..sig
2093        })
2094    }
2095
2096    /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
2097    /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
2098    pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2099        elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2100            self.associated_items(trait_did)
2101                .filter_by_name_unhygienic(assoc_name.name)
2102                .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2103        })
2104    }
2105
2106    /// Given a `ty`, return whether it's an `impl Future<...>`.
2107    pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2108        let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2109            return false;
2110        };
2111        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2112
2113        self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2114            let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2115                return false;
2116            };
2117            trait_predicate.trait_ref.def_id == future_trait
2118                && trait_predicate.polarity == ClausePolarity::Positive
2119        })
2120    }
2121
2122    /// Given a closure signature, returns an equivalent fn signature. Detuples
2123    /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
2124    /// you would get a `fn(u32, i32)`.
2125    /// `unsafety` determines the unsafety of the fn signature. If you pass
2126    /// `hir::Safety::Unsafe` in the previous example, then you would get
2127    /// an `unsafe fn (u32, i32)`.
2128    /// It cannot convert a closure that requires unsafe.
2129    pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2130        sig.map_bound(|s| {
2131            let params = match s.inputs()[0].kind() {
2132                ty::Tuple(params) => *params,
2133                _ => ::rustc_span::macros::bug_impl(None, format_args!("impossible case reached"),
    Location::caller())bug!(),
2134            };
2135            // Ignore splatting, it is unsupported on closures.
2136            if !s.splatted().is_none() {
    ::core::panicking::panic("assertion failed: s.splatted().is_none()")
};assert!(s.splatted().is_none());
2137            self.mk_fn_sig(
2138                params,
2139                s.output(),
2140                s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2141            )
2142        })
2143    }
2144
2145    #[inline]
2146    pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2147        self.interners.intern_predicate(binder)
2148    }
2149
2150    #[inline]
2151    pub fn reuse_or_mk_predicate(
2152        self,
2153        pred: Predicate<'tcx>,
2154        binder: Binder<'tcx, PredicateKind<'tcx>>,
2155    ) -> Predicate<'tcx> {
2156        if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2157    }
2158
2159    /// If you have a [`ty::Alias`], you should almost certainly be calling
2160    /// [`Self::check_alias_term_args_compatible`] instead. This method assumes that inherent alias
2161    /// consts always have `impl`-form args, and will return an invalid result if the `def_id` comes
2162    /// from a [`ty::AliasConstKind::InherentSelf`] (see the doc on that for what "impl form args"
2163    /// means).
2164    pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2165        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)
2166            && #[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 });
2167        self.check_args_compatible_inner(def_id, args, is_inherent_assoc_ty)
2168    }
2169
2170    pub fn check_alias_term_args_compatible(
2171        self,
2172        kind: ty::AliasTermKind<'tcx>,
2173        args: &'tcx [ty::GenericArg<'tcx>],
2174    ) -> bool {
2175        let (def_id, is_self_args) = match kind {
2176            ty::AliasTermKind::ProjectionTy { def_id }
2177            | ty::AliasTermKind::OpaqueTy { def_id }
2178            | ty::AliasTermKind::FreeTy { def_id }
2179            | ty::AliasTermKind::AnonConst { def_id }
2180            | ty::AliasTermKind::ProjectionConst { def_id }
2181            | ty::AliasTermKind::FreeConst { def_id }
2182            | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2183            ty::AliasTermKind::InherentTy { def_id }
2184            | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2185        };
2186        self.check_args_compatible_inner(def_id, args, is_self_args)
2187    }
2188
2189    fn check_args_compatible_inner(
2190        self,
2191        def_id: DefId,
2192        args: &'tcx [ty::GenericArg<'tcx>],
2193        is_self_args: bool,
2194    ) -> bool {
2195        let generics = self.generics_of(def_id);
2196        let own_args = if is_self_args {
2197            if generics.own_params.len() + 1 != args.len() {
2198                return false;
2199            }
2200
2201            if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
    ty::GenericArgKind::Type(_) => true,
    _ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2202                return false;
2203            }
2204
2205            &args[1..]
2206        } else {
2207            if generics.count() != args.len() {
2208                return false;
2209            }
2210
2211            let (parent_args, own_args) = args.split_at(generics.parent_count);
2212
2213            // In the type system, IATs and IACs (inherent associated types/consts) themselves have a
2214            // weird arg setup (self + own args), but nested items *in* IATs (namely: opaques, i.e.
2215            // ATPITs) do not. So, set `is_self_args` to false for the parent generic check.
2216            if let Some(parent) = generics.parent
2217                && !self.check_args_compatible_inner(parent, parent_args, false)
2218            {
2219                return false;
2220            }
2221
2222            own_args
2223        };
2224
2225        for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2226            match (&param.kind, arg.kind()) {
2227                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2228                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2229                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2230                _ => return false,
2231            }
2232        }
2233
2234        true
2235    }
2236
2237    /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
2238    /// and print out the args if not.
2239    ///
2240    /// If you have a [`ty::Alias`], you should use
2241    /// [`Self::debug_assert_alias_term_args_compatible`] instead. See note on
2242    /// [`Self::check_args_compatible`].
2243    pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2244        if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2245            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)
2246                && #[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 });
2247            self.emit_bug_args_compatible(def_id, args, is_inherent_assoc_ty);
2248        }
2249    }
2250
2251    pub fn debug_assert_alias_term_args_compatible(
2252        self,
2253        kind: ty::AliasTermKind<'tcx>,
2254        args: ty::GenericArgsRef<'tcx>,
2255    ) {
2256        if truecfg!(debug_assertions) {
2257            self.debug_assert_alias_term_kind_matches_def_kind(kind);
2258            if !self.check_alias_term_args_compatible(kind, args) {
2259                let (def_id, is_self_args) = match kind {
2260                    ty::AliasTermKind::ProjectionTy { def_id }
2261                    | ty::AliasTermKind::OpaqueTy { def_id }
2262                    | ty::AliasTermKind::FreeTy { def_id }
2263                    | ty::AliasTermKind::AnonConst { def_id }
2264                    | ty::AliasTermKind::ProjectionConst { def_id }
2265                    | ty::AliasTermKind::FreeConst { def_id }
2266                    | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2267                    ty::AliasTermKind::InherentTy { def_id }
2268                    | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2269                };
2270                self.emit_bug_args_compatible(def_id, args, is_self_args);
2271            }
2272        }
2273    }
2274
2275    fn debug_assert_alias_term_kind_matches_def_kind(self, kind: ty::AliasTermKind<'tcx>) {
2276        match kind {
2277            ty::AliasTermKind::ProjectionTy { def_id } => {
2278                if true {
    {
        match self.def_kind(def_id) {
            DefKind::AssocTy => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AssocTy", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy);
2279                if true {
    {
        match self.def_kind(self.parent(def_id)) {
            DefKind::Trait | DefKind::Impl { of_trait: true } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Trait | DefKind::Impl { of_trait: true }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(
2280                    self.def_kind(self.parent(def_id)),
2281                    DefKind::Trait | DefKind::Impl { of_trait: true }
2282                );
2283            }
2284            ty::AliasTermKind::InherentTy { def_id } => {
2285                if true {
    {
        match self.def_kind(def_id) {
            DefKind::AssocTy => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AssocTy", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy);
2286                if true {
    {
        match self.def_kind(self.parent(def_id)) {
            DefKind::Impl { of_trait: false } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Impl { of_trait: false }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(
2287                    self.def_kind(self.parent(def_id)),
2288                    DefKind::Impl { of_trait: false }
2289                );
2290            }
2291            ty::AliasTermKind::OpaqueTy { def_id } => {
2292                if true {
    {
        match self.def_kind(def_id) {
            DefKind::OpaqueTy => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::OpaqueTy", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::OpaqueTy);
2293            }
2294            ty::AliasTermKind::FreeTy { def_id } => {
2295                if true {
    {
        match self.def_kind(def_id) {
            DefKind::TyAlias => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::TyAlias", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::TyAlias);
2296            }
2297            ty::AliasTermKind::AnonConst { def_id } => {
2298                if true {
    {
        match self.def_kind(def_id) {
            DefKind::AnonConst => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AnonConst", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AnonConst);
2299            }
2300            ty::AliasTermKind::ProjectionConst { def_id } => {
2301                if true {
    {
        match self.def_kind(def_id) {
            DefKind::AssocConst => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AssocConst", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocConst);
2302                if true {
    {
        match self.def_kind(self.parent(def_id)) {
            DefKind::Trait | DefKind::Impl { of_trait: true } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Trait | DefKind::Impl { of_trait: true }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(
2303                    self.def_kind(self.parent(def_id)),
2304                    DefKind::Trait | DefKind::Impl { of_trait: true }
2305                );
2306            }
2307            ty::AliasTermKind::InherentConstSelf { def_id }
2308            | ty::AliasTermKind::InherentConstImpl { def_id } => {
2309                if true {
    {
        match self.def_kind(def_id) {
            DefKind::AssocConst => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AssocConst", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocConst);
2310                if true {
    {
        match self.def_kind(self.parent(def_id)) {
            DefKind::Impl { of_trait: false } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Impl { of_trait: false }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(
2311                    self.def_kind(self.parent(def_id)),
2312                    DefKind::Impl { of_trait: false }
2313                );
2314            }
2315            ty::AliasTermKind::FreeConst { def_id } => {
2316                if true {
    {
        match self.def_kind(def_id) {
            DefKind::Const => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Const", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::Const);
2317            }
2318        }
2319    }
2320
2321    fn emit_bug_args_compatible(
2322        self,
2323        def_id: DefId,
2324        args: &'tcx [ty::GenericArg<'tcx>],
2325        is_self_args: bool,
2326    ) -> ! {
2327        if is_self_args {
2328            ::rustc_span::macros::bug_impl(None,
    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()))), Location::caller());bug!(
2329                "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2330                self.def_path_str(def_id),
2331                args,
2332                // Make `[Self, GAT_ARGS...]` (this could be simplified)
2333                self.mk_args_from_iter(
2334                    [self.types.self_param.into()].into_iter().chain(
2335                        self.generics_of(def_id)
2336                            .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2337                            .iter()
2338                            .copied()
2339                    )
2340                )
2341            );
2342        } else {
2343            ::rustc_span::macros::bug_impl(None,
    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)),
    Location::caller());bug!(
2344                "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2345                self.def_path_str(def_id),
2346                args,
2347                ty::GenericArgs::identity_for_item(self, def_id)
2348            );
2349        }
2350    }
2351
2352    #[inline(always)]
2353    pub(crate) fn check_and_mk_args(
2354        self,
2355        def_id: DefId,
2356        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2357    ) -> GenericArgsRef<'tcx> {
2358        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2359        self.debug_assert_args_compatible(def_id, args);
2360        args
2361    }
2362
2363    #[inline]
2364    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2365        self.interners.intern_const(kind)
2366    }
2367
2368    // Avoid this in favour of more specific `Ty::new_*` methods, where possible.
2369    #[allow(rustc::usage_of_ty_tykind)]
2370    #[inline]
2371    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2372        self.interners.intern_ty(st)
2373    }
2374
2375    pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2376        match param.kind {
2377            GenericParamDefKind::Lifetime => {
2378                ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2379            }
2380            GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2381            GenericParamDefKind::Const { .. } => {
2382                ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2383                    .into()
2384            }
2385        }
2386    }
2387
2388    pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2389        self.mk_place_elem(place, PlaceElem::Field(f, ty))
2390    }
2391
2392    pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2393        self.mk_place_elem(place, PlaceElem::Deref)
2394    }
2395
2396    pub fn mk_place_downcast(
2397        self,
2398        place: Place<'tcx>,
2399        adt_def: AdtDef<'tcx>,
2400        variant_index: VariantIdx,
2401    ) -> Place<'tcx> {
2402        self.mk_place_elem(
2403            place,
2404            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2405        )
2406    }
2407
2408    pub fn mk_place_downcast_unnamed(
2409        self,
2410        place: Place<'tcx>,
2411        variant_index: VariantIdx,
2412    ) -> Place<'tcx> {
2413        self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2414    }
2415
2416    pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2417        self.mk_place_elem(place, PlaceElem::Index(index))
2418    }
2419
2420    /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2421    /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2422    /// flight.
2423    pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2424        Place {
2425            local: place.local,
2426            projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2427        }
2428    }
2429
2430    pub fn mk_poly_existential_predicates(
2431        self,
2432        eps: &[PolyExistentialPredicate<'tcx>],
2433    ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2434        if !!eps.is_empty() {
    ::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2435        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!(
2436            eps.array_windows()
2437                .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2438                    != Ordering::Greater)
2439        );
2440        self.intern_poly_existential_predicates(eps)
2441    }
2442
2443    pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2444        // FIXME consider asking the input slice to be sorted to avoid
2445        // re-interning permutations, in which case that would be asserted
2446        // here.
2447        self.interners.intern_clauses(clauses)
2448    }
2449
2450    pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2451        // FIXME consider asking the input slice to be sorted to avoid
2452        // re-interning permutations, in which case that would be asserted
2453        // here.
2454        self.intern_local_def_ids(def_ids)
2455    }
2456
2457    pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2458    where
2459        I: Iterator<Item = T>,
2460        T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2461    {
2462        T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2463    }
2464
2465    pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2466    where
2467        I: Iterator<Item = T>,
2468        T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2469    {
2470        T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2471    }
2472
2473    pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2474    where
2475        I: Iterator<Item = T>,
2476        T: CollectAndApply<
2477                &'tcx ty::CapturedPlace<'tcx>,
2478                &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2479            >,
2480    {
2481        T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2482    }
2483
2484    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2485    where
2486        I: Iterator<Item = T>,
2487        T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2488    {
2489        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2490    }
2491
2492    // Unlike various other `mk_*_from_iter` functions, this one uses `I:
2493    // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
2494    // variant, because of the need to combine `inputs` and `output`. This
2495    // explains the lack of `_from_iter` suffix.
2496    pub fn mk_fn_sig<I, T>(
2497        self,
2498        inputs: I,
2499        output: I::Item,
2500        fn_sig_kind: FnSigKind<'tcx>,
2501    ) -> T::Output
2502    where
2503        I: IntoIterator<Item = T>,
2504        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2505    {
2506        T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2507            inputs_and_output: self.mk_type_list(xs),
2508            fn_sig_kind,
2509        })
2510    }
2511
2512    /// `mk_fn_sig`, but with a Rust ABI, and no C-variadic argument.
2513    pub fn mk_fn_sig_rust_abi<I, T>(
2514        self,
2515        inputs: I,
2516        output: I::Item,
2517        safety: hir::Safety,
2518    ) -> T::Output
2519    where
2520        I: IntoIterator<Item = T>,
2521        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2522    {
2523        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2524    }
2525
2526    /// `mk_fn_sig`, but with a safe Rust ABI, and no C-variadic argument.
2527    pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2528    where
2529        I: IntoIterator<Item = T>,
2530        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2531    {
2532        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2533    }
2534
2535    /// `mk_fn_sig`, but with an **un**safe Rust ABI, and no C-variadic argument.
2536    pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2537    where
2538        I: IntoIterator<Item = T>,
2539        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2540    {
2541        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2542    }
2543
2544    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2545    where
2546        I: Iterator<Item = T>,
2547        T: CollectAndApply<
2548                PolyExistentialPredicate<'tcx>,
2549                &'tcx List<PolyExistentialPredicate<'tcx>>,
2550            >,
2551    {
2552        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2553    }
2554
2555    pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2556    where
2557        I: Iterator<Item = T>,
2558        T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2559    {
2560        T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2561    }
2562
2563    pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2564    where
2565        I: Iterator<Item = T>,
2566        T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2567    {
2568        T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2569    }
2570
2571    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2572    where
2573        I: Iterator<Item = T>,
2574        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2575    {
2576        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2577    }
2578
2579    pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2580    where
2581        I: Iterator<Item = T>,
2582        T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2583    {
2584        T::collect_and_apply(iter, |xs| self.mk_args(xs))
2585    }
2586
2587    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2588    where
2589        I: Iterator<Item = T>,
2590        T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2591    {
2592        T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2593    }
2594
2595    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2596    where
2597        I: Iterator<Item = T>,
2598        T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2599    {
2600        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2601    }
2602
2603    pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2604    where
2605        I: Iterator<Item = T>,
2606        T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2607    {
2608        T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2609    }
2610
2611    pub fn mk_args_trait(
2612        self,
2613        self_ty: Ty<'tcx>,
2614        rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2615    ) -> GenericArgsRef<'tcx> {
2616        self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2617    }
2618
2619    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2620    where
2621        I: Iterator<Item = T>,
2622        T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2623    {
2624        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2625    }
2626
2627    pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2628    where
2629        I: Iterator<Item = T>,
2630        T: CollectAndApply<
2631                ty::ArgOutlivesClause<'tcx>,
2632                &'tcx ty::List<ty::ArgOutlivesClause<'tcx>>,
2633            >,
2634    {
2635        T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2636    }
2637
2638    /// Emit a lint at `span` from a lint struct (some type that implements `Diagnostic`,
2639    /// typically generated by `#[derive(Diagnostic)]`).
2640    #[track_caller]
2641    pub fn emit_node_span_lint(
2642        self,
2643        lint: &'static Lint,
2644        hir_id: HirId,
2645        span: impl Into<MultiSpan>,
2646        decorator: impl for<'a> Diagnostic<'a>,
2647    ) {
2648        let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2649        emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2650    }
2651
2652    /// Find the appropriate span where `use` and outer attributes can be inserted at.
2653    pub fn crate_level_attribute_injection_span(self) -> Span {
2654        let node = self.hir_node(hir::CRATE_HIR_ID);
2655        let hir::Node::Crate(m) = node else { ::rustc_span::macros::bug_impl(None, format_args!("impossible case reached"),
    Location::caller())bug!() };
2656        m.spans.inject_use_span.shrink_to_lo()
2657    }
2658
2659    pub fn disabled_nightly_features(
2660        self,
2661        diag: &mut Diag<'_>,
2662        features: impl IntoIterator<Item = (String, Symbol)>,
2663    ) {
2664        if !self.sess.is_nightly_build() {
2665            return;
2666        }
2667
2668        let span = self.crate_level_attribute_injection_span();
2669        for (desc, feature) in features {
2670            // FIXME: make this string translatable
2671            let msg =
2672                ::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}");
2673            diag.span_suggestion_verbose(
2674                span,
2675                msg,
2676                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
    })format!("#![feature({feature})]\n"),
2677                Applicability::MaybeIncorrect,
2678            );
2679        }
2680    }
2681
2682    /// Emit a lint from a lint struct (some type that implements `Diagnostic`, typically generated
2683    /// by `#[derive(Diagnostic)]`).
2684    #[track_caller]
2685    pub fn emit_node_lint(
2686        self,
2687        lint: &'static Lint,
2688        id: HirId,
2689        decorator: impl for<'a> Diagnostic<'a>,
2690    ) {
2691        let level_spec = self.lint_level_spec_at_node(lint, id);
2692        emit_lint_base(self.sess, lint, level_spec, None, decorator);
2693    }
2694
2695    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2696        let map = self.in_scope_traits_map(id.owner)?;
2697        let candidates = map.get(&id.local_id)?;
2698        Some(candidates)
2699    }
2700
2701    pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2702        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_middle/src/ty/context.rs:2702",
                        "rustc_middle::ty::context", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_middle/src/ty/context.rs"),
                        ::tracing_core::__macro_support::Option::Some(2702u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
                        ::tracing_core::field::FieldSet::new(&["message",
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("id")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("id");
                                            NAME.as_str()
                                        }], ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("named_region")
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&id)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(?id, "named_region");
2703        self.named_variable_map(id.owner).get(&id.local_id).cloned()
2704    }
2705
2706    pub fn is_late_bound(self, id: HirId) -> bool {
2707        self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2708    }
2709
2710    pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2711        self.mk_bound_variable_kinds(
2712            &self
2713                .late_bound_vars_map(id.owner)
2714                .get(&id.local_id)
2715                .cloned()
2716                .unwrap_or_else(|| ::rustc_span::macros::bug_impl(None,
    format_args!("No bound vars found for {0}", self.hir_id_to_string(id)),
    Location::caller())bug!("No bound vars found for {}", self.hir_id_to_string(id))),
2717        )
2718    }
2719
2720    /// Given the def-id of an early-bound lifetime on an opaque corresponding to
2721    /// a duplicated captured lifetime, map it back to the early- or late-bound
2722    /// lifetime of the function from which it originally as captured. If it is
2723    /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
2724    /// of the signature.
2725    // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
2726    // re-use the generics of the opaque, this function will need to be tweaked slightly.
2727    pub fn map_opaque_lifetime_to_parent_lifetime(
2728        self,
2729        mut opaque_lifetime_param_def_id: LocalDefId,
2730    ) -> ty::Region<'tcx> {
2731        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!(
2732            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2733            "{opaque_lifetime_param_def_id:?} is a {}",
2734            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2735        );
2736
2737        loop {
2738            let parent = self.local_parent(opaque_lifetime_param_def_id);
2739            let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2740
2741            let Some((lifetime, _)) = lifetime_mapping
2742                .iter()
2743                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2744            else {
2745                ::rustc_span::macros::bug_impl(None,
    format_args!("duplicated lifetime param should be present"),
    Location::caller());bug!("duplicated lifetime param should be present");
2746            };
2747
2748            match *lifetime {
2749                resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2750                    let new_parent = self.local_parent(ebv);
2751
2752                    // If we map to another opaque, then it should be a parent
2753                    // of the opaque we mapped from. Continue mapping.
2754                    if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
    DefKind::OpaqueTy => true,
    _ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2755                        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);
2756                        opaque_lifetime_param_def_id = ebv;
2757                        continue;
2758                    }
2759
2760                    let generics = self.generics_of(new_parent);
2761                    return ty::Region::new_early_param(
2762                        self,
2763                        ty::EarlyParamRegion {
2764                            index: generics
2765                                .param_def_id_to_index(self, ebv.to_def_id())
2766                                .expect("early-bound var should be present in fn generics"),
2767                            name: self.item_name(ebv.to_def_id()),
2768                        },
2769                    );
2770                }
2771                resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2772                    let new_parent = self.local_parent(lbv);
2773                    return ty::Region::new_late_param(
2774                        self,
2775                        new_parent.to_def_id(),
2776                        ty::LateParamRegionKind::Named(lbv.to_def_id()),
2777                    );
2778                }
2779                resolve_bound_vars::ResolvedArg::Error(guar) => {
2780                    return ty::Region::new_error(self, guar);
2781                }
2782                _ => {
2783                    return ty::Region::new_error_with_message(
2784                        self,
2785                        self.def_span(opaque_lifetime_param_def_id),
2786                        "cannot resolve lifetime",
2787                    );
2788                }
2789            }
2790        }
2791    }
2792
2793    /// Whether `def_id` is a stable const fn (i.e., doesn't need any feature gates to be called).
2794    ///
2795    /// When this is `false`, the function may still be callable as a `const fn` due to features
2796    /// being enabled!
2797    pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2798        self.is_const_fn(def_id)
2799            && match self.lookup_const_stability(def_id) {
2800                None => true, // a fn in a non-staged_api crate
2801                Some(stability) if stability.is_const_stable() => true,
2802                _ => false,
2803            }
2804    }
2805
2806    /// Whether the trait impl is marked const. This does not consider stability or feature gates.
2807    pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2808        self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2809            && #[allow(non_exhaustive_omitted_patterns)] match self.impl_trait_header(def_id).constness
    {
    hir::Constness::Const { always: false } => true,
    _ => false,
}matches!(
2810                self.impl_trait_header(def_id).constness,
2811                hir::Constness::Const { always: false }
2812            )
2813    }
2814
2815    pub fn is_sdylib_interface_build(self) -> bool {
2816        self.sess.opts.unstable_opts.build_sdylib_interface
2817    }
2818
2819    pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2820        let def_id = def_id.into_query_key();
2821        match self.def_kind(def_id) {
2822            DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2823            _ => None,
2824        }
2825    }
2826
2827    pub fn next_trait_solver_globally(self) -> bool {
2828        self.sess.opts.unstable_opts.next_solver.globally && !self.features().generic_const_exprs()
2829    }
2830
2831    pub fn next_trait_solver_in_coherence(self) -> bool {
2832        self.sess.opts.unstable_opts.next_solver.coherence
2833    }
2834
2835    pub fn disable_trait_solver_fast_paths(self) -> bool {
2836        self.sess.opts.unstable_opts.disable_fast_paths
2837    }
2838
2839    pub fn disable_param_env_normalization_hack(self) -> bool {
2840        self.sess.opts.unstable_opts.disable_param_env_normalization_hack
2841    }
2842
2843    pub fn renormalize_rigid_aliases(self) -> bool {
2844        self.sess.opts.unstable_opts.renormalize_rigid_aliases
2845    }
2846
2847    #[allow(rustc::bad_opt_access)]
2848    pub fn use_typing_mode_post_typeck_until_borrowck(self) -> bool {
2849        self.next_trait_solver_globally()
2850            || self.sess.opts.unstable_opts.typing_mode_post_typeck_until_borrowck
2851    }
2852
2853    pub fn assumptions_on_binders(self) -> bool {
2854        self.sess.opts.unstable_opts.assumptions_on_binders
2855    }
2856
2857    pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2858        self.opt_rpitit_info(def_id).is_some()
2859    }
2860
2861    pub fn get_impl_future_output_ty(self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
2862        let (def_id, args) = match *ty.kind() {
2863            ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
2864            ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, args, .. })
2865                if self.is_impl_trait_in_trait(def_id) =>
2866            {
2867                (def_id, args)
2868            }
2869            _ => return None,
2870        };
2871
2872        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2873        let item_def_id = self.associated_item_def_ids(future_trait)[0];
2874
2875        self.explicit_item_self_bounds(def_id)
2876            .iter_instantiated_copied(self, args)
2877            .map(ty::Unnormalized::skip_norm_wip)
2878            .find_map(|(predicate, _)| {
2879                predicate
2880                    .kind()
2881                    .map_bound(|kind| match kind {
2882                        ty::ClauseKind::Projection(projection_predicate)
2883                            if projection_predicate.def_id() == item_def_id =>
2884                        {
2885                            projection_predicate.term.as_type()
2886                        }
2887                        _ => None,
2888                    })
2889                    .no_bound_vars()
2890                    .flatten()
2891            })
2892    }
2893
2894    /// Named module children from all kinds of items, including imports.
2895    /// In addition to regular items this list also includes struct and variant constructors, and
2896    /// items inside `extern {}` blocks because all of them introduce names into parent module.
2897    ///
2898    /// Module here is understood in name resolution sense - it can be a `mod` item,
2899    /// or a crate root, or an enum, or a trait.
2900    ///
2901    /// This is not a query, making it a query causes perf regressions
2902    /// (probably due to hashing spans in `ModChild`ren).
2903    pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2904        self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2905    }
2906
2907    /// Return the crate imported by given use item.
2908    pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2909        self.resolutions(()).extern_crate_map.get(&def_id).copied()
2910    }
2911
2912    pub fn resolver_for_lowering(
2913        self,
2914    ) -> (&'tcx Steal<ResolverAstLowering<'tcx>>, &'tcx Steal<ast::Crate>) {
2915        let (resolver, krate, _) = self.resolver_for_lowering_raw(());
2916        (resolver, krate)
2917    }
2918
2919    pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2920        make_metadata(self)
2921    }
2922
2923    pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2924        if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2925            self.coroutine_kind(def_id)
2926            && let ty::Coroutine(_, args) =
2927                self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2928            && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2929        {
2930            true
2931        } else {
2932            false
2933        }
2934    }
2935
2936    /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
2937    pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2938        {
        {
            'done:
                {
                for i in ::rustc_attr_ir::HasAttrs::get_attrs(def_id, &self) {
                    #[allow(unused_imports)]
                    use ::rustc_attr_ir::AttributeKind::*;
                    let i: &::rustc_attr_ir::Attribute = i;
                    match i {
                        ::rustc_attr_ir::Attribute::Parsed(DoNotRecommend) => {
                            break 'done Some(());
                        }
                        ::rustc_attr_ir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }
    }.is_some()find_attr!(self, def_id, DoNotRecommend)
2939    }
2940
2941    pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2942        let def_id = def_id.into_query_key();
2943        self.trivial_const(def_id).is_some()
2944    }
2945
2946    /// Whether this def is one of the special bin crate entrypoint functions that must have a
2947    /// monomorphization and also not be internalized in the bin crate.
2948    pub fn is_entrypoint(self, def_id: DefId) -> bool {
2949        if self.is_lang_item(def_id, LangItem::Start) {
2950            return true;
2951        }
2952        if let Some((entry_def_id, _)) = self.entry_fn(())
2953            && entry_def_id == def_id
2954        {
2955            return true;
2956        }
2957        false
2958    }
2959}
2960
2961pub fn provide(providers: &mut Providers) {
2962    providers.is_panic_runtime = |tcx, LocalCrate| {
        'done:
            {
            for i in tcx.hir_krate_attrs() {
                #[allow(unused_imports)]
                use ::rustc_attr_ir::AttributeKind::*;
                let i: &::rustc_attr_ir::Attribute = i;
                match i {
                    ::rustc_attr_ir::Attribute::Parsed(PanicRuntime) => {
                        break 'done Some(());
                    }
                    ::rustc_attr_ir::Attribute::Unparsed(..) =>
                        {}
                        #[deny(unreachable_patterns)]
                        _ => {}
                }
            }
            None
        }
    }.is_some()find_attr!(tcx, crate, PanicRuntime);
2963    providers.is_compiler_builtins = |tcx, LocalCrate| {
        'done:
            {
            for i in tcx.hir_krate_attrs() {
                #[allow(unused_imports)]
                use ::rustc_attr_ir::AttributeKind::*;
                let i: &::rustc_attr_ir::Attribute = i;
                match i {
                    ::rustc_attr_ir::Attribute::Parsed(CompilerBuiltins) => {
                        break 'done Some(());
                    }
                    ::rustc_attr_ir::Attribute::Unparsed(..) =>
                        {}
                        #[deny(unreachable_patterns)]
                        _ => {}
                }
            }
            None
        }
    }.is_some()find_attr!(tcx, crate, CompilerBuiltins);
2964    providers.has_panic_handler = |tcx, LocalCrate| {
2965        // We want to check if the panic handler was defined in this crate
2966        tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2967    };
2968    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2969}