Skip to main content

rustc_middle/ty/
context.rs

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