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