Skip to main content

rustc_middle/ty/
context.rs

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