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