Skip to main content

rustc_middle/ty/
context.rs

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