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