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::VisitorExt;
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, 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 => crate::util::bug::bug_fmt(format_args!("{0:?} is not an assoc item of a trait impl: {1:?}",
        key, other))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
862                | DefKind::AssocConst { .. }
863                | DefKind::Const { .. }
864                | DefKind::GlobalAsm
865        ) {
866            CodegenFnAttrs::EMPTY
867        } else {
868            crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
        def_id, def_kind))bug!(
869                "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
870                def_id,
871                def_kind
872            )
873        }
874    }
875
876    pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
877        self.arena.alloc(Steal::new(thir))
878    }
879
880    pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
881        self.arena.alloc(Steal::new(mir))
882    }
883
884    pub fn alloc_steal_promoted(
885        self,
886        promoted: IndexVec<Promoted, Body<'tcx>>,
887    ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
888        self.arena.alloc(Steal::new(promoted))
889    }
890
891    pub fn mk_adt_def(
892        self,
893        did: DefId,
894        kind: AdtKind,
895        variants: IndexVec<VariantIdx, ty::VariantDef>,
896        repr: ReprOptions,
897    ) -> ty::AdtDef<'tcx> {
898        self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
899    }
900
901    /// Allocates a read-only byte or string literal for `mir::interpret` with alignment 1.
902    /// Returns the same `AllocId` if called again with the same bytes.
903    pub fn allocate_bytes_dedup<'a>(
904        self,
905        bytes: impl Into<Cow<'a, [u8]>>,
906        salt: usize,
907    ) -> interpret::AllocId {
908        // Create an allocation that just contains these bytes.
909        let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
910        let alloc = self.mk_const_alloc(alloc);
911        self.reserve_and_set_memory_dedup(alloc, salt)
912    }
913
914    /// Traits added on all bounds by default, excluding `Sized` which is treated separately.
915    pub fn default_traits(self) -> &'static [LangItem] {
916        if self.sess.opts.unstable_opts.experimental_default_bounds {
917            &[
918                LangItem::DefaultTrait1,
919                LangItem::DefaultTrait2,
920                LangItem::DefaultTrait3,
921                LangItem::DefaultTrait4,
922            ]
923        } else {
924            &[]
925        }
926    }
927
928    pub fn is_default_trait(self, def_id: DefId) -> bool {
929        self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
930    }
931
932    pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
933        #[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))
934    }
935
936    pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> T::Lifted {
937        value.lift_to_interner(self)
938    }
939
940    /// Creates a type context. To use the context call `fn enter` which
941    /// provides a `TyCtxt`.
942    ///
943    /// By only providing the `TyCtxt` inside of the closure we enforce that the type
944    /// context and any interned value (types, args, etc.) can only be used while `ty::tls`
945    /// has a valid reference to the context, to allow formatting values that need it.
946    pub fn create_global_ctxt<T>(
947        gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
948        sess: &'tcx Session,
949        crate_types: Vec<CrateType>,
950        stable_crate_id: StableCrateId,
951        arena: &'tcx WorkerLocal<Arena<'tcx>>,
952        hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
953        untracked: Untracked,
954        incr_comp_session: Option<&'tcx IncrCompSession>,
955        dep_graph: DepGraph,
956        query_system: QuerySystem<'tcx>,
957        hooks: crate::hooks::Providers,
958        current_gcx: CurrentGcx,
959        f: impl FnOnce(TyCtxt<'tcx>) -> T,
960    ) -> T {
961        let data_layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
962            sess.dcx().emit_fatal(err);
963        });
964        let interners = CtxtInterners::new(arena);
965        let common_types = CommonTypes::new(&interners);
966        let common_lifetimes = CommonLifetimes::new(&interners);
967        let common_consts = CommonConsts::new(&interners, &common_types);
968
969        let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
970            sess,
971            crate_types,
972            stable_crate_id,
973            arena,
974            hir_arena,
975            interners,
976            incr_comp_session,
977            dep_graph,
978            hooks,
979            prof: sess.prof.clone(),
980            types: common_types,
981            lifetimes: common_lifetimes,
982            consts: common_consts,
983            untracked,
984            query_system,
985            caches: Default::default(),
986            data_layout,
987            alloc_map: interpret::AllocMap::new(),
988            current_gcx,
989        });
990
991        // This is a separate function to work around a crash with parallel rustc (#135870)
992        gcx.enter(f)
993    }
994
995    /// Obtain all lang items of this crate and all dependencies (recursively)
996    pub fn lang_items(self) -> &'tcx rustc_hir::attrs::lang_items::LanguageItems {
997        self.get_lang_items(())
998    }
999
1000    /// Gets a `Ty` representing the [`LangItem::OrderingEnum`]
1001    #[track_caller]
1002    pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1003        let ordering_enum = self.require_lang_item(LangItem::OrderingEnum, span);
1004        self.type_of(ordering_enum).no_bound_vars().unwrap()
1005    }
1006
1007    /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
1008    /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
1009    pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1010        self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1011    }
1012
1013    /// Obtain the diagnostic item's name
1014    pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1015        self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1016    }
1017
1018    /// Check whether the diagnostic item with the given `name` has the given `DefId`.
1019    pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1020        self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1021    }
1022
1023    pub fn is_coroutine(self, def_id: DefId) -> bool {
1024        self.coroutine_kind(def_id).is_some()
1025    }
1026
1027    pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1028        self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1029    }
1030
1031    /// Returns true if the const is guaranteed to have a directly represented RHS. This is either
1032    /// because it has a directly represented RHS, or is a trait definition that is marked as
1033    /// requiring its implementation to have a directly represented RHS.
1034    ///
1035    /// Note: Be very careful with using this method - under `generic_const_args`, a trait can
1036    /// declare a regular const, but an `impl` could implement it with a directly represented const
1037    /// (a la refinement). This method would return false in such a case.
1038    pub fn is_direct_const(self, def_id: DefId) -> bool {
1039        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!(
1040            self.def_kind(def_id),
1041            DefKind::Const { .. } | DefKind::AssocConst { .. }
1042        );
1043        self.is_type_const_syntax(def_id) || self.const_of_item(def_id).is_some()
1044    }
1045
1046    /// Check if the given `def_id` is declared with `type const` syntax (mgca)
1047    ///
1048    /// This is NOT the same as whether the `def_id` can be represented in/used by the type system.
1049    /// For that, you probably want to ask `is_direct_const()` or `const_of_item().is_some()`.
1050    pub fn is_type_const_syntax(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1051        let def_id = def_id.into_query_key();
1052        match self.def_kind(def_id) {
1053            DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1054                is_type_const
1055            }
1056            _ => false,
1057        }
1058    }
1059
1060    /// Returns the movability of the coroutine of `def_id`, or panics
1061    /// if given a `def_id` that is not a coroutine.
1062    pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1063        self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1064    }
1065
1066    /// Returns `true` if the node pointed to by `def_id` is a coroutine for an async construct.
1067    pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1068        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
        true,
    _ => false,
}matches!(
1069            self.coroutine_kind(def_id),
1070            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1071        )
1072    }
1073
1074    // Whether the body owner is synthetic, which in this case means it does not correspond to
1075    // meaningful HIR. This is currently used to skip over MIR borrowck.
1076    pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1077        #[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)
1078    }
1079
1080    /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`.
1081    /// This means it is neither an `async` or `gen` construct.
1082    pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1083        #[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(_)))
1084    }
1085
1086    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `gen` construct.
1087    pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1088        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
        true,
    _ => false,
}matches!(
1089            self.coroutine_kind(def_id),
1090            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1091        )
1092    }
1093
1094    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `async gen` construct.
1095    pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1096        #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
    Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
        => true,
    _ => false,
}matches!(
1097            self.coroutine_kind(def_id),
1098            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1099        )
1100    }
1101
1102    pub fn features(self) -> &'tcx rustc_feature::Features {
1103        self.features_query(())
1104    }
1105
1106    pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1107        let id = id.into_query_key();
1108        // Accessing the DefKey is ok, since it is part of DefPathHash.
1109        if let Some(id) = id.as_local() {
1110            self.definitions_untracked().def_key(id)
1111        } else {
1112            self.cstore_untracked().def_key(id)
1113        }
1114    }
1115
1116    /// Converts a `DefId` into its fully expanded `DefPath` (every
1117    /// `DefId` is really just an interned `DefPath`).
1118    ///
1119    /// Note that if `id` is not local to this crate, the result will
1120    ///  be a non-local `DefPath`.
1121    pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1122        // Accessing the DefPath is ok, since it is part of DefPathHash.
1123        if let Some(id) = id.as_local() {
1124            self.definitions_untracked().def_path(id)
1125        } else {
1126            self.cstore_untracked().def_path(id)
1127        }
1128    }
1129
1130    #[inline]
1131    pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1132        // Accessing the DefPathHash is ok, it is incr. comp. stable.
1133        if let Some(def_id) = def_id.as_local() {
1134            self.definitions_untracked().def_path_hash(def_id)
1135        } else {
1136            self.cstore_untracked().def_path_hash(def_id)
1137        }
1138    }
1139
1140    #[inline]
1141    pub fn crate_types(self) -> &'tcx [CrateType] {
1142        &self.crate_types
1143    }
1144
1145    pub fn needs_metadata(self) -> bool {
1146        self.crate_types().iter().any(|ty| match *ty {
1147            CrateType::Executable
1148            | CrateType::StaticLib
1149            | CrateType::Cdylib
1150            | CrateType::Sdylib => false,
1151            CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1152        })
1153    }
1154
1155    pub fn needs_hir_hash(self) -> bool {
1156        // Why is the hir hash needed for these configurations?
1157        // - debug_assertions: for the "fingerprint the result" check in
1158        //   `rustc_query_impl::execution::execute_job`.
1159        // - incremental: for query lookups.
1160        // - needs_metadata: it is included in the crate metadata through the crate_hash query
1161        // - instrument_coverage: for putting into coverage data (see
1162        //   `hash_mir_source`).
1163        // - metrics_dir: metrics use the strict version hash in the filenames
1164        //   for dumped metrics files to prevent overwriting distinct metrics
1165        //   for similar source builds (may change in the future, this is part
1166        //   of the proof of concept impl for the metrics initiative project goal)
1167        truecfg!(debug_assertions)
1168            || self.sess.opts.incremental.is_some()
1169            || self.needs_metadata()
1170            || self.sess.instrument_coverage()
1171            || self.sess.opts.unstable_opts.metrics_dir.is_some()
1172    }
1173
1174    #[inline]
1175    pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1176        if crate_num == LOCAL_CRATE {
1177            self.stable_crate_id
1178        } else {
1179            self.cstore_untracked().stable_crate_id(crate_num)
1180        }
1181    }
1182
1183    /// Maps a StableCrateId to the corresponding CrateNum. This method assumes
1184    /// that the crate in question has already been loaded by the CrateStore.
1185    #[inline]
1186    pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1187        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1188            LOCAL_CRATE
1189        } else {
1190            *self
1191                .untracked()
1192                .stable_crate_ids
1193                .read()
1194                .get(&stable_crate_id)
1195                .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
        stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1196        }
1197    }
1198
1199    /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
1200    /// session, if it still exists. This is used during incremental compilation to
1201    /// turn a deserialized `DefPathHash` into its current `DefId`.
1202    pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1203        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs:1203",
                        "rustc_middle::ty::context", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs"),
                        ::tracing_core::__macro_support::Option::Some(1203u32),
                        ::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);
1204
1205        let stable_crate_id = hash.stable_crate_id();
1206
1207        // If this is a DefPathHash from the local crate, we can look up the
1208        // DefId in the tcx's `Definitions`.
1209        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1210            Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1211        } else {
1212            self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1213        }
1214    }
1215
1216    pub fn def_path_debug_str(self, def_id: DefId) -> String {
1217        // We are explicitly not going through queries here in order to get
1218        // crate name and stable crate id since this code is called from debug!()
1219        // statements within the query system and we'd run into endless
1220        // recursion otherwise.
1221        let (crate_name, stable_crate_id) = if def_id.is_local() {
1222            (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1223        } else {
1224            let cstore = &*self.cstore_untracked();
1225            (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1226        };
1227
1228        ::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!(
1229            "{}[{:04x}]{}",
1230            crate_name,
1231            // Don't print the whole stable crate id. That's just
1232            // annoying in debug output.
1233            stable_crate_id.as_u64() >> (8 * 6),
1234            self.def_path(def_id).to_string_no_crate_verbose()
1235        )
1236    }
1237
1238    pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1239        self.sess.dcx()
1240    }
1241
1242    /// Checks to see if the caller (`body_features`) has all the features required by the callee
1243    /// (`callee_features`).
1244    pub fn is_target_feature_call_safe(
1245        self,
1246        callee_features: &[TargetFeature],
1247        body_features: &[TargetFeature],
1248    ) -> bool {
1249        // If the called function has target features the calling function hasn't,
1250        // the call requires `unsafe`. Don't check this on wasm
1251        // targets, though. For more information on wasm see the
1252        // is_like_wasm check in hir_analysis/src/collect.rs
1253        self.sess.target.options.is_like_wasm
1254            || callee_features
1255                .iter()
1256                .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1257    }
1258
1259    /// Returns the safe version of the signature of the given function, if calling it
1260    /// would be safe in the context of the given caller.
1261    pub fn adjust_target_feature_sig(
1262        self,
1263        fun_def: DefId,
1264        fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1265        caller: DefId,
1266    ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1267        let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1268        let caller_features = &self.body_codegen_attrs(caller).target_features;
1269        if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1270            return Some(fun_sig.map_bound(|sig| ty::FnSig {
1271                fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1272                ..sig
1273            }));
1274        }
1275        None
1276    }
1277
1278    /// Helper to get a tracked environment variable via. [`TyCtxt::env_var_os`] and converting to
1279    /// UTF-8 like [`std::env::var`].
1280    pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1281        match self.env_var_os(key.as_ref()) {
1282            Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1283            None => Err(VarError::NotPresent),
1284        }
1285    }
1286}
1287
1288impl<'tcx> TyCtxtAt<'tcx> {
1289    /// Create a new definition within the incr. comp. engine.
1290    pub fn create_def(
1291        self,
1292        parent: LocalDefId,
1293        name: Option<Symbol>,
1294        def_kind: DefKind,
1295        override_def_path_data: Option<DefPathData>,
1296        disambiguator: &mut PerParentDisambiguatorState,
1297    ) -> TyCtxtFeed<'tcx, LocalDefId> {
1298        let feed =
1299            self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1300
1301        feed.def_span(self.span);
1302        feed
1303    }
1304}
1305
1306impl<'tcx> TyCtxt<'tcx> {
1307    /// `tcx`-dependent operations performed for every created definition.
1308    pub fn create_def(
1309        self,
1310        parent: LocalDefId,
1311        name: Option<Symbol>,
1312        def_kind: DefKind,
1313        override_def_path_data: Option<DefPathData>,
1314        disambiguator: &mut PerParentDisambiguatorState,
1315    ) -> TyCtxtFeed<'tcx, LocalDefId> {
1316        let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1317        // The following call has the side effect of modifying the tables inside `definitions`.
1318        // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1319        // decode the on-disk cache.
1320        //
1321        // Any LocalDefId which is used within queries, either as key or result, either:
1322        // - has been created before the construction of the TyCtxt;
1323        // - has been created by this call to `create_def`.
1324        // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1325        // comp. engine itself.
1326        let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1327
1328        // This function modifies `self.definitions` using a side-effect.
1329        // We need to ensure that these side effects are re-run by the incr. comp. engine.
1330        // Depending on the forever-red node will tell the graph that the calling query
1331        // needs to be re-evaluated.
1332        self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1333
1334        let feed = TyCtxtFeed { tcx: self, key: def_id };
1335        feed.def_kind(def_kind);
1336        // Unique types created for closures participate in type privacy checking.
1337        // They have visibilities inherited from the module they are defined in.
1338        // Visibilities for opaque types are meaningless, but still provided
1339        // so that all items have visibilities.
1340        if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
    DefKind::Closure | DefKind::OpaqueTy => true,
    _ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1341            let parent_mod = self.parent_module_from_def_id(def_id);
1342            feed.visibility(ty::Visibility::Restricted(parent_mod.to_mod_id()));
1343        }
1344
1345        feed
1346    }
1347
1348    pub fn create_crate_num(
1349        self,
1350        stable_crate_id: StableCrateId,
1351    ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1352        let mut lock = self.untracked().stable_crate_ids.write();
1353        if let Some(&existing) = lock.get(&stable_crate_id) {
1354            return Err(existing);
1355        }
1356        let num = CrateNum::new(lock.len());
1357        lock.insert(stable_crate_id, num);
1358        Ok(TyCtxtFeed { key: num, tcx: self })
1359    }
1360
1361    pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1362        // Depend on the `analysis` query to ensure compilation if finished.
1363        self.ensure_ok().analysis(());
1364
1365        let definitions = &self.untracked.definitions;
1366        gen {
1367            let mut i = 0;
1368
1369            // Recompute the number of definitions each time, because our caller may be creating
1370            // new ones.
1371            while i < { definitions.read().num_definitions() } {
1372                let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1373                yield LocalDefId { local_def_index };
1374                i += 1;
1375            }
1376
1377            // Freeze definitions once we finish iterating on them, to prevent adding new ones.
1378            definitions.freeze();
1379        }
1380    }
1381
1382    pub fn definitions(self) -> &'tcx rustc_hir::definitions::Definitions {
1383        // Depend on the `analysis` query to ensure compilation if finished.
1384        self.ensure_ok().analysis(());
1385
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()
1389    }
1390
1391    pub fn def_path_hash_to_def_index_map(
1392        self,
1393    ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1394        // Create a dependency to the crate to be sure we re-execute this when the amount of
1395        // definitions change.
1396        self.ensure_ok().hir_crate_items(());
1397        // Freeze definitions once we start iterating on them, to prevent adding new ones
1398        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1399        self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1400    }
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 cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1406        FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1407    }
1408
1409    /// Give out access to the untracked data without any sanity checks.
1410    pub fn untracked(self) -> &'tcx Untracked {
1411        &self.untracked
1412    }
1413    /// Note that this is *untracked* and should only be used within the query
1414    /// system if the result is otherwise tracked through queries
1415    #[inline]
1416    pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1417        self.untracked.definitions.read()
1418    }
1419
1420    /// Note that this is *untracked* and should only be used within the query
1421    /// system if the result is otherwise tracked through queries
1422    #[inline]
1423    pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1424        self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1425    }
1426
1427    #[inline(always)]
1428    pub fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashState<'_>) -> R) -> R {
1429        f(StableHashState::new(self.sess, &self.untracked))
1430    }
1431
1432    #[inline]
1433    pub fn local_crate_exports_generics(self) -> bool {
1434        // compiler-builtins has some special treatment in codegen, which can result in confusing
1435        // behavior if another crate ends up calling into its monomorphizations.
1436        // https://github.com/rust-lang/rust/issues/150173
1437        if self.is_compiler_builtins(LOCAL_CRATE) {
1438            return false;
1439        }
1440        self.crate_types().iter().any(|crate_type| {
1441            match crate_type {
1442                CrateType::Executable
1443                | CrateType::StaticLib
1444                | CrateType::ProcMacro
1445                | CrateType::Cdylib
1446                | CrateType::Sdylib => false,
1447
1448                // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
1449                // We want to block export of generics from dylibs,
1450                // but we must fix rust-lang/rust#65890 before we can
1451                // do that robustly.
1452                CrateType::Dylib => true,
1453
1454                CrateType::Rlib => true,
1455            }
1456        })
1457    }
1458
1459    /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
1460    pub fn is_suitable_region(
1461        self,
1462        generic_param_scope: LocalDefId,
1463        mut region: Region<'tcx>,
1464    ) -> Option<FreeRegionInfo> {
1465        let (suitable_region_binding_scope, region_def_id) = loop {
1466            let def_id =
1467                region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1468            let scope = self.local_parent(def_id);
1469            if self.def_kind(scope) == DefKind::OpaqueTy {
1470                // Lifetime params of opaque types are synthetic and thus irrelevant to
1471                // diagnostics. Map them back to their origin!
1472                region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1473                continue;
1474            }
1475            break (scope, def_id.into());
1476        };
1477
1478        let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1479            Node::Item(..) | Node::TraitItem(..) => false,
1480            Node::ImplItem(impl_item) => match impl_item.impl_kind {
1481                // For now, we do not try to target impls of traits. This is
1482                // because this message is going to suggest that the user
1483                // change the fn signature, but they may not be free to do so,
1484                // since the signature must match the trait.
1485                //
1486                // FIXME(#42706) -- in some cases, we could do better here.
1487                hir::ImplItemImplKind::Trait { .. } => true,
1488                _ => false,
1489            },
1490            _ => false,
1491        };
1492
1493        Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1494    }
1495
1496    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
1497    pub fn return_type_impl_or_dyn_traits(
1498        self,
1499        scope_def_id: LocalDefId,
1500    ) -> Vec<&'tcx hir::Ty<'tcx>> {
1501        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1502        let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1503            self.hir_fn_decl_by_hir_id(hir_id)
1504        else {
1505            return ::alloc::vec::Vec::new()vec![];
1506        };
1507
1508        let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1509        v.visit_ty_unambig(hir_output);
1510        v.0
1511    }
1512
1513    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in
1514    /// its return type, and the associated alias span when type alias is used,
1515    /// along with a span for lifetime suggestion (if there are existing generics).
1516    pub fn return_type_impl_or_dyn_traits_with_type_alias(
1517        self,
1518        scope_def_id: LocalDefId,
1519    ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1520        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1521        let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1522        // when the return type is a type alias
1523        if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1524            && let hir::TyKind::Path(hir::QPath::Resolved(
1525                None,
1526                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1527            && let Some(local_id) = def_id.as_local()
1528            && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias
1529            && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
1530        {
1531            v.visit_ty_unambig(alias_ty);
1532            if !v.0.is_empty() {
1533                return Some((
1534                    v.0,
1535                    alias_generics.span,
1536                    alias_generics.span_for_lifetime_suggestion(),
1537                ));
1538            }
1539        }
1540        None
1541    }
1542
1543    /// Determines whether identifiers in the assembly have strict naming rules.
1544    /// Currently, only NVPTX* targets need it.
1545    pub fn has_strict_asm_symbol_naming(self) -> bool {
1546        self.sess.target.llvm_target.starts_with("nvptx")
1547    }
1548
1549    /// Returns `&'static core::panic::Location<'static>`.
1550    pub fn caller_location_ty(self) -> Ty<'tcx> {
1551        Ty::new_imm_ref(
1552            self,
1553            self.lifetimes.re_static,
1554            self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1555                .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1556                .skip_norm_wip(),
1557        )
1558    }
1559
1560    /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
1561    pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1562        let kind = self.def_kind(def_id);
1563        (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1564    }
1565
1566    pub fn type_length_limit(self) -> Limit {
1567        self.limits(()).type_length_limit
1568    }
1569
1570    pub fn recursion_limit(self) -> Limit {
1571        self.limits(()).recursion_limit
1572    }
1573
1574    pub fn move_size_limit(self) -> Limit {
1575        self.limits(()).move_size_limit
1576    }
1577
1578    pub fn pattern_complexity_limit(self) -> Limit {
1579        self.limits(()).pattern_complexity_limit
1580    }
1581
1582    /// All traits in the crate graph, including those not visible to the user.
1583    pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1584        iter::once(LOCAL_CRATE)
1585            .chain(self.crates(()).iter().copied())
1586            .flat_map(move |cnum| self.traits(cnum).iter().copied())
1587    }
1588
1589    /// All traits that are visible within the crate graph (i.e. excluding private dependencies).
1590    pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1591        let visible_crates =
1592            self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1593
1594        iter::once(LOCAL_CRATE)
1595            .chain(visible_crates)
1596            .flat_map(move |cnum| self.traits(cnum).iter().copied())
1597    }
1598
1599    #[inline]
1600    pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1601        self.visibility(def_id).expect_local()
1602    }
1603
1604    /// Returns the origin of the opaque type `def_id`.
1605    {}
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/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs"),
                                ::tracing_core::__macro_support::Option::Some(1605u32),
                                ::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/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs:1605",
                        "rustc_middle::ty::context", ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs"),
                        ::tracing_core::__macro_support::Option::Some(1605u32),
                        ::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)]
1606    pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1607        self.hir_expect_opaque_ty(def_id).origin
1608    }
1609
1610    pub fn finish(self) {
1611        // We assume that no queries are run past here. If there are new queries
1612        // after this point, they'll show up as "<unknown>" in self-profiling data.
1613        self.alloc_self_profile_query_strings();
1614
1615        self.save_dep_graph();
1616        self.verify_query_key_hashes();
1617
1618        if let Err((path, error)) = self.dep_graph.finish_encoding() {
1619            self.sess
1620                .dcx()
1621                .emit_fatal(crate::diagnostics::FailedWritingFile { path: &path, error });
1622        }
1623    }
1624
1625    pub fn report_unused_features(self) {
1626        #[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for UnusedFeature
            where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnusedFeature { feature: __binding_0 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("feature `{$feature}` is declared but not used")));
                        ;
                        diag.arg("feature", __binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
1627        #[diag("feature `{$feature}` is declared but not used")]
1628        struct UnusedFeature {
1629            feature: Symbol,
1630        }
1631
1632        // Collect first to avoid holding the lock while linting.
1633        let used_features = self.query_system.used_features.lock();
1634        let unused_features = self
1635            .features()
1636            .enabled_features_iter_stable_order()
1637            .filter(|(f, _)| {
1638                !used_features.contains_key(f)
1639                // FIXME: `restricted_std` is used to tell a standard library built
1640                // for a platform that it doesn't know how to support. But it
1641                // could only gate a private mod (see `__restricted_std_workaround`)
1642                // with `cfg(not(restricted_std))`, so it cannot be recorded as used
1643                // in downstream crates. It should never be linted, but should we
1644                // hack this in the linter to ignore it?
1645                && f.as_str() != "restricted_std"
1646                // `doc_cfg` affects rustdoc behavior: rustdoc checks it via
1647                // `tcx.features().doc_cfg()`, but a normal rustc compilation may
1648                // never observe that use. Do not lint it as unused here.
1649                && *f != sym::doc_cfg
1650            })
1651            .collect::<Vec<_>>();
1652
1653        for (feature, span) in unused_features {
1654            self.emit_node_span_lint(
1655                UNUSED_FEATURES,
1656                CRATE_HIR_ID,
1657                span,
1658                UnusedFeature { feature },
1659            );
1660        }
1661    }
1662}
1663
1664macro_rules! nop_lift {
1665    ($set:ident; $ty:ty => $lifted:ty) => {
1666        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1667            type Lifted = $lifted;
1668            #[track_caller]
1669            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1670                // Assert that the set has the right type.
1671                // Given an argument that has an interned type, the return type has the type of
1672                // the corresponding interner set. This won't actually return anything, we're
1673                // just doing this to compute said type!
1674                fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1675                    _x: Interned<'tcx, Inner>,
1676                ) -> InternedSet<'tcx, Inner> {
1677                    unreachable!()
1678                }
1679                fn _type_eq<T>(_x: &T, _y: &T) {}
1680                fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1681                    // If `x` is a newtype around an `Interned<T>`, then `interner` is an
1682                    // interner of appropriate type. (Ideally we'd also check that `x` is a
1683                    // newtype with just that one field. Not sure how to do that.)
1684                    let interner = _intern_set_ty_from_interned_ty(x.0);
1685                    // Now check that this is the same type as `interners.$set`.
1686                    _type_eq(&interner, &tcx.interners.$set);
1687                }
1688
1689                assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1690                // SAFETY: we just checked that `self` is interned and therefore is valid for the
1691                // entire lifetime of the `TyCtxt`.
1692                unsafe { mem::transmute(self) }
1693            }
1694        }
1695    };
1696}
1697
1698macro_rules! nop_list_lift {
1699    ($set:ident; $ty:ty => $lifted:ty) => {
1700        nop_list_lift! { $set: List; $ty => $lifted }
1701    };
1702    // Allows defining own list type
1703    ($set:ident: $list:ident; $ty:ty => $lifted:ty) => {
1704        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a $list<$ty> {
1705            type Lifted = &'tcx $list<$lifted>;
1706            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1707                // Assert that the set has the right type.
1708                if false {
1709                    let _x: &InternedSet<'tcx, $list<$lifted>> = &tcx.interners.$set;
1710                }
1711
1712                if self.is_empty() {
1713                    return $list::empty();
1714                }
1715                assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1716                // SAFETY: we just checked that `self` is interned and therefore is valid for the
1717                // entire lifetime of the `TyCtxt`.
1718                unsafe { mem::transmute(self) }
1719            }
1720        }
1721    };
1722}
1723
1724impl<'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> }
1725impl<'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> }
1726impl<'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> }
1727impl<'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> }
1728impl<'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> }
1729impl<'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> }
1730impl<'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> }
1731impl<'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> }
1732
1733impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, RegionKind<'a>> {
1734    type Lifted = Interned<'tcx, RegionKind<'tcx>>;
1735
1736    #[track_caller]
1737    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1738        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)));
1739        // SAFETY: we just checked that `self` is interned in this `TyCtxt`, so
1740        // its pointee is valid for the entire lifetime of the target `TyCtxt`.
1741        unsafe { mem::transmute(self) }
1742    }
1743}
1744
1745impl<'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> }
1746impl<'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> }
1747impl<'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! {
1748    poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1749}
1750impl<'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> }
1751impl<'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> }
1752impl<'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> }
1753
1754// This is the impl for `&'a GenericArgs<'a>`.
1755impl<'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> }
1756
1757macro_rules! sty_debug_print {
1758    ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1759        #[allow(non_snake_case, reason = "we're using variant names as local variables")]
1760        mod inner {
1761            use crate::ty::{self, TyCtxt};
1762            use crate::ty::context::InternedInSet;
1763
1764            #[derive(Copy, Clone)]
1765            struct DebugStat {
1766                total: usize,
1767                lt_infer: usize,
1768                ty_infer: usize,
1769                ct_infer: usize,
1770                all_infer: usize,
1771            }
1772
1773            pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1774                let mut total = DebugStat {
1775                    total: 0,
1776                    lt_infer: 0,
1777                    ty_infer: 0,
1778                    ct_infer: 0,
1779                    all_infer: 0,
1780                };
1781                $(let mut $variant = total;)*
1782
1783                for shard in tcx.interners.type_.lock_shards() {
1784                    // It seems that ordering doesn't affect anything here.
1785                    #[allow(rustc::potential_query_instability)]
1786                    let types = shard.iter();
1787                    for &(InternedInSet(t), ()) in types {
1788                        let variant = match t.internee {
1789                            ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1790                                ty::Float(..) | ty::Str | ty::Never => continue,
1791                            ty::Error(_) => /* unimportant */ continue,
1792                            $(ty::$variant(..) => &mut $variant,)*
1793                        };
1794                        let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1795                        let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1796                        let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1797
1798                        variant.total += 1;
1799                        total.total += 1;
1800                        if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1801                        if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1802                        if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1803                        if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1804                    }
1805                }
1806                writeln!(fmt, "Ty interner             total           ty lt ct all")?;
1807                $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
1808                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1809                    stringify!($variant),
1810                    uses = $variant.total,
1811                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
1812                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
1813                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
1814                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
1815                    all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
1816                )*
1817                writeln!(fmt, "                  total {uses:6}        \
1818                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1819                    uses = total.total,
1820                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
1821                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
1822                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
1823                    all = total.all_infer as f64 * 100.0  / total.total as f64)
1824            }
1825        }
1826
1827        inner::go($fmt, $ctxt)
1828    }}
1829}
1830
1831impl<'tcx> TyCtxt<'tcx> {
1832    pub fn debug_stats(self) -> impl fmt::Debug {
1833        fmt::from_fn(move |fmt| {
1834            {
    #[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!(
1835                fmt,
1836                self,
1837                Adt,
1838                Array,
1839                Slice,
1840                RawPtr,
1841                Ref,
1842                FnDef,
1843                FnPtr,
1844                UnsafeBinder,
1845                Placeholder,
1846                Coroutine,
1847                CoroutineWitness,
1848                Dynamic,
1849                Closure,
1850                CoroutineClosure,
1851                Tuple,
1852                Bound,
1853                Param,
1854                Infer,
1855                Alias,
1856                Pat,
1857                Foreign
1858            )?;
1859
1860            fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
        self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1861            fmt.write_fmt(format_args!("Region interner: #{0}\n",
        self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1862            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())?;
1863            fmt.write_fmt(format_args!("Layout interner: #{0}\n",
        self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1864
1865            Ok(())
1866        })
1867    }
1868}
1869
1870// This type holds a `T` in the interner. The `T` is stored in the arena and
1871// this type just holds a pointer to it, but it still effectively owns it. It
1872// impls `Borrow` so that it can be looked up using the original
1873// (non-arena-memory-owning) types.
1874struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1875
1876impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1877    fn clone(&self) -> Self {
1878        *self
1879    }
1880}
1881
1882impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1883
1884impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1885    fn into_pointer(&self) -> *const () {
1886        self.0 as *const _ as *const ()
1887    }
1888}
1889
1890#[allow(rustc::usage_of_ty_tykind)]
1891impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1892    fn borrow(&self) -> &T {
1893        &self.0.internee
1894    }
1895}
1896
1897impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1898    fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1899        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1900        // `x == y`.
1901        self.0.internee == other.0.internee
1902    }
1903}
1904
1905impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1906
1907impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1908    fn hash<H: Hasher>(&self, s: &mut H) {
1909        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1910        self.0.internee.hash(s)
1911    }
1912}
1913
1914impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1915    fn borrow(&self) -> &[T] {
1916        &self.0[..]
1917    }
1918}
1919
1920impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1921    fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1922        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1923        // `x == y`.
1924        self.0[..] == other.0[..]
1925    }
1926}
1927
1928impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1929
1930impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1931    fn hash<H: Hasher>(&self, s: &mut H) {
1932        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1933        self.0[..].hash(s)
1934    }
1935}
1936
1937impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1938    fn borrow(&self) -> &[T] {
1939        &self.0[..]
1940    }
1941}
1942
1943impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1944    fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1945        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1946        // `x == y`.
1947        self.0[..] == other.0[..]
1948    }
1949}
1950
1951impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1952
1953impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1954    fn hash<H: Hasher>(&self, s: &mut H) {
1955        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1956        self.0[..].hash(s)
1957    }
1958}
1959
1960macro_rules! direct_interners {
1961    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1962        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1963            fn borrow<'a>(&'a self) -> &'a $ty {
1964                &self.0
1965            }
1966        }
1967
1968        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1969            fn eq(&self, other: &Self) -> bool {
1970                // The `Borrow` trait requires that `x.borrow() == y.borrow()`
1971                // equals `x == y`.
1972                self.0 == other.0
1973            }
1974        }
1975
1976        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1977
1978        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1979            fn hash<H: Hasher>(&self, s: &mut H) {
1980                // The `Borrow` trait requires that `x.borrow().hash(s) ==
1981                // x.hash(s)`.
1982                self.0.hash(s)
1983            }
1984        }
1985
1986        impl<'tcx> TyCtxt<'tcx> {
1987            $vis fn $method(self, v: $ty) -> $ret_ty {
1988                $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1989                    InternedInSet(self.interners.arena.alloc(v))
1990                }).0))
1991            }
1992        })+
1993    }
1994}
1995
1996// Functions with a `mk_` prefix are intended for use outside this file and
1997// crate. Functions with an `intern_` prefix are intended for use within this
1998// crate only, and have a corresponding `mk_` function.
1999impl<'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! {
2000    region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2001    valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2002    pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2003    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2004    layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2005    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2006    external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2007        ExternalConstraints -> ExternalConstraints<'tcx>,
2008    canonical_inputs: intern_canonical_input(CanonicalInputData<TyCtxt<'tcx>>): CanonicalInput -> CanonicalInput<'tcx>,
2009}
2010
2011macro_rules! slice_interners {
2012    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2013        impl<'tcx> TyCtxt<'tcx> {
2014            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2015                if v.is_empty() {
2016                    List::empty()
2017                } else {
2018                    self.interners.$field.intern_ref(v, || {
2019                        InternedInSet(List::from_arena(&*self.arena, (), v))
2020                    }).0
2021                }
2022            })+
2023        }
2024    );
2025}
2026
2027// These functions intern slices. They all have a corresponding
2028// `mk_foo_from_iter` function that interns an iterator. The slice version
2029// should be used when possible, because it's faster.
2030impl<'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!(
2031    const_lists: pub mk_const_list(Const<'tcx>),
2032    args: pub mk_args(GenericArg<'tcx>),
2033    type_lists: pub mk_type_list(Ty<'tcx>),
2034    canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2035    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2036    projs: pub mk_projs(ProjectionKind),
2037    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2038    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2039    fields: pub mk_fields(FieldIdx),
2040    local_def_ids: intern_local_def_ids(LocalDefId),
2041    captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2042    patterns: pub mk_patterns(Pattern<'tcx>),
2043    outlives: pub mk_outlives(ty::ArgOutlivesClause<'tcx>),
2044    predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2045);
2046
2047impl<'tcx> TyCtxt<'tcx> {
2048    /// Given a `fn` sig, returns an equivalent `unsafe fn` type;
2049    /// that is, a `fn` type that is equivalent in every way for being
2050    /// unsafe.
2051    pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2052        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2053        Ty::new_fn_ptr(
2054            self,
2055            sig.map_bound(|sig| ty::FnSig {
2056                fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2057                ..sig
2058            }),
2059        )
2060    }
2061
2062    /// Given a `fn` sig, returns an equivalent `unsafe fn` sig;
2063    /// that is, a `fn` sig that is equivalent in every way for being
2064    /// unsafe.
2065    pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2066        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2067        sig.map_bound(|sig| ty::FnSig {
2068            fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2069            ..sig
2070        })
2071    }
2072
2073    /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
2074    /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
2075    pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2076        elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2077            self.associated_items(trait_did)
2078                .filter_by_name_unhygienic(assoc_name.name)
2079                .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2080        })
2081    }
2082
2083    /// Given a `ty`, return whether it's an `impl Future<...>`.
2084    pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2085        let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2086            return false;
2087        };
2088        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2089
2090        self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2091            let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2092                return false;
2093            };
2094            trait_predicate.trait_ref.def_id == future_trait
2095                && trait_predicate.polarity == ClausePolarity::Positive
2096        })
2097    }
2098
2099    /// Given a closure signature, returns an equivalent fn signature. Detuples
2100    /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
2101    /// you would get a `fn(u32, i32)`.
2102    /// `unsafety` determines the unsafety of the fn signature. If you pass
2103    /// `hir::Safety::Unsafe` in the previous example, then you would get
2104    /// an `unsafe fn (u32, i32)`.
2105    /// It cannot convert a closure that requires unsafe.
2106    pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2107        sig.map_bound(|s| {
2108            let params = match s.inputs()[0].kind() {
2109                ty::Tuple(params) => *params,
2110                _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2111            };
2112            // Ignore splatting, it is unsupported on closures.
2113            if !s.splatted().is_none() {
    ::core::panicking::panic("assertion failed: s.splatted().is_none()")
};assert!(s.splatted().is_none());
2114            self.mk_fn_sig(
2115                params,
2116                s.output(),
2117                s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2118            )
2119        })
2120    }
2121
2122    #[inline]
2123    pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2124        self.interners.intern_predicate(binder)
2125    }
2126
2127    #[inline]
2128    pub fn reuse_or_mk_predicate(
2129        self,
2130        pred: Predicate<'tcx>,
2131        binder: Binder<'tcx, PredicateKind<'tcx>>,
2132    ) -> Predicate<'tcx> {
2133        if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2134    }
2135
2136    /// If you have a [`ty::Alias`], you should almost certainly be calling
2137    /// [`Self::check_alias_term_args_compatible`] instead. This method assumes that inherent alias
2138    /// consts always have `impl`-form args, and will return an invalid result if the `def_id` comes
2139    /// from a [`ty::AliasConstKind::InherentSelf`] (see the doc on that for what "impl form args"
2140    /// means).
2141    pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2142        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)
2143            && #[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 });
2144        self.check_args_compatible_inner(def_id, args, is_inherent_assoc_ty)
2145    }
2146
2147    pub fn check_alias_term_args_compatible(
2148        self,
2149        kind: ty::AliasTermKind<'tcx>,
2150        args: &'tcx [ty::GenericArg<'tcx>],
2151    ) -> bool {
2152        let (def_id, is_self_args) = match kind {
2153            ty::AliasTermKind::ProjectionTy { def_id }
2154            | ty::AliasTermKind::OpaqueTy { def_id }
2155            | ty::AliasTermKind::FreeTy { def_id }
2156            | ty::AliasTermKind::AnonConst { def_id }
2157            | ty::AliasTermKind::ProjectionConst { def_id }
2158            | ty::AliasTermKind::FreeConst { def_id }
2159            | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2160            ty::AliasTermKind::InherentTy { def_id }
2161            | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2162        };
2163        self.check_args_compatible_inner(def_id, args, is_self_args)
2164    }
2165
2166    fn check_args_compatible_inner(
2167        self,
2168        def_id: DefId,
2169        args: &'tcx [ty::GenericArg<'tcx>],
2170        is_self_args: bool,
2171    ) -> bool {
2172        let generics = self.generics_of(def_id);
2173        let own_args = if is_self_args {
2174            if generics.own_params.len() + 1 != args.len() {
2175                return false;
2176            }
2177
2178            if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
    ty::GenericArgKind::Type(_) => true,
    _ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2179                return false;
2180            }
2181
2182            &args[1..]
2183        } else {
2184            if generics.count() != args.len() {
2185                return false;
2186            }
2187
2188            let (parent_args, own_args) = args.split_at(generics.parent_count);
2189
2190            // In the type system, IATs and IACs (inherent associated types/consts) themselves have a
2191            // weird arg setup (self + own args), but nested items *in* IATs (namely: opaques, i.e.
2192            // ATPITs) do not. So, set `is_self_args` to false for the parent generic check.
2193            if let Some(parent) = generics.parent
2194                && !self.check_args_compatible_inner(parent, parent_args, false)
2195            {
2196                return false;
2197            }
2198
2199            own_args
2200        };
2201
2202        for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2203            match (&param.kind, arg.kind()) {
2204                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2205                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2206                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2207                _ => return false,
2208            }
2209        }
2210
2211        true
2212    }
2213
2214    /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
2215    /// and print out the args if not.
2216    ///
2217    /// If you have a [`ty::Alias`], you should use
2218    /// [`Self::debug_assert_alias_term_args_compatible`] instead. See note on
2219    /// [`Self::check_args_compatible`].
2220    pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2221        if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2222            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)
2223                && #[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 });
2224            self.emit_bug_args_compatible(def_id, args, is_inherent_assoc_ty);
2225        }
2226    }
2227
2228    pub fn debug_assert_alias_term_args_compatible(
2229        self,
2230        kind: ty::AliasTermKind<'tcx>,
2231        args: ty::GenericArgsRef<'tcx>,
2232    ) {
2233        if truecfg!(debug_assertions) {
2234            self.debug_assert_alias_term_kind_matches_def_kind(kind);
2235            if !self.check_alias_term_args_compatible(kind, args) {
2236                let (def_id, is_self_args) = match kind {
2237                    ty::AliasTermKind::ProjectionTy { def_id }
2238                    | ty::AliasTermKind::OpaqueTy { def_id }
2239                    | ty::AliasTermKind::FreeTy { def_id }
2240                    | ty::AliasTermKind::AnonConst { def_id }
2241                    | ty::AliasTermKind::ProjectionConst { def_id }
2242                    | ty::AliasTermKind::FreeConst { def_id }
2243                    | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2244                    ty::AliasTermKind::InherentTy { def_id }
2245                    | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2246                };
2247                self.emit_bug_args_compatible(def_id, args, is_self_args);
2248            }
2249        }
2250    }
2251
2252    fn debug_assert_alias_term_kind_matches_def_kind(self, kind: ty::AliasTermKind<'tcx>) {
2253        match kind {
2254            ty::AliasTermKind::ProjectionTy { def_id } => {
2255                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);
2256                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!(
2257                    self.def_kind(self.parent(def_id)),
2258                    DefKind::Trait | DefKind::Impl { of_trait: true }
2259                );
2260            }
2261            ty::AliasTermKind::InherentTy { def_id } => {
2262                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);
2263                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!(
2264                    self.def_kind(self.parent(def_id)),
2265                    DefKind::Impl { of_trait: false }
2266                );
2267            }
2268            ty::AliasTermKind::OpaqueTy { def_id } => {
2269                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);
2270            }
2271            ty::AliasTermKind::FreeTy { def_id } => {
2272                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);
2273            }
2274            ty::AliasTermKind::AnonConst { def_id } => {
2275                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);
2276            }
2277            ty::AliasTermKind::ProjectionConst { def_id } => {
2278                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 { .. });
2279                if true {
    {
        match self.def_kind(self.parent(def_id)) {
            DefKind::Trait | DefKind::Impl { of_trait: true } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Trait | DefKind::Impl { of_trait: true }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(
2280                    self.def_kind(self.parent(def_id)),
2281                    DefKind::Trait | DefKind::Impl { of_trait: true }
2282                );
2283            }
2284            ty::AliasTermKind::InherentConstSelf { def_id }
2285            | ty::AliasTermKind::InherentConstImpl { def_id } => {
2286                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 { .. });
2287                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!(
2288                    self.def_kind(self.parent(def_id)),
2289                    DefKind::Impl { of_trait: false }
2290                );
2291            }
2292            ty::AliasTermKind::FreeConst { def_id } => {
2293                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 { .. });
2294            }
2295        }
2296    }
2297
2298    fn emit_bug_args_compatible(
2299        self,
2300        def_id: DefId,
2301        args: &'tcx [ty::GenericArg<'tcx>],
2302        is_self_args: bool,
2303    ) -> ! {
2304        if is_self_args {
2305            crate::util::bug::bug_fmt(format_args!("args not compatible with generics for {0}: args={1:#?}, generics={2:#?}",
        self.def_path_str(def_id), args,
        self.mk_args_from_iter([self.types.self_param.into()].into_iter().chain(self.generics_of(def_id).own_args(ty::GenericArgs::identity_for_item(self,
                                def_id)).iter().copied()))));bug!(
2306                "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2307                self.def_path_str(def_id),
2308                args,
2309                // Make `[Self, GAT_ARGS...]` (this could be simplified)
2310                self.mk_args_from_iter(
2311                    [self.types.self_param.into()].into_iter().chain(
2312                        self.generics_of(def_id)
2313                            .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2314                            .iter()
2315                            .copied()
2316                    )
2317                )
2318            );
2319        } else {
2320            crate::util::bug::bug_fmt(format_args!("args not compatible with generics for {0}: args={1:#?}, generics={2:#?}",
        self.def_path_str(def_id), args,
        ty::GenericArgs::identity_for_item(self, def_id)));bug!(
2321                "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2322                self.def_path_str(def_id),
2323                args,
2324                ty::GenericArgs::identity_for_item(self, def_id)
2325            );
2326        }
2327    }
2328
2329    #[inline(always)]
2330    pub(crate) fn check_and_mk_args(
2331        self,
2332        def_id: DefId,
2333        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2334    ) -> GenericArgsRef<'tcx> {
2335        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2336        self.debug_assert_args_compatible(def_id, args);
2337        args
2338    }
2339
2340    #[inline]
2341    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2342        self.interners.intern_const(kind)
2343    }
2344
2345    // Avoid this in favour of more specific `Ty::new_*` methods, where possible.
2346    #[allow(rustc::usage_of_ty_tykind)]
2347    #[inline]
2348    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2349        self.interners.intern_ty(st)
2350    }
2351
2352    pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2353        match param.kind {
2354            GenericParamDefKind::Lifetime => {
2355                ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2356            }
2357            GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2358            GenericParamDefKind::Const { .. } => {
2359                ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2360                    .into()
2361            }
2362        }
2363    }
2364
2365    pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2366        self.mk_place_elem(place, PlaceElem::Field(f, ty))
2367    }
2368
2369    pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2370        self.mk_place_elem(place, PlaceElem::Deref)
2371    }
2372
2373    pub fn mk_place_downcast(
2374        self,
2375        place: Place<'tcx>,
2376        adt_def: AdtDef<'tcx>,
2377        variant_index: VariantIdx,
2378    ) -> Place<'tcx> {
2379        self.mk_place_elem(
2380            place,
2381            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2382        )
2383    }
2384
2385    pub fn mk_place_downcast_unnamed(
2386        self,
2387        place: Place<'tcx>,
2388        variant_index: VariantIdx,
2389    ) -> Place<'tcx> {
2390        self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2391    }
2392
2393    pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2394        self.mk_place_elem(place, PlaceElem::Index(index))
2395    }
2396
2397    /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2398    /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2399    /// flight.
2400    pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2401        Place {
2402            local: place.local,
2403            projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2404        }
2405    }
2406
2407    pub fn mk_poly_existential_predicates(
2408        self,
2409        eps: &[PolyExistentialPredicate<'tcx>],
2410    ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2411        if !!eps.is_empty() {
    ::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2412        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!(
2413            eps.array_windows()
2414                .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2415                    != Ordering::Greater)
2416        );
2417        self.intern_poly_existential_predicates(eps)
2418    }
2419
2420    pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2421        // FIXME consider asking the input slice to be sorted to avoid
2422        // re-interning permutations, in which case that would be asserted
2423        // here.
2424        self.interners.intern_clauses(clauses)
2425    }
2426
2427    pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2428        // FIXME consider asking the input slice to be sorted to avoid
2429        // re-interning permutations, in which case that would be asserted
2430        // here.
2431        self.intern_local_def_ids(def_ids)
2432    }
2433
2434    pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2435    where
2436        I: Iterator<Item = T>,
2437        T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2438    {
2439        T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2440    }
2441
2442    pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2443    where
2444        I: Iterator<Item = T>,
2445        T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2446    {
2447        T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2448    }
2449
2450    pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2451    where
2452        I: Iterator<Item = T>,
2453        T: CollectAndApply<
2454                &'tcx ty::CapturedPlace<'tcx>,
2455                &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2456            >,
2457    {
2458        T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2459    }
2460
2461    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2462    where
2463        I: Iterator<Item = T>,
2464        T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2465    {
2466        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2467    }
2468
2469    // Unlike various other `mk_*_from_iter` functions, this one uses `I:
2470    // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
2471    // variant, because of the need to combine `inputs` and `output`. This
2472    // explains the lack of `_from_iter` suffix.
2473    pub fn mk_fn_sig<I, T>(
2474        self,
2475        inputs: I,
2476        output: I::Item,
2477        fn_sig_kind: FnSigKind<'tcx>,
2478    ) -> T::Output
2479    where
2480        I: IntoIterator<Item = T>,
2481        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2482    {
2483        T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2484            inputs_and_output: self.mk_type_list(xs),
2485            fn_sig_kind,
2486        })
2487    }
2488
2489    /// `mk_fn_sig`, but with a Rust ABI, and no C-variadic argument.
2490    pub fn mk_fn_sig_rust_abi<I, T>(
2491        self,
2492        inputs: I,
2493        output: I::Item,
2494        safety: hir::Safety,
2495    ) -> T::Output
2496    where
2497        I: IntoIterator<Item = T>,
2498        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2499    {
2500        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2501    }
2502
2503    /// `mk_fn_sig`, but with a safe Rust ABI, and no C-variadic argument.
2504    pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2505    where
2506        I: IntoIterator<Item = T>,
2507        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2508    {
2509        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2510    }
2511
2512    /// `mk_fn_sig`, but with an **un**safe Rust ABI, and no C-variadic argument.
2513    pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2514    where
2515        I: IntoIterator<Item = T>,
2516        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2517    {
2518        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2519    }
2520
2521    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2522    where
2523        I: Iterator<Item = T>,
2524        T: CollectAndApply<
2525                PolyExistentialPredicate<'tcx>,
2526                &'tcx List<PolyExistentialPredicate<'tcx>>,
2527            >,
2528    {
2529        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2530    }
2531
2532    pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2533    where
2534        I: Iterator<Item = T>,
2535        T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2536    {
2537        T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2538    }
2539
2540    pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2541    where
2542        I: Iterator<Item = T>,
2543        T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2544    {
2545        T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2546    }
2547
2548    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2549    where
2550        I: Iterator<Item = T>,
2551        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2552    {
2553        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2554    }
2555
2556    pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2557    where
2558        I: Iterator<Item = T>,
2559        T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2560    {
2561        T::collect_and_apply(iter, |xs| self.mk_args(xs))
2562    }
2563
2564    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2565    where
2566        I: Iterator<Item = T>,
2567        T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2568    {
2569        T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2570    }
2571
2572    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2573    where
2574        I: Iterator<Item = T>,
2575        T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2576    {
2577        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2578    }
2579
2580    pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2581    where
2582        I: Iterator<Item = T>,
2583        T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2584    {
2585        T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2586    }
2587
2588    pub fn mk_args_trait(
2589        self,
2590        self_ty: Ty<'tcx>,
2591        rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2592    ) -> GenericArgsRef<'tcx> {
2593        self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2594    }
2595
2596    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2597    where
2598        I: Iterator<Item = T>,
2599        T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2600    {
2601        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2602    }
2603
2604    pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2605    where
2606        I: Iterator<Item = T>,
2607        T: CollectAndApply<
2608                ty::ArgOutlivesClause<'tcx>,
2609                &'tcx ty::List<ty::ArgOutlivesClause<'tcx>>,
2610            >,
2611    {
2612        T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2613    }
2614
2615    /// Emit a lint at `span` from a lint struct (some type that implements `Diagnostic`,
2616    /// typically generated by `#[derive(Diagnostic)]`).
2617    #[track_caller]
2618    pub fn emit_node_span_lint(
2619        self,
2620        lint: &'static Lint,
2621        hir_id: HirId,
2622        span: impl Into<MultiSpan>,
2623        decorator: impl for<'a> Diagnostic<'a, ()>,
2624    ) {
2625        let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2626        emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2627    }
2628
2629    /// Find the appropriate span where `use` and outer attributes can be inserted at.
2630    pub fn crate_level_attribute_injection_span(self) -> Span {
2631        let node = self.hir_node(hir::CRATE_HIR_ID);
2632        let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2633        m.spans.inject_use_span.shrink_to_lo()
2634    }
2635
2636    pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2637        self,
2638        diag: &mut Diag<'_, E>,
2639        features: impl IntoIterator<Item = (String, Symbol)>,
2640    ) {
2641        if !self.sess.is_nightly_build() {
2642            return;
2643        }
2644
2645        let span = self.crate_level_attribute_injection_span();
2646        for (desc, feature) in features {
2647            // FIXME: make this string translatable
2648            let msg =
2649                ::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}");
2650            diag.span_suggestion_verbose(
2651                span,
2652                msg,
2653                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
    })format!("#![feature({feature})]\n"),
2654                Applicability::MaybeIncorrect,
2655            );
2656        }
2657    }
2658
2659    /// Emit a lint from a lint struct (some type that implements `Diagnostic`, typically generated
2660    /// by `#[derive(Diagnostic)]`).
2661    #[track_caller]
2662    pub fn emit_node_lint(
2663        self,
2664        lint: &'static Lint,
2665        id: HirId,
2666        decorator: impl for<'a> Diagnostic<'a, ()>,
2667    ) {
2668        let level_spec = self.lint_level_spec_at_node(lint, id);
2669        emit_lint_base(self.sess, lint, level_spec, None, decorator);
2670    }
2671
2672    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2673        let map = self.in_scope_traits_map(id.owner)?;
2674        let candidates = map.get(&id.local_id)?;
2675        Some(candidates)
2676    }
2677
2678    pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2679        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs:2679",
                        "rustc_middle::ty::context", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs"),
                        ::tracing_core::__macro_support::Option::Some(2679u32),
                        ::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");
2680        self.named_variable_map(id.owner).get(&id.local_id).cloned()
2681    }
2682
2683    pub fn is_late_bound(self, id: HirId) -> bool {
2684        self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2685    }
2686
2687    pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2688        self.mk_bound_variable_kinds(
2689            &self
2690                .late_bound_vars_map(id.owner)
2691                .get(&id.local_id)
2692                .cloned()
2693                .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("No bound vars found for {0}",
        self.hir_id_to_string(id)))bug!("No bound vars found for {}", self.hir_id_to_string(id))),
2694        )
2695    }
2696
2697    /// Given the def-id of an early-bound lifetime on an opaque corresponding to
2698    /// a duplicated captured lifetime, map it back to the early- or late-bound
2699    /// lifetime of the function from which it originally as captured. If it is
2700    /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
2701    /// of the signature.
2702    // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
2703    // re-use the generics of the opaque, this function will need to be tweaked slightly.
2704    pub fn map_opaque_lifetime_to_parent_lifetime(
2705        self,
2706        mut opaque_lifetime_param_def_id: LocalDefId,
2707    ) -> ty::Region<'tcx> {
2708        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!(
2709            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2710            "{opaque_lifetime_param_def_id:?} is a {}",
2711            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2712        );
2713
2714        loop {
2715            let parent = self.local_parent(opaque_lifetime_param_def_id);
2716            let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2717
2718            let Some((lifetime, _)) = lifetime_mapping
2719                .iter()
2720                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2721            else {
2722                crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2723            };
2724
2725            match *lifetime {
2726                resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2727                    let new_parent = self.local_parent(ebv);
2728
2729                    // If we map to another opaque, then it should be a parent
2730                    // of the opaque we mapped from. Continue mapping.
2731                    if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
    DefKind::OpaqueTy => true,
    _ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2732                        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);
2733                        opaque_lifetime_param_def_id = ebv;
2734                        continue;
2735                    }
2736
2737                    let generics = self.generics_of(new_parent);
2738                    return ty::Region::new_early_param(
2739                        self,
2740                        ty::EarlyParamRegion {
2741                            index: generics
2742                                .param_def_id_to_index(self, ebv.to_def_id())
2743                                .expect("early-bound var should be present in fn generics"),
2744                            name: self.item_name(ebv.to_def_id()),
2745                        },
2746                    );
2747                }
2748                resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2749                    let new_parent = self.local_parent(lbv);
2750                    return ty::Region::new_late_param(
2751                        self,
2752                        new_parent.to_def_id(),
2753                        ty::LateParamRegionKind::Named(lbv.to_def_id()),
2754                    );
2755                }
2756                resolve_bound_vars::ResolvedArg::Error(guar) => {
2757                    return ty::Region::new_error(self, guar);
2758                }
2759                _ => {
2760                    return ty::Region::new_error_with_message(
2761                        self,
2762                        self.def_span(opaque_lifetime_param_def_id),
2763                        "cannot resolve lifetime",
2764                    );
2765                }
2766            }
2767        }
2768    }
2769
2770    /// Whether `def_id` is a stable const fn (i.e., doesn't need any feature gates to be called).
2771    ///
2772    /// When this is `false`, the function may still be callable as a `const fn` due to features
2773    /// being enabled!
2774    pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2775        self.is_const_fn(def_id)
2776            && match self.lookup_const_stability(def_id) {
2777                None => true, // a fn in a non-staged_api crate
2778                Some(stability) if stability.is_const_stable() => true,
2779                _ => false,
2780            }
2781    }
2782
2783    /// Whether the trait impl is marked const. This does not consider stability or feature gates.
2784    pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2785        self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2786            && #[allow(non_exhaustive_omitted_patterns)] match self.impl_trait_header(def_id).constness
    {
    hir::Constness::Const { always: false } => true,
    _ => false,
}matches!(
2787                self.impl_trait_header(def_id).constness,
2788                hir::Constness::Const { always: false }
2789            )
2790    }
2791
2792    pub fn is_sdylib_interface_build(self) -> bool {
2793        self.sess.opts.unstable_opts.build_sdylib_interface
2794    }
2795
2796    pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2797        let def_id = def_id.into_query_key();
2798        match self.def_kind(def_id) {
2799            DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2800            _ => None,
2801        }
2802    }
2803
2804    pub fn next_trait_solver_globally(self) -> bool {
2805        self.sess.opts.unstable_opts.next_solver.globally && !self.features().generic_const_exprs()
2806    }
2807
2808    pub fn next_trait_solver_in_coherence(self) -> bool {
2809        self.sess.opts.unstable_opts.next_solver.coherence
2810    }
2811
2812    pub fn disable_trait_solver_fast_paths(self) -> bool {
2813        self.sess.opts.unstable_opts.disable_fast_paths
2814    }
2815
2816    pub fn disable_param_env_normalization_hack(self) -> bool {
2817        self.sess.opts.unstable_opts.disable_param_env_normalization_hack
2818    }
2819
2820    pub fn renormalize_rigid_aliases(self) -> bool {
2821        self.sess.opts.unstable_opts.renormalize_rigid_aliases
2822    }
2823
2824    #[allow(rustc::bad_opt_access)]
2825    pub fn use_typing_mode_post_typeck_until_borrowck(self) -> bool {
2826        self.next_trait_solver_globally()
2827            || self.sess.opts.unstable_opts.typing_mode_post_typeck_until_borrowck
2828    }
2829
2830    pub fn assumptions_on_binders(self) -> bool {
2831        self.sess.opts.unstable_opts.assumptions_on_binders
2832    }
2833
2834    pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2835        self.opt_rpitit_info(def_id).is_some()
2836    }
2837
2838    pub fn get_impl_future_output_ty(self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
2839        let (def_id, args) = match *ty.kind() {
2840            ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
2841            ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, args, .. })
2842                if self.is_impl_trait_in_trait(def_id) =>
2843            {
2844                (def_id, args)
2845            }
2846            _ => return None,
2847        };
2848
2849        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2850        let item_def_id = self.associated_item_def_ids(future_trait)[0];
2851
2852        self.explicit_item_self_bounds(def_id)
2853            .iter_instantiated_copied(self, args)
2854            .map(ty::Unnormalized::skip_norm_wip)
2855            .find_map(|(predicate, _)| {
2856                predicate
2857                    .kind()
2858                    .map_bound(|kind| match kind {
2859                        ty::ClauseKind::Projection(projection_predicate)
2860                            if projection_predicate.def_id() == item_def_id =>
2861                        {
2862                            projection_predicate.term.as_type()
2863                        }
2864                        _ => None,
2865                    })
2866                    .no_bound_vars()
2867                    .flatten()
2868            })
2869    }
2870
2871    /// Named module children from all kinds of items, including imports.
2872    /// In addition to regular items this list also includes struct and variant constructors, and
2873    /// items inside `extern {}` blocks because all of them introduce names into parent module.
2874    ///
2875    /// Module here is understood in name resolution sense - it can be a `mod` item,
2876    /// or a crate root, or an enum, or a trait.
2877    ///
2878    /// This is not a query, making it a query causes perf regressions
2879    /// (probably due to hashing spans in `ModChild`ren).
2880    pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2881        self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2882    }
2883
2884    /// Return the crate imported by given use item.
2885    pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2886        self.resolutions(()).extern_crate_map.get(&def_id).copied()
2887    }
2888
2889    pub fn resolver_for_lowering(
2890        self,
2891    ) -> (&'tcx Steal<ResolverAstLowering<'tcx>>, &'tcx Steal<ast::Crate>) {
2892        let (resolver, krate, _) = self.resolver_for_lowering_raw(());
2893        (resolver, krate)
2894    }
2895
2896    pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2897        make_metadata(self)
2898    }
2899
2900    pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2901        if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2902            self.coroutine_kind(def_id)
2903            && let ty::Coroutine(_, args) =
2904                self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2905            && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2906        {
2907            true
2908        } else {
2909            false
2910        }
2911    }
2912
2913    /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
2914    pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2915        {
        {
            '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)
2916    }
2917
2918    pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2919        let def_id = def_id.into_query_key();
2920        self.trivial_const(def_id).is_some()
2921    }
2922
2923    /// Whether this def is one of the special bin crate entrypoint functions that must have a
2924    /// monomorphization and also not be internalized in the bin crate.
2925    pub fn is_entrypoint(self, def_id: DefId) -> bool {
2926        if self.is_lang_item(def_id, LangItem::Start) {
2927            return true;
2928        }
2929        if let Some((entry_def_id, _)) = self.entry_fn(())
2930            && entry_def_id == def_id
2931        {
2932            return true;
2933        }
2934        false
2935    }
2936}
2937
2938pub fn provide(providers: &mut Providers) {
2939    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);
2940    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);
2941    providers.has_panic_handler = |tcx, LocalCrate| {
2942        // We want to check if the panic handler was defined in this crate
2943        tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2944    };
2945    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2946}