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