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