Skip to main content

rustc_middle/ty/
context.rs

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