1#![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::hash::{Hash, Hasher};
11use std::marker::PhantomData;
12use std::ops::{Bound, Deref};
13use std::sync::{Arc, OnceLock};
14use std::{fmt, iter, mem};
15
16use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
17use rustc_ast as ast;
18use rustc_data_structures::defer;
19use rustc_data_structures::fingerprint::Fingerprint;
20use rustc_data_structures::fx::FxHashMap;
21use rustc_data_structures::intern::Interned;
22use rustc_data_structures::profiling::SelfProfilerRef;
23use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
24use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
25use rustc_data_structures::steal::Steal;
26use rustc_data_structures::sync::{
27 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
28};
29use rustc_data_structures::unord::UnordSet;
30use rustc_errors::{
31 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan,
32};
33use rustc_hir::def::{CtorKind, DefKind};
34use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
35use rustc_hir::definitions::Definitions;
36use rustc_hir::intravisit::VisitorExt;
37use rustc_hir::lang_items::LangItem;
38use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
39use rustc_index::IndexVec;
40use rustc_macros::{HashStable, TyDecodable, TyEncodable};
41use rustc_query_system::cache::WithDepNode;
42use rustc_query_system::dep_graph::DepNodeIndex;
43use rustc_query_system::ich::StableHashingContext;
44use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
45use rustc_session::config::CrateType;
46use rustc_session::cstore::{CrateStoreDyn, Untracked};
47use rustc_session::lint::Lint;
48use rustc_session::{Limit, MetadataKind, Session};
49use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
50use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
51use rustc_type_ir::TyKind::*;
52use rustc_type_ir::lang_items::TraitSolverLangItem;
53pub use rustc_type_ir::lift::Lift;
54use rustc_type_ir::{
55 CollectAndApply, Interner, TypeFlags, TypeFoldable, WithCachedTypeInfo, elaborate, search_graph,
56};
57use tracing::{debug, instrument};
58
59use crate::arena::Arena;
60use crate::dep_graph::{DepGraph, DepKindStruct};
61use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
62use crate::lint::lint_level;
63use crate::metadata::ModChild;
64use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
65use crate::middle::{resolve_bound_vars, stability};
66use crate::mir::interpret::{self, Allocation, ConstAllocation};
67use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
68use crate::query::plumbing::QuerySystem;
69use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
70use crate::thir::Thir;
71use crate::traits;
72use crate::traits::solve;
73use crate::traits::solve::{
74 ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData,
75};
76use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
77use crate::ty::{
78 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
79 GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, ParamTy,
80 Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
81 PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
82 ValTree, ValTreeKind, Visibility,
83};
84
85#[allow(rustc::usage_of_ty_tykind)]
86impl<'tcx> Interner for TyCtxt<'tcx> {
87 type DefId = DefId;
88 type LocalDefId = LocalDefId;
89 type Span = Span;
90
91 type GenericArgs = ty::GenericArgsRef<'tcx>;
92
93 type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
94 type GenericArg = ty::GenericArg<'tcx>;
95 type Term = ty::Term<'tcx>;
96 type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
97
98 type BoundVarKind = ty::BoundVariableKind;
99 type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
100
101 fn mk_predefined_opaques_in_body(
102 self,
103 data: PredefinedOpaquesData<Self>,
104 ) -> Self::PredefinedOpaques {
105 self.mk_predefined_opaques_in_body(data)
106 }
107 type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
108 type CanonicalVars = CanonicalVarInfos<'tcx>;
109 fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
110 self.mk_canonical_var_infos(infos)
111 }
112
113 type ExternalConstraints = ExternalConstraints<'tcx>;
114 fn mk_external_constraints(
115 self,
116 data: ExternalConstraintsData<Self>,
117 ) -> ExternalConstraints<'tcx> {
118 self.mk_external_constraints(data)
119 }
120 type DepNodeIndex = DepNodeIndex;
121 fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
122 self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
123 }
124 type Ty = Ty<'tcx>;
125 type Tys = &'tcx List<Ty<'tcx>>;
126
127 type FnInputTys = &'tcx [Ty<'tcx>];
128 type ParamTy = ParamTy;
129 type BoundTy = ty::BoundTy;
130
131 type PlaceholderTy = ty::PlaceholderType;
132 type ErrorGuaranteed = ErrorGuaranteed;
133 type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
134
135 type AllocId = crate::mir::interpret::AllocId;
136 type Pat = Pattern<'tcx>;
137 type Safety = hir::Safety;
138 type Abi = ExternAbi;
139 type Const = ty::Const<'tcx>;
140 type PlaceholderConst = ty::PlaceholderConst;
141
142 type ParamConst = ty::ParamConst;
143 type BoundConst = ty::BoundVar;
144 type ValueConst = ty::Value<'tcx>;
145 type ExprConst = ty::Expr<'tcx>;
146 type ValTree = ty::ValTree<'tcx>;
147
148 type Region = Region<'tcx>;
149 type EarlyParamRegion = ty::EarlyParamRegion;
150 type LateParamRegion = ty::LateParamRegion;
151 type BoundRegion = ty::BoundRegion;
152 type PlaceholderRegion = ty::PlaceholderRegion;
153
154 type ParamEnv = ty::ParamEnv<'tcx>;
155 type Predicate = Predicate<'tcx>;
156
157 type Clause = Clause<'tcx>;
158 type Clauses = ty::Clauses<'tcx>;
159
160 type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
161 fn mk_tracked<T: fmt::Debug + Clone>(
162 self,
163 data: T,
164 dep_node: DepNodeIndex,
165 ) -> Self::Tracked<T> {
166 WithDepNode::new(dep_node, data)
167 }
168 fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
169 tracked.get(self)
170 }
171
172 fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
173 f(&mut *self.new_solver_evaluation_cache.lock())
174 }
175
176 fn evaluation_is_concurrent(&self) -> bool {
177 self.sess.threads() > 1
178 }
179
180 fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
181 self.expand_abstract_consts(t)
182 }
183
184 type GenericsOf = &'tcx ty::Generics;
185
186 fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
187 self.generics_of(def_id)
188 }
189
190 type VariancesOf = &'tcx [ty::Variance];
191
192 fn variances_of(self, def_id: DefId) -> Self::VariancesOf {
193 self.variances_of(def_id)
194 }
195
196 fn opt_alias_variances(
197 self,
198 kind: impl Into<ty::AliasTermKind>,
199 def_id: DefId,
200 ) -> Option<&'tcx [ty::Variance]> {
201 self.opt_alias_variances(kind, def_id)
202 }
203
204 fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
205 self.type_of(def_id)
206 }
207
208 type AdtDef = ty::AdtDef<'tcx>;
209 fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
210 self.adt_def(adt_def_id)
211 }
212
213 fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
214 match self.def_kind(alias.def_id) {
215 DefKind::AssocTy => {
216 if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
217 {
218 ty::Inherent
219 } else {
220 ty::Projection
221 }
222 }
223 DefKind::OpaqueTy => ty::Opaque,
224 DefKind::TyAlias => ty::Weak,
225 kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
226 }
227 }
228
229 fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind {
230 match self.def_kind(alias.def_id) {
231 DefKind::AssocTy => {
232 if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
233 {
234 ty::AliasTermKind::InherentTy
235 } else {
236 ty::AliasTermKind::ProjectionTy
237 }
238 }
239 DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
240 DefKind::TyAlias => ty::AliasTermKind::WeakTy,
241 DefKind::AssocConst => ty::AliasTermKind::ProjectionConst,
242 DefKind::AnonConst | DefKind::Const | DefKind::Ctor(_, CtorKind::Const) => {
243 ty::AliasTermKind::UnevaluatedConst
244 }
245 kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
246 }
247 }
248
249 fn trait_ref_and_own_args_for_alias(
250 self,
251 def_id: DefId,
252 args: ty::GenericArgsRef<'tcx>,
253 ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
254 assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
255 let trait_def_id = self.parent(def_id);
256 assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
257 let trait_generics = self.generics_of(trait_def_id);
258 (
259 ty::TraitRef::new_from_args(self, trait_def_id, args.truncate_to(self, trait_generics)),
260 &args[trait_generics.count()..],
261 )
262 }
263
264 fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
265 self.mk_args(args)
266 }
267
268 fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
269 where
270 I: Iterator<Item = T>,
271 T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
272 {
273 self.mk_args_from_iter(args)
274 }
275
276 fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
277 self.check_args_compatible(def_id, args)
278 }
279
280 fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
281 self.debug_assert_args_compatible(def_id, args);
282 }
283
284 fn debug_assert_existential_args_compatible(
288 self,
289 def_id: Self::DefId,
290 args: Self::GenericArgs,
291 ) {
292 if cfg!(debug_assertions) {
295 self.debug_assert_args_compatible(
296 def_id,
297 self.mk_args_from_iter(
298 [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
299 ),
300 );
301 }
302 }
303
304 fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
305 where
306 I: Iterator<Item = T>,
307 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
308 {
309 self.mk_type_list_from_iter(args)
310 }
311
312 fn parent(self, def_id: DefId) -> DefId {
313 self.parent(def_id)
314 }
315
316 fn recursion_limit(self) -> usize {
317 self.recursion_limit().0
318 }
319
320 type Features = &'tcx rustc_feature::Features;
321
322 fn features(self) -> Self::Features {
323 self.features()
324 }
325
326 fn coroutine_hidden_types(
327 self,
328 def_id: DefId,
329 ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> {
330 self.coroutine_hidden_types(def_id)
331 }
332
333 fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
334 self.fn_sig(def_id)
335 }
336
337 fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
338 self.coroutine_movability(def_id)
339 }
340
341 fn coroutine_for_closure(self, def_id: DefId) -> DefId {
342 self.coroutine_for_closure(def_id)
343 }
344
345 fn generics_require_sized_self(self, def_id: DefId) -> bool {
346 self.generics_require_sized_self(def_id)
347 }
348
349 fn item_bounds(
350 self,
351 def_id: DefId,
352 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
353 self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
354 }
355
356 fn item_self_bounds(
357 self,
358 def_id: DefId,
359 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
360 self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
361 }
362
363 fn item_non_self_bounds(
364 self,
365 def_id: DefId,
366 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
367 self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
368 }
369
370 fn predicates_of(
371 self,
372 def_id: DefId,
373 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
374 ty::EarlyBinder::bind(
375 self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
376 )
377 }
378
379 fn own_predicates_of(
380 self,
381 def_id: DefId,
382 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
383 ty::EarlyBinder::bind(
384 self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
385 )
386 }
387
388 fn explicit_super_predicates_of(
389 self,
390 def_id: DefId,
391 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
392 self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
393 }
394
395 fn explicit_implied_predicates_of(
396 self,
397 def_id: DefId,
398 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
399 self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
400 }
401
402 fn impl_is_const(self, def_id: DefId) -> bool {
403 debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
404 self.is_conditionally_const(def_id)
405 }
406
407 fn fn_is_const(self, def_id: DefId) -> bool {
408 debug_assert_matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
409 self.is_conditionally_const(def_id)
410 }
411
412 fn alias_has_const_conditions(self, def_id: DefId) -> bool {
413 debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
414 self.is_conditionally_const(def_id)
415 }
416
417 fn const_conditions(
418 self,
419 def_id: DefId,
420 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
421 ty::EarlyBinder::bind(
422 self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
423 )
424 }
425
426 fn explicit_implied_const_bounds(
427 self,
428 def_id: DefId,
429 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
430 ty::EarlyBinder::bind(
431 self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
432 )
433 }
434
435 fn has_target_features(self, def_id: DefId) -> bool {
436 !self.codegen_fn_attrs(def_id).target_features.is_empty()
437 }
438
439 fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
440 self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None)
441 }
442
443 fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
444 self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
445 }
446
447 fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
448 lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
449 }
450
451 fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
452 self.associated_items(def_id)
453 .in_definition_order()
454 .filter(|assoc_item| matches!(assoc_item.kind, ty::AssocKind::Type))
455 .map(|assoc_item| assoc_item.def_id)
456 }
457
458 fn for_each_relevant_impl(
462 self,
463 trait_def_id: DefId,
464 self_ty: Ty<'tcx>,
465 mut f: impl FnMut(DefId),
466 ) {
467 let tcx = self;
468 let trait_impls = tcx.trait_impls_of(trait_def_id);
469 let mut consider_impls_for_simplified_type = |simp| {
470 if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
471 for &impl_def_id in impls_for_type {
472 f(impl_def_id);
473 }
474 }
475 };
476
477 match self_ty.kind() {
478 ty::Bool
479 | ty::Char
480 | ty::Int(_)
481 | ty::Uint(_)
482 | ty::Float(_)
483 | ty::Adt(_, _)
484 | ty::Foreign(_)
485 | ty::Str
486 | ty::Array(_, _)
487 | ty::Pat(_, _)
488 | ty::Slice(_)
489 | ty::RawPtr(_, _)
490 | ty::Ref(_, _, _)
491 | ty::FnDef(_, _)
492 | ty::FnPtr(..)
493 | ty::Dynamic(_, _, _)
494 | ty::Closure(..)
495 | ty::CoroutineClosure(..)
496 | ty::Coroutine(_, _)
497 | ty::Never
498 | ty::Tuple(_)
499 | ty::UnsafeBinder(_) => {
500 let simp = ty::fast_reject::simplify_type(
501 tcx,
502 self_ty,
503 ty::fast_reject::TreatParams::AsRigid,
504 )
505 .unwrap();
506 consider_impls_for_simplified_type(simp);
507 }
508
509 ty::Infer(ty::IntVar(_)) => {
512 use ty::IntTy::*;
513 use ty::UintTy::*;
514 let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
516 let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
517 let possible_integers = [
518 ty::SimplifiedType::Int(I8),
520 ty::SimplifiedType::Int(I16),
521 ty::SimplifiedType::Int(I32),
522 ty::SimplifiedType::Int(I64),
523 ty::SimplifiedType::Int(I128),
524 ty::SimplifiedType::Int(Isize),
525 ty::SimplifiedType::Uint(U8),
527 ty::SimplifiedType::Uint(U16),
528 ty::SimplifiedType::Uint(U32),
529 ty::SimplifiedType::Uint(U64),
530 ty::SimplifiedType::Uint(U128),
531 ty::SimplifiedType::Uint(Usize),
532 ];
533 for simp in possible_integers {
534 consider_impls_for_simplified_type(simp);
535 }
536 }
537
538 ty::Infer(ty::FloatVar(_)) => {
539 let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
541 let possible_floats = [
542 ty::SimplifiedType::Float(ty::FloatTy::F16),
543 ty::SimplifiedType::Float(ty::FloatTy::F32),
544 ty::SimplifiedType::Float(ty::FloatTy::F64),
545 ty::SimplifiedType::Float(ty::FloatTy::F128),
546 ];
547
548 for simp in possible_floats {
549 consider_impls_for_simplified_type(simp);
550 }
551 }
552
553 ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
558
559 ty::CoroutineWitness(..) => (),
563
564 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
566 | ty::Param(_)
567 | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
568 }
569
570 let trait_impls = tcx.trait_impls_of(trait_def_id);
571 for &impl_def_id in trait_impls.blanket_impls() {
572 f(impl_def_id);
573 }
574 }
575
576 fn has_item_definition(self, def_id: DefId) -> bool {
577 self.defaultness(def_id).has_value()
578 }
579
580 fn impl_is_default(self, impl_def_id: DefId) -> bool {
581 self.defaultness(impl_def_id).is_default()
582 }
583
584 fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
585 self.impl_trait_ref(impl_def_id).unwrap()
586 }
587
588 fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
589 self.impl_polarity(impl_def_id)
590 }
591
592 fn trait_is_auto(self, trait_def_id: DefId) -> bool {
593 self.trait_is_auto(trait_def_id)
594 }
595
596 fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
597 self.trait_is_coinductive(trait_def_id)
598 }
599
600 fn trait_is_alias(self, trait_def_id: DefId) -> bool {
601 self.trait_is_alias(trait_def_id)
602 }
603
604 fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
605 self.is_dyn_compatible(trait_def_id)
606 }
607
608 fn trait_is_fundamental(self, def_id: DefId) -> bool {
609 self.trait_def(def_id).is_fundamental
610 }
611
612 fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
613 self.trait_def(trait_def_id).implement_via_object
614 }
615
616 fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
617 self.trait_def(trait_def_id).safety.is_unsafe()
618 }
619
620 fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
621 self.is_impl_trait_in_trait(def_id)
622 }
623
624 fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
625 self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
626 }
627
628 fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
629 self.is_general_coroutine(coroutine_def_id)
630 }
631
632 fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
633 self.coroutine_is_async(coroutine_def_id)
634 }
635
636 fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
637 self.coroutine_is_gen(coroutine_def_id)
638 }
639
640 fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
641 self.coroutine_is_async_gen(coroutine_def_id)
642 }
643
644 type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
645 fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
646 self.unsizing_params_for_adt(adt_def_id)
647 }
648
649 fn find_const_ty_from_env(
650 self,
651 param_env: ty::ParamEnv<'tcx>,
652 placeholder: Self::PlaceholderConst,
653 ) -> Ty<'tcx> {
654 placeholder.find_const_ty_from_env(param_env)
655 }
656
657 fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
658 self,
659 binder: ty::Binder<'tcx, T>,
660 ) -> ty::Binder<'tcx, T> {
661 self.anonymize_bound_vars(binder)
662 }
663
664 fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::DefiningOpaqueTypes {
665 self.opaque_types_defined_by(defining_anchor)
666 }
667}
668
669macro_rules! bidirectional_lang_item_map {
670 ($($name:ident),+ $(,)?) => {
671 fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
672 match lang_item {
673 $(TraitSolverLangItem::$name => LangItem::$name,)+
674 }
675 }
676
677 fn lang_item_to_trait_lang_item(lang_item: LangItem) -> Option<TraitSolverLangItem> {
678 Some(match lang_item {
679 $(LangItem::$name => TraitSolverLangItem::$name,)+
680 _ => return None,
681 })
682 }
683 }
684}
685
686bidirectional_lang_item_map! {
687AsyncDestruct,
689 AsyncFn,
690 AsyncFnKindHelper,
691 AsyncFnKindUpvars,
692 AsyncFnMut,
693 AsyncFnOnce,
694 AsyncFnOnceOutput,
695 AsyncIterator,
696 BikeshedGuaranteedNoDrop,
697 CallOnceFuture,
698 CallRefFuture,
699 Clone,
700 Copy,
701 Coroutine,
702 CoroutineReturn,
703 CoroutineYield,
704 Destruct,
705 DiscriminantKind,
706 Drop,
707 DynMetadata,
708 Fn,
709 FnMut,
710 FnOnce,
711 FnPtrTrait,
712 FusedIterator,
713 Future,
714 FutureOutput,
715 Iterator,
716 Metadata,
717 Option,
718 PointeeTrait,
719 Poll,
720 Sized,
721 TransmuteTrait,
722 Tuple,
723 Unpin,
724 Unsize,
725}
727
728impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
729 fn is_local(self) -> bool {
730 self.is_local()
731 }
732
733 fn as_local(self) -> Option<LocalDefId> {
734 self.as_local()
735 }
736}
737
738impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
739 fn rust() -> Self {
740 ExternAbi::Rust
741 }
742
743 fn is_rust(self) -> bool {
744 matches!(self, ExternAbi::Rust)
745 }
746}
747
748impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
749 fn safe() -> Self {
750 hir::Safety::Safe
751 }
752
753 fn is_safe(self) -> bool {
754 self.is_safe()
755 }
756
757 fn prefix_str(self) -> &'static str {
758 self.prefix_str()
759 }
760}
761
762impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
763 fn generic_const_exprs(self) -> bool {
764 self.generic_const_exprs()
765 }
766
767 fn coroutine_clone(self) -> bool {
768 self.coroutine_clone()
769 }
770
771 fn associated_const_equality(self) -> bool {
772 self.associated_const_equality()
773 }
774}
775
776impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
777 fn dummy() -> Self {
778 DUMMY_SP
779 }
780}
781
782type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
783
784pub struct CtxtInterners<'tcx> {
785 arena: &'tcx WorkerLocal<Arena<'tcx>>,
787
788 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
791 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
792 args: InternedSet<'tcx, GenericArgs<'tcx>>,
793 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
794 canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
795 region: InternedSet<'tcx, RegionKind<'tcx>>,
796 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
797 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
798 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
799 projs: InternedSet<'tcx, List<ProjectionKind>>,
800 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
801 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
802 pat: InternedSet<'tcx, PatternKind<'tcx>>,
803 const_allocation: InternedSet<'tcx, Allocation>,
804 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
805 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
806 adt_def: InternedSet<'tcx, AdtDefData>,
807 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
808 predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
809 fields: InternedSet<'tcx, List<FieldIdx>>,
810 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
811 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
812 offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
813 valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
814}
815
816impl<'tcx> CtxtInterners<'tcx> {
817 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
818 const N: usize = 2048;
821 CtxtInterners {
822 arena,
823 type_: InternedSet::with_capacity(N * 16),
827 const_lists: InternedSet::with_capacity(N * 4),
828 args: InternedSet::with_capacity(N * 4),
829 type_lists: InternedSet::with_capacity(N * 4),
830 region: InternedSet::with_capacity(N * 4),
831 poly_existential_predicates: InternedSet::with_capacity(N / 4),
832 canonical_var_infos: InternedSet::with_capacity(N / 2),
833 predicate: InternedSet::with_capacity(N),
834 clauses: InternedSet::with_capacity(N),
835 projs: InternedSet::with_capacity(N * 4),
836 place_elems: InternedSet::with_capacity(N * 2),
837 const_: InternedSet::with_capacity(N * 2),
838 pat: InternedSet::with_capacity(N),
839 const_allocation: InternedSet::with_capacity(N),
840 bound_variable_kinds: InternedSet::with_capacity(N * 2),
841 layout: InternedSet::with_capacity(N),
842 adt_def: InternedSet::with_capacity(N),
843 external_constraints: InternedSet::with_capacity(N),
844 predefined_opaques_in_body: InternedSet::with_capacity(N),
845 fields: InternedSet::with_capacity(N * 4),
846 local_def_ids: InternedSet::with_capacity(N),
847 captures: InternedSet::with_capacity(N),
848 offset_of: InternedSet::with_capacity(N),
849 valtree: InternedSet::with_capacity(N),
850 }
851 }
852
853 #[allow(rustc::usage_of_ty_tykind)]
855 #[inline(never)]
856 fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
857 Ty(Interned::new_unchecked(
858 self.type_
859 .intern(kind, |kind| {
860 let flags = super::flags::FlagComputation::for_kind(&kind);
861 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
862
863 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
864 internee: kind,
865 stable_hash,
866 flags: flags.flags,
867 outer_exclusive_binder: flags.outer_exclusive_binder,
868 }))
869 })
870 .0,
871 ))
872 }
873
874 #[allow(rustc::usage_of_ty_tykind)]
876 #[inline(never)]
877 fn intern_const(
878 &self,
879 kind: ty::ConstKind<'tcx>,
880 sess: &Session,
881 untracked: &Untracked,
882 ) -> Const<'tcx> {
883 Const(Interned::new_unchecked(
884 self.const_
885 .intern(kind, |kind: ty::ConstKind<'_>| {
886 let flags = super::flags::FlagComputation::for_const_kind(&kind);
887 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
888
889 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
890 internee: kind,
891 stable_hash,
892 flags: flags.flags,
893 outer_exclusive_binder: flags.outer_exclusive_binder,
894 }))
895 })
896 .0,
897 ))
898 }
899
900 fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
901 &self,
902 flags: &ty::flags::FlagComputation,
903 sess: &'a Session,
904 untracked: &'a Untracked,
905 val: &T,
906 ) -> Fingerprint {
907 if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
910 Fingerprint::ZERO
911 } else {
912 let mut hasher = StableHasher::new();
913 let mut hcx = StableHashingContext::new(sess, untracked);
914 val.hash_stable(&mut hcx, &mut hasher);
915 hasher.finish()
916 }
917 }
918
919 #[inline(never)]
921 fn intern_predicate(
922 &self,
923 kind: Binder<'tcx, PredicateKind<'tcx>>,
924 sess: &Session,
925 untracked: &Untracked,
926 ) -> Predicate<'tcx> {
927 Predicate(Interned::new_unchecked(
928 self.predicate
929 .intern(kind, |kind| {
930 let flags = super::flags::FlagComputation::for_predicate(kind);
931
932 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
933
934 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
935 internee: kind,
936 stable_hash,
937 flags: flags.flags,
938 outer_exclusive_binder: flags.outer_exclusive_binder,
939 }))
940 })
941 .0,
942 ))
943 }
944
945 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
946 if clauses.is_empty() {
947 ListWithCachedTypeInfo::empty()
948 } else {
949 self.clauses
950 .intern_ref(clauses, || {
951 let flags = super::flags::FlagComputation::for_clauses(clauses);
952
953 InternedInSet(ListWithCachedTypeInfo::from_arena(
954 &*self.arena,
955 flags.into(),
956 clauses,
957 ))
958 })
959 .0
960 }
961 }
962}
963
964const NUM_PREINTERNED_TY_VARS: u32 = 100;
969const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
970const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
971const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
972
973const NUM_PREINTERNED_RE_VARS: u32 = 500;
975const NUM_PREINTERNED_RE_LATE_BOUNDS_I: u32 = 2;
976const NUM_PREINTERNED_RE_LATE_BOUNDS_V: u32 = 20;
977
978pub struct CommonTypes<'tcx> {
979 pub unit: Ty<'tcx>,
980 pub bool: Ty<'tcx>,
981 pub char: Ty<'tcx>,
982 pub isize: Ty<'tcx>,
983 pub i8: Ty<'tcx>,
984 pub i16: Ty<'tcx>,
985 pub i32: Ty<'tcx>,
986 pub i64: Ty<'tcx>,
987 pub i128: Ty<'tcx>,
988 pub usize: Ty<'tcx>,
989 pub u8: Ty<'tcx>,
990 pub u16: Ty<'tcx>,
991 pub u32: Ty<'tcx>,
992 pub u64: Ty<'tcx>,
993 pub u128: Ty<'tcx>,
994 pub f16: Ty<'tcx>,
995 pub f32: Ty<'tcx>,
996 pub f64: Ty<'tcx>,
997 pub f128: Ty<'tcx>,
998 pub str_: Ty<'tcx>,
999 pub never: Ty<'tcx>,
1000 pub self_param: Ty<'tcx>,
1001
1002 pub trait_object_dummy_self: Ty<'tcx>,
1007
1008 pub ty_vars: Vec<Ty<'tcx>>,
1010
1011 pub fresh_tys: Vec<Ty<'tcx>>,
1013
1014 pub fresh_int_tys: Vec<Ty<'tcx>>,
1016
1017 pub fresh_float_tys: Vec<Ty<'tcx>>,
1019}
1020
1021pub struct CommonLifetimes<'tcx> {
1022 pub re_static: Region<'tcx>,
1024
1025 pub re_erased: Region<'tcx>,
1027
1028 pub re_vars: Vec<Region<'tcx>>,
1030
1031 pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
1035}
1036
1037pub struct CommonConsts<'tcx> {
1038 pub unit: Const<'tcx>,
1039 pub true_: Const<'tcx>,
1040 pub false_: Const<'tcx>,
1041 pub(crate) valtree_zst: ValTree<'tcx>,
1043}
1044
1045impl<'tcx> CommonTypes<'tcx> {
1046 fn new(
1047 interners: &CtxtInterners<'tcx>,
1048 sess: &Session,
1049 untracked: &Untracked,
1050 ) -> CommonTypes<'tcx> {
1051 let mk = |ty| interners.intern_ty(ty, sess, untracked);
1052
1053 let ty_vars =
1054 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1055 let fresh_tys: Vec<_> =
1056 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1057 let fresh_int_tys: Vec<_> =
1058 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1059 let fresh_float_tys: Vec<_> =
1060 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1061
1062 CommonTypes {
1063 unit: mk(Tuple(List::empty())),
1064 bool: mk(Bool),
1065 char: mk(Char),
1066 never: mk(Never),
1067 isize: mk(Int(ty::IntTy::Isize)),
1068 i8: mk(Int(ty::IntTy::I8)),
1069 i16: mk(Int(ty::IntTy::I16)),
1070 i32: mk(Int(ty::IntTy::I32)),
1071 i64: mk(Int(ty::IntTy::I64)),
1072 i128: mk(Int(ty::IntTy::I128)),
1073 usize: mk(Uint(ty::UintTy::Usize)),
1074 u8: mk(Uint(ty::UintTy::U8)),
1075 u16: mk(Uint(ty::UintTy::U16)),
1076 u32: mk(Uint(ty::UintTy::U32)),
1077 u64: mk(Uint(ty::UintTy::U64)),
1078 u128: mk(Uint(ty::UintTy::U128)),
1079 f16: mk(Float(ty::FloatTy::F16)),
1080 f32: mk(Float(ty::FloatTy::F32)),
1081 f64: mk(Float(ty::FloatTy::F64)),
1082 f128: mk(Float(ty::FloatTy::F128)),
1083 str_: mk(Str),
1084 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1085
1086 trait_object_dummy_self: fresh_tys[0],
1087
1088 ty_vars,
1089 fresh_tys,
1090 fresh_int_tys,
1091 fresh_float_tys,
1092 }
1093 }
1094}
1095
1096impl<'tcx> CommonLifetimes<'tcx> {
1097 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1098 let mk = |r| {
1099 Region(Interned::new_unchecked(
1100 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1101 ))
1102 };
1103
1104 let re_vars =
1105 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1106
1107 let re_late_bounds = (0..NUM_PREINTERNED_RE_LATE_BOUNDS_I)
1108 .map(|i| {
1109 (0..NUM_PREINTERNED_RE_LATE_BOUNDS_V)
1110 .map(|v| {
1111 mk(ty::ReBound(
1112 ty::DebruijnIndex::from(i),
1113 ty::BoundRegion {
1114 var: ty::BoundVar::from(v),
1115 kind: ty::BoundRegionKind::Anon,
1116 },
1117 ))
1118 })
1119 .collect()
1120 })
1121 .collect();
1122
1123 CommonLifetimes {
1124 re_static: mk(ty::ReStatic),
1125 re_erased: mk(ty::ReErased),
1126 re_vars,
1127 re_late_bounds,
1128 }
1129 }
1130}
1131
1132impl<'tcx> CommonConsts<'tcx> {
1133 fn new(
1134 interners: &CtxtInterners<'tcx>,
1135 types: &CommonTypes<'tcx>,
1136 sess: &Session,
1137 untracked: &Untracked,
1138 ) -> CommonConsts<'tcx> {
1139 let mk_const = |c| {
1140 interners.intern_const(
1141 c, sess, untracked,
1143 )
1144 };
1145
1146 let mk_valtree = |v| {
1147 ty::ValTree(Interned::new_unchecked(
1148 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1149 ))
1150 };
1151
1152 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1153 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1154 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1155
1156 CommonConsts {
1157 unit: mk_const(ty::ConstKind::Value(ty::Value {
1158 ty: types.unit,
1159 valtree: valtree_zst,
1160 })),
1161 true_: mk_const(ty::ConstKind::Value(ty::Value {
1162 ty: types.bool,
1163 valtree: valtree_true,
1164 })),
1165 false_: mk_const(ty::ConstKind::Value(ty::Value {
1166 ty: types.bool,
1167 valtree: valtree_false,
1168 })),
1169 valtree_zst,
1170 }
1171 }
1172}
1173
1174#[derive(Debug)]
1177pub struct FreeRegionInfo {
1178 pub scope: LocalDefId,
1180 pub region_def_id: DefId,
1182 pub is_impl_item: bool,
1184}
1185
1186#[derive(Copy, Clone)]
1188pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1189 pub tcx: TyCtxt<'tcx>,
1190 key: KEY,
1192}
1193
1194impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1197
1198#[derive(Copy, Clone)]
1203pub struct Feed<'tcx, KEY: Copy> {
1204 _tcx: PhantomData<TyCtxt<'tcx>>,
1205 key: KEY,
1207}
1208
1209impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1212
1213impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1214 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1215 self.key.fmt(f)
1216 }
1217}
1218
1219impl<'tcx> TyCtxt<'tcx> {
1224 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1227 self.dep_graph.assert_ignored();
1228 TyCtxtFeed { tcx: self, key: () }
1229 }
1230
1231 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1234 let key = self.untracked().source_span.push(span);
1235 assert_eq!(key, CRATE_DEF_ID);
1236 TyCtxtFeed { tcx: self, key }
1237 }
1238
1239 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1243 debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1244 TyCtxtFeed { tcx: self, key }.type_of(value)
1245 }
1246}
1247
1248impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1249 #[inline(always)]
1250 pub fn key(&self) -> KEY {
1251 self.key
1252 }
1253
1254 #[inline(always)]
1255 pub fn downgrade(self) -> Feed<'tcx, KEY> {
1256 Feed { _tcx: PhantomData, key: self.key }
1257 }
1258}
1259
1260impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1261 #[inline(always)]
1262 pub fn key(&self) -> KEY {
1263 self.key
1264 }
1265
1266 #[inline(always)]
1267 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1268 TyCtxtFeed { tcx, key: self.key }
1269 }
1270}
1271
1272impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1273 #[inline(always)]
1274 pub fn def_id(&self) -> LocalDefId {
1275 self.key
1276 }
1277
1278 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1280 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1281 }
1282
1283 pub fn feed_hir(&self) {
1285 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1286
1287 let node = hir::OwnerNode::Synthetic;
1288 let bodies = Default::default();
1289 let attrs = hir::AttributeMap::EMPTY;
1290
1291 let (opt_hash_including_bodies, _) =
1292 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque);
1293 let node = node.into();
1294 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1295 opt_hash_including_bodies,
1296 nodes: IndexVec::from_elem_n(
1297 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1298 1,
1299 ),
1300 bodies,
1301 })));
1302 self.feed_owner_id().hir_attr_map(attrs);
1303 }
1304}
1305
1306#[derive(Copy, Clone)]
1324#[rustc_diagnostic_item = "TyCtxt"]
1325#[rustc_pass_by_value]
1326pub struct TyCtxt<'tcx> {
1327 gcx: &'tcx GlobalCtxt<'tcx>,
1328}
1329
1330unsafe impl DynSend for TyCtxt<'_> {}
1334unsafe impl DynSync for TyCtxt<'_> {}
1335fn _assert_tcx_fields() {
1336 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1337 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1338}
1339
1340impl<'tcx> Deref for TyCtxt<'tcx> {
1341 type Target = &'tcx GlobalCtxt<'tcx>;
1342 #[inline(always)]
1343 fn deref(&self) -> &Self::Target {
1344 &self.gcx
1345 }
1346}
1347
1348pub struct GlobalCtxt<'tcx> {
1350 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1351 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1352
1353 interners: CtxtInterners<'tcx>,
1354
1355 pub sess: &'tcx Session,
1356 crate_types: Vec<CrateType>,
1357 stable_crate_id: StableCrateId,
1363
1364 pub dep_graph: DepGraph,
1365
1366 pub prof: SelfProfilerRef,
1367
1368 pub types: CommonTypes<'tcx>,
1370
1371 pub lifetimes: CommonLifetimes<'tcx>,
1373
1374 pub consts: CommonConsts<'tcx>,
1376
1377 pub(crate) hooks: crate::hooks::Providers,
1380
1381 untracked: Untracked,
1382
1383 pub query_system: QuerySystem<'tcx>,
1384 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1385
1386 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1388
1389 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1392
1393 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1397
1398 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1400
1401 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1402
1403 pub data_layout: TargetDataLayout,
1405
1406 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1408
1409 current_gcx: CurrentGcx,
1410}
1411
1412impl<'tcx> GlobalCtxt<'tcx> {
1413 pub fn enter<F, R>(&'tcx self, f: F) -> R
1416 where
1417 F: FnOnce(TyCtxt<'tcx>) -> R,
1418 {
1419 let icx = tls::ImplicitCtxt::new(self);
1420
1421 let _on_drop = defer(move || {
1423 *self.current_gcx.value.write() = None;
1424 });
1425
1426 {
1428 let mut guard = self.current_gcx.value.write();
1429 assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1430 *guard = Some(self as *const _ as *const ());
1431 }
1432
1433 tls::enter_context(&icx, || f(icx.tcx))
1434 }
1435}
1436
1437#[derive(Clone)]
1444pub struct CurrentGcx {
1445 value: Arc<RwLock<Option<*const ()>>>,
1448}
1449
1450unsafe impl DynSend for CurrentGcx {}
1451unsafe impl DynSync for CurrentGcx {}
1452
1453impl CurrentGcx {
1454 pub fn new() -> Self {
1455 Self { value: Arc::new(RwLock::new(None)) }
1456 }
1457
1458 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1459 let read_guard = self.value.read();
1460 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1461 f(unsafe { &*gcx })
1465 }
1466}
1467
1468impl<'tcx> TyCtxt<'tcx> {
1469 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1470 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1473 if typeck_root_def_id != def_id.to_def_id() {
1474 return self.has_typeck_results(typeck_root_def_id.expect_local());
1475 }
1476
1477 self.hir_node_by_def_id(def_id).body_id().is_some()
1478 }
1479
1480 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1485 let def_kind = self.def_kind(def_id);
1486 if def_kind.has_codegen_attrs() {
1487 self.codegen_fn_attrs(def_id)
1488 } else if matches!(
1489 def_kind,
1490 DefKind::AnonConst
1491 | DefKind::AssocConst
1492 | DefKind::Const
1493 | DefKind::InlineConst
1494 | DefKind::GlobalAsm
1495 ) {
1496 CodegenFnAttrs::EMPTY
1497 } else {
1498 bug!(
1499 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1500 def_id,
1501 def_kind
1502 )
1503 }
1504 }
1505
1506 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1507 self.arena.alloc(Steal::new(thir))
1508 }
1509
1510 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1511 self.arena.alloc(Steal::new(mir))
1512 }
1513
1514 pub fn alloc_steal_promoted(
1515 self,
1516 promoted: IndexVec<Promoted, Body<'tcx>>,
1517 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1518 self.arena.alloc(Steal::new(promoted))
1519 }
1520
1521 pub fn mk_adt_def(
1522 self,
1523 did: DefId,
1524 kind: AdtKind,
1525 variants: IndexVec<VariantIdx, ty::VariantDef>,
1526 repr: ReprOptions,
1527 ) -> ty::AdtDef<'tcx> {
1528 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1529 }
1530
1531 pub fn allocate_bytes_dedup(self, bytes: &[u8], salt: usize) -> interpret::AllocId {
1534 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
1536 let alloc = self.mk_const_alloc(alloc);
1537 self.reserve_and_set_memory_dedup(alloc, salt)
1538 }
1539
1540 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1544 let get = |name| {
1545 let Some(attr) = self.get_attr(def_id, name) else {
1546 return Bound::Unbounded;
1547 };
1548 debug!("layout_scalar_valid_range: attr={:?}", attr);
1549 if let Some(
1550 &[
1551 ast::MetaItemInner::Lit(ast::MetaItemLit {
1552 kind: ast::LitKind::Int(a, _), ..
1553 }),
1554 ],
1555 ) = attr.meta_item_list().as_deref()
1556 {
1557 Bound::Included(a.get())
1558 } else {
1559 self.dcx().span_delayed_bug(
1560 attr.span(),
1561 "invalid rustc_layout_scalar_valid_range attribute",
1562 );
1563 Bound::Unbounded
1564 }
1565 };
1566 (
1567 get(sym::rustc_layout_scalar_valid_range_start),
1568 get(sym::rustc_layout_scalar_valid_range_end),
1569 )
1570 }
1571
1572 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1573 value.lift_to_interner(self)
1574 }
1575
1576 pub fn create_global_ctxt<T>(
1583 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1584 s: &'tcx Session,
1585 crate_types: Vec<CrateType>,
1586 stable_crate_id: StableCrateId,
1587 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1588 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1589 untracked: Untracked,
1590 dep_graph: DepGraph,
1591 query_kinds: &'tcx [DepKindStruct<'tcx>],
1592 query_system: QuerySystem<'tcx>,
1593 hooks: crate::hooks::Providers,
1594 current_gcx: CurrentGcx,
1595 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1596 ) -> T {
1597 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1598 s.dcx().emit_fatal(err);
1599 });
1600 let interners = CtxtInterners::new(arena);
1601 let common_types = CommonTypes::new(&interners, s, &untracked);
1602 let common_lifetimes = CommonLifetimes::new(&interners);
1603 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1604
1605 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1606 sess: s,
1607 crate_types,
1608 stable_crate_id,
1609 arena,
1610 hir_arena,
1611 interners,
1612 dep_graph,
1613 hooks,
1614 prof: s.prof.clone(),
1615 types: common_types,
1616 lifetimes: common_lifetimes,
1617 consts: common_consts,
1618 untracked,
1619 query_system,
1620 query_kinds,
1621 ty_rcache: Default::default(),
1622 selection_cache: Default::default(),
1623 evaluation_cache: Default::default(),
1624 new_solver_evaluation_cache: Default::default(),
1625 canonical_param_env_cache: Default::default(),
1626 data_layout,
1627 alloc_map: interpret::AllocMap::new(),
1628 current_gcx,
1629 });
1630
1631 gcx.enter(f)
1633 }
1634
1635 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1637 self.get_lang_items(())
1638 }
1639
1640 #[track_caller]
1642 pub fn ty_ordering_enum(self, span: Option<Span>) -> Ty<'tcx> {
1643 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1644 self.type_of(ordering_enum).no_bound_vars().unwrap()
1645 }
1646
1647 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1650 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1651 }
1652
1653 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1655 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1656 }
1657
1658 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1660 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1661 }
1662
1663 pub fn is_coroutine(self, def_id: DefId) -> bool {
1664 self.coroutine_kind(def_id).is_some()
1665 }
1666
1667 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1670 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1671 }
1672
1673 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1675 matches!(
1676 self.coroutine_kind(def_id),
1677 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1678 )
1679 }
1680
1681 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1684 matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1685 }
1686
1687 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1690 matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1691 }
1692
1693 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1695 matches!(
1696 self.coroutine_kind(def_id),
1697 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1698 )
1699 }
1700
1701 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1703 matches!(
1704 self.coroutine_kind(def_id),
1705 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1706 )
1707 }
1708
1709 pub fn stability(self) -> &'tcx stability::Index {
1710 self.stability_index(())
1711 }
1712
1713 pub fn features(self) -> &'tcx rustc_feature::Features {
1714 self.features_query(())
1715 }
1716
1717 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1718 let id = id.into_query_param();
1719 if let Some(id) = id.as_local() {
1721 self.definitions_untracked().def_key(id)
1722 } else {
1723 self.cstore_untracked().def_key(id)
1724 }
1725 }
1726
1727 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1733 if let Some(id) = id.as_local() {
1735 self.definitions_untracked().def_path(id)
1736 } else {
1737 self.cstore_untracked().def_path(id)
1738 }
1739 }
1740
1741 #[inline]
1742 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1743 if let Some(def_id) = def_id.as_local() {
1745 self.definitions_untracked().def_path_hash(def_id)
1746 } else {
1747 self.cstore_untracked().def_path_hash(def_id)
1748 }
1749 }
1750
1751 #[inline]
1752 pub fn crate_types(self) -> &'tcx [CrateType] {
1753 &self.crate_types
1754 }
1755
1756 pub fn metadata_kind(self) -> MetadataKind {
1757 self.crate_types()
1758 .iter()
1759 .map(|ty| match *ty {
1760 CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => {
1761 MetadataKind::None
1762 }
1763 CrateType::Rlib => MetadataKind::Uncompressed,
1764 CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
1765 })
1766 .max()
1767 .unwrap_or(MetadataKind::None)
1768 }
1769
1770 pub fn needs_metadata(self) -> bool {
1771 self.metadata_kind() != MetadataKind::None
1772 }
1773
1774 pub fn needs_crate_hash(self) -> bool {
1775 cfg!(debug_assertions)
1783 || self.sess.opts.incremental.is_some()
1784 || self.needs_metadata()
1785 || self.sess.instrument_coverage()
1786 }
1787
1788 #[inline]
1789 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1790 if crate_num == LOCAL_CRATE {
1791 self.stable_crate_id
1792 } else {
1793 self.cstore_untracked().stable_crate_id(crate_num)
1794 }
1795 }
1796
1797 #[inline]
1800 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1801 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1802 LOCAL_CRATE
1803 } else {
1804 *self
1805 .untracked()
1806 .stable_crate_ids
1807 .read()
1808 .get(&stable_crate_id)
1809 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1810 }
1811 }
1812
1813 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1817 debug!("def_path_hash_to_def_id({:?})", hash);
1818
1819 let stable_crate_id = hash.stable_crate_id();
1820
1821 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1824 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1825 } else {
1826 Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
1827 }
1828 }
1829
1830 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1831 let (crate_name, stable_crate_id) = if def_id.is_local() {
1836 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1837 } else {
1838 let cstore = &*self.cstore_untracked();
1839 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1840 };
1841
1842 format!(
1843 "{}[{:04x}]{}",
1844 crate_name,
1845 stable_crate_id.as_u64() >> (8 * 6),
1848 self.def_path(def_id).to_string_no_crate_verbose()
1849 )
1850 }
1851
1852 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1853 self.sess.dcx()
1854 }
1855
1856 pub fn is_target_feature_call_safe(
1857 self,
1858 callee_features: &[TargetFeature],
1859 body_features: &[TargetFeature],
1860 ) -> bool {
1861 self.sess.target.options.is_like_wasm
1866 || callee_features
1867 .iter()
1868 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1869 }
1870
1871 pub fn adjust_target_feature_sig(
1874 self,
1875 fun_def: DefId,
1876 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1877 caller: DefId,
1878 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1879 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1880 let callee_features = &self.codegen_fn_attrs(caller).target_features;
1881 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
1882 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
1883 }
1884 None
1885 }
1886}
1887
1888impl<'tcx> TyCtxtAt<'tcx> {
1889 pub fn create_def(
1891 self,
1892 parent: LocalDefId,
1893 name: Option<Symbol>,
1894 def_kind: DefKind,
1895 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1896 let feed = self.tcx.create_def(parent, name, def_kind);
1897
1898 feed.def_span(self.span);
1899 feed
1900 }
1901}
1902
1903impl<'tcx> TyCtxt<'tcx> {
1904 pub fn create_def(
1906 self,
1907 parent: LocalDefId,
1908 name: Option<Symbol>,
1909 def_kind: DefKind,
1910 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1911 let data = def_kind.def_path_data(name);
1912 let def_id = self.untracked.definitions.write().create_def(parent, data);
1927
1928 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1933
1934 let feed = TyCtxtFeed { tcx: self, key: def_id };
1935 feed.def_kind(def_kind);
1936 if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1941 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1942 feed.visibility(ty::Visibility::Restricted(parent_mod));
1943 }
1944
1945 feed
1946 }
1947
1948 pub fn create_crate_num(
1949 self,
1950 stable_crate_id: StableCrateId,
1951 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1952 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
1953 return Err(existing);
1954 }
1955
1956 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
1957 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
1958 Ok(TyCtxtFeed { key: num, tcx: self })
1959 }
1960
1961 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1962 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1965
1966 let definitions = &self.untracked.definitions;
1967 std::iter::from_coroutine(
1968 #[coroutine]
1969 || {
1970 let mut i = 0;
1971
1972 while i < { definitions.read().num_definitions() } {
1975 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1976 yield LocalDefId { local_def_index };
1977 i += 1;
1978 }
1979
1980 definitions.freeze();
1982 },
1983 )
1984 }
1985
1986 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1987 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1990
1991 self.untracked.definitions.freeze().def_path_table()
1994 }
1995
1996 pub fn def_path_hash_to_def_index_map(
1997 self,
1998 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1999 self.ensure_ok().hir_crate(());
2002 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2005 }
2006
2007 #[inline]
2010 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2011 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2012 }
2013
2014 pub fn untracked(self) -> &'tcx Untracked {
2016 &self.untracked
2017 }
2018 #[inline]
2021 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2022 self.untracked.definitions.read()
2023 }
2024
2025 #[inline]
2028 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2029 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2030 }
2031
2032 #[inline(always)]
2033 pub fn with_stable_hashing_context<R>(
2034 self,
2035 f: impl FnOnce(StableHashingContext<'_>) -> R,
2036 ) -> R {
2037 f(StableHashingContext::new(self.sess, &self.untracked))
2038 }
2039
2040 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2041 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2042 }
2043
2044 #[inline]
2045 pub fn local_crate_exports_generics(self) -> bool {
2046 self.crate_types().iter().any(|crate_type| {
2047 match crate_type {
2048 CrateType::Executable
2049 | CrateType::Staticlib
2050 | CrateType::ProcMacro
2051 | CrateType::Cdylib => false,
2052
2053 CrateType::Dylib => true,
2058
2059 CrateType::Rlib => true,
2060 }
2061 })
2062 }
2063
2064 pub fn is_suitable_region(
2066 self,
2067 generic_param_scope: LocalDefId,
2068 mut region: Region<'tcx>,
2069 ) -> Option<FreeRegionInfo> {
2070 let (suitable_region_binding_scope, region_def_id) = loop {
2071 let def_id =
2072 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2073 let scope = self.local_parent(def_id);
2074 if self.def_kind(scope) == DefKind::OpaqueTy {
2075 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2078 continue;
2079 }
2080 break (scope, def_id.into());
2081 };
2082
2083 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2084 Node::Item(..) | Node::TraitItem(..) => false,
2085 Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2086 _ => false,
2087 };
2088
2089 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2090 }
2091
2092 pub fn return_type_impl_or_dyn_traits(
2094 self,
2095 scope_def_id: LocalDefId,
2096 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2097 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2098 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2099 self.hir_fn_decl_by_hir_id(hir_id)
2100 else {
2101 return vec![];
2102 };
2103
2104 let mut v = TraitObjectVisitor(vec![], self.hir());
2105 v.visit_ty_unambig(hir_output);
2106 v.0
2107 }
2108
2109 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2113 self,
2114 scope_def_id: LocalDefId,
2115 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2116 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2117 let mut v = TraitObjectVisitor(vec![], self.hir());
2118 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2120 && let hir::TyKind::Path(hir::QPath::Resolved(
2121 None,
2122 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2123 && let Some(local_id) = def_id.as_local()
2124 && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics()
2126 {
2127 v.visit_ty_unambig(alias_ty);
2128 if !v.0.is_empty() {
2129 return Some((
2130 v.0,
2131 alias_generics.span,
2132 alias_generics.span_for_lifetime_suggestion(),
2133 ));
2134 }
2135 }
2136 None
2137 }
2138
2139 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2141 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2142 if self.impl_trait_ref(container_id).is_some() {
2143 return true;
2150 }
2151 false
2152 }
2153
2154 pub fn has_strict_asm_symbol_naming(self) -> bool {
2157 self.sess.target.arch.contains("nvptx")
2158 }
2159
2160 pub fn caller_location_ty(self) -> Ty<'tcx> {
2162 Ty::new_imm_ref(
2163 self,
2164 self.lifetimes.re_static,
2165 self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
2166 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2167 )
2168 }
2169
2170 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2172 let kind = self.def_kind(def_id);
2173 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2174 }
2175
2176 pub fn type_length_limit(self) -> Limit {
2177 self.limits(()).type_length_limit
2178 }
2179
2180 pub fn recursion_limit(self) -> Limit {
2181 self.limits(()).recursion_limit
2182 }
2183
2184 pub fn move_size_limit(self) -> Limit {
2185 self.limits(()).move_size_limit
2186 }
2187
2188 pub fn pattern_complexity_limit(self) -> Limit {
2189 self.limits(()).pattern_complexity_limit
2190 }
2191
2192 pub fn all_traits(self) -> impl Iterator<Item = DefId> {
2194 iter::once(LOCAL_CRATE)
2195 .chain(self.crates(()).iter().copied())
2196 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2197 }
2198
2199 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2201 let visible_crates =
2202 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2203
2204 iter::once(LOCAL_CRATE)
2205 .chain(visible_crates)
2206 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2207 }
2208
2209 #[inline]
2210 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2211 self.visibility(def_id).expect_local()
2212 }
2213
2214 #[instrument(skip(self), level = "trace", ret)]
2216 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2217 self.hir_expect_opaque_ty(def_id).origin
2218 }
2219
2220 pub fn finish(self) {
2221 self.alloc_self_profile_query_strings();
2224
2225 self.save_dep_graph();
2226 self.query_key_hash_verify_all();
2227
2228 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2229 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2230 }
2231 }
2232}
2233
2234macro_rules! nop_lift {
2235 ($set:ident; $ty:ty => $lifted:ty) => {
2236 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2237 type Lifted = $lifted;
2238 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2239 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2244 _x: Interned<'tcx, Inner>,
2245 ) -> InternedSet<'tcx, Inner> {
2246 unreachable!()
2247 }
2248 fn _type_eq<T>(_x: &T, _y: &T) {}
2249 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2250 let interner = _intern_set_ty_from_interned_ty(x.0);
2254 _type_eq(&interner, &tcx.interners.$set);
2256 }
2257
2258 tcx.interners
2259 .$set
2260 .contains_pointer_to(&InternedInSet(&*self.0.0))
2261 .then(|| unsafe { mem::transmute(self) })
2264 }
2265 }
2266 };
2267}
2268
2269macro_rules! nop_list_lift {
2270 ($set:ident; $ty:ty => $lifted:ty) => {
2271 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2272 type Lifted = &'tcx List<$lifted>;
2273 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2274 if false {
2276 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2277 }
2278
2279 if self.is_empty() {
2280 return Some(List::empty());
2281 }
2282 tcx.interners
2283 .$set
2284 .contains_pointer_to(&InternedInSet(self))
2285 .then(|| unsafe { mem::transmute(self) })
2286 }
2287 }
2288 };
2289}
2290
2291nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2292nop_lift! { region; Region<'a> => Region<'tcx> }
2293nop_lift! { const_; Const<'a> => Const<'tcx> }
2294nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2295nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2296nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2297nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2298nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2299nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2300
2301nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2302nop_list_lift! {
2303 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2304}
2305nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2306
2307nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2309
2310macro_rules! sty_debug_print {
2311 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2312 #[allow(non_snake_case)]
2315 mod inner {
2316 use crate::ty::{self, TyCtxt};
2317 use crate::ty::context::InternedInSet;
2318
2319 #[derive(Copy, Clone)]
2320 struct DebugStat {
2321 total: usize,
2322 lt_infer: usize,
2323 ty_infer: usize,
2324 ct_infer: usize,
2325 all_infer: usize,
2326 }
2327
2328 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2329 let mut total = DebugStat {
2330 total: 0,
2331 lt_infer: 0,
2332 ty_infer: 0,
2333 ct_infer: 0,
2334 all_infer: 0,
2335 };
2336 $(let mut $variant = total;)*
2337
2338 for shard in tcx.interners.type_.lock_shards() {
2339 let types = shard.iter();
2340 for &(InternedInSet(t), ()) in types {
2341 let variant = match t.internee {
2342 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2343 ty::Float(..) | ty::Str | ty::Never => continue,
2344 ty::Error(_) => continue,
2345 $(ty::$variant(..) => &mut $variant,)*
2346 };
2347 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2348 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2349 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2350
2351 variant.total += 1;
2352 total.total += 1;
2353 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2354 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2355 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2356 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2357 }
2358 }
2359 writeln!(fmt, "Ty interner total ty lt ct all")?;
2360 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2361 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2362 stringify!($variant),
2363 uses = $variant.total,
2364 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2365 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2366 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2367 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2368 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2369 )*
2370 writeln!(fmt, " total {uses:6} \
2371 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2372 uses = total.total,
2373 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2374 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2375 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2376 all = total.all_infer as f64 * 100.0 / total.total as f64)
2377 }
2378 }
2379
2380 inner::go($fmt, $ctxt)
2381 }}
2382}
2383
2384impl<'tcx> TyCtxt<'tcx> {
2385 pub fn debug_stats(self) -> impl fmt::Debug {
2386 fmt::from_fn(move |fmt| {
2387 sty_debug_print!(
2388 fmt,
2389 self,
2390 Adt,
2391 Array,
2392 Slice,
2393 RawPtr,
2394 Ref,
2395 FnDef,
2396 FnPtr,
2397 UnsafeBinder,
2398 Placeholder,
2399 Coroutine,
2400 CoroutineWitness,
2401 Dynamic,
2402 Closure,
2403 CoroutineClosure,
2404 Tuple,
2405 Bound,
2406 Param,
2407 Infer,
2408 Alias,
2409 Pat,
2410 Foreign
2411 )?;
2412
2413 writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2414 writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2415 writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2416 writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2417
2418 Ok(())
2419 })
2420 }
2421}
2422
2423struct InternedInSet<'tcx, T: ?Sized>(&'tcx T);
2428
2429impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> {
2430 fn clone(&self) -> Self {
2431 InternedInSet(self.0)
2432 }
2433}
2434
2435impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {}
2436
2437impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
2438 fn into_pointer(&self) -> *const () {
2439 self.0 as *const _ as *const ()
2440 }
2441}
2442
2443#[allow(rustc::usage_of_ty_tykind)]
2444impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2445 fn borrow(&self) -> &T {
2446 &self.0.internee
2447 }
2448}
2449
2450impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2451 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2452 self.0.internee == other.0.internee
2455 }
2456}
2457
2458impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2459
2460impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2461 fn hash<H: Hasher>(&self, s: &mut H) {
2462 self.0.internee.hash(s)
2464 }
2465}
2466
2467impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2468 fn borrow(&self) -> &[T] {
2469 &self.0[..]
2470 }
2471}
2472
2473impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2474 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2475 self.0[..] == other.0[..]
2478 }
2479}
2480
2481impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2482
2483impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2484 fn hash<H: Hasher>(&self, s: &mut H) {
2485 self.0[..].hash(s)
2487 }
2488}
2489
2490impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2491 fn borrow(&self) -> &[T] {
2492 &self.0[..]
2493 }
2494}
2495
2496impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2497 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2498 self.0[..] == other.0[..]
2501 }
2502}
2503
2504impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2505
2506impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2507 fn hash<H: Hasher>(&self, s: &mut H) {
2508 self.0[..].hash(s)
2510 }
2511}
2512
2513macro_rules! direct_interners {
2514 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2515 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2516 fn borrow<'a>(&'a self) -> &'a $ty {
2517 &self.0
2518 }
2519 }
2520
2521 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2522 fn eq(&self, other: &Self) -> bool {
2523 self.0 == other.0
2526 }
2527 }
2528
2529 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2530
2531 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2532 fn hash<H: Hasher>(&self, s: &mut H) {
2533 self.0.hash(s)
2536 }
2537 }
2538
2539 impl<'tcx> TyCtxt<'tcx> {
2540 $vis fn $method(self, v: $ty) -> $ret_ty {
2541 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2542 InternedInSet(self.interners.arena.alloc(v))
2543 }).0))
2544 }
2545 })+
2546 }
2547}
2548
2549direct_interners! {
2553 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2554 valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2555 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2556 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2557 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2558 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2559 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2560 ExternalConstraints -> ExternalConstraints<'tcx>,
2561 predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2562 PredefinedOpaques -> PredefinedOpaques<'tcx>,
2563}
2564
2565macro_rules! slice_interners {
2566 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2567 impl<'tcx> TyCtxt<'tcx> {
2568 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2569 if v.is_empty() {
2570 List::empty()
2571 } else {
2572 self.interners.$field.intern_ref(v, || {
2573 InternedInSet(List::from_arena(&*self.arena, (), v))
2574 }).0
2575 }
2576 })+
2577 }
2578 );
2579}
2580
2581slice_interners!(
2585 const_lists: pub mk_const_list(Const<'tcx>),
2586 args: pub mk_args(GenericArg<'tcx>),
2587 type_lists: pub mk_type_list(Ty<'tcx>),
2588 canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
2589 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2590 projs: pub mk_projs(ProjectionKind),
2591 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2592 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2593 fields: pub mk_fields(FieldIdx),
2594 local_def_ids: intern_local_def_ids(LocalDefId),
2595 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2596 offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2597);
2598
2599impl<'tcx> TyCtxt<'tcx> {
2600 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2604 assert!(sig.safety().is_safe());
2605 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2606 }
2607
2608 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2611 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2612 self.associated_items(trait_did)
2613 .filter_by_name_unhygienic(assoc_name.name)
2614 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2615 })
2616 }
2617
2618 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2620 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2621 let future_trait = self.require_lang_item(LangItem::Future, None);
2622
2623 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2624 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2625 return false;
2626 };
2627 trait_predicate.trait_ref.def_id == future_trait
2628 && trait_predicate.polarity == PredicatePolarity::Positive
2629 })
2630 }
2631
2632 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2640 sig.map_bound(|s| {
2641 let params = match s.inputs()[0].kind() {
2642 ty::Tuple(params) => *params,
2643 _ => bug!(),
2644 };
2645 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2646 })
2647 }
2648
2649 #[inline]
2650 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2651 self.interners.intern_predicate(
2652 binder,
2653 self.sess,
2654 &self.untracked,
2656 )
2657 }
2658
2659 #[inline]
2660 pub fn reuse_or_mk_predicate(
2661 self,
2662 pred: Predicate<'tcx>,
2663 binder: Binder<'tcx, PredicateKind<'tcx>>,
2664 ) -> Predicate<'tcx> {
2665 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2666 }
2667
2668 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2669 self.check_args_compatible_inner(def_id, args, false)
2670 }
2671
2672 fn check_args_compatible_inner(
2673 self,
2674 def_id: DefId,
2675 args: &'tcx [ty::GenericArg<'tcx>],
2676 nested: bool,
2677 ) -> bool {
2678 let generics = self.generics_of(def_id);
2679
2680 let own_args = if !nested
2683 && let DefKind::AssocTy = self.def_kind(def_id)
2684 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2685 {
2686 if generics.own_params.len() + 1 != args.len() {
2687 return false;
2688 }
2689
2690 if !matches!(args[0].unpack(), ty::GenericArgKind::Type(_)) {
2691 return false;
2692 }
2693
2694 &args[1..]
2695 } else {
2696 if generics.count() != args.len() {
2697 return false;
2698 }
2699
2700 let (parent_args, own_args) = args.split_at(generics.parent_count);
2701
2702 if let Some(parent) = generics.parent
2703 && !self.check_args_compatible_inner(parent, parent_args, true)
2704 {
2705 return false;
2706 }
2707
2708 own_args
2709 };
2710
2711 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2712 match (¶m.kind, arg.unpack()) {
2713 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2714 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2715 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2716 _ => return false,
2717 }
2718 }
2719
2720 true
2721 }
2722
2723 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2726 if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2727 if let DefKind::AssocTy = self.def_kind(def_id)
2728 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2729 {
2730 bug!(
2731 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2732 self.def_path_str(def_id),
2733 args,
2734 self.mk_args_from_iter(
2736 [self.types.self_param.into()].into_iter().chain(
2737 self.generics_of(def_id)
2738 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2739 .iter()
2740 .copied()
2741 )
2742 )
2743 );
2744 } else {
2745 bug!(
2746 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2747 self.def_path_str(def_id),
2748 args,
2749 ty::GenericArgs::identity_for_item(self, def_id)
2750 );
2751 }
2752 }
2753 }
2754
2755 #[inline(always)]
2756 pub(crate) fn check_and_mk_args(
2757 self,
2758 def_id: DefId,
2759 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2760 ) -> GenericArgsRef<'tcx> {
2761 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2762 self.debug_assert_args_compatible(def_id, args);
2763 args
2764 }
2765
2766 #[inline]
2767 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2768 self.interners.intern_const(
2769 kind,
2770 self.sess,
2771 &self.untracked,
2773 )
2774 }
2775
2776 #[allow(rustc::usage_of_ty_tykind)]
2778 #[inline]
2779 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2780 self.interners.intern_ty(
2781 st,
2782 self.sess,
2783 &self.untracked,
2785 )
2786 }
2787
2788 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2789 match param.kind {
2790 GenericParamDefKind::Lifetime => {
2791 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2792 }
2793 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2794 GenericParamDefKind::Const { .. } => {
2795 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2796 .into()
2797 }
2798 }
2799 }
2800
2801 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2802 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2803 }
2804
2805 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2806 self.mk_place_elem(place, PlaceElem::Deref)
2807 }
2808
2809 pub fn mk_place_downcast(
2810 self,
2811 place: Place<'tcx>,
2812 adt_def: AdtDef<'tcx>,
2813 variant_index: VariantIdx,
2814 ) -> Place<'tcx> {
2815 self.mk_place_elem(
2816 place,
2817 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2818 )
2819 }
2820
2821 pub fn mk_place_downcast_unnamed(
2822 self,
2823 place: Place<'tcx>,
2824 variant_index: VariantIdx,
2825 ) -> Place<'tcx> {
2826 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2827 }
2828
2829 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2830 self.mk_place_elem(place, PlaceElem::Index(index))
2831 }
2832
2833 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2837 let mut projection = place.projection.to_vec();
2838 projection.push(elem);
2839
2840 Place { local: place.local, projection: self.mk_place_elems(&projection) }
2841 }
2842
2843 pub fn mk_poly_existential_predicates(
2844 self,
2845 eps: &[PolyExistentialPredicate<'tcx>],
2846 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2847 assert!(!eps.is_empty());
2848 assert!(
2849 eps.array_windows()
2850 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2851 != Ordering::Greater)
2852 );
2853 self.intern_poly_existential_predicates(eps)
2854 }
2855
2856 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2857 self.interners.intern_clauses(clauses)
2861 }
2862
2863 pub fn mk_local_def_ids(self, clauses: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2864 self.intern_local_def_ids(clauses)
2868 }
2869
2870 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2871 where
2872 I: Iterator<Item = T>,
2873 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2874 {
2875 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2876 }
2877
2878 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2879 where
2880 I: Iterator<Item = T>,
2881 T: CollectAndApply<
2882 &'tcx ty::CapturedPlace<'tcx>,
2883 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2884 >,
2885 {
2886 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2887 }
2888
2889 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2890 where
2891 I: Iterator<Item = T>,
2892 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2893 {
2894 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2895 }
2896
2897 pub fn mk_fn_sig<I, T>(
2902 self,
2903 inputs: I,
2904 output: I::Item,
2905 c_variadic: bool,
2906 safety: hir::Safety,
2907 abi: ExternAbi,
2908 ) -> T::Output
2909 where
2910 I: IntoIterator<Item = T>,
2911 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2912 {
2913 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2914 inputs_and_output: self.mk_type_list(xs),
2915 c_variadic,
2916 safety,
2917 abi,
2918 })
2919 }
2920
2921 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2922 where
2923 I: Iterator<Item = T>,
2924 T: CollectAndApply<
2925 PolyExistentialPredicate<'tcx>,
2926 &'tcx List<PolyExistentialPredicate<'tcx>>,
2927 >,
2928 {
2929 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2930 }
2931
2932 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2933 where
2934 I: Iterator<Item = T>,
2935 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2936 {
2937 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2938 }
2939
2940 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2941 where
2942 I: Iterator<Item = T>,
2943 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2944 {
2945 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2946 }
2947
2948 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2949 where
2950 I: Iterator<Item = T>,
2951 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2952 {
2953 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2954 }
2955
2956 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2957 where
2958 I: Iterator<Item = T>,
2959 T: CollectAndApply<CanonicalVarInfo<'tcx>, &'tcx List<CanonicalVarInfo<'tcx>>>,
2960 {
2961 T::collect_and_apply(iter, |xs| self.mk_canonical_var_infos(xs))
2962 }
2963
2964 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2965 where
2966 I: Iterator<Item = T>,
2967 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2968 {
2969 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2970 }
2971
2972 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2973 where
2974 I: Iterator<Item = T>,
2975 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2976 {
2977 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2978 }
2979
2980 pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
2981 where
2982 I: Iterator<Item = T>,
2983 T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
2984 {
2985 T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
2986 }
2987
2988 pub fn mk_args_trait(
2989 self,
2990 self_ty: Ty<'tcx>,
2991 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2992 ) -> GenericArgsRef<'tcx> {
2993 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2994 }
2995
2996 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2997 where
2998 I: Iterator<Item = T>,
2999 T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3000 {
3001 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3002 }
3003
3004 #[track_caller]
3007 pub fn emit_node_span_lint(
3008 self,
3009 lint: &'static Lint,
3010 hir_id: HirId,
3011 span: impl Into<MultiSpan>,
3012 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3013 ) {
3014 let (level, src) = self.lint_level_at_node(lint, hir_id);
3015 lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
3016 decorator.decorate_lint(lint);
3017 })
3018 }
3019
3020 #[rustc_lint_diagnostics]
3024 #[track_caller]
3025 pub fn node_span_lint(
3026 self,
3027 lint: &'static Lint,
3028 hir_id: HirId,
3029 span: impl Into<MultiSpan>,
3030 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3031 ) {
3032 let (level, src) = self.lint_level_at_node(lint, hir_id);
3033 lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
3034 }
3035
3036 pub fn crate_level_attribute_injection_span(self, hir_id: HirId) -> Option<Span> {
3039 for (_hir_id, node) in self.hir_parent_iter(hir_id) {
3040 if let hir::Node::Crate(m) = node {
3041 return Some(m.spans.inject_use_span.shrink_to_lo());
3042 }
3043 }
3044 None
3045 }
3046
3047 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3048 self,
3049 diag: &mut Diag<'_, E>,
3050 hir_id: Option<HirId>,
3051 features: impl IntoIterator<Item = (String, Symbol)>,
3052 ) {
3053 if !self.sess.is_nightly_build() {
3054 return;
3055 }
3056
3057 let span = hir_id.and_then(|id| self.crate_level_attribute_injection_span(id));
3058 for (desc, feature) in features {
3059 let msg =
3061 format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3062 if let Some(span) = span {
3063 diag.span_suggestion_verbose(
3064 span,
3065 msg,
3066 format!("#![feature({feature})]\n"),
3067 Applicability::MaybeIncorrect,
3068 );
3069 } else {
3070 diag.help(msg);
3071 }
3072 }
3073 }
3074
3075 #[track_caller]
3078 pub fn emit_node_lint(
3079 self,
3080 lint: &'static Lint,
3081 id: HirId,
3082 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3083 ) {
3084 self.node_lint(lint, id, |lint| {
3085 decorator.decorate_lint(lint);
3086 })
3087 }
3088
3089 #[rustc_lint_diagnostics]
3093 #[track_caller]
3094 pub fn node_lint(
3095 self,
3096 lint: &'static Lint,
3097 id: HirId,
3098 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3099 ) {
3100 let (level, src) = self.lint_level_at_node(lint, id);
3101 lint_level(self.sess, lint, level, src, None, decorate);
3102 }
3103
3104 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3105 let map = self.in_scope_traits_map(id.owner)?;
3106 let candidates = map.get(&id.local_id)?;
3107 Some(candidates)
3108 }
3109
3110 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3111 debug!(?id, "named_region");
3112 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3113 }
3114
3115 pub fn is_late_bound(self, id: HirId) -> bool {
3116 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3117 }
3118
3119 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3120 self.mk_bound_variable_kinds(
3121 &self
3122 .late_bound_vars_map(id.owner)
3123 .get(&id.local_id)
3124 .cloned()
3125 .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3126 )
3127 }
3128
3129 pub fn map_opaque_lifetime_to_parent_lifetime(
3137 self,
3138 mut opaque_lifetime_param_def_id: LocalDefId,
3139 ) -> ty::Region<'tcx> {
3140 debug_assert!(
3141 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3142 "{opaque_lifetime_param_def_id:?} is a {}",
3143 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3144 );
3145
3146 loop {
3147 let parent = self.local_parent(opaque_lifetime_param_def_id);
3148 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3149
3150 let Some((lifetime, _)) = lifetime_mapping
3151 .iter()
3152 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3153 else {
3154 bug!("duplicated lifetime param should be present");
3155 };
3156
3157 match *lifetime {
3158 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3159 let new_parent = self.local_parent(ebv);
3160
3161 if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3164 debug_assert_eq!(self.local_parent(parent), new_parent);
3165 opaque_lifetime_param_def_id = ebv;
3166 continue;
3167 }
3168
3169 let generics = self.generics_of(new_parent);
3170 return ty::Region::new_early_param(
3171 self,
3172 ty::EarlyParamRegion {
3173 index: generics
3174 .param_def_id_to_index(self, ebv.to_def_id())
3175 .expect("early-bound var should be present in fn generics"),
3176 name: self.item_name(ebv.to_def_id()),
3177 },
3178 );
3179 }
3180 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3181 let new_parent = self.local_parent(lbv);
3182 return ty::Region::new_late_param(
3183 self,
3184 new_parent.to_def_id(),
3185 ty::LateParamRegionKind::Named(
3186 lbv.to_def_id(),
3187 self.item_name(lbv.to_def_id()),
3188 ),
3189 );
3190 }
3191 resolve_bound_vars::ResolvedArg::Error(guar) => {
3192 return ty::Region::new_error(self, guar);
3193 }
3194 _ => {
3195 return ty::Region::new_error_with_message(
3196 self,
3197 self.def_span(opaque_lifetime_param_def_id),
3198 "cannot resolve lifetime",
3199 );
3200 }
3201 }
3202 }
3203 }
3204
3205 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3210 self.is_const_fn(def_id)
3211 && match self.lookup_const_stability(def_id) {
3212 None => true, Some(stability) if stability.is_const_stable() => true,
3214 _ => false,
3215 }
3216 }
3217
3218 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3220 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3221 && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3222 }
3223
3224 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3225 match self.def_kind(def_id) {
3226 DefKind::Fn | DefKind::AssocFn => {}
3227 _ => return None,
3228 }
3229 self.intrinsic_raw(def_id)
3230 }
3231
3232 pub fn next_trait_solver_globally(self) -> bool {
3233 self.sess.opts.unstable_opts.next_solver.globally
3234 }
3235
3236 pub fn next_trait_solver_in_coherence(self) -> bool {
3237 self.sess.opts.unstable_opts.next_solver.coherence
3238 }
3239
3240 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3241 self.opt_rpitit_info(def_id).is_some()
3242 }
3243
3244 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3254 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3255 }
3256
3257 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3258 self.resolver_for_lowering_raw(()).0
3259 }
3260
3261 pub fn impl_trait_ref(
3264 self,
3265 def_id: impl IntoQueryParam<DefId>,
3266 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3267 Some(self.impl_trait_header(def_id)?.trait_ref)
3268 }
3269
3270 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3271 self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3272 }
3273
3274 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3275 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3276 self.coroutine_kind(def_id)
3277 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3278 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3279 {
3280 true
3281 } else {
3282 false
3283 }
3284 }
3285
3286 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3288 self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3289 }
3290}
3291
3292#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3301pub struct DeducedParamAttrs {
3302 pub read_only: bool,
3305}
3306
3307pub fn provide(providers: &mut Providers) {
3308 providers.maybe_unused_trait_imports =
3309 |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
3310 providers.names_imported_by_glob_use = |tcx, id| {
3311 tcx.arena.alloc(UnordSet::from(
3312 tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default(),
3313 ))
3314 };
3315
3316 providers.extern_mod_stmt_cnum =
3317 |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
3318 providers.is_panic_runtime =
3319 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3320 providers.is_compiler_builtins =
3321 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3322 providers.has_panic_handler = |tcx, LocalCrate| {
3323 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3325 };
3326 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3327}
3328
3329pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3330 attrs.iter().any(|x| x.has_name(name))
3331}