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