rustc_middle/ty/
context.rs

1//! Type context book-keeping.
2
3#![allow(rustc::usage_of_ty_tykind)]
4
5pub mod tls;
6
7use std::assert_matches::{assert_matches, debug_assert_matches};
8use std::borrow::Borrow;
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::PhantomData;
14use std::ops::{Bound, 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::fingerprint::Fingerprint;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::jobserver::Proxy;
25use rustc_data_structures::profiling::SelfProfilerRef;
26use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
27use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
28use rustc_data_structures::steal::Steal;
29use rustc_data_structures::sync::{
30    self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
31};
32use rustc_errors::{
33    Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan,
34};
35use rustc_hir::def::{CtorKind, DefKind};
36use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
37use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
38use rustc_hir::intravisit::VisitorExt;
39use rustc_hir::lang_items::LangItem;
40use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
41use rustc_index::IndexVec;
42use rustc_macros::{HashStable, TyDecodable, TyEncodable};
43use rustc_query_system::cache::WithDepNode;
44use rustc_query_system::dep_graph::DepNodeIndex;
45use rustc_query_system::ich::StableHashingContext;
46use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
47use rustc_session::config::CrateType;
48use rustc_session::cstore::{CrateStoreDyn, Untracked};
49use rustc_session::lint::Lint;
50use rustc_session::{Limit, MetadataKind, Session};
51use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
52use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
53use rustc_type_ir::TyKind::*;
54use rustc_type_ir::lang_items::TraitSolverLangItem;
55pub use rustc_type_ir::lift::Lift;
56use rustc_type_ir::{
57    CollectAndApply, Interner, TypeFlags, TypeFoldable, WithCachedTypeInfo, elaborate, search_graph,
58};
59use tracing::{debug, instrument};
60
61use crate::arena::Arena;
62use crate::dep_graph::{DepGraph, DepKindStruct};
63use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
64use crate::lint::lint_level;
65use crate::metadata::ModChild;
66use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
67use crate::middle::{resolve_bound_vars, stability};
68use crate::mir::interpret::{self, Allocation, ConstAllocation};
69use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
70use crate::query::plumbing::QuerySystem;
71use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
72use crate::thir::Thir;
73use crate::traits;
74use crate::traits::solve;
75use crate::traits::solve::{
76    ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData,
77};
78use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
79use crate::ty::{
80    self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
81    GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, ParamTy,
82    Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
83    PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
84    ValTree, ValTreeKind, Visibility,
85};
86
87#[allow(rustc::usage_of_ty_tykind)]
88impl<'tcx> Interner for TyCtxt<'tcx> {
89    type DefId = DefId;
90    type LocalDefId = LocalDefId;
91    type Span = Span;
92
93    type GenericArgs = ty::GenericArgsRef<'tcx>;
94
95    type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
96    type GenericArg = ty::GenericArg<'tcx>;
97    type Term = ty::Term<'tcx>;
98    type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
99
100    type BoundVarKind = ty::BoundVariableKind;
101    type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
102
103    fn mk_predefined_opaques_in_body(
104        self,
105        data: PredefinedOpaquesData<Self>,
106    ) -> Self::PredefinedOpaques {
107        self.mk_predefined_opaques_in_body(data)
108    }
109    type LocalDefIds = &'tcx ty::List<LocalDefId>;
110    type CanonicalVars = CanonicalVarInfos<'tcx>;
111    fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
112        self.mk_canonical_var_infos(infos)
113    }
114
115    type ExternalConstraints = ExternalConstraints<'tcx>;
116    fn mk_external_constraints(
117        self,
118        data: ExternalConstraintsData<Self>,
119    ) -> ExternalConstraints<'tcx> {
120        self.mk_external_constraints(data)
121    }
122    type DepNodeIndex = DepNodeIndex;
123    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
124        self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
125    }
126    type Ty = Ty<'tcx>;
127    type Tys = &'tcx List<Ty<'tcx>>;
128
129    type FnInputTys = &'tcx [Ty<'tcx>];
130    type ParamTy = ParamTy;
131    type BoundTy = ty::BoundTy;
132
133    type PlaceholderTy = ty::PlaceholderType;
134    type ErrorGuaranteed = ErrorGuaranteed;
135    type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
136
137    type AllocId = crate::mir::interpret::AllocId;
138    type Pat = Pattern<'tcx>;
139    type PatList = &'tcx List<Pattern<'tcx>>;
140    type Safety = hir::Safety;
141    type Abi = ExternAbi;
142    type Const = ty::Const<'tcx>;
143    type PlaceholderConst = ty::PlaceholderConst;
144
145    type ParamConst = ty::ParamConst;
146    type BoundConst = ty::BoundVar;
147    type ValueConst = ty::Value<'tcx>;
148    type ExprConst = ty::Expr<'tcx>;
149    type ValTree = ty::ValTree<'tcx>;
150
151    type Region = Region<'tcx>;
152    type EarlyParamRegion = ty::EarlyParamRegion;
153    type LateParamRegion = ty::LateParamRegion;
154    type BoundRegion = ty::BoundRegion;
155    type PlaceholderRegion = ty::PlaceholderRegion;
156
157    type ParamEnv = ty::ParamEnv<'tcx>;
158    type Predicate = Predicate<'tcx>;
159
160    type Clause = Clause<'tcx>;
161    type Clauses = ty::Clauses<'tcx>;
162
163    type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
164    fn mk_tracked<T: fmt::Debug + Clone>(
165        self,
166        data: T,
167        dep_node: DepNodeIndex,
168    ) -> Self::Tracked<T> {
169        WithDepNode::new(dep_node, data)
170    }
171    fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
172        tracked.get(self)
173    }
174
175    fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
176        f(&mut *self.new_solver_evaluation_cache.lock())
177    }
178
179    fn evaluation_is_concurrent(&self) -> bool {
180        self.sess.threads() > 1
181    }
182
183    fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
184        self.expand_abstract_consts(t)
185    }
186
187    type GenericsOf = &'tcx ty::Generics;
188
189    fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
190        self.generics_of(def_id)
191    }
192
193    type VariancesOf = &'tcx [ty::Variance];
194
195    fn variances_of(self, def_id: DefId) -> Self::VariancesOf {
196        self.variances_of(def_id)
197    }
198
199    fn opt_alias_variances(
200        self,
201        kind: impl Into<ty::AliasTermKind>,
202        def_id: DefId,
203    ) -> Option<&'tcx [ty::Variance]> {
204        self.opt_alias_variances(kind, def_id)
205    }
206
207    fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
208        self.type_of(def_id)
209    }
210    fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
211        self.type_of_opaque_hir_typeck(def_id)
212    }
213
214    type AdtDef = ty::AdtDef<'tcx>;
215    fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
216        self.adt_def(adt_def_id)
217    }
218
219    fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
220        match self.def_kind(alias.def_id) {
221            DefKind::AssocTy => {
222                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
223                {
224                    ty::Inherent
225                } else {
226                    ty::Projection
227                }
228            }
229            DefKind::OpaqueTy => ty::Opaque,
230            DefKind::TyAlias => ty::Free,
231            kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
232        }
233    }
234
235    fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind {
236        match self.def_kind(alias.def_id) {
237            DefKind::AssocTy => {
238                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
239                {
240                    ty::AliasTermKind::InherentTy
241                } else {
242                    ty::AliasTermKind::ProjectionTy
243                }
244            }
245            DefKind::AssocConst => {
246                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
247                {
248                    ty::AliasTermKind::InherentConst
249                } else {
250                    ty::AliasTermKind::ProjectionConst
251                }
252            }
253            DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
254            DefKind::TyAlias => ty::AliasTermKind::FreeTy,
255            DefKind::Const => ty::AliasTermKind::FreeConst,
256            DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
257                ty::AliasTermKind::UnevaluatedConst
258            }
259            kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
260        }
261    }
262
263    fn trait_ref_and_own_args_for_alias(
264        self,
265        def_id: DefId,
266        args: ty::GenericArgsRef<'tcx>,
267    ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
268        assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
269        let trait_def_id = self.parent(def_id);
270        assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
271        let trait_generics = self.generics_of(trait_def_id);
272        (
273            ty::TraitRef::new_from_args(self, trait_def_id, args.truncate_to(self, trait_generics)),
274            &args[trait_generics.count()..],
275        )
276    }
277
278    fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
279        self.mk_args(args)
280    }
281
282    fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
283    where
284        I: Iterator<Item = T>,
285        T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
286    {
287        self.mk_args_from_iter(args)
288    }
289
290    fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
291        self.check_args_compatible(def_id, args)
292    }
293
294    fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
295        self.debug_assert_args_compatible(def_id, args);
296    }
297
298    /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
299    /// are compatible with the `DefId`. Since we're missing a `Self` type, stick on
300    /// a dummy self type and forward to `debug_assert_args_compatible`.
301    fn debug_assert_existential_args_compatible(
302        self,
303        def_id: Self::DefId,
304        args: Self::GenericArgs,
305    ) {
306        // FIXME: We could perhaps add a `skip: usize` to `debug_assert_args_compatible`
307        // to avoid needing to reintern the set of args...
308        if cfg!(debug_assertions) {
309            self.debug_assert_args_compatible(
310                def_id,
311                self.mk_args_from_iter(
312                    [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
313                ),
314            );
315        }
316    }
317
318    fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
319    where
320        I: Iterator<Item = T>,
321        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
322    {
323        self.mk_type_list_from_iter(args)
324    }
325
326    fn parent(self, def_id: DefId) -> DefId {
327        self.parent(def_id)
328    }
329
330    fn recursion_limit(self) -> usize {
331        self.recursion_limit().0
332    }
333
334    type Features = &'tcx rustc_feature::Features;
335
336    fn features(self) -> Self::Features {
337        self.features()
338    }
339
340    fn coroutine_hidden_types(
341        self,
342        def_id: DefId,
343    ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> {
344        self.coroutine_hidden_types(def_id)
345    }
346
347    fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
348        self.fn_sig(def_id)
349    }
350
351    fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
352        self.coroutine_movability(def_id)
353    }
354
355    fn coroutine_for_closure(self, def_id: DefId) -> DefId {
356        self.coroutine_for_closure(def_id)
357    }
358
359    fn generics_require_sized_self(self, def_id: DefId) -> bool {
360        self.generics_require_sized_self(def_id)
361    }
362
363    fn item_bounds(
364        self,
365        def_id: DefId,
366    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
367        self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
368    }
369
370    fn item_self_bounds(
371        self,
372        def_id: DefId,
373    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
374        self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
375    }
376
377    fn item_non_self_bounds(
378        self,
379        def_id: DefId,
380    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
381        self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
382    }
383
384    fn predicates_of(
385        self,
386        def_id: DefId,
387    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
388        ty::EarlyBinder::bind(
389            self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
390        )
391    }
392
393    fn own_predicates_of(
394        self,
395        def_id: DefId,
396    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
397        ty::EarlyBinder::bind(
398            self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
399        )
400    }
401
402    fn explicit_super_predicates_of(
403        self,
404        def_id: DefId,
405    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
406        self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
407    }
408
409    fn explicit_implied_predicates_of(
410        self,
411        def_id: DefId,
412    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
413        self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
414    }
415
416    fn impl_is_const(self, def_id: DefId) -> bool {
417        debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
418        self.is_conditionally_const(def_id)
419    }
420
421    fn fn_is_const(self, def_id: DefId) -> bool {
422        debug_assert_matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
423        self.is_conditionally_const(def_id)
424    }
425
426    fn alias_has_const_conditions(self, def_id: DefId) -> bool {
427        debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
428        self.is_conditionally_const(def_id)
429    }
430
431    fn const_conditions(
432        self,
433        def_id: DefId,
434    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
435        ty::EarlyBinder::bind(
436            self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
437        )
438    }
439
440    fn explicit_implied_const_bounds(
441        self,
442        def_id: DefId,
443    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
444        ty::EarlyBinder::bind(
445            self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
446        )
447    }
448
449    fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
450        self.impl_self_is_guaranteed_unsized(impl_def_id)
451    }
452
453    fn has_target_features(self, def_id: DefId) -> bool {
454        !self.codegen_fn_attrs(def_id).target_features.is_empty()
455    }
456
457    fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
458        self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None)
459    }
460
461    fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
462        self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
463    }
464
465    fn is_default_trait(self, def_id: DefId) -> bool {
466        self.is_default_trait(def_id)
467    }
468
469    fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
470        lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
471    }
472
473    fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
474        self.associated_items(def_id)
475            .in_definition_order()
476            .filter(|assoc_item| assoc_item.is_type())
477            .map(|assoc_item| assoc_item.def_id)
478    }
479
480    // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`,
481    // since we want to skip over blanket impls for non-rigid aliases, and also we
482    // only want to consider types that *actually* unify with float/int vars.
483    fn for_each_relevant_impl(
484        self,
485        trait_def_id: DefId,
486        self_ty: Ty<'tcx>,
487        mut f: impl FnMut(DefId),
488    ) {
489        let tcx = self;
490        let trait_impls = tcx.trait_impls_of(trait_def_id);
491        let mut consider_impls_for_simplified_type = |simp| {
492            if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
493                for &impl_def_id in impls_for_type {
494                    f(impl_def_id);
495                }
496            }
497        };
498
499        match self_ty.kind() {
500            ty::Bool
501            | ty::Char
502            | ty::Int(_)
503            | ty::Uint(_)
504            | ty::Float(_)
505            | ty::Adt(_, _)
506            | ty::Foreign(_)
507            | ty::Str
508            | ty::Array(_, _)
509            | ty::Pat(_, _)
510            | ty::Slice(_)
511            | ty::RawPtr(_, _)
512            | ty::Ref(_, _, _)
513            | ty::FnDef(_, _)
514            | ty::FnPtr(..)
515            | ty::Dynamic(_, _, _)
516            | ty::Closure(..)
517            | ty::CoroutineClosure(..)
518            | ty::Coroutine(_, _)
519            | ty::Never
520            | ty::Tuple(_)
521            | ty::UnsafeBinder(_) => {
522                let simp = ty::fast_reject::simplify_type(
523                    tcx,
524                    self_ty,
525                    ty::fast_reject::TreatParams::AsRigid,
526                )
527                .unwrap();
528                consider_impls_for_simplified_type(simp);
529            }
530
531            // HACK: For integer and float variables we have to manually look at all impls
532            // which have some integer or float as a self type.
533            ty::Infer(ty::IntVar(_)) => {
534                use ty::IntTy::*;
535                use ty::UintTy::*;
536                // This causes a compiler error if any new integer kinds are added.
537                let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
538                let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
539                let possible_integers = [
540                    // signed integers
541                    ty::SimplifiedType::Int(I8),
542                    ty::SimplifiedType::Int(I16),
543                    ty::SimplifiedType::Int(I32),
544                    ty::SimplifiedType::Int(I64),
545                    ty::SimplifiedType::Int(I128),
546                    ty::SimplifiedType::Int(Isize),
547                    // unsigned integers
548                    ty::SimplifiedType::Uint(U8),
549                    ty::SimplifiedType::Uint(U16),
550                    ty::SimplifiedType::Uint(U32),
551                    ty::SimplifiedType::Uint(U64),
552                    ty::SimplifiedType::Uint(U128),
553                    ty::SimplifiedType::Uint(Usize),
554                ];
555                for simp in possible_integers {
556                    consider_impls_for_simplified_type(simp);
557                }
558            }
559
560            ty::Infer(ty::FloatVar(_)) => {
561                // This causes a compiler error if any new float kinds are added.
562                let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
563                let possible_floats = [
564                    ty::SimplifiedType::Float(ty::FloatTy::F16),
565                    ty::SimplifiedType::Float(ty::FloatTy::F32),
566                    ty::SimplifiedType::Float(ty::FloatTy::F64),
567                    ty::SimplifiedType::Float(ty::FloatTy::F128),
568                ];
569
570                for simp in possible_floats {
571                    consider_impls_for_simplified_type(simp);
572                }
573            }
574
575            // The only traits applying to aliases and placeholders are blanket impls.
576            //
577            // Impls which apply to an alias after normalization are handled by
578            // `assemble_candidates_after_normalizing_self_ty`.
579            ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
580
581            // FIXME: These should ideally not exist as a self type. It would be nice for
582            // the builtin auto trait impls of coroutines to instead directly recurse
583            // into the witness.
584            ty::CoroutineWitness(..) => (),
585
586            // These variants should not exist as a self type.
587            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
588            | ty::Param(_)
589            | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
590        }
591
592        let trait_impls = tcx.trait_impls_of(trait_def_id);
593        for &impl_def_id in trait_impls.blanket_impls() {
594            f(impl_def_id);
595        }
596    }
597
598    fn has_item_definition(self, def_id: DefId) -> bool {
599        self.defaultness(def_id).has_value()
600    }
601
602    fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
603        self.specializes((impl_def_id, victim_def_id))
604    }
605
606    fn impl_is_default(self, impl_def_id: DefId) -> bool {
607        self.defaultness(impl_def_id).is_default()
608    }
609
610    fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
611        self.impl_trait_ref(impl_def_id).unwrap()
612    }
613
614    fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
615        self.impl_polarity(impl_def_id)
616    }
617
618    fn trait_is_auto(self, trait_def_id: DefId) -> bool {
619        self.trait_is_auto(trait_def_id)
620    }
621
622    fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
623        self.trait_is_coinductive(trait_def_id)
624    }
625
626    fn trait_is_alias(self, trait_def_id: DefId) -> bool {
627        self.trait_is_alias(trait_def_id)
628    }
629
630    fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
631        self.is_dyn_compatible(trait_def_id)
632    }
633
634    fn trait_is_fundamental(self, def_id: DefId) -> bool {
635        self.trait_def(def_id).is_fundamental
636    }
637
638    fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
639        self.trait_def(trait_def_id).implement_via_object
640    }
641
642    fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
643        self.trait_def(trait_def_id).safety.is_unsafe()
644    }
645
646    fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
647        self.is_impl_trait_in_trait(def_id)
648    }
649
650    fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
651        self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
652    }
653
654    fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
655        self.is_general_coroutine(coroutine_def_id)
656    }
657
658    fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
659        self.coroutine_is_async(coroutine_def_id)
660    }
661
662    fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
663        self.coroutine_is_gen(coroutine_def_id)
664    }
665
666    fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
667        self.coroutine_is_async_gen(coroutine_def_id)
668    }
669
670    type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
671    fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
672        self.unsizing_params_for_adt(adt_def_id)
673    }
674
675    fn find_const_ty_from_env(
676        self,
677        param_env: ty::ParamEnv<'tcx>,
678        placeholder: Self::PlaceholderConst,
679    ) -> Ty<'tcx> {
680        placeholder.find_const_ty_from_env(param_env)
681    }
682
683    fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
684        self,
685        binder: ty::Binder<'tcx, T>,
686    ) -> ty::Binder<'tcx, T> {
687        self.anonymize_bound_vars(binder)
688    }
689
690    fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
691        self.opaque_types_defined_by(defining_anchor)
692    }
693
694    fn opaque_types_and_coroutines_defined_by(
695        self,
696        defining_anchor: Self::LocalDefId,
697    ) -> Self::LocalDefIds {
698        if self.next_trait_solver_globally() {
699            let coroutines_defined_by = self
700                .nested_bodies_within(defining_anchor)
701                .iter()
702                .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
703            self.mk_local_def_ids_from_iter(
704                self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
705            )
706        } else {
707            self.opaque_types_defined_by(defining_anchor)
708        }
709    }
710}
711
712macro_rules! bidirectional_lang_item_map {
713    ($($name:ident),+ $(,)?) => {
714        fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
715            match lang_item {
716                $(TraitSolverLangItem::$name => LangItem::$name,)+
717            }
718        }
719
720        fn lang_item_to_trait_lang_item(lang_item: LangItem) -> Option<TraitSolverLangItem> {
721            Some(match lang_item {
722                $(LangItem::$name => TraitSolverLangItem::$name,)+
723                _ => return None,
724            })
725        }
726    }
727}
728
729bidirectional_lang_item_map! {
730// tidy-alphabetical-start
731    AsyncFn,
732    AsyncFnKindHelper,
733    AsyncFnKindUpvars,
734    AsyncFnMut,
735    AsyncFnOnce,
736    AsyncFnOnceOutput,
737    AsyncIterator,
738    BikeshedGuaranteedNoDrop,
739    CallOnceFuture,
740    CallRefFuture,
741    Clone,
742    Copy,
743    Coroutine,
744    CoroutineReturn,
745    CoroutineYield,
746    Destruct,
747    DiscriminantKind,
748    Drop,
749    DynMetadata,
750    Fn,
751    FnMut,
752    FnOnce,
753    FnPtrTrait,
754    FusedIterator,
755    Future,
756    FutureOutput,
757    Iterator,
758    Metadata,
759    Option,
760    PointeeTrait,
761    Poll,
762    Sized,
763    TransmuteTrait,
764    Tuple,
765    Unpin,
766    Unsize,
767// tidy-alphabetical-end
768}
769
770impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
771    fn is_local(self) -> bool {
772        self.is_local()
773    }
774
775    fn as_local(self) -> Option<LocalDefId> {
776        self.as_local()
777    }
778}
779
780impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
781    fn rust() -> Self {
782        ExternAbi::Rust
783    }
784
785    fn is_rust(self) -> bool {
786        matches!(self, ExternAbi::Rust)
787    }
788}
789
790impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
791    fn safe() -> Self {
792        hir::Safety::Safe
793    }
794
795    fn is_safe(self) -> bool {
796        self.is_safe()
797    }
798
799    fn prefix_str(self) -> &'static str {
800        self.prefix_str()
801    }
802}
803
804impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
805    fn generic_const_exprs(self) -> bool {
806        self.generic_const_exprs()
807    }
808
809    fn coroutine_clone(self) -> bool {
810        self.coroutine_clone()
811    }
812
813    fn associated_const_equality(self) -> bool {
814        self.associated_const_equality()
815    }
816}
817
818impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
819    fn dummy() -> Self {
820        DUMMY_SP
821    }
822}
823
824type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
825
826pub struct CtxtInterners<'tcx> {
827    /// The arena that types, regions, etc. are allocated from.
828    arena: &'tcx WorkerLocal<Arena<'tcx>>,
829
830    // Specifically use a speedy hash algorithm for these hash sets, since
831    // they're accessed quite often.
832    type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
833    const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
834    args: InternedSet<'tcx, GenericArgs<'tcx>>,
835    type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
836    canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
837    region: InternedSet<'tcx, RegionKind<'tcx>>,
838    poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
839    predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
840    clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
841    projs: InternedSet<'tcx, List<ProjectionKind>>,
842    place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
843    const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
844    pat: InternedSet<'tcx, PatternKind<'tcx>>,
845    const_allocation: InternedSet<'tcx, Allocation>,
846    bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
847    layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
848    adt_def: InternedSet<'tcx, AdtDefData>,
849    external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
850    predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
851    fields: InternedSet<'tcx, List<FieldIdx>>,
852    local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
853    captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
854    offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
855    valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
856    patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
857}
858
859impl<'tcx> CtxtInterners<'tcx> {
860    fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
861        // Default interner size - this value has been chosen empirically, and may need to be adjusted
862        // as the compiler evolves.
863        const N: usize = 2048;
864        CtxtInterners {
865            arena,
866            // The factors have been chosen by @FractalFir based on observed interner sizes, and local perf runs.
867            // To get the interner sizes, insert `eprintln` printing the size of the interner in functions like `intern_ty`.
868            // Bigger benchmarks tend to give more accurate ratios, so use something like `x perf eprintln --includes cargo`.
869            type_: InternedSet::with_capacity(N * 16),
870            const_lists: InternedSet::with_capacity(N * 4),
871            args: InternedSet::with_capacity(N * 4),
872            type_lists: InternedSet::with_capacity(N * 4),
873            region: InternedSet::with_capacity(N * 4),
874            poly_existential_predicates: InternedSet::with_capacity(N / 4),
875            canonical_var_infos: InternedSet::with_capacity(N / 2),
876            predicate: InternedSet::with_capacity(N),
877            clauses: InternedSet::with_capacity(N),
878            projs: InternedSet::with_capacity(N * 4),
879            place_elems: InternedSet::with_capacity(N * 2),
880            const_: InternedSet::with_capacity(N * 2),
881            pat: InternedSet::with_capacity(N),
882            const_allocation: InternedSet::with_capacity(N),
883            bound_variable_kinds: InternedSet::with_capacity(N * 2),
884            layout: InternedSet::with_capacity(N),
885            adt_def: InternedSet::with_capacity(N),
886            external_constraints: InternedSet::with_capacity(N),
887            predefined_opaques_in_body: InternedSet::with_capacity(N),
888            fields: InternedSet::with_capacity(N * 4),
889            local_def_ids: InternedSet::with_capacity(N),
890            captures: InternedSet::with_capacity(N),
891            offset_of: InternedSet::with_capacity(N),
892            valtree: InternedSet::with_capacity(N),
893            patterns: InternedSet::with_capacity(N),
894        }
895    }
896
897    /// Interns a type. (Use `mk_*` functions instead, where possible.)
898    #[allow(rustc::usage_of_ty_tykind)]
899    #[inline(never)]
900    fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
901        Ty(Interned::new_unchecked(
902            self.type_
903                .intern(kind, |kind| {
904                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
905                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
906
907                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
908                        internee: kind,
909                        stable_hash,
910                        flags: flags.flags,
911                        outer_exclusive_binder: flags.outer_exclusive_binder,
912                    }))
913                })
914                .0,
915        ))
916    }
917
918    /// Interns a const. (Use `mk_*` functions instead, where possible.)
919    #[allow(rustc::usage_of_ty_tykind)]
920    #[inline(never)]
921    fn intern_const(
922        &self,
923        kind: ty::ConstKind<'tcx>,
924        sess: &Session,
925        untracked: &Untracked,
926    ) -> Const<'tcx> {
927        Const(Interned::new_unchecked(
928            self.const_
929                .intern(kind, |kind: ty::ConstKind<'_>| {
930                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
931                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
932
933                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
934                        internee: kind,
935                        stable_hash,
936                        flags: flags.flags,
937                        outer_exclusive_binder: flags.outer_exclusive_binder,
938                    }))
939                })
940                .0,
941        ))
942    }
943
944    fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
945        &self,
946        flags: &ty::FlagComputation<TyCtxt<'tcx>>,
947        sess: &'a Session,
948        untracked: &'a Untracked,
949        val: &T,
950    ) -> Fingerprint {
951        // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them.
952        // Without incremental, we rarely stable-hash types, so let's not do it proactively.
953        if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
954            Fingerprint::ZERO
955        } else {
956            let mut hasher = StableHasher::new();
957            let mut hcx = StableHashingContext::new(sess, untracked);
958            val.hash_stable(&mut hcx, &mut hasher);
959            hasher.finish()
960        }
961    }
962
963    /// Interns a predicate. (Use `mk_predicate` instead, where possible.)
964    #[inline(never)]
965    fn intern_predicate(
966        &self,
967        kind: Binder<'tcx, PredicateKind<'tcx>>,
968        sess: &Session,
969        untracked: &Untracked,
970    ) -> Predicate<'tcx> {
971        Predicate(Interned::new_unchecked(
972            self.predicate
973                .intern(kind, |kind| {
974                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
975
976                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
977
978                    InternedInSet(self.arena.alloc(WithCachedTypeInfo {
979                        internee: kind,
980                        stable_hash,
981                        flags: flags.flags,
982                        outer_exclusive_binder: flags.outer_exclusive_binder,
983                    }))
984                })
985                .0,
986        ))
987    }
988
989    fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
990        if clauses.is_empty() {
991            ListWithCachedTypeInfo::empty()
992        } else {
993            self.clauses
994                .intern_ref(clauses, || {
995                    let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
996
997                    InternedInSet(ListWithCachedTypeInfo::from_arena(
998                        &*self.arena,
999                        flags.into(),
1000                        clauses,
1001                    ))
1002                })
1003                .0
1004        }
1005    }
1006}
1007
1008// For these preinterned values, an alternative would be to have
1009// variable-length vectors that grow as needed. But that turned out to be
1010// slightly more complex and no faster.
1011
1012const NUM_PREINTERNED_TY_VARS: u32 = 100;
1013const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
1014const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
1015const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
1016
1017// This number may seem high, but it is reached in all but the smallest crates.
1018const NUM_PREINTERNED_RE_VARS: u32 = 500;
1019const NUM_PREINTERNED_RE_LATE_BOUNDS_I: u32 = 2;
1020const NUM_PREINTERNED_RE_LATE_BOUNDS_V: u32 = 20;
1021
1022pub struct CommonTypes<'tcx> {
1023    pub unit: Ty<'tcx>,
1024    pub bool: Ty<'tcx>,
1025    pub char: Ty<'tcx>,
1026    pub isize: Ty<'tcx>,
1027    pub i8: Ty<'tcx>,
1028    pub i16: Ty<'tcx>,
1029    pub i32: Ty<'tcx>,
1030    pub i64: Ty<'tcx>,
1031    pub i128: Ty<'tcx>,
1032    pub usize: Ty<'tcx>,
1033    pub u8: Ty<'tcx>,
1034    pub u16: Ty<'tcx>,
1035    pub u32: Ty<'tcx>,
1036    pub u64: Ty<'tcx>,
1037    pub u128: Ty<'tcx>,
1038    pub f16: Ty<'tcx>,
1039    pub f32: Ty<'tcx>,
1040    pub f64: Ty<'tcx>,
1041    pub f128: Ty<'tcx>,
1042    pub str_: Ty<'tcx>,
1043    pub never: Ty<'tcx>,
1044    pub self_param: Ty<'tcx>,
1045
1046    /// Dummy type used for the `Self` of a `TraitRef` created for converting
1047    /// a trait object, and which gets removed in `ExistentialTraitRef`.
1048    /// This type must not appear anywhere in other converted types.
1049    /// `Infer(ty::FreshTy(0))` does the job.
1050    pub trait_object_dummy_self: Ty<'tcx>,
1051
1052    /// Pre-interned `Infer(ty::TyVar(n))` for small values of `n`.
1053    pub ty_vars: Vec<Ty<'tcx>>,
1054
1055    /// Pre-interned `Infer(ty::FreshTy(n))` for small values of `n`.
1056    pub fresh_tys: Vec<Ty<'tcx>>,
1057
1058    /// Pre-interned `Infer(ty::FreshIntTy(n))` for small values of `n`.
1059    pub fresh_int_tys: Vec<Ty<'tcx>>,
1060
1061    /// Pre-interned `Infer(ty::FreshFloatTy(n))` for small values of `n`.
1062    pub fresh_float_tys: Vec<Ty<'tcx>>,
1063}
1064
1065pub struct CommonLifetimes<'tcx> {
1066    /// `ReStatic`
1067    pub re_static: Region<'tcx>,
1068
1069    /// Erased region, used outside of type inference.
1070    pub re_erased: Region<'tcx>,
1071
1072    /// Pre-interned `ReVar(ty::RegionVar(n))` for small values of `n`.
1073    pub re_vars: Vec<Region<'tcx>>,
1074
1075    /// Pre-interned values of the form:
1076    /// `ReBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon })`
1077    /// for small values of `i` and `v`.
1078    pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
1079}
1080
1081pub struct CommonConsts<'tcx> {
1082    pub unit: Const<'tcx>,
1083    pub true_: Const<'tcx>,
1084    pub false_: Const<'tcx>,
1085    /// Use [`ty::ValTree::zst`] instead.
1086    pub(crate) valtree_zst: ValTree<'tcx>,
1087}
1088
1089impl<'tcx> CommonTypes<'tcx> {
1090    fn new(
1091        interners: &CtxtInterners<'tcx>,
1092        sess: &Session,
1093        untracked: &Untracked,
1094    ) -> CommonTypes<'tcx> {
1095        let mk = |ty| interners.intern_ty(ty, sess, untracked);
1096
1097        let ty_vars =
1098            (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1099        let fresh_tys: Vec<_> =
1100            (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1101        let fresh_int_tys: Vec<_> =
1102            (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1103        let fresh_float_tys: Vec<_> =
1104            (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1105
1106        CommonTypes {
1107            unit: mk(Tuple(List::empty())),
1108            bool: mk(Bool),
1109            char: mk(Char),
1110            never: mk(Never),
1111            isize: mk(Int(ty::IntTy::Isize)),
1112            i8: mk(Int(ty::IntTy::I8)),
1113            i16: mk(Int(ty::IntTy::I16)),
1114            i32: mk(Int(ty::IntTy::I32)),
1115            i64: mk(Int(ty::IntTy::I64)),
1116            i128: mk(Int(ty::IntTy::I128)),
1117            usize: mk(Uint(ty::UintTy::Usize)),
1118            u8: mk(Uint(ty::UintTy::U8)),
1119            u16: mk(Uint(ty::UintTy::U16)),
1120            u32: mk(Uint(ty::UintTy::U32)),
1121            u64: mk(Uint(ty::UintTy::U64)),
1122            u128: mk(Uint(ty::UintTy::U128)),
1123            f16: mk(Float(ty::FloatTy::F16)),
1124            f32: mk(Float(ty::FloatTy::F32)),
1125            f64: mk(Float(ty::FloatTy::F64)),
1126            f128: mk(Float(ty::FloatTy::F128)),
1127            str_: mk(Str),
1128            self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1129
1130            trait_object_dummy_self: fresh_tys[0],
1131
1132            ty_vars,
1133            fresh_tys,
1134            fresh_int_tys,
1135            fresh_float_tys,
1136        }
1137    }
1138}
1139
1140impl<'tcx> CommonLifetimes<'tcx> {
1141    fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1142        let mk = |r| {
1143            Region(Interned::new_unchecked(
1144                interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1145            ))
1146        };
1147
1148        let re_vars =
1149            (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1150
1151        let re_late_bounds = (0..NUM_PREINTERNED_RE_LATE_BOUNDS_I)
1152            .map(|i| {
1153                (0..NUM_PREINTERNED_RE_LATE_BOUNDS_V)
1154                    .map(|v| {
1155                        mk(ty::ReBound(
1156                            ty::DebruijnIndex::from(i),
1157                            ty::BoundRegion {
1158                                var: ty::BoundVar::from(v),
1159                                kind: ty::BoundRegionKind::Anon,
1160                            },
1161                        ))
1162                    })
1163                    .collect()
1164            })
1165            .collect();
1166
1167        CommonLifetimes {
1168            re_static: mk(ty::ReStatic),
1169            re_erased: mk(ty::ReErased),
1170            re_vars,
1171            re_late_bounds,
1172        }
1173    }
1174}
1175
1176impl<'tcx> CommonConsts<'tcx> {
1177    fn new(
1178        interners: &CtxtInterners<'tcx>,
1179        types: &CommonTypes<'tcx>,
1180        sess: &Session,
1181        untracked: &Untracked,
1182    ) -> CommonConsts<'tcx> {
1183        let mk_const = |c| {
1184            interners.intern_const(
1185                c, sess, // This is only used to create a stable hashing context.
1186                untracked,
1187            )
1188        };
1189
1190        let mk_valtree = |v| {
1191            ty::ValTree(Interned::new_unchecked(
1192                interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1193            ))
1194        };
1195
1196        let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1197        let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1198        let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1199
1200        CommonConsts {
1201            unit: mk_const(ty::ConstKind::Value(ty::Value {
1202                ty: types.unit,
1203                valtree: valtree_zst,
1204            })),
1205            true_: mk_const(ty::ConstKind::Value(ty::Value {
1206                ty: types.bool,
1207                valtree: valtree_true,
1208            })),
1209            false_: mk_const(ty::ConstKind::Value(ty::Value {
1210                ty: types.bool,
1211                valtree: valtree_false,
1212            })),
1213            valtree_zst,
1214        }
1215    }
1216}
1217
1218/// This struct contains information regarding a free parameter region,
1219/// either a `ReEarlyParam` or `ReLateParam`.
1220#[derive(Debug)]
1221pub struct FreeRegionInfo {
1222    /// `LocalDefId` of the scope.
1223    pub scope: LocalDefId,
1224    /// the `DefId` of the free region.
1225    pub region_def_id: DefId,
1226    /// checks if bound region is in Impl Item
1227    pub is_impl_item: bool,
1228}
1229
1230/// This struct should only be created by `create_def`.
1231#[derive(Copy, Clone)]
1232pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1233    pub tcx: TyCtxt<'tcx>,
1234    // Do not allow direct access, as downstream code must not mutate this field.
1235    key: KEY,
1236}
1237
1238/// Never return a `Feed` from a query. Only queries that create a `DefId` are
1239/// allowed to feed queries for that `DefId`.
1240impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1241
1242/// The same as `TyCtxtFeed`, but does not contain a `TyCtxt`.
1243/// Use this to pass around when you have a `TyCtxt` elsewhere.
1244/// Just an optimization to save space and not store hundreds of
1245/// `TyCtxtFeed` in the resolver.
1246#[derive(Copy, Clone)]
1247pub struct Feed<'tcx, KEY: Copy> {
1248    _tcx: PhantomData<TyCtxt<'tcx>>,
1249    // Do not allow direct access, as downstream code must not mutate this field.
1250    key: KEY,
1251}
1252
1253/// Never return a `Feed` from a query. Only queries that create a `DefId` are
1254/// allowed to feed queries for that `DefId`.
1255impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1256
1257impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1258    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1259        self.key.fmt(f)
1260    }
1261}
1262
1263/// Some workarounds to use cases that cannot use `create_def`.
1264/// Do not add new ways to create `TyCtxtFeed` without consulting
1265/// with T-compiler and making an analysis about why your addition
1266/// does not cause incremental compilation issues.
1267impl<'tcx> TyCtxt<'tcx> {
1268    /// Can only be fed before queries are run, and is thus exempt from any
1269    /// incremental issues. Do not use except for the initial query feeding.
1270    pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1271        self.dep_graph.assert_ignored();
1272        TyCtxtFeed { tcx: self, key: () }
1273    }
1274
1275    /// Only used in the resolver to register the `CRATE_DEF_ID` `DefId` and feed
1276    /// some queries for it. It will panic if used twice.
1277    pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1278        let key = self.untracked().source_span.push(span);
1279        assert_eq!(key, CRATE_DEF_ID);
1280        TyCtxtFeed { tcx: self, key }
1281    }
1282
1283    /// In order to break cycles involving `AnonConst`, we need to set the expected type by side
1284    /// effect. However, we do not want this as a general capability, so this interface restricts
1285    /// to the only allowed case.
1286    pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1287        debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1288        TyCtxtFeed { tcx: self, key }.type_of(value)
1289    }
1290}
1291
1292impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1293    #[inline(always)]
1294    pub fn key(&self) -> KEY {
1295        self.key
1296    }
1297
1298    #[inline(always)]
1299    pub fn downgrade(self) -> Feed<'tcx, KEY> {
1300        Feed { _tcx: PhantomData, key: self.key }
1301    }
1302}
1303
1304impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1305    #[inline(always)]
1306    pub fn key(&self) -> KEY {
1307        self.key
1308    }
1309
1310    #[inline(always)]
1311    pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1312        TyCtxtFeed { tcx, key: self.key }
1313    }
1314}
1315
1316impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1317    #[inline(always)]
1318    pub fn def_id(&self) -> LocalDefId {
1319        self.key
1320    }
1321
1322    // Caller must ensure that `self.key` ID is indeed an owner.
1323    pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1324        TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1325    }
1326
1327    // Fills in all the important parts needed by HIR queries
1328    pub fn feed_hir(&self) {
1329        self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1330
1331        let node = hir::OwnerNode::Synthetic;
1332        let bodies = Default::default();
1333        let attrs = hir::AttributeMap::EMPTY;
1334
1335        let (opt_hash_including_bodies, _) =
1336            self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque);
1337        let node = node.into();
1338        self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1339            opt_hash_including_bodies,
1340            nodes: IndexVec::from_elem_n(
1341                hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1342                1,
1343            ),
1344            bodies,
1345        })));
1346        self.feed_owner_id().hir_attr_map(attrs);
1347    }
1348}
1349
1350/// The central data structure of the compiler. It stores references
1351/// to the various **arenas** and also houses the results of the
1352/// various **compiler queries** that have been performed. See the
1353/// [rustc dev guide] for more details.
1354///
1355/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html
1356///
1357/// An implementation detail: `TyCtxt` is a wrapper type for [GlobalCtxt],
1358/// which is the struct that actually holds all the data. `TyCtxt` derefs to
1359/// `GlobalCtxt`, and in practice `TyCtxt` is passed around everywhere, and all
1360/// operations are done via `TyCtxt`. A `TyCtxt` is obtained for a `GlobalCtxt`
1361/// by calling `enter` with a closure `f`. That function creates both the
1362/// `TyCtxt`, and an `ImplicitCtxt` around it that is put into TLS. Within `f`:
1363/// - The `ImplicitCtxt` is available implicitly via TLS.
1364/// - The `TyCtxt` is available explicitly via the `tcx` parameter, and also
1365///   implicitly within the `ImplicitCtxt`. Explicit access is preferred when
1366///   possible.
1367#[derive(Copy, Clone)]
1368#[rustc_diagnostic_item = "TyCtxt"]
1369#[rustc_pass_by_value]
1370pub struct TyCtxt<'tcx> {
1371    gcx: &'tcx GlobalCtxt<'tcx>,
1372}
1373
1374// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. Its
1375// field are asserted to implement these traits below, so this is trivially safe, and it greatly
1376// speeds-up compilation of this crate and its dependents.
1377unsafe impl DynSend for TyCtxt<'_> {}
1378unsafe impl DynSync for TyCtxt<'_> {}
1379fn _assert_tcx_fields() {
1380    sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1381    sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1382}
1383
1384impl<'tcx> Deref for TyCtxt<'tcx> {
1385    type Target = &'tcx GlobalCtxt<'tcx>;
1386    #[inline(always)]
1387    fn deref(&self) -> &Self::Target {
1388        &self.gcx
1389    }
1390}
1391
1392/// See [TyCtxt] for details about this type.
1393pub struct GlobalCtxt<'tcx> {
1394    pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1395    pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1396
1397    interners: CtxtInterners<'tcx>,
1398
1399    pub sess: &'tcx Session,
1400    crate_types: Vec<CrateType>,
1401    /// The `stable_crate_id` is constructed out of the crate name and all the
1402    /// `-C metadata` arguments passed to the compiler. Its value forms a unique
1403    /// global identifier for the crate. It is used to allow multiple crates
1404    /// with the same name to coexist. See the
1405    /// `rustc_symbol_mangling` crate for more information.
1406    stable_crate_id: StableCrateId,
1407
1408    pub dep_graph: DepGraph,
1409
1410    pub prof: SelfProfilerRef,
1411
1412    /// Common types, pre-interned for your convenience.
1413    pub types: CommonTypes<'tcx>,
1414
1415    /// Common lifetimes, pre-interned for your convenience.
1416    pub lifetimes: CommonLifetimes<'tcx>,
1417
1418    /// Common consts, pre-interned for your convenience.
1419    pub consts: CommonConsts<'tcx>,
1420
1421    /// Hooks to be able to register functions in other crates that can then still
1422    /// be called from rustc_middle.
1423    pub(crate) hooks: crate::hooks::Providers,
1424
1425    untracked: Untracked,
1426
1427    pub query_system: QuerySystem<'tcx>,
1428    pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1429
1430    // Internal caches for metadata decoding. No need to track deps on this.
1431    pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1432
1433    /// Caches the results of trait selection. This cache is used
1434    /// for things that do not have to do with the parameters in scope.
1435    pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1436
1437    /// Caches the results of trait evaluation. This cache is used
1438    /// for things that do not have to do with the parameters in scope.
1439    /// Merge this with `selection_cache`?
1440    pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1441
1442    /// Caches the results of goal evaluation in the new solver.
1443    pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1444
1445    pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1446
1447    /// Data layout specification for the current target.
1448    pub data_layout: TargetDataLayout,
1449
1450    /// Stores memory for globals (statics/consts).
1451    pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1452
1453    current_gcx: CurrentGcx,
1454
1455    /// A jobserver reference used to release then acquire a token while waiting on a query.
1456    pub jobserver_proxy: Arc<Proxy>,
1457}
1458
1459impl<'tcx> GlobalCtxt<'tcx> {
1460    /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
1461    /// `f`.
1462    pub fn enter<F, R>(&'tcx self, f: F) -> R
1463    where
1464        F: FnOnce(TyCtxt<'tcx>) -> R,
1465    {
1466        let icx = tls::ImplicitCtxt::new(self);
1467
1468        // Reset `current_gcx` to `None` when we exit.
1469        let _on_drop = defer(move || {
1470            *self.current_gcx.value.write() = None;
1471        });
1472
1473        // Set this `GlobalCtxt` as the current one.
1474        {
1475            let mut guard = self.current_gcx.value.write();
1476            assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1477            *guard = Some(self as *const _ as *const ());
1478        }
1479
1480        tls::enter_context(&icx, || f(icx.tcx))
1481    }
1482}
1483
1484/// This is used to get a reference to a `GlobalCtxt` if one is available.
1485///
1486/// This is needed to allow the deadlock handler access to `GlobalCtxt` to look for query cycles.
1487/// It cannot use the `TLV` global because that's only guaranteed to be defined on the thread
1488/// creating the `GlobalCtxt`. Other threads have access to the `TLV` only inside Rayon jobs, but
1489/// the deadlock handler is not called inside such a job.
1490#[derive(Clone)]
1491pub struct CurrentGcx {
1492    /// This stores a pointer to a `GlobalCtxt`. This is set to `Some` inside `GlobalCtxt::enter`
1493    /// and reset to `None` when that function returns or unwinds.
1494    value: Arc<RwLock<Option<*const ()>>>,
1495}
1496
1497unsafe impl DynSend for CurrentGcx {}
1498unsafe impl DynSync for CurrentGcx {}
1499
1500impl CurrentGcx {
1501    pub fn new() -> Self {
1502        Self { value: Arc::new(RwLock::new(None)) }
1503    }
1504
1505    pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1506        let read_guard = self.value.read();
1507        let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1508        // SAFETY: We hold the read lock for the `GlobalCtxt` pointer. That prevents
1509        // `GlobalCtxt::enter` from returning as it would first acquire the write lock.
1510        // This ensures the `GlobalCtxt` is live during `f`.
1511        f(unsafe { &*gcx })
1512    }
1513}
1514
1515impl<'tcx> TyCtxt<'tcx> {
1516    pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1517        // Closures' typeck results come from their outermost function,
1518        // as they are part of the same "inference environment".
1519        let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1520        if typeck_root_def_id != def_id.to_def_id() {
1521            return self.has_typeck_results(typeck_root_def_id.expect_local());
1522        }
1523
1524        self.hir_node_by_def_id(def_id).body_id().is_some()
1525    }
1526
1527    /// Expects a body and returns its codegen attributes.
1528    ///
1529    /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for
1530    /// constants.
1531    pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1532        let def_kind = self.def_kind(def_id);
1533        if def_kind.has_codegen_attrs() {
1534            self.codegen_fn_attrs(def_id)
1535        } else if matches!(
1536            def_kind,
1537            DefKind::AnonConst
1538                | DefKind::AssocConst
1539                | DefKind::Const
1540                | DefKind::InlineConst
1541                | DefKind::GlobalAsm
1542        ) {
1543            CodegenFnAttrs::EMPTY
1544        } else {
1545            bug!(
1546                "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1547                def_id,
1548                def_kind
1549            )
1550        }
1551    }
1552
1553    pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1554        self.arena.alloc(Steal::new(thir))
1555    }
1556
1557    pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1558        self.arena.alloc(Steal::new(mir))
1559    }
1560
1561    pub fn alloc_steal_promoted(
1562        self,
1563        promoted: IndexVec<Promoted, Body<'tcx>>,
1564    ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1565        self.arena.alloc(Steal::new(promoted))
1566    }
1567
1568    pub fn mk_adt_def(
1569        self,
1570        did: DefId,
1571        kind: AdtKind,
1572        variants: IndexVec<VariantIdx, ty::VariantDef>,
1573        repr: ReprOptions,
1574    ) -> ty::AdtDef<'tcx> {
1575        self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1576    }
1577
1578    /// Allocates a read-only byte or string literal for `mir::interpret` with alignment 1.
1579    /// Returns the same `AllocId` if called again with the same bytes.
1580    pub fn allocate_bytes_dedup(self, bytes: &[u8], salt: usize) -> interpret::AllocId {
1581        // Create an allocation that just contains these bytes.
1582        let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
1583        let alloc = self.mk_const_alloc(alloc);
1584        self.reserve_and_set_memory_dedup(alloc, salt)
1585    }
1586
1587    pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1588        match self.sess.opts.unstable_opts.experimental_default_bounds {
1589            true => &[
1590                LangItem::Sized,
1591                LangItem::DefaultTrait1,
1592                LangItem::DefaultTrait2,
1593                LangItem::DefaultTrait3,
1594                LangItem::DefaultTrait4,
1595            ],
1596            false => &[LangItem::Sized],
1597        }
1598    }
1599
1600    pub fn is_default_trait(self, def_id: DefId) -> bool {
1601        self.default_traits()
1602            .iter()
1603            .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
1604    }
1605
1606    /// Returns a range of the start/end indices specified with the
1607    /// `rustc_layout_scalar_valid_range` attribute.
1608    // FIXME(eddyb) this is an awkward spot for this method, maybe move it?
1609    pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1610        let get = |name| {
1611            let Some(attr) = self.get_attr(def_id, name) else {
1612                return Bound::Unbounded;
1613            };
1614            debug!("layout_scalar_valid_range: attr={:?}", attr);
1615            if let Some(
1616                &[
1617                    ast::MetaItemInner::Lit(ast::MetaItemLit {
1618                        kind: ast::LitKind::Int(a, _), ..
1619                    }),
1620                ],
1621            ) = attr.meta_item_list().as_deref()
1622            {
1623                Bound::Included(a.get())
1624            } else {
1625                self.dcx().span_delayed_bug(
1626                    attr.span(),
1627                    "invalid rustc_layout_scalar_valid_range attribute",
1628                );
1629                Bound::Unbounded
1630            }
1631        };
1632        (
1633            get(sym::rustc_layout_scalar_valid_range_start),
1634            get(sym::rustc_layout_scalar_valid_range_end),
1635        )
1636    }
1637
1638    pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1639        value.lift_to_interner(self)
1640    }
1641
1642    /// Creates a type context. To use the context call `fn enter` which
1643    /// provides a `TyCtxt`.
1644    ///
1645    /// By only providing the `TyCtxt` inside of the closure we enforce that the type
1646    /// context and any interned value (types, args, etc.) can only be used while `ty::tls`
1647    /// has a valid reference to the context, to allow formatting values that need it.
1648    pub fn create_global_ctxt<T>(
1649        gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1650        s: &'tcx Session,
1651        crate_types: Vec<CrateType>,
1652        stable_crate_id: StableCrateId,
1653        arena: &'tcx WorkerLocal<Arena<'tcx>>,
1654        hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1655        untracked: Untracked,
1656        dep_graph: DepGraph,
1657        query_kinds: &'tcx [DepKindStruct<'tcx>],
1658        query_system: QuerySystem<'tcx>,
1659        hooks: crate::hooks::Providers,
1660        current_gcx: CurrentGcx,
1661        jobserver_proxy: Arc<Proxy>,
1662        f: impl FnOnce(TyCtxt<'tcx>) -> T,
1663    ) -> T {
1664        let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1665            s.dcx().emit_fatal(err);
1666        });
1667        let interners = CtxtInterners::new(arena);
1668        let common_types = CommonTypes::new(&interners, s, &untracked);
1669        let common_lifetimes = CommonLifetimes::new(&interners);
1670        let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1671
1672        let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1673            sess: s,
1674            crate_types,
1675            stable_crate_id,
1676            arena,
1677            hir_arena,
1678            interners,
1679            dep_graph,
1680            hooks,
1681            prof: s.prof.clone(),
1682            types: common_types,
1683            lifetimes: common_lifetimes,
1684            consts: common_consts,
1685            untracked,
1686            query_system,
1687            query_kinds,
1688            ty_rcache: Default::default(),
1689            selection_cache: Default::default(),
1690            evaluation_cache: Default::default(),
1691            new_solver_evaluation_cache: Default::default(),
1692            canonical_param_env_cache: Default::default(),
1693            data_layout,
1694            alloc_map: interpret::AllocMap::new(),
1695            current_gcx,
1696            jobserver_proxy,
1697        });
1698
1699        // This is a separate function to work around a crash with parallel rustc (#135870)
1700        gcx.enter(f)
1701    }
1702
1703    /// Obtain all lang items of this crate and all dependencies (recursively)
1704    pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1705        self.get_lang_items(())
1706    }
1707
1708    /// Gets a `Ty` representing the [`LangItem::OrderingEnum`]
1709    #[track_caller]
1710    pub fn ty_ordering_enum(self, span: Option<Span>) -> Ty<'tcx> {
1711        let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1712        self.type_of(ordering_enum).no_bound_vars().unwrap()
1713    }
1714
1715    /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
1716    /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
1717    pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1718        self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1719    }
1720
1721    /// Obtain the diagnostic item's name
1722    pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1723        self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1724    }
1725
1726    /// Check whether the diagnostic item with the given `name` has the given `DefId`.
1727    pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1728        self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1729    }
1730
1731    pub fn is_coroutine(self, def_id: DefId) -> bool {
1732        self.coroutine_kind(def_id).is_some()
1733    }
1734
1735    pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1736        self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1737    }
1738
1739    /// Returns the movability of the coroutine of `def_id`, or panics
1740    /// if given a `def_id` that is not a coroutine.
1741    pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1742        self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1743    }
1744
1745    /// Returns `true` if the node pointed to by `def_id` is a coroutine for an async construct.
1746    pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1747        matches!(
1748            self.coroutine_kind(def_id),
1749            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1750        )
1751    }
1752
1753    // Whether the body owner is synthetic, which in this case means it does not correspond to
1754    // meaningful HIR. This is currently used to skip over MIR borrowck.
1755    pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1756        matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1757    }
1758
1759    /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`.
1760    /// This means it is neither an `async` or `gen` construct.
1761    pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1762        matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1763    }
1764
1765    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `gen` construct.
1766    pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1767        matches!(
1768            self.coroutine_kind(def_id),
1769            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1770        )
1771    }
1772
1773    /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `async gen` construct.
1774    pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1775        matches!(
1776            self.coroutine_kind(def_id),
1777            Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1778        )
1779    }
1780
1781    pub fn stability(self) -> &'tcx stability::Index {
1782        self.stability_index(())
1783    }
1784
1785    pub fn features(self) -> &'tcx rustc_feature::Features {
1786        self.features_query(())
1787    }
1788
1789    pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1790        let id = id.into_query_param();
1791        // Accessing the DefKey is ok, since it is part of DefPathHash.
1792        if let Some(id) = id.as_local() {
1793            self.definitions_untracked().def_key(id)
1794        } else {
1795            self.cstore_untracked().def_key(id)
1796        }
1797    }
1798
1799    /// Converts a `DefId` into its fully expanded `DefPath` (every
1800    /// `DefId` is really just an interned `DefPath`).
1801    ///
1802    /// Note that if `id` is not local to this crate, the result will
1803    ///  be a non-local `DefPath`.
1804    pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1805        // Accessing the DefPath is ok, since it is part of DefPathHash.
1806        if let Some(id) = id.as_local() {
1807            self.definitions_untracked().def_path(id)
1808        } else {
1809            self.cstore_untracked().def_path(id)
1810        }
1811    }
1812
1813    #[inline]
1814    pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1815        // Accessing the DefPathHash is ok, it is incr. comp. stable.
1816        if let Some(def_id) = def_id.as_local() {
1817            self.definitions_untracked().def_path_hash(def_id)
1818        } else {
1819            self.cstore_untracked().def_path_hash(def_id)
1820        }
1821    }
1822
1823    #[inline]
1824    pub fn crate_types(self) -> &'tcx [CrateType] {
1825        &self.crate_types
1826    }
1827
1828    pub fn metadata_kind(self) -> MetadataKind {
1829        self.crate_types()
1830            .iter()
1831            .map(|ty| match *ty {
1832                CrateType::Executable
1833                | CrateType::Staticlib
1834                | CrateType::Cdylib
1835                | CrateType::Sdylib => MetadataKind::None,
1836                CrateType::Rlib => MetadataKind::Uncompressed,
1837                CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
1838            })
1839            .max()
1840            .unwrap_or(MetadataKind::None)
1841    }
1842
1843    pub fn needs_metadata(self) -> bool {
1844        self.metadata_kind() != MetadataKind::None
1845    }
1846
1847    pub fn needs_crate_hash(self) -> bool {
1848        // Why is the crate hash needed for these configurations?
1849        // - debug_assertions: for the "fingerprint the result" check in
1850        //   `rustc_query_system::query::plumbing::execute_job`.
1851        // - incremental: for query lookups.
1852        // - needs_metadata: for putting into crate metadata.
1853        // - instrument_coverage: for putting into coverage data (see
1854        //   `hash_mir_source`).
1855        // - metrics_dir: metrics use the strict version hash in the filenames
1856        //   for dumped metrics files to prevent overwriting distinct metrics
1857        //   for similar source builds (may change in the future, this is part
1858        //   of the proof of concept impl for the metrics initiative project goal)
1859        cfg!(debug_assertions)
1860            || self.sess.opts.incremental.is_some()
1861            || self.needs_metadata()
1862            || self.sess.instrument_coverage()
1863            || self.sess.opts.unstable_opts.metrics_dir.is_some()
1864    }
1865
1866    #[inline]
1867    pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1868        if crate_num == LOCAL_CRATE {
1869            self.stable_crate_id
1870        } else {
1871            self.cstore_untracked().stable_crate_id(crate_num)
1872        }
1873    }
1874
1875    /// Maps a StableCrateId to the corresponding CrateNum. This method assumes
1876    /// that the crate in question has already been loaded by the CrateStore.
1877    #[inline]
1878    pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1879        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1880            LOCAL_CRATE
1881        } else {
1882            *self
1883                .untracked()
1884                .stable_crate_ids
1885                .read()
1886                .get(&stable_crate_id)
1887                .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1888        }
1889    }
1890
1891    /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
1892    /// session, if it still exists. This is used during incremental compilation to
1893    /// turn a deserialized `DefPathHash` into its current `DefId`.
1894    pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1895        debug!("def_path_hash_to_def_id({:?})", hash);
1896
1897        let stable_crate_id = hash.stable_crate_id();
1898
1899        // If this is a DefPathHash from the local crate, we can look up the
1900        // DefId in the tcx's `Definitions`.
1901        if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1902            Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1903        } else {
1904            Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
1905        }
1906    }
1907
1908    pub fn def_path_debug_str(self, def_id: DefId) -> String {
1909        // We are explicitly not going through queries here in order to get
1910        // crate name and stable crate id since this code is called from debug!()
1911        // statements within the query system and we'd run into endless
1912        // recursion otherwise.
1913        let (crate_name, stable_crate_id) = if def_id.is_local() {
1914            (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1915        } else {
1916            let cstore = &*self.cstore_untracked();
1917            (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1918        };
1919
1920        format!(
1921            "{}[{:04x}]{}",
1922            crate_name,
1923            // Don't print the whole stable crate id. That's just
1924            // annoying in debug output.
1925            stable_crate_id.as_u64() >> (8 * 6),
1926            self.def_path(def_id).to_string_no_crate_verbose()
1927        )
1928    }
1929
1930    pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1931        self.sess.dcx()
1932    }
1933
1934    pub fn is_target_feature_call_safe(
1935        self,
1936        callee_features: &[TargetFeature],
1937        body_features: &[TargetFeature],
1938    ) -> bool {
1939        // If the called function has target features the calling function hasn't,
1940        // the call requires `unsafe`. Don't check this on wasm
1941        // targets, though. For more information on wasm see the
1942        // is_like_wasm check in hir_analysis/src/collect.rs
1943        self.sess.target.options.is_like_wasm
1944            || callee_features
1945                .iter()
1946                .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1947    }
1948
1949    /// Returns the safe version of the signature of the given function, if calling it
1950    /// would be safe in the context of the given caller.
1951    pub fn adjust_target_feature_sig(
1952        self,
1953        fun_def: DefId,
1954        fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1955        caller: DefId,
1956    ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1957        let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1958        let callee_features = &self.codegen_fn_attrs(caller).target_features;
1959        if self.is_target_feature_call_safe(&fun_features, &callee_features) {
1960            return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
1961        }
1962        None
1963    }
1964
1965    /// Helper to get a tracked environment variable via. [`TyCtxt::env_var_os`] and converting to
1966    /// UTF-8 like [`std::env::var`].
1967    pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1968        match self.env_var_os(key.as_ref()) {
1969            Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1970            None => Err(VarError::NotPresent),
1971        }
1972    }
1973}
1974
1975impl<'tcx> TyCtxtAt<'tcx> {
1976    /// Create a new definition within the incr. comp. engine.
1977    pub fn create_def(
1978        self,
1979        parent: LocalDefId,
1980        name: Option<Symbol>,
1981        def_kind: DefKind,
1982        override_def_path_data: Option<DefPathData>,
1983        disambiguator: &mut DisambiguatorState,
1984    ) -> TyCtxtFeed<'tcx, LocalDefId> {
1985        let feed =
1986            self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1987
1988        feed.def_span(self.span);
1989        feed
1990    }
1991}
1992
1993impl<'tcx> TyCtxt<'tcx> {
1994    /// `tcx`-dependent operations performed for every created definition.
1995    pub fn create_def(
1996        self,
1997        parent: LocalDefId,
1998        name: Option<Symbol>,
1999        def_kind: DefKind,
2000        override_def_path_data: Option<DefPathData>,
2001        disambiguator: &mut DisambiguatorState,
2002    ) -> TyCtxtFeed<'tcx, LocalDefId> {
2003        let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2004        // The following call has the side effect of modifying the tables inside `definitions`.
2005        // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
2006        // decode the on-disk cache.
2007        //
2008        // Any LocalDefId which is used within queries, either as key or result, either:
2009        // - has been created before the construction of the TyCtxt;
2010        // - has been created by this call to `create_def`.
2011        // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
2012        // comp. engine itself.
2013        let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2014
2015        // This function modifies `self.definitions` using a side-effect.
2016        // We need to ensure that these side effects are re-run by the incr. comp. engine.
2017        // Depending on the forever-red node will tell the graph that the calling query
2018        // needs to be re-evaluated.
2019        self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2020
2021        let feed = TyCtxtFeed { tcx: self, key: def_id };
2022        feed.def_kind(def_kind);
2023        // Unique types created for closures participate in type privacy checking.
2024        // They have visibilities inherited from the module they are defined in.
2025        // Visibilities for opaque types are meaningless, but still provided
2026        // so that all items have visibilities.
2027        if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2028            let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2029            feed.visibility(ty::Visibility::Restricted(parent_mod));
2030        }
2031
2032        feed
2033    }
2034
2035    pub fn create_crate_num(
2036        self,
2037        stable_crate_id: StableCrateId,
2038    ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2039        if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2040            return Err(existing);
2041        }
2042
2043        let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2044        self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2045        Ok(TyCtxtFeed { key: num, tcx: self })
2046    }
2047
2048    pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2049        // Create a dependency to the red node to be sure we re-execute this when the amount of
2050        // definitions change.
2051        self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2052
2053        let definitions = &self.untracked.definitions;
2054        std::iter::from_coroutine(
2055            #[coroutine]
2056            || {
2057                let mut i = 0;
2058
2059                // Recompute the number of definitions each time, because our caller may be creating
2060                // new ones.
2061                while i < { definitions.read().num_definitions() } {
2062                    let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2063                    yield LocalDefId { local_def_index };
2064                    i += 1;
2065                }
2066
2067                // Freeze definitions once we finish iterating on them, to prevent adding new ones.
2068                definitions.freeze();
2069            },
2070        )
2071    }
2072
2073    pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2074        // Create a dependency to the crate to be sure we re-execute this when the amount of
2075        // definitions change.
2076        self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2077
2078        // Freeze definitions once we start iterating on them, to prevent adding new ones
2079        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
2080        self.untracked.definitions.freeze().def_path_table()
2081    }
2082
2083    pub fn def_path_hash_to_def_index_map(
2084        self,
2085    ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2086        // Create a dependency to the crate to be sure we re-execute this when the amount of
2087        // definitions change.
2088        self.ensure_ok().hir_crate(());
2089        // Freeze definitions once we start iterating on them, to prevent adding new ones
2090        // while iterating. If some query needs to add definitions, it should be `ensure`d above.
2091        self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2092    }
2093
2094    /// Note that this is *untracked* and should only be used within the query
2095    /// system if the result is otherwise tracked through queries
2096    #[inline]
2097    pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2098        FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2099    }
2100
2101    /// Give out access to the untracked data without any sanity checks.
2102    pub fn untracked(self) -> &'tcx Untracked {
2103        &self.untracked
2104    }
2105    /// Note that this is *untracked* and should only be used within the query
2106    /// system if the result is otherwise tracked through queries
2107    #[inline]
2108    pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2109        self.untracked.definitions.read()
2110    }
2111
2112    /// Note that this is *untracked* and should only be used within the query
2113    /// system if the result is otherwise tracked through queries
2114    #[inline]
2115    pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2116        self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2117    }
2118
2119    #[inline(always)]
2120    pub fn with_stable_hashing_context<R>(
2121        self,
2122        f: impl FnOnce(StableHashingContext<'_>) -> R,
2123    ) -> R {
2124        f(StableHashingContext::new(self.sess, &self.untracked))
2125    }
2126
2127    pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2128        self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2129    }
2130
2131    #[inline]
2132    pub fn local_crate_exports_generics(self) -> bool {
2133        self.crate_types().iter().any(|crate_type| {
2134            match crate_type {
2135                CrateType::Executable
2136                | CrateType::Staticlib
2137                | CrateType::ProcMacro
2138                | CrateType::Cdylib
2139                | CrateType::Sdylib => false,
2140
2141                // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
2142                // We want to block export of generics from dylibs,
2143                // but we must fix rust-lang/rust#65890 before we can
2144                // do that robustly.
2145                CrateType::Dylib => true,
2146
2147                CrateType::Rlib => true,
2148            }
2149        })
2150    }
2151
2152    /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
2153    pub fn is_suitable_region(
2154        self,
2155        generic_param_scope: LocalDefId,
2156        mut region: Region<'tcx>,
2157    ) -> Option<FreeRegionInfo> {
2158        let (suitable_region_binding_scope, region_def_id) = loop {
2159            let def_id =
2160                region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2161            let scope = self.local_parent(def_id);
2162            if self.def_kind(scope) == DefKind::OpaqueTy {
2163                // Lifetime params of opaque types are synthetic and thus irrelevant to
2164                // diagnostics. Map them back to their origin!
2165                region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2166                continue;
2167            }
2168            break (scope, def_id.into());
2169        };
2170
2171        let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2172            Node::Item(..) | Node::TraitItem(..) => false,
2173            Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2174            _ => false,
2175        };
2176
2177        Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2178    }
2179
2180    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
2181    pub fn return_type_impl_or_dyn_traits(
2182        self,
2183        scope_def_id: LocalDefId,
2184    ) -> Vec<&'tcx hir::Ty<'tcx>> {
2185        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2186        let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2187            self.hir_fn_decl_by_hir_id(hir_id)
2188        else {
2189            return vec![];
2190        };
2191
2192        let mut v = TraitObjectVisitor(vec![]);
2193        v.visit_ty_unambig(hir_output);
2194        v.0
2195    }
2196
2197    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in
2198    /// its return type, and the associated alias span when type alias is used,
2199    /// along with a span for lifetime suggestion (if there are existing generics).
2200    pub fn return_type_impl_or_dyn_traits_with_type_alias(
2201        self,
2202        scope_def_id: LocalDefId,
2203    ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2204        let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2205        let mut v = TraitObjectVisitor(vec![]);
2206        // when the return type is a type alias
2207        if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2208            && let hir::TyKind::Path(hir::QPath::Resolved(
2209                None,
2210                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2211            && let Some(local_id) = def_id.as_local()
2212            && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias
2213            && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
2214        {
2215            v.visit_ty_unambig(alias_ty);
2216            if !v.0.is_empty() {
2217                return Some((
2218                    v.0,
2219                    alias_generics.span,
2220                    alias_generics.span_for_lifetime_suggestion(),
2221                ));
2222            }
2223        }
2224        None
2225    }
2226
2227    /// Checks if the bound region is in Impl Item.
2228    pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2229        let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2230        if self.impl_trait_ref(container_id).is_some() {
2231            // For now, we do not try to target impls of traits. This is
2232            // because this message is going to suggest that the user
2233            // change the fn signature, but they may not be free to do so,
2234            // since the signature must match the trait.
2235            //
2236            // FIXME(#42706) -- in some cases, we could do better here.
2237            return true;
2238        }
2239        false
2240    }
2241
2242    /// Determines whether identifiers in the assembly have strict naming rules.
2243    /// Currently, only NVPTX* targets need it.
2244    pub fn has_strict_asm_symbol_naming(self) -> bool {
2245        self.sess.target.arch.contains("nvptx")
2246    }
2247
2248    /// Returns `&'static core::panic::Location<'static>`.
2249    pub fn caller_location_ty(self) -> Ty<'tcx> {
2250        Ty::new_imm_ref(
2251            self,
2252            self.lifetimes.re_static,
2253            self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
2254                .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2255        )
2256    }
2257
2258    /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
2259    pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2260        let kind = self.def_kind(def_id);
2261        (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2262    }
2263
2264    pub fn type_length_limit(self) -> Limit {
2265        self.limits(()).type_length_limit
2266    }
2267
2268    pub fn recursion_limit(self) -> Limit {
2269        self.limits(()).recursion_limit
2270    }
2271
2272    pub fn move_size_limit(self) -> Limit {
2273        self.limits(()).move_size_limit
2274    }
2275
2276    pub fn pattern_complexity_limit(self) -> Limit {
2277        self.limits(()).pattern_complexity_limit
2278    }
2279
2280    /// All traits in the crate graph, including those not visible to the user.
2281    pub fn all_traits(self) -> impl Iterator<Item = DefId> {
2282        iter::once(LOCAL_CRATE)
2283            .chain(self.crates(()).iter().copied())
2284            .flat_map(move |cnum| self.traits(cnum).iter().copied())
2285    }
2286
2287    /// All traits that are visible within the crate graph (i.e. excluding private dependencies).
2288    pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2289        let visible_crates =
2290            self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2291
2292        iter::once(LOCAL_CRATE)
2293            .chain(visible_crates)
2294            .flat_map(move |cnum| self.traits(cnum).iter().copied())
2295    }
2296
2297    #[inline]
2298    pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2299        self.visibility(def_id).expect_local()
2300    }
2301
2302    /// Returns the origin of the opaque type `def_id`.
2303    #[instrument(skip(self), level = "trace", ret)]
2304    pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2305        self.hir_expect_opaque_ty(def_id).origin
2306    }
2307
2308    pub fn finish(self) {
2309        // We assume that no queries are run past here. If there are new queries
2310        // after this point, they'll show up as "<unknown>" in self-profiling data.
2311        self.alloc_self_profile_query_strings();
2312
2313        self.save_dep_graph();
2314        self.query_key_hash_verify_all();
2315
2316        if let Err((path, error)) = self.dep_graph.finish_encoding() {
2317            self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2318        }
2319    }
2320}
2321
2322macro_rules! nop_lift {
2323    ($set:ident; $ty:ty => $lifted:ty) => {
2324        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2325            type Lifted = $lifted;
2326            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2327                // Assert that the set has the right type.
2328                // Given an argument that has an interned type, the return type has the type of
2329                // the corresponding interner set. This won't actually return anything, we're
2330                // just doing this to compute said type!
2331                fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2332                    _x: Interned<'tcx, Inner>,
2333                ) -> InternedSet<'tcx, Inner> {
2334                    unreachable!()
2335                }
2336                fn _type_eq<T>(_x: &T, _y: &T) {}
2337                fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2338                    // If `x` is a newtype around an `Interned<T>`, then `interner` is an
2339                    // interner of appropriate type. (Ideally we'd also check that `x` is a
2340                    // newtype with just that one field. Not sure how to do that.)
2341                    let interner = _intern_set_ty_from_interned_ty(x.0);
2342                    // Now check that this is the same type as `interners.$set`.
2343                    _type_eq(&interner, &tcx.interners.$set);
2344                }
2345
2346                tcx.interners
2347                    .$set
2348                    .contains_pointer_to(&InternedInSet(&*self.0.0))
2349                    // SAFETY: `self` is interned and therefore valid
2350                    // for the entire lifetime of the `TyCtxt`.
2351                    .then(|| unsafe { mem::transmute(self) })
2352            }
2353        }
2354    };
2355}
2356
2357macro_rules! nop_list_lift {
2358    ($set:ident; $ty:ty => $lifted:ty) => {
2359        impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2360            type Lifted = &'tcx List<$lifted>;
2361            fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2362                // Assert that the set has the right type.
2363                if false {
2364                    let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2365                }
2366
2367                if self.is_empty() {
2368                    return Some(List::empty());
2369                }
2370                tcx.interners
2371                    .$set
2372                    .contains_pointer_to(&InternedInSet(self))
2373                    .then(|| unsafe { mem::transmute(self) })
2374            }
2375        }
2376    };
2377}
2378
2379nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2380nop_lift! { region; Region<'a> => Region<'tcx> }
2381nop_lift! { const_; Const<'a> => Const<'tcx> }
2382nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2383nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2384nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2385nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2386nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2387nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2388
2389nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2390nop_list_lift! {
2391    poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2392}
2393nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2394
2395// This is the impl for `&'a GenericArgs<'a>`.
2396nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2397
2398macro_rules! sty_debug_print {
2399    ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2400        // Curious inner module to allow variant names to be used as
2401        // variable names.
2402        #[allow(non_snake_case)]
2403        mod inner {
2404            use crate::ty::{self, TyCtxt};
2405            use crate::ty::context::InternedInSet;
2406
2407            #[derive(Copy, Clone)]
2408            struct DebugStat {
2409                total: usize,
2410                lt_infer: usize,
2411                ty_infer: usize,
2412                ct_infer: usize,
2413                all_infer: usize,
2414            }
2415
2416            pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2417                let mut total = DebugStat {
2418                    total: 0,
2419                    lt_infer: 0,
2420                    ty_infer: 0,
2421                    ct_infer: 0,
2422                    all_infer: 0,
2423                };
2424                $(let mut $variant = total;)*
2425
2426                for shard in tcx.interners.type_.lock_shards() {
2427                    // It seems that ordering doesn't affect anything here.
2428                    #[allow(rustc::potential_query_instability)]
2429                    let types = shard.iter();
2430                    for &(InternedInSet(t), ()) in types {
2431                        let variant = match t.internee {
2432                            ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2433                                ty::Float(..) | ty::Str | ty::Never => continue,
2434                            ty::Error(_) => /* unimportant */ continue,
2435                            $(ty::$variant(..) => &mut $variant,)*
2436                        };
2437                        let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2438                        let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2439                        let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2440
2441                        variant.total += 1;
2442                        total.total += 1;
2443                        if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2444                        if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2445                        if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2446                        if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2447                    }
2448                }
2449                writeln!(fmt, "Ty interner             total           ty lt ct all")?;
2450                $(writeln!(fmt, "    {:18}: {uses:6} {usespc:4.1}%, \
2451                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2452                    stringify!($variant),
2453                    uses = $variant.total,
2454                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
2455                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
2456                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
2457                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
2458                    all = $variant.all_infer as f64 * 100.0  / total.total as f64)?;
2459                )*
2460                writeln!(fmt, "                  total {uses:6}        \
2461                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2462                    uses = total.total,
2463                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
2464                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
2465                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
2466                    all = total.all_infer as f64 * 100.0  / total.total as f64)
2467            }
2468        }
2469
2470        inner::go($fmt, $ctxt)
2471    }}
2472}
2473
2474impl<'tcx> TyCtxt<'tcx> {
2475    pub fn debug_stats(self) -> impl fmt::Debug {
2476        fmt::from_fn(move |fmt| {
2477            sty_debug_print!(
2478                fmt,
2479                self,
2480                Adt,
2481                Array,
2482                Slice,
2483                RawPtr,
2484                Ref,
2485                FnDef,
2486                FnPtr,
2487                UnsafeBinder,
2488                Placeholder,
2489                Coroutine,
2490                CoroutineWitness,
2491                Dynamic,
2492                Closure,
2493                CoroutineClosure,
2494                Tuple,
2495                Bound,
2496                Param,
2497                Infer,
2498                Alias,
2499                Pat,
2500                Foreign
2501            )?;
2502
2503            writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2504            writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2505            writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2506            writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2507
2508            Ok(())
2509        })
2510    }
2511}
2512
2513// This type holds a `T` in the interner. The `T` is stored in the arena and
2514// this type just holds a pointer to it, but it still effectively owns it. It
2515// impls `Borrow` so that it can be looked up using the original
2516// (non-arena-memory-owning) types.
2517struct InternedInSet<'tcx, T: ?Sized>(&'tcx T);
2518
2519impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> {
2520    fn clone(&self) -> Self {
2521        InternedInSet(self.0)
2522    }
2523}
2524
2525impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {}
2526
2527impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
2528    fn into_pointer(&self) -> *const () {
2529        self.0 as *const _ as *const ()
2530    }
2531}
2532
2533#[allow(rustc::usage_of_ty_tykind)]
2534impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2535    fn borrow(&self) -> &T {
2536        &self.0.internee
2537    }
2538}
2539
2540impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2541    fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2542        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2543        // `x == y`.
2544        self.0.internee == other.0.internee
2545    }
2546}
2547
2548impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2549
2550impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2551    fn hash<H: Hasher>(&self, s: &mut H) {
2552        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2553        self.0.internee.hash(s)
2554    }
2555}
2556
2557impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2558    fn borrow(&self) -> &[T] {
2559        &self.0[..]
2560    }
2561}
2562
2563impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2564    fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2565        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2566        // `x == y`.
2567        self.0[..] == other.0[..]
2568    }
2569}
2570
2571impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2572
2573impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2574    fn hash<H: Hasher>(&self, s: &mut H) {
2575        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2576        self.0[..].hash(s)
2577    }
2578}
2579
2580impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2581    fn borrow(&self) -> &[T] {
2582        &self.0[..]
2583    }
2584}
2585
2586impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2587    fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2588        // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
2589        // `x == y`.
2590        self.0[..] == other.0[..]
2591    }
2592}
2593
2594impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2595
2596impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2597    fn hash<H: Hasher>(&self, s: &mut H) {
2598        // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
2599        self.0[..].hash(s)
2600    }
2601}
2602
2603macro_rules! direct_interners {
2604    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2605        $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2606            fn borrow<'a>(&'a self) -> &'a $ty {
2607                &self.0
2608            }
2609        }
2610
2611        impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2612            fn eq(&self, other: &Self) -> bool {
2613                // The `Borrow` trait requires that `x.borrow() == y.borrow()`
2614                // equals `x == y`.
2615                self.0 == other.0
2616            }
2617        }
2618
2619        impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2620
2621        impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2622            fn hash<H: Hasher>(&self, s: &mut H) {
2623                // The `Borrow` trait requires that `x.borrow().hash(s) ==
2624                // x.hash(s)`.
2625                self.0.hash(s)
2626            }
2627        }
2628
2629        impl<'tcx> TyCtxt<'tcx> {
2630            $vis fn $method(self, v: $ty) -> $ret_ty {
2631                $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2632                    InternedInSet(self.interners.arena.alloc(v))
2633                }).0))
2634            }
2635        })+
2636    }
2637}
2638
2639// Functions with a `mk_` prefix are intended for use outside this file and
2640// crate. Functions with an `intern_` prefix are intended for use within this
2641// crate only, and have a corresponding `mk_` function.
2642direct_interners! {
2643    region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2644    valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2645    pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2646    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2647    layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2648    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2649    external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2650        ExternalConstraints -> ExternalConstraints<'tcx>,
2651    predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2652        PredefinedOpaques -> PredefinedOpaques<'tcx>,
2653}
2654
2655macro_rules! slice_interners {
2656    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2657        impl<'tcx> TyCtxt<'tcx> {
2658            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2659                if v.is_empty() {
2660                    List::empty()
2661                } else {
2662                    self.interners.$field.intern_ref(v, || {
2663                        InternedInSet(List::from_arena(&*self.arena, (), v))
2664                    }).0
2665                }
2666            })+
2667        }
2668    );
2669}
2670
2671// These functions intern slices. They all have a corresponding
2672// `mk_foo_from_iter` function that interns an iterator. The slice version
2673// should be used when possible, because it's faster.
2674slice_interners!(
2675    const_lists: pub mk_const_list(Const<'tcx>),
2676    args: pub mk_args(GenericArg<'tcx>),
2677    type_lists: pub mk_type_list(Ty<'tcx>),
2678    canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
2679    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2680    projs: pub mk_projs(ProjectionKind),
2681    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2682    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2683    fields: pub mk_fields(FieldIdx),
2684    local_def_ids: intern_local_def_ids(LocalDefId),
2685    captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2686    offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2687    patterns: pub mk_patterns(Pattern<'tcx>),
2688);
2689
2690impl<'tcx> TyCtxt<'tcx> {
2691    /// Given a `fn` type, returns an equivalent `unsafe fn` type;
2692    /// that is, a `fn` type that is equivalent in every way for being
2693    /// unsafe.
2694    pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2695        assert!(sig.safety().is_safe());
2696        Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2697    }
2698
2699    /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
2700    /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
2701    pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2702        elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2703            self.associated_items(trait_did)
2704                .filter_by_name_unhygienic(assoc_name.name)
2705                .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2706        })
2707    }
2708
2709    /// Given a `ty`, return whether it's an `impl Future<...>`.
2710    pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2711        let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2712        let future_trait = self.require_lang_item(LangItem::Future, None);
2713
2714        self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2715            let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2716                return false;
2717            };
2718            trait_predicate.trait_ref.def_id == future_trait
2719                && trait_predicate.polarity == PredicatePolarity::Positive
2720        })
2721    }
2722
2723    /// Given a closure signature, returns an equivalent fn signature. Detuples
2724    /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
2725    /// you would get a `fn(u32, i32)`.
2726    /// `unsafety` determines the unsafety of the fn signature. If you pass
2727    /// `hir::Safety::Unsafe` in the previous example, then you would get
2728    /// an `unsafe fn (u32, i32)`.
2729    /// It cannot convert a closure that requires unsafe.
2730    pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2731        sig.map_bound(|s| {
2732            let params = match s.inputs()[0].kind() {
2733                ty::Tuple(params) => *params,
2734                _ => bug!(),
2735            };
2736            self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2737        })
2738    }
2739
2740    #[inline]
2741    pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2742        self.interners.intern_predicate(
2743            binder,
2744            self.sess,
2745            // This is only used to create a stable hashing context.
2746            &self.untracked,
2747        )
2748    }
2749
2750    #[inline]
2751    pub fn reuse_or_mk_predicate(
2752        self,
2753        pred: Predicate<'tcx>,
2754        binder: Binder<'tcx, PredicateKind<'tcx>>,
2755    ) -> Predicate<'tcx> {
2756        if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2757    }
2758
2759    pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2760        self.check_args_compatible_inner(def_id, args, false)
2761    }
2762
2763    fn check_args_compatible_inner(
2764        self,
2765        def_id: DefId,
2766        args: &'tcx [ty::GenericArg<'tcx>],
2767        nested: bool,
2768    ) -> bool {
2769        let generics = self.generics_of(def_id);
2770
2771        // IATs themselves have a weird arg setup (self + own args), but nested items *in* IATs
2772        // (namely: opaques, i.e. ATPITs) do not.
2773        let own_args = if !nested
2774            && let DefKind::AssocTy = self.def_kind(def_id)
2775            && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2776        {
2777            if generics.own_params.len() + 1 != args.len() {
2778                return false;
2779            }
2780
2781            if !matches!(args[0].unpack(), ty::GenericArgKind::Type(_)) {
2782                return false;
2783            }
2784
2785            &args[1..]
2786        } else {
2787            if generics.count() != args.len() {
2788                return false;
2789            }
2790
2791            let (parent_args, own_args) = args.split_at(generics.parent_count);
2792
2793            if let Some(parent) = generics.parent
2794                && !self.check_args_compatible_inner(parent, parent_args, true)
2795            {
2796                return false;
2797            }
2798
2799            own_args
2800        };
2801
2802        for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2803            match (&param.kind, arg.unpack()) {
2804                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2805                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2806                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2807                _ => return false,
2808            }
2809        }
2810
2811        true
2812    }
2813
2814    /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
2815    /// and print out the args if not.
2816    pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2817        if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2818            if let DefKind::AssocTy = self.def_kind(def_id)
2819                && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2820            {
2821                bug!(
2822                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2823                    self.def_path_str(def_id),
2824                    args,
2825                    // Make `[Self, GAT_ARGS...]` (this could be simplified)
2826                    self.mk_args_from_iter(
2827                        [self.types.self_param.into()].into_iter().chain(
2828                            self.generics_of(def_id)
2829                                .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2830                                .iter()
2831                                .copied()
2832                        )
2833                    )
2834                );
2835            } else {
2836                bug!(
2837                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2838                    self.def_path_str(def_id),
2839                    args,
2840                    ty::GenericArgs::identity_for_item(self, def_id)
2841                );
2842            }
2843        }
2844    }
2845
2846    #[inline(always)]
2847    pub(crate) fn check_and_mk_args(
2848        self,
2849        def_id: DefId,
2850        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2851    ) -> GenericArgsRef<'tcx> {
2852        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2853        self.debug_assert_args_compatible(def_id, args);
2854        args
2855    }
2856
2857    #[inline]
2858    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2859        self.interners.intern_const(
2860            kind,
2861            self.sess,
2862            // This is only used to create a stable hashing context.
2863            &self.untracked,
2864        )
2865    }
2866
2867    // Avoid this in favour of more specific `Ty::new_*` methods, where possible.
2868    #[allow(rustc::usage_of_ty_tykind)]
2869    #[inline]
2870    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2871        self.interners.intern_ty(
2872            st,
2873            self.sess,
2874            // This is only used to create a stable hashing context.
2875            &self.untracked,
2876        )
2877    }
2878
2879    pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2880        match param.kind {
2881            GenericParamDefKind::Lifetime => {
2882                ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2883            }
2884            GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2885            GenericParamDefKind::Const { .. } => {
2886                ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2887                    .into()
2888            }
2889        }
2890    }
2891
2892    pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2893        self.mk_place_elem(place, PlaceElem::Field(f, ty))
2894    }
2895
2896    pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2897        self.mk_place_elem(place, PlaceElem::Deref)
2898    }
2899
2900    pub fn mk_place_downcast(
2901        self,
2902        place: Place<'tcx>,
2903        adt_def: AdtDef<'tcx>,
2904        variant_index: VariantIdx,
2905    ) -> Place<'tcx> {
2906        self.mk_place_elem(
2907            place,
2908            PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2909        )
2910    }
2911
2912    pub fn mk_place_downcast_unnamed(
2913        self,
2914        place: Place<'tcx>,
2915        variant_index: VariantIdx,
2916    ) -> Place<'tcx> {
2917        self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2918    }
2919
2920    pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2921        self.mk_place_elem(place, PlaceElem::Index(index))
2922    }
2923
2924    /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
2925    /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
2926    /// flight.
2927    pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2928        let mut projection = place.projection.to_vec();
2929        projection.push(elem);
2930
2931        Place { local: place.local, projection: self.mk_place_elems(&projection) }
2932    }
2933
2934    pub fn mk_poly_existential_predicates(
2935        self,
2936        eps: &[PolyExistentialPredicate<'tcx>],
2937    ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2938        assert!(!eps.is_empty());
2939        assert!(
2940            eps.array_windows()
2941                .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2942                    != Ordering::Greater)
2943        );
2944        self.intern_poly_existential_predicates(eps)
2945    }
2946
2947    pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2948        // FIXME consider asking the input slice to be sorted to avoid
2949        // re-interning permutations, in which case that would be asserted
2950        // here.
2951        self.interners.intern_clauses(clauses)
2952    }
2953
2954    pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2955        // FIXME consider asking the input slice to be sorted to avoid
2956        // re-interning permutations, in which case that would be asserted
2957        // here.
2958        self.intern_local_def_ids(def_ids)
2959    }
2960
2961    pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2962    where
2963        I: Iterator<Item = T>,
2964        T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2965    {
2966        T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2967    }
2968
2969    pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2970    where
2971        I: Iterator<Item = T>,
2972        T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2973    {
2974        T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2975    }
2976
2977    pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2978    where
2979        I: Iterator<Item = T>,
2980        T: CollectAndApply<
2981                &'tcx ty::CapturedPlace<'tcx>,
2982                &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2983            >,
2984    {
2985        T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2986    }
2987
2988    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2989    where
2990        I: Iterator<Item = T>,
2991        T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2992    {
2993        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2994    }
2995
2996    // Unlike various other `mk_*_from_iter` functions, this one uses `I:
2997    // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
2998    // variant, because of the need to combine `inputs` and `output`. This
2999    // explains the lack of `_from_iter` suffix.
3000    pub fn mk_fn_sig<I, T>(
3001        self,
3002        inputs: I,
3003        output: I::Item,
3004        c_variadic: bool,
3005        safety: hir::Safety,
3006        abi: ExternAbi,
3007    ) -> T::Output
3008    where
3009        I: IntoIterator<Item = T>,
3010        T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3011    {
3012        T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3013            inputs_and_output: self.mk_type_list(xs),
3014            c_variadic,
3015            safety,
3016            abi,
3017        })
3018    }
3019
3020    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3021    where
3022        I: Iterator<Item = T>,
3023        T: CollectAndApply<
3024                PolyExistentialPredicate<'tcx>,
3025                &'tcx List<PolyExistentialPredicate<'tcx>>,
3026            >,
3027    {
3028        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3029    }
3030
3031    pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3032    where
3033        I: Iterator<Item = T>,
3034        T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3035    {
3036        T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3037    }
3038
3039    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3040    where
3041        I: Iterator<Item = T>,
3042        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3043    {
3044        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3045    }
3046
3047    pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3048    where
3049        I: Iterator<Item = T>,
3050        T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3051    {
3052        T::collect_and_apply(iter, |xs| self.mk_args(xs))
3053    }
3054
3055    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3056    where
3057        I: Iterator<Item = T>,
3058        T: CollectAndApply<CanonicalVarInfo<'tcx>, &'tcx List<CanonicalVarInfo<'tcx>>>,
3059    {
3060        T::collect_and_apply(iter, |xs| self.mk_canonical_var_infos(xs))
3061    }
3062
3063    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3064    where
3065        I: Iterator<Item = T>,
3066        T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3067    {
3068        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3069    }
3070
3071    pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3072    where
3073        I: Iterator<Item = T>,
3074        T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3075    {
3076        T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3077    }
3078
3079    pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
3080    where
3081        I: Iterator<Item = T>,
3082        T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
3083    {
3084        T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
3085    }
3086
3087    pub fn mk_args_trait(
3088        self,
3089        self_ty: Ty<'tcx>,
3090        rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3091    ) -> GenericArgsRef<'tcx> {
3092        self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3093    }
3094
3095    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3096    where
3097        I: Iterator<Item = T>,
3098        T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3099    {
3100        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3101    }
3102
3103    /// Emit a lint at `span` from a lint struct (some type that implements `LintDiagnostic`,
3104    /// typically generated by `#[derive(LintDiagnostic)]`).
3105    #[track_caller]
3106    pub fn emit_node_span_lint(
3107        self,
3108        lint: &'static Lint,
3109        hir_id: HirId,
3110        span: impl Into<MultiSpan>,
3111        decorator: impl for<'a> LintDiagnostic<'a, ()>,
3112    ) {
3113        let level = self.lint_level_at_node(lint, hir_id);
3114        lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3115            decorator.decorate_lint(lint);
3116        })
3117    }
3118
3119    /// Emit a lint at the appropriate level for a hir node, with an associated span.
3120    ///
3121    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
3122    #[rustc_lint_diagnostics]
3123    #[track_caller]
3124    pub fn node_span_lint(
3125        self,
3126        lint: &'static Lint,
3127        hir_id: HirId,
3128        span: impl Into<MultiSpan>,
3129        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3130    ) {
3131        let level = self.lint_level_at_node(lint, hir_id);
3132        lint_level(self.sess, lint, level, Some(span.into()), decorate);
3133    }
3134
3135    /// Find the crate root and the appropriate span where `use` and outer attributes can be
3136    /// inserted at.
3137    pub fn crate_level_attribute_injection_span(self, hir_id: HirId) -> Option<Span> {
3138        for (_hir_id, node) in self.hir_parent_iter(hir_id) {
3139            if let hir::Node::Crate(m) = node {
3140                return Some(m.spans.inject_use_span.shrink_to_lo());
3141            }
3142        }
3143        None
3144    }
3145
3146    pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3147        self,
3148        diag: &mut Diag<'_, E>,
3149        hir_id: Option<HirId>,
3150        features: impl IntoIterator<Item = (String, Symbol)>,
3151    ) {
3152        if !self.sess.is_nightly_build() {
3153            return;
3154        }
3155
3156        let span = hir_id.and_then(|id| self.crate_level_attribute_injection_span(id));
3157        for (desc, feature) in features {
3158            // FIXME: make this string translatable
3159            let msg =
3160                format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3161            if let Some(span) = span {
3162                diag.span_suggestion_verbose(
3163                    span,
3164                    msg,
3165                    format!("#![feature({feature})]\n"),
3166                    Applicability::MaybeIncorrect,
3167                );
3168            } else {
3169                diag.help(msg);
3170            }
3171        }
3172    }
3173
3174    /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically
3175    /// generated by `#[derive(LintDiagnostic)]`).
3176    #[track_caller]
3177    pub fn emit_node_lint(
3178        self,
3179        lint: &'static Lint,
3180        id: HirId,
3181        decorator: impl for<'a> LintDiagnostic<'a, ()>,
3182    ) {
3183        self.node_lint(lint, id, |lint| {
3184            decorator.decorate_lint(lint);
3185        })
3186    }
3187
3188    /// Emit a lint at the appropriate level for a hir node.
3189    ///
3190    /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
3191    #[rustc_lint_diagnostics]
3192    #[track_caller]
3193    pub fn node_lint(
3194        self,
3195        lint: &'static Lint,
3196        id: HirId,
3197        decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3198    ) {
3199        let level = self.lint_level_at_node(lint, id);
3200        lint_level(self.sess, lint, level, None, decorate);
3201    }
3202
3203    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3204        let map = self.in_scope_traits_map(id.owner)?;
3205        let candidates = map.get(&id.local_id)?;
3206        Some(candidates)
3207    }
3208
3209    pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3210        debug!(?id, "named_region");
3211        self.named_variable_map(id.owner).get(&id.local_id).cloned()
3212    }
3213
3214    pub fn is_late_bound(self, id: HirId) -> bool {
3215        self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3216    }
3217
3218    pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3219        self.mk_bound_variable_kinds(
3220            &self
3221                .late_bound_vars_map(id.owner)
3222                .get(&id.local_id)
3223                .cloned()
3224                .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3225        )
3226    }
3227
3228    /// Given the def-id of an early-bound lifetime on an opaque corresponding to
3229    /// a duplicated captured lifetime, map it back to the early- or late-bound
3230    /// lifetime of the function from which it originally as captured. If it is
3231    /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
3232    /// of the signature.
3233    // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
3234    // re-use the generics of the opaque, this function will need to be tweaked slightly.
3235    pub fn map_opaque_lifetime_to_parent_lifetime(
3236        self,
3237        mut opaque_lifetime_param_def_id: LocalDefId,
3238    ) -> ty::Region<'tcx> {
3239        debug_assert!(
3240            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3241            "{opaque_lifetime_param_def_id:?} is a {}",
3242            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3243        );
3244
3245        loop {
3246            let parent = self.local_parent(opaque_lifetime_param_def_id);
3247            let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3248
3249            let Some((lifetime, _)) = lifetime_mapping
3250                .iter()
3251                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3252            else {
3253                bug!("duplicated lifetime param should be present");
3254            };
3255
3256            match *lifetime {
3257                resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3258                    let new_parent = self.local_parent(ebv);
3259
3260                    // If we map to another opaque, then it should be a parent
3261                    // of the opaque we mapped from. Continue mapping.
3262                    if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3263                        debug_assert_eq!(self.local_parent(parent), new_parent);
3264                        opaque_lifetime_param_def_id = ebv;
3265                        continue;
3266                    }
3267
3268                    let generics = self.generics_of(new_parent);
3269                    return ty::Region::new_early_param(
3270                        self,
3271                        ty::EarlyParamRegion {
3272                            index: generics
3273                                .param_def_id_to_index(self, ebv.to_def_id())
3274                                .expect("early-bound var should be present in fn generics"),
3275                            name: self.item_name(ebv.to_def_id()),
3276                        },
3277                    );
3278                }
3279                resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3280                    let new_parent = self.local_parent(lbv);
3281                    return ty::Region::new_late_param(
3282                        self,
3283                        new_parent.to_def_id(),
3284                        ty::LateParamRegionKind::Named(
3285                            lbv.to_def_id(),
3286                            self.item_name(lbv.to_def_id()),
3287                        ),
3288                    );
3289                }
3290                resolve_bound_vars::ResolvedArg::Error(guar) => {
3291                    return ty::Region::new_error(self, guar);
3292                }
3293                _ => {
3294                    return ty::Region::new_error_with_message(
3295                        self,
3296                        self.def_span(opaque_lifetime_param_def_id),
3297                        "cannot resolve lifetime",
3298                    );
3299                }
3300            }
3301        }
3302    }
3303
3304    /// Whether `def_id` is a stable const fn (i.e., doesn't need any feature gates to be called).
3305    ///
3306    /// When this is `false`, the function may still be callable as a `const fn` due to features
3307    /// being enabled!
3308    pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3309        self.is_const_fn(def_id)
3310            && match self.lookup_const_stability(def_id) {
3311                None => true, // a fn in a non-staged_api crate
3312                Some(stability) if stability.is_const_stable() => true,
3313                _ => false,
3314            }
3315    }
3316
3317    /// Whether the trait impl is marked const. This does not consider stability or feature gates.
3318    pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3319        self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3320            && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3321    }
3322
3323    pub fn is_sdylib_interface_build(self) -> bool {
3324        self.sess.opts.unstable_opts.build_sdylib_interface
3325    }
3326
3327    pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3328        match self.def_kind(def_id) {
3329            DefKind::Fn | DefKind::AssocFn => {}
3330            _ => return None,
3331        }
3332        self.intrinsic_raw(def_id)
3333    }
3334
3335    pub fn next_trait_solver_globally(self) -> bool {
3336        self.sess.opts.unstable_opts.next_solver.globally
3337    }
3338
3339    pub fn next_trait_solver_in_coherence(self) -> bool {
3340        self.sess.opts.unstable_opts.next_solver.coherence
3341    }
3342
3343    #[allow(rustc::bad_opt_access)]
3344    pub fn use_typing_mode_borrowck(self) -> bool {
3345        self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3346    }
3347
3348    pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3349        self.opt_rpitit_info(def_id).is_some()
3350    }
3351
3352    /// Named module children from all kinds of items, including imports.
3353    /// In addition to regular items this list also includes struct and variant constructors, and
3354    /// items inside `extern {}` blocks because all of them introduce names into parent module.
3355    ///
3356    /// Module here is understood in name resolution sense - it can be a `mod` item,
3357    /// or a crate root, or an enum, or a trait.
3358    ///
3359    /// This is not a query, making it a query causes perf regressions
3360    /// (probably due to hashing spans in `ModChild`ren).
3361    pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3362        self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3363    }
3364
3365    pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3366        self.resolver_for_lowering_raw(()).0
3367    }
3368
3369    /// Given an `impl_id`, return the trait it implements.
3370    /// Return `None` if this is an inherent impl.
3371    pub fn impl_trait_ref(
3372        self,
3373        def_id: impl IntoQueryParam<DefId>,
3374    ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3375        Some(self.impl_trait_header(def_id)?.trait_ref)
3376    }
3377
3378    pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3379        self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3380    }
3381
3382    pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3383        if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3384            self.coroutine_kind(def_id)
3385            && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3386            && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3387        {
3388            true
3389        } else {
3390            false
3391        }
3392    }
3393
3394    /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
3395    pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3396        self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3397    }
3398}
3399
3400/// Parameter attributes that can only be determined by examining the body of a function instead
3401/// of just its signature.
3402///
3403/// These can be useful for optimization purposes when a function is directly called. We compute
3404/// them and store them into the crate metadata so that downstream crates can make use of them.
3405///
3406/// Right now, we only have `read_only`, but `no_capture` and `no_alias` might be useful in the
3407/// future.
3408#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3409pub struct DeducedParamAttrs {
3410    /// The parameter is marked immutable in the function and contains no `UnsafeCell` (i.e. its
3411    /// type is freeze).
3412    pub read_only: bool,
3413}
3414
3415pub fn provide(providers: &mut Providers) {
3416    providers.maybe_unused_trait_imports =
3417        |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
3418    providers.names_imported_by_glob_use = |tcx, id| {
3419        tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
3420    };
3421
3422    providers.extern_mod_stmt_cnum =
3423        |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
3424    providers.is_panic_runtime =
3425        |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3426    providers.is_compiler_builtins =
3427        |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3428    providers.has_panic_handler = |tcx, LocalCrate| {
3429        // We want to check if the panic handler was defined in this crate
3430        tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3431    };
3432    providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3433}
3434
3435pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3436    attrs.iter().any(|x| x.has_name(name))
3437}
OSZAR »