Skip to main content

rustc_middle/ty/
context.rs

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