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;
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        #[allow(non_snake_case, reason = "we're using variant names as local variables")]
1740        mod inner {
1741            use crate::ty::{self, TyCtxt};
1742            use crate::ty::context::InternedInSet;
1743
1744            #[derive(Copy, Clone)]
1745            struct DebugStat {
1746                total: usize,
1747                lt_infer: usize,
1748                ty_infer: usize,
1749                ct_infer: usize,
1750                all_infer: usize,
1751            }
1752
1753            pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1754                let mut total = DebugStat {
1755                    total: 0,
1756                    lt_infer: 0,
1757                    ty_infer: 0,
1758                    ct_infer: 0,
1759                    all_infer: 0,
1760                };
1761                $(let mut $variant = total;)*
1762
1763                for shard in tcx.interners.type_.lock_shards() {
1764                    // It seems that ordering doesn't affect anything here.
1765                    #[allow(rustc::potential_query_instability)]
1766                    let types = shard.iter();
1767                    for &(InternedInSet(t), ()) in types {
1768                        let variant = match t.internee {
1769                            ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1770                                ty::Float(..) | ty::Str | ty::Never => continue,
1771                            ty::Error(_) => /* unimportant */ continue,
1772                            $(ty::$variant(..) => &mut $variant,)*
1773                        };
1774                        let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1775                        let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1776                        let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1777
1778                        variant.total += 1;
1779                        total.total += 1;
1780                        if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1781                        if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1782                        if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1783                        if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1784                    }
1785                }
1786                writeln!(fmt, "Ty interner             total           ty lt ct all")?;
1787                $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
1788                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1789                    stringify!($variant),
1790                    uses = $variant.total,
1791                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
1792                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
1793                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
1794                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
1795                    all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
1796                )*
1797                writeln!(fmt, "                  total {uses:6}        \
1798                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1799                    uses = total.total,
1800                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
1801                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
1802                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
1803                    all = total.all_infer as f64 * 100.0  / total.total as f64)
1804            }
1805        }
1806
1807        inner::go($fmt, $ctxt)
1808    }}
1809}
1810
1811impl<'tcx> TyCtxt<'tcx> {
1812    pub fn debug_stats(self) -> impl fmt::Debug {
1813        fmt::from_fn(move |fmt| {
1814            {
    #[allow(non_snake_case, reason =
    "we're using variant names as local variables")]
    mod inner {
        use crate::ty::{self, TyCtxt};
        use crate::ty::context::InternedInSet;
        struct DebugStat {
            total: usize,
            lt_infer: usize,
            ty_infer: usize,
            ct_infer: usize,
            all_infer: usize,
        }
        #[automatically_derived]
        impl ::core::marker::Copy for DebugStat { }
        #[automatically_derived]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone for DebugStat { }
        #[automatically_derived]
        impl ::core::clone::Clone for DebugStat {
            #[inline]
            fn clone(&self) -> DebugStat {
                let _: ::core::clone::AssertParamIsClone<usize>;
                *self
            }
        }
        pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>)
            -> std::fmt::Result {
            let mut total =
                DebugStat {
                    total: 0,
                    lt_infer: 0,
                    ty_infer: 0,
                    ct_infer: 0,
                    all_infer: 0,
                };
            let mut Adt = total;
            let mut Array = total;
            let mut Slice = total;
            let mut RawPtr = total;
            let mut Ref = total;
            let mut FnDef = total;
            let mut FnPtr = total;
            let mut UnsafeBinder = total;
            let mut Placeholder = total;
            let mut Coroutine = total;
            let mut CoroutineWitness = total;
            let mut Dynamic = total;
            let mut Closure = total;
            let mut CoroutineClosure = total;
            let mut Tuple = total;
            let mut Bound = total;
            let mut Param = total;
            let mut Infer = total;
            let mut Alias = total;
            let mut Pat = total;
            let mut Foreign = total;
            for shard in tcx.interners.type_.lock_shards() {
                #[allow(rustc :: potential_query_instability)]
                let types = shard.iter();
                for &(InternedInSet(t), ()) in types {
                    let variant =
                        match t.internee {
                            ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
                                ty::Float(..) | ty::Str | ty::Never => continue,
                            ty::Error(_) => continue,
                            ty::Adt(..) => &mut Adt,
                            ty::Array(..) => &mut Array,
                            ty::Slice(..) => &mut Slice,
                            ty::RawPtr(..) => &mut RawPtr,
                            ty::Ref(..) => &mut Ref,
                            ty::FnDef(..) => &mut FnDef,
                            ty::FnPtr(..) => &mut FnPtr,
                            ty::UnsafeBinder(..) => &mut UnsafeBinder,
                            ty::Placeholder(..) => &mut Placeholder,
                            ty::Coroutine(..) => &mut Coroutine,
                            ty::CoroutineWitness(..) => &mut CoroutineWitness,
                            ty::Dynamic(..) => &mut Dynamic,
                            ty::Closure(..) => &mut Closure,
                            ty::CoroutineClosure(..) => &mut CoroutineClosure,
                            ty::Tuple(..) => &mut Tuple,
                            ty::Bound(..) => &mut Bound,
                            ty::Param(..) => &mut Param,
                            ty::Infer(..) => &mut Infer,
                            ty::Alias(..) => &mut Alias,
                            ty::Pat(..) => &mut Pat,
                            ty::Foreign(..) => &mut Foreign,
                        };
                    let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
                    let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
                    let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
                    variant.total += 1;
                    total.total += 1;
                    if lt { total.lt_infer += 1; variant.lt_infer += 1 }
                    if ty { total.ty_infer += 1; variant.ty_infer += 1 }
                    if ct { total.ct_infer += 1; variant.ct_infer += 1 }
                    if lt && ty && ct {
                        total.all_infer += 1;
                        variant.all_infer += 1
                    }
                }
            }
            fmt.write_fmt(format_args!("Ty interner             total           ty lt ct all\n"))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Adt", Adt.total,
                        Adt.total as f64 * 100.0 / total.total as f64,
                        Adt.ty_infer as f64 * 100.0 / total.total as f64,
                        Adt.lt_infer as f64 * 100.0 / total.total as f64,
                        Adt.ct_infer as f64 * 100.0 / total.total as f64,
                        Adt.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Array", Array.total,
                        Array.total as f64 * 100.0 / total.total as f64,
                        Array.ty_infer as f64 * 100.0 / total.total as f64,
                        Array.lt_infer as f64 * 100.0 / total.total as f64,
                        Array.ct_infer as f64 * 100.0 / total.total as f64,
                        Array.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Slice", Slice.total,
                        Slice.total as f64 * 100.0 / total.total as f64,
                        Slice.ty_infer as f64 * 100.0 / total.total as f64,
                        Slice.lt_infer as f64 * 100.0 / total.total as f64,
                        Slice.ct_infer as f64 * 100.0 / total.total as f64,
                        Slice.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "RawPtr", RawPtr.total,
                        RawPtr.total as f64 * 100.0 / total.total as f64,
                        RawPtr.ty_infer as f64 * 100.0 / total.total as f64,
                        RawPtr.lt_infer as f64 * 100.0 / total.total as f64,
                        RawPtr.ct_infer as f64 * 100.0 / total.total as f64,
                        RawPtr.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Ref", Ref.total,
                        Ref.total as f64 * 100.0 / total.total as f64,
                        Ref.ty_infer as f64 * 100.0 / total.total as f64,
                        Ref.lt_infer as f64 * 100.0 / total.total as f64,
                        Ref.ct_infer as f64 * 100.0 / total.total as f64,
                        Ref.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "FnDef", FnDef.total,
                        FnDef.total as f64 * 100.0 / total.total as f64,
                        FnDef.ty_infer as f64 * 100.0 / total.total as f64,
                        FnDef.lt_infer as f64 * 100.0 / total.total as f64,
                        FnDef.ct_infer as f64 * 100.0 / total.total as f64,
                        FnDef.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "FnPtr", FnPtr.total,
                        FnPtr.total as f64 * 100.0 / total.total as f64,
                        FnPtr.ty_infer as f64 * 100.0 / total.total as f64,
                        FnPtr.lt_infer as f64 * 100.0 / total.total as f64,
                        FnPtr.ct_infer as f64 * 100.0 / total.total as f64,
                        FnPtr.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "UnsafeBinder", UnsafeBinder.total,
                        UnsafeBinder.total as f64 * 100.0 / total.total as f64,
                        UnsafeBinder.ty_infer as f64 * 100.0 / total.total as f64,
                        UnsafeBinder.lt_infer as f64 * 100.0 / total.total as f64,
                        UnsafeBinder.ct_infer as f64 * 100.0 / total.total as f64,
                        UnsafeBinder.all_infer as f64 * 100.0 /
                            total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Placeholder", Placeholder.total,
                        Placeholder.total as f64 * 100.0 / total.total as f64,
                        Placeholder.ty_infer as f64 * 100.0 / total.total as f64,
                        Placeholder.lt_infer as f64 * 100.0 / total.total as f64,
                        Placeholder.ct_infer as f64 * 100.0 / total.total as f64,
                        Placeholder.all_infer as f64 * 100.0 /
                            total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Coroutine", Coroutine.total,
                        Coroutine.total as f64 * 100.0 / total.total as f64,
                        Coroutine.ty_infer as f64 * 100.0 / total.total as f64,
                        Coroutine.lt_infer as f64 * 100.0 / total.total as f64,
                        Coroutine.ct_infer as f64 * 100.0 / total.total as f64,
                        Coroutine.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "CoroutineWitness", CoroutineWitness.total,
                        CoroutineWitness.total as f64 * 100.0 / total.total as f64,
                        CoroutineWitness.ty_infer as f64 * 100.0 /
                            total.total as f64,
                        CoroutineWitness.lt_infer as f64 * 100.0 /
                            total.total as f64,
                        CoroutineWitness.ct_infer as f64 * 100.0 /
                            total.total as f64,
                        CoroutineWitness.all_infer as f64 * 100.0 /
                            total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Dynamic", Dynamic.total,
                        Dynamic.total as f64 * 100.0 / total.total as f64,
                        Dynamic.ty_infer as f64 * 100.0 / total.total as f64,
                        Dynamic.lt_infer as f64 * 100.0 / total.total as f64,
                        Dynamic.ct_infer as f64 * 100.0 / total.total as f64,
                        Dynamic.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Closure", Closure.total,
                        Closure.total as f64 * 100.0 / total.total as f64,
                        Closure.ty_infer as f64 * 100.0 / total.total as f64,
                        Closure.lt_infer as f64 * 100.0 / total.total as f64,
                        Closure.ct_infer as f64 * 100.0 / total.total as f64,
                        Closure.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "CoroutineClosure", CoroutineClosure.total,
                        CoroutineClosure.total as f64 * 100.0 / total.total as f64,
                        CoroutineClosure.ty_infer as f64 * 100.0 /
                            total.total as f64,
                        CoroutineClosure.lt_infer as f64 * 100.0 /
                            total.total as f64,
                        CoroutineClosure.ct_infer as f64 * 100.0 /
                            total.total as f64,
                        CoroutineClosure.all_infer as f64 * 100.0 /
                            total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Tuple", Tuple.total,
                        Tuple.total as f64 * 100.0 / total.total as f64,
                        Tuple.ty_infer as f64 * 100.0 / total.total as f64,
                        Tuple.lt_infer as f64 * 100.0 / total.total as f64,
                        Tuple.ct_infer as f64 * 100.0 / total.total as f64,
                        Tuple.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Bound", Bound.total,
                        Bound.total as f64 * 100.0 / total.total as f64,
                        Bound.ty_infer as f64 * 100.0 / total.total as f64,
                        Bound.lt_infer as f64 * 100.0 / total.total as f64,
                        Bound.ct_infer as f64 * 100.0 / total.total as f64,
                        Bound.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Param", Param.total,
                        Param.total as f64 * 100.0 / total.total as f64,
                        Param.ty_infer as f64 * 100.0 / total.total as f64,
                        Param.lt_infer as f64 * 100.0 / total.total as f64,
                        Param.ct_infer as f64 * 100.0 / total.total as f64,
                        Param.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Infer", Infer.total,
                        Infer.total as f64 * 100.0 / total.total as f64,
                        Infer.ty_infer as f64 * 100.0 / total.total as f64,
                        Infer.lt_infer as f64 * 100.0 / total.total as f64,
                        Infer.ct_infer as f64 * 100.0 / total.total as f64,
                        Infer.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Alias", Alias.total,
                        Alias.total as f64 * 100.0 / total.total as f64,
                        Alias.ty_infer as f64 * 100.0 / total.total as f64,
                        Alias.lt_infer as f64 * 100.0 / total.total as f64,
                        Alias.ct_infer as f64 * 100.0 / total.total as f64,
                        Alias.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Pat", Pat.total,
                        Pat.total as f64 * 100.0 / total.total as f64,
                        Pat.ty_infer as f64 * 100.0 / total.total as f64,
                        Pat.lt_infer as f64 * 100.0 / total.total as f64,
                        Pat.ct_infer as f64 * 100.0 / total.total as f64,
                        Pat.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("    {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
                        "Foreign", Foreign.total,
                        Foreign.total as f64 * 100.0 / total.total as f64,
                        Foreign.ty_infer as f64 * 100.0 / total.total as f64,
                        Foreign.lt_infer as f64 * 100.0 / total.total as f64,
                        Foreign.ct_infer as f64 * 100.0 / total.total as f64,
                        Foreign.all_infer as f64 * 100.0 / total.total as f64))?;
            fmt.write_fmt(format_args!("                  total {0:6}        {1:4.1}% {2:5.1}% {3:4.1}% {4:4.1}%\n",
                    total.total,
                    total.ty_infer as f64 * 100.0 / total.total as f64,
                    total.lt_infer as f64 * 100.0 / total.total as f64,
                    total.ct_infer as f64 * 100.0 / total.total as f64,
                    total.all_infer as f64 * 100.0 / total.total as f64))
        }
    }
    inner::go(fmt, self)
}sty_debug_print!(
1815                fmt,
1816                self,
1817                Adt,
1818                Array,
1819                Slice,
1820                RawPtr,
1821                Ref,
1822                FnDef,
1823                FnPtr,
1824                UnsafeBinder,
1825                Placeholder,
1826                Coroutine,
1827                CoroutineWitness,
1828                Dynamic,
1829                Closure,
1830                CoroutineClosure,
1831                Tuple,
1832                Bound,
1833                Param,
1834                Infer,
1835                Alias,
1836                Pat,
1837                Foreign
1838            )?;
1839
1840            fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
        self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1841            fmt.write_fmt(format_args!("Region interner: #{0}\n",
        self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1842            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())?;
1843            fmt.write_fmt(format_args!("Layout interner: #{0}\n",
        self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1844
1845            Ok(())
1846        })
1847    }
1848}
1849
1850// This type holds a `T` in the interner. The `T` is stored in the arena and
1851// this type just holds a pointer to it, but it still effectively owns it. It
1852// impls `Borrow` so that it can be looked up using the original
1853// (non-arena-memory-owning) types.
1854struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1855
1856impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1857    fn clone(&self) -> Self {
1858        *self
1859    }
1860}
1861
1862impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1863
1864impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1865    fn into_pointer(&self) -> *const () {
1866        self.0 as *const _ as *const ()
1867    }
1868}
1869
1870#[allow(rustc::usage_of_ty_tykind)]
1871impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1872    fn borrow(&self) -> &T {
1873        &self.0.internee
1874    }
1875}
1876
1877impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1878    fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1879        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1880        // `x == y`.
1881        self.0.internee == other.0.internee
1882    }
1883}
1884
1885impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1886
1887impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1888    fn hash<H: Hasher>(&self, s: &mut H) {
1889        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1890        self.0.internee.hash(s)
1891    }
1892}
1893
1894impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1895    fn borrow(&self) -> &[T] {
1896        &self.0[..]
1897    }
1898}
1899
1900impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1901    fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1902        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1903        // `x == y`.
1904        self.0[..] == other.0[..]
1905    }
1906}
1907
1908impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1909
1910impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1911    fn hash<H: Hasher>(&self, s: &mut H) {
1912        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1913        self.0[..].hash(s)
1914    }
1915}
1916
1917impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1918    fn borrow(&self) -> &[T] {
1919        &self.0[..]
1920    }
1921}
1922
1923impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1924    fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1925        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
1926        // `x == y`.
1927        self.0[..] == other.0[..]
1928    }
1929}
1930
1931impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1932
1933impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1934    fn hash<H: Hasher>(&self, s: &mut H) {
1935        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
1936        self.0[..].hash(s)
1937    }
1938}
1939
1940macro_rules! direct_interners {
1941    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1942        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1943            fn borrow<'a>(&'a self) -> &'a $ty {
1944                &self.0
1945            }
1946        }
1947
1948        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1949            fn eq(&self, other: &Self) -> bool {
1950                // The `Borrow` trait requires that `x.borrow() == y.borrow()`
1951                // equals `x == y`.
1952                self.0 == other.0
1953            }
1954        }
1955
1956        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1957
1958        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1959            fn hash<H: Hasher>(&self, s: &mut H) {
1960                // The `Borrow` trait requires that `x.borrow().hash(s) ==
1961                // x.hash(s)`.
1962                self.0.hash(s)
1963            }
1964        }
1965
1966        impl<'tcx> TyCtxt<'tcx> {
1967            $vis fn $method(self, v: $ty) -> $ret_ty {
1968                $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1969                    InternedInSet(self.interners.arena.alloc(v))
1970                }).0))
1971            }
1972        })+
1973    }
1974}
1975
1976// Functions with a `mk_` prefix are intended for use outside this file and
1977// crate. Functions with an `intern_` prefix are intended for use within this
1978// crate only, and have a corresponding `mk_` function.
1979impl<'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! {
1980    region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
1981    valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
1982    pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
1983    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
1984    layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
1985    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
1986    external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
1987        ExternalConstraints -> ExternalConstraints<'tcx>,
1988}
1989
1990macro_rules! slice_interners {
1991    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
1992        impl<'tcx> TyCtxt<'tcx> {
1993            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
1994                if v.is_empty() {
1995                    List::empty()
1996                } else {
1997                    self.interners.$field.intern_ref(v, || {
1998                        InternedInSet(List::from_arena(&*self.arena, (), v))
1999                    }).0
2000                }
2001            })+
2002        }
2003    );
2004}
2005
2006// These functions intern slices. They all have a corresponding
2007// `mk_foo_from_iter` function that interns an iterator. The slice version
2008// should be used when possible, because it's faster.
2009impl<'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!(
2010    const_lists: pub mk_const_list(Const<'tcx>),
2011    args: pub mk_args(GenericArg<'tcx>),
2012    type_lists: pub mk_type_list(Ty<'tcx>),
2013    canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2014    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2015    projs: pub mk_projs(ProjectionKind),
2016    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2017    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2018    fields: pub mk_fields(FieldIdx),
2019    local_def_ids: intern_local_def_ids(LocalDefId),
2020    captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2021    patterns: pub mk_patterns(Pattern<'tcx>),
2022    outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2023    predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2024);
2025
2026impl<'tcx> TyCtxt<'tcx> {
2027    /// Given a `fn` sig, returns an equivalent `unsafe fn` type;
2028    /// that is, a `fn` type that is equivalent in every way for being
2029    /// unsafe.
2030    pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2031        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2032        Ty::new_fn_ptr(
2033            self,
2034            sig.map_bound(|sig| ty::FnSig {
2035                fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2036                ..sig
2037            }),
2038        )
2039    }
2040
2041    /// Given a `fn` sig, returns an equivalent `unsafe fn` sig;
2042    /// that is, a `fn` sig that is equivalent in every way for being
2043    /// unsafe.
2044    pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2045        if !sig.safety().is_safe() {
    ::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2046        sig.map_bound(|sig| ty::FnSig {
2047            fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2048            ..sig
2049        })
2050    }
2051
2052    /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
2053    /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
2054    pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2055        elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2056            self.associated_items(trait_did)
2057                .filter_by_name_unhygienic(assoc_name.name)
2058                .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2059        })
2060    }
2061
2062    /// Given a `ty`, return whether it's an `impl Future<...>`.
2063    pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2064        let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2065            return false;
2066        };
2067        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2068
2069        self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2070            let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2071                return false;
2072            };
2073            trait_predicate.trait_ref.def_id == future_trait
2074                && trait_predicate.polarity == PredicatePolarity::Positive
2075        })
2076    }
2077
2078    /// Given a closure signature, returns an equivalent fn signature. Detuples
2079    /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
2080    /// you would get a `fn(u32, i32)`.
2081    /// `unsafety` determines the unsafety of the fn signature. If you pass
2082    /// `hir::Safety::Unsafe` in the previous example, then you would get
2083    /// an `unsafe fn (u32, i32)`.
2084    /// It cannot convert a closure that requires unsafe.
2085    pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2086        sig.map_bound(|s| {
2087            let params = match s.inputs()[0].kind() {
2088                ty::Tuple(params) => *params,
2089                _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2090            };
2091            // Ignore splatting, it is unsupported on closures.
2092            if !s.splatted().is_none() {
    ::core::panicking::panic("assertion failed: s.splatted().is_none()")
};assert!(s.splatted().is_none());
2093            self.mk_fn_sig(
2094                params,
2095                s.output(),
2096                s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2097            )
2098        })
2099    }
2100
2101    #[inline]
2102    pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2103        self.interners.intern_predicate(binder)
2104    }
2105
2106    #[inline]
2107    pub fn reuse_or_mk_predicate(
2108        self,
2109        pred: Predicate<'tcx>,
2110        binder: Binder<'tcx, PredicateKind<'tcx>>,
2111    ) -> Predicate<'tcx> {
2112        if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2113    }
2114
2115    pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2116        self.check_args_compatible_inner(def_id, args, false)
2117    }
2118
2119    fn check_args_compatible_inner(
2120        self,
2121        def_id: DefId,
2122        args: &'tcx [ty::GenericArg<'tcx>],
2123        nested: bool,
2124    ) -> bool {
2125        let generics = self.generics_of(def_id);
2126
2127        // IATs and IACs (inherent associated types/consts with `type const`) themselves have a
2128        // weird arg setup (self + own args), but nested items *in* IATs (namely: opaques, i.e.
2129        // ATPITs) do not.
2130        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)
2131            && #[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 });
2132        let is_inherent_assoc_type_const =
2133            #[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 })
2134                && #[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 });
2135        let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2136            if generics.own_params.len() + 1 != args.len() {
2137                return false;
2138            }
2139
2140            if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
    ty::GenericArgKind::Type(_) => true,
    _ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2141                return false;
2142            }
2143
2144            &args[1..]
2145        } else {
2146            if generics.count() != args.len() {
2147                return false;
2148            }
2149
2150            let (parent_args, own_args) = args.split_at(generics.parent_count);
2151
2152            if let Some(parent) = generics.parent
2153                && !self.check_args_compatible_inner(parent, parent_args, true)
2154            {
2155                return false;
2156            }
2157
2158            own_args
2159        };
2160
2161        for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2162            match (&param.kind, arg.kind()) {
2163                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2164                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2165                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2166                _ => return false,
2167            }
2168        }
2169
2170        true
2171    }
2172
2173    /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
2174    /// and print out the args if not.
2175    pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2176        if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2177            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)
2178                && #[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 });
2179            let is_inherent_assoc_type_const =
2180                #[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 })
2181                    && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
    {
    DefKind::Impl { of_trait: false } => true,
    _ => false,
}matches!(
2182                        self.def_kind(self.parent(def_id)),
2183                        DefKind::Impl { of_trait: false }
2184                    );
2185            if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2186                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!(
2187                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2188                    self.def_path_str(def_id),
2189                    args,
2190                    // Make `[Self, GAT_ARGS...]` (this could be simplified)
2191                    self.mk_args_from_iter(
2192                        [self.types.self_param.into()].into_iter().chain(
2193                            self.generics_of(def_id)
2194                                .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2195                                .iter()
2196                                .copied()
2197                        )
2198                    )
2199                );
2200            } else {
2201                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!(
2202                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2203                    self.def_path_str(def_id),
2204                    args,
2205                    ty::GenericArgs::identity_for_item(self, def_id)
2206                );
2207            }
2208        }
2209    }
2210
2211    #[inline(always)]
2212    pub(crate) fn check_and_mk_args(
2213        self,
2214        def_id: DefId,
2215        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2216    ) -> GenericArgsRef<'tcx> {
2217        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2218        self.debug_assert_args_compatible(def_id, args);
2219        args
2220    }
2221
2222    #[inline]
2223    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2224        self.interners.intern_const(kind)
2225    }
2226
2227    // Avoid this in favour of more specific `Ty::new_*` methods, where possible.
2228    #[allow(rustc::usage_of_ty_tykind)]
2229    #[inline]
2230    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2231        self.interners.intern_ty(st)
2232    }
2233
2234    pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2235        match param.kind {
2236            GenericParamDefKind::Lifetime => {
2237                ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2238            }
2239            GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2240            GenericParamDefKind::Const { .. } => {
2241                ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2242                    .into()
2243            }
2244        }
2245    }
2246
2247    pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2248        self.mk_place_elem(place, PlaceElem::Field(f, ty))
2249    }
2250
2251    pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2252        self.mk_place_elem(place, PlaceElem::Deref)
2253    }
2254
2255    pub fn mk_place_downcast(
2256        self,
2257        place: Place<'tcx>,
2258        adt_def: AdtDef<'tcx>,
2259        variant_index: VariantIdx,
2260    ) -> Place<'tcx> {
2261        self.mk_place_elem(
2262            place,
2263            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2264        )
2265    }
2266
2267    pub fn mk_place_downcast_unnamed(
2268        self,
2269        place: Place<'tcx>,
2270        variant_index: VariantIdx,
2271    ) -> Place<'tcx> {
2272        self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2273    }
2274
2275    pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2276        self.mk_place_elem(place, PlaceElem::Index(index))
2277    }
2278
2279    /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2280    /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2281    /// flight.
2282    pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2283        Place {
2284            local: place.local,
2285            projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2286        }
2287    }
2288
2289    pub fn mk_poly_existential_predicates(
2290        self,
2291        eps: &[PolyExistentialPredicate<'tcx>],
2292    ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2293        if !!eps.is_empty() {
    ::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2294        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!(
2295            eps.array_windows()
2296                .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2297                    != Ordering::Greater)
2298        );
2299        self.intern_poly_existential_predicates(eps)
2300    }
2301
2302    pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2303        // FIXME consider asking the input slice to be sorted to avoid
2304        // re-interning permutations, in which case that would be asserted
2305        // here.
2306        self.interners.intern_clauses(clauses)
2307    }
2308
2309    pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2310        // FIXME consider asking the input slice to be sorted to avoid
2311        // re-interning permutations, in which case that would be asserted
2312        // here.
2313        self.intern_local_def_ids(def_ids)
2314    }
2315
2316    pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2317    where
2318        I: Iterator<Item = T>,
2319        T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2320    {
2321        T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2322    }
2323
2324    pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2325    where
2326        I: Iterator<Item = T>,
2327        T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2328    {
2329        T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2330    }
2331
2332    pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2333    where
2334        I: Iterator<Item = T>,
2335        T: CollectAndApply<
2336                &'tcx ty::CapturedPlace<'tcx>,
2337                &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2338            >,
2339    {
2340        T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2341    }
2342
2343    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2344    where
2345        I: Iterator<Item = T>,
2346        T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2347    {
2348        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2349    }
2350
2351    // Unlike various other `mk_*_from_iter` functions, this one uses `I:
2352    // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
2353    // variant, because of the need to combine `inputs` and `output`. This
2354    // explains the lack of `_from_iter` suffix.
2355    pub fn mk_fn_sig<I, T>(
2356        self,
2357        inputs: I,
2358        output: I::Item,
2359        fn_sig_kind: FnSigKind<'tcx>,
2360    ) -> T::Output
2361    where
2362        I: IntoIterator<Item = T>,
2363        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2364    {
2365        T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2366            inputs_and_output: self.mk_type_list(xs),
2367            fn_sig_kind,
2368        })
2369    }
2370
2371    /// `mk_fn_sig`, but with a Rust ABI, and no C-variadic argument.
2372    pub fn mk_fn_sig_rust_abi<I, T>(
2373        self,
2374        inputs: I,
2375        output: I::Item,
2376        safety: hir::Safety,
2377    ) -> T::Output
2378    where
2379        I: IntoIterator<Item = T>,
2380        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2381    {
2382        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2383    }
2384
2385    /// `mk_fn_sig`, but with a safe Rust ABI, and no C-variadic argument.
2386    pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2387    where
2388        I: IntoIterator<Item = T>,
2389        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2390    {
2391        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2392    }
2393
2394    /// `mk_fn_sig`, but with an **un**safe Rust ABI, and no C-variadic argument.
2395    pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2396    where
2397        I: IntoIterator<Item = T>,
2398        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2399    {
2400        self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2401    }
2402
2403    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2404    where
2405        I: Iterator<Item = T>,
2406        T: CollectAndApply<
2407                PolyExistentialPredicate<'tcx>,
2408                &'tcx List<PolyExistentialPredicate<'tcx>>,
2409            >,
2410    {
2411        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2412    }
2413
2414    pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2415    where
2416        I: Iterator<Item = T>,
2417        T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2418    {
2419        T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2420    }
2421
2422    pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2423    where
2424        I: Iterator<Item = T>,
2425        T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2426    {
2427        T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2428    }
2429
2430    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2431    where
2432        I: Iterator<Item = T>,
2433        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2434    {
2435        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2436    }
2437
2438    pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2439    where
2440        I: Iterator<Item = T>,
2441        T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2442    {
2443        T::collect_and_apply(iter, |xs| self.mk_args(xs))
2444    }
2445
2446    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2447    where
2448        I: Iterator<Item = T>,
2449        T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2450    {
2451        T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2452    }
2453
2454    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2455    where
2456        I: Iterator<Item = T>,
2457        T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2458    {
2459        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2460    }
2461
2462    pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2463    where
2464        I: Iterator<Item = T>,
2465        T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2466    {
2467        T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2468    }
2469
2470    pub fn mk_args_trait(
2471        self,
2472        self_ty: Ty<'tcx>,
2473        rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2474    ) -> GenericArgsRef<'tcx> {
2475        self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2476    }
2477
2478    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2479    where
2480        I: Iterator<Item = T>,
2481        T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2482    {
2483        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2484    }
2485
2486    pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2487    where
2488        I: Iterator<Item = T>,
2489        T: CollectAndApply<
2490                ty::ArgOutlivesPredicate<'tcx>,
2491                &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2492            >,
2493    {
2494        T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2495    }
2496
2497    /// Emit a lint at `span` from a lint struct (some type that implements `Diagnostic`,
2498    /// typically generated by `#[derive(Diagnostic)]`).
2499    #[track_caller]
2500    pub fn emit_node_span_lint(
2501        self,
2502        lint: &'static Lint,
2503        hir_id: HirId,
2504        span: impl Into<MultiSpan>,
2505        decorator: impl for<'a> Diagnostic<'a, ()>,
2506    ) {
2507        let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2508        emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2509    }
2510
2511    /// Find the appropriate span where `use` and outer attributes can be inserted at.
2512    pub fn crate_level_attribute_injection_span(self) -> Span {
2513        let node = self.hir_node(hir::CRATE_HIR_ID);
2514        let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2515        m.spans.inject_use_span.shrink_to_lo()
2516    }
2517
2518    pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2519        self,
2520        diag: &mut Diag<'_, E>,
2521        features: impl IntoIterator<Item = (String, Symbol)>,
2522    ) {
2523        if !self.sess.is_nightly_build() {
2524            return;
2525        }
2526
2527        let span = self.crate_level_attribute_injection_span();
2528        for (desc, feature) in features {
2529            // FIXME: make this string translatable
2530            let msg =
2531                ::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}");
2532            diag.span_suggestion_verbose(
2533                span,
2534                msg,
2535                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
    })format!("#![feature({feature})]\n"),
2536                Applicability::MaybeIncorrect,
2537            );
2538        }
2539    }
2540
2541    /// Emit a lint from a lint struct (some type that implements `Diagnostic`, typically generated
2542    /// by `#[derive(Diagnostic)]`).
2543    #[track_caller]
2544    pub fn emit_node_lint(
2545        self,
2546        lint: &'static Lint,
2547        id: HirId,
2548        decorator: impl for<'a> Diagnostic<'a, ()>,
2549    ) {
2550        let level_spec = self.lint_level_spec_at_node(lint, id);
2551        emit_lint_base(self.sess, lint, level_spec, None, decorator);
2552    }
2553
2554    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2555        let map = self.in_scope_traits_map(id.owner)?;
2556        let candidates = map.get(&id.local_id)?;
2557        Some(candidates)
2558    }
2559
2560    pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2561        {
    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:2561",
                        "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(2561u32),
                        ::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");
2562        self.named_variable_map(id.owner).get(&id.local_id).cloned()
2563    }
2564
2565    pub fn is_late_bound(self, id: HirId) -> bool {
2566        self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2567    }
2568
2569    pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2570        self.mk_bound_variable_kinds(
2571            &self
2572                .late_bound_vars_map(id.owner)
2573                .get(&id.local_id)
2574                .cloned()
2575                .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))),
2576        )
2577    }
2578
2579    /// Given the def-id of an early-bound lifetime on an opaque corresponding to
2580    /// a duplicated captured lifetime, map it back to the early- or late-bound
2581    /// lifetime of the function from which it originally as captured. If it is
2582    /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
2583    /// of the signature.
2584    // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
2585    // re-use the generics of the opaque, this function will need to be tweaked slightly.
2586    pub fn map_opaque_lifetime_to_parent_lifetime(
2587        self,
2588        mut opaque_lifetime_param_def_id: LocalDefId,
2589    ) -> ty::Region<'tcx> {
2590        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!(
2591            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2592            "{opaque_lifetime_param_def_id:?} is a {}",
2593            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2594        );
2595
2596        loop {
2597            let parent = self.local_parent(opaque_lifetime_param_def_id);
2598            let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2599
2600            let Some((lifetime, _)) = lifetime_mapping
2601                .iter()
2602                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2603            else {
2604                crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2605            };
2606
2607            match *lifetime {
2608                resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2609                    let new_parent = self.local_parent(ebv);
2610
2611                    // If we map to another opaque, then it should be a parent
2612                    // of the opaque we mapped from. Continue mapping.
2613                    if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
    DefKind::OpaqueTy => true,
    _ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2614                        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);
2615                        opaque_lifetime_param_def_id = ebv;
2616                        continue;
2617                    }
2618
2619                    let generics = self.generics_of(new_parent);
2620                    return ty::Region::new_early_param(
2621                        self,
2622                        ty::EarlyParamRegion {
2623                            index: generics
2624                                .param_def_id_to_index(self, ebv.to_def_id())
2625                                .expect("early-bound var should be present in fn generics"),
2626                            name: self.item_name(ebv.to_def_id()),
2627                        },
2628                    );
2629                }
2630                resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2631                    let new_parent = self.local_parent(lbv);
2632                    return ty::Region::new_late_param(
2633                        self,
2634                        new_parent.to_def_id(),
2635                        ty::LateParamRegionKind::Named(lbv.to_def_id()),
2636                    );
2637                }
2638                resolve_bound_vars::ResolvedArg::Error(guar) => {
2639                    return ty::Region::new_error(self, guar);
2640                }
2641                _ => {
2642                    return ty::Region::new_error_with_message(
2643                        self,
2644                        self.def_span(opaque_lifetime_param_def_id),
2645                        "cannot resolve lifetime",
2646                    );
2647                }
2648            }
2649        }
2650    }
2651
2652    /// Whether `def_id` is a stable const fn (i.e., doesn't need any feature gates to be called).
2653    ///
2654    /// When this is `false`, the function may still be callable as a `const fn` due to features
2655    /// being enabled!
2656    pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2657        self.is_const_fn(def_id)
2658            && match self.lookup_const_stability(def_id) {
2659                None => true, // a fn in a non-staged_api crate
2660                Some(stability) if stability.is_const_stable() => true,
2661                _ => false,
2662            }
2663    }
2664
2665    /// Whether the trait impl is marked const. This does not consider stability or feature gates.
2666    pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2667        self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2668            && #[allow(non_exhaustive_omitted_patterns)] match self.impl_trait_header(def_id).constness
    {
    hir::Constness::Const { always: false } => true,
    _ => false,
}matches!(
2669                self.impl_trait_header(def_id).constness,
2670                hir::Constness::Const { always: false }
2671            )
2672    }
2673
2674    pub fn is_sdylib_interface_build(self) -> bool {
2675        self.sess.opts.unstable_opts.build_sdylib_interface
2676    }
2677
2678    pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2679        let def_id = def_id.into_query_key();
2680        match self.def_kind(def_id) {
2681            DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2682            _ => None,
2683        }
2684    }
2685
2686    pub fn next_trait_solver_globally(self) -> bool {
2687        self.sess.opts.unstable_opts.next_solver.globally
2688    }
2689
2690    pub fn next_trait_solver_in_coherence(self) -> bool {
2691        self.sess.opts.unstable_opts.next_solver.coherence
2692    }
2693
2694    pub fn disable_trait_solver_fast_paths(self) -> bool {
2695        self.sess.opts.unstable_opts.disable_fast_paths
2696    }
2697
2698    pub fn disable_param_env_normalization_hack(self) -> bool {
2699        self.sess.opts.unstable_opts.disable_param_env_normalization_hack
2700    }
2701
2702    pub fn renormalize_rigid_aliases(self) -> bool {
2703        self.sess.opts.unstable_opts.renormalize_rigid_aliases
2704    }
2705
2706    #[allow(rustc::bad_opt_access)]
2707    pub fn use_typing_mode_post_typeck_until_borrowck(self) -> bool {
2708        self.next_trait_solver_globally()
2709            || self.sess.opts.unstable_opts.typing_mode_post_typeck_until_borrowck
2710    }
2711
2712    pub fn assumptions_on_binders(self) -> bool {
2713        self.sess.opts.unstable_opts.assumptions_on_binders
2714    }
2715
2716    pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2717        self.opt_rpitit_info(def_id).is_some()
2718    }
2719
2720    pub fn get_impl_future_output_ty(self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
2721        let (def_id, args) = match *ty.kind() {
2722            ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
2723            ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, args, .. })
2724                if self.is_impl_trait_in_trait(def_id) =>
2725            {
2726                (def_id, args)
2727            }
2728            _ => return None,
2729        };
2730
2731        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2732        let item_def_id = self.associated_item_def_ids(future_trait)[0];
2733
2734        self.explicit_item_self_bounds(def_id)
2735            .iter_instantiated_copied(self, args)
2736            .map(ty::Unnormalized::skip_norm_wip)
2737            .find_map(|(predicate, _)| {
2738                predicate
2739                    .kind()
2740                    .map_bound(|kind| match kind {
2741                        ty::ClauseKind::Projection(projection_predicate)
2742                            if projection_predicate.def_id() == item_def_id =>
2743                        {
2744                            projection_predicate.term.as_type()
2745                        }
2746                        _ => None,
2747                    })
2748                    .no_bound_vars()
2749                    .flatten()
2750            })
2751    }
2752
2753    /// Named module children from all kinds of items, including imports.
2754    /// In addition to regular items this list also includes struct and variant constructors, and
2755    /// items inside `extern {}` blocks because all of them introduce names into parent module.
2756    ///
2757    /// Module here is understood in name resolution sense - it can be a `mod` item,
2758    /// or a crate root, or an enum, or a trait.
2759    ///
2760    /// This is not a query, making it a query causes perf regressions
2761    /// (probably due to hashing spans in `ModChild`ren).
2762    pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2763        self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2764    }
2765
2766    /// Return the crate imported by given use item.
2767    pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2768        self.resolutions(()).extern_crate_map.get(&def_id).copied()
2769    }
2770
2771    pub fn resolver_for_lowering(
2772        self,
2773    ) -> (&'tcx Steal<ty::ResolverAstLowering<'tcx>>, &'tcx Steal<ast::Crate>) {
2774        let (resolver, krate, _) = self.resolver_for_lowering_raw(());
2775        (resolver, krate)
2776    }
2777
2778    pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2779        make_metadata(self)
2780    }
2781
2782    pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2783        if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2784            self.coroutine_kind(def_id)
2785            && let ty::Coroutine(_, args) =
2786                self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2787            && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2788        {
2789            true
2790        } else {
2791            false
2792        }
2793    }
2794
2795    /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
2796    pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2797        {
        {
            '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)
2798    }
2799
2800    pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2801        let def_id = def_id.into_query_key();
2802        self.trivial_const(def_id).is_some()
2803    }
2804
2805    /// Whether this def is one of the special bin crate entrypoint functions that must have a
2806    /// monomorphization and also not be internalized in the bin crate.
2807    pub fn is_entrypoint(self, def_id: DefId) -> bool {
2808        if self.is_lang_item(def_id, LangItem::Start) {
2809            return true;
2810        }
2811        if let Some((entry_def_id, _)) = self.entry_fn(())
2812            && entry_def_id == def_id
2813        {
2814            return true;
2815        }
2816        false
2817    }
2818}
2819
2820pub fn provide(providers: &mut Providers) {
2821    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);
2822    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);
2823    providers.has_panic_handler = |tcx, LocalCrate| {
2824        // We want to check if the panic handler was defined in this crate
2825        tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2826    };
2827    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2828}