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, _) = self.tcx.hash_owner_nodes(node, &bodies, &attrs.map);
1292 let node = node.into();
1293 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1294 opt_hash_including_bodies,
1295 nodes: IndexVec::from_elem_n(
1296 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1297 1,
1298 ),
1299 bodies,
1300 })));
1301 self.feed_owner_id().hir_attr_map(attrs);
1302 }
1303}
1304
1305#[derive(Copy, Clone)]
1323#[rustc_diagnostic_item = "TyCtxt"]
1324#[rustc_pass_by_value]
1325pub struct TyCtxt<'tcx> {
1326 gcx: &'tcx GlobalCtxt<'tcx>,
1327}
1328
1329unsafe impl DynSend for TyCtxt<'_> {}
1333unsafe impl DynSync for TyCtxt<'_> {}
1334fn _assert_tcx_fields() {
1335 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1336 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1337}
1338
1339impl<'tcx> Deref for TyCtxt<'tcx> {
1340 type Target = &'tcx GlobalCtxt<'tcx>;
1341 #[inline(always)]
1342 fn deref(&self) -> &Self::Target {
1343 &self.gcx
1344 }
1345}
1346
1347pub struct GlobalCtxt<'tcx> {
1349 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1350 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1351
1352 interners: CtxtInterners<'tcx>,
1353
1354 pub sess: &'tcx Session,
1355 crate_types: Vec<CrateType>,
1356 stable_crate_id: StableCrateId,
1362
1363 pub dep_graph: DepGraph,
1364
1365 pub prof: SelfProfilerRef,
1366
1367 pub types: CommonTypes<'tcx>,
1369
1370 pub lifetimes: CommonLifetimes<'tcx>,
1372
1373 pub consts: CommonConsts<'tcx>,
1375
1376 pub(crate) hooks: crate::hooks::Providers,
1379
1380 untracked: Untracked,
1381
1382 pub query_system: QuerySystem<'tcx>,
1383 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1384
1385 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1387
1388 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1391
1392 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1396
1397 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1399
1400 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1401
1402 pub data_layout: TargetDataLayout,
1404
1405 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1407
1408 current_gcx: CurrentGcx,
1409}
1410
1411impl<'tcx> GlobalCtxt<'tcx> {
1412 pub fn enter<F, R>(&'tcx self, f: F) -> R
1415 where
1416 F: FnOnce(TyCtxt<'tcx>) -> R,
1417 {
1418 let icx = tls::ImplicitCtxt::new(self);
1419
1420 let _on_drop = defer(move || {
1422 *self.current_gcx.value.write() = None;
1423 });
1424
1425 {
1427 let mut guard = self.current_gcx.value.write();
1428 assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1429 *guard = Some(self as *const _ as *const ());
1430 }
1431
1432 tls::enter_context(&icx, || f(icx.tcx))
1433 }
1434}
1435
1436#[derive(Clone)]
1443pub struct CurrentGcx {
1444 value: Arc<RwLock<Option<*const ()>>>,
1447}
1448
1449unsafe impl DynSend for CurrentGcx {}
1450unsafe impl DynSync for CurrentGcx {}
1451
1452impl CurrentGcx {
1453 pub fn new() -> Self {
1454 Self { value: Arc::new(RwLock::new(None)) }
1455 }
1456
1457 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1458 let read_guard = self.value.read();
1459 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1460 f(unsafe { &*gcx })
1464 }
1465}
1466
1467impl<'tcx> TyCtxt<'tcx> {
1468 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1469 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1472 if typeck_root_def_id != def_id.to_def_id() {
1473 return self.has_typeck_results(typeck_root_def_id.expect_local());
1474 }
1475
1476 self.hir_node_by_def_id(def_id).body_id().is_some()
1477 }
1478
1479 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1484 let def_kind = self.def_kind(def_id);
1485 if def_kind.has_codegen_attrs() {
1486 self.codegen_fn_attrs(def_id)
1487 } else if matches!(
1488 def_kind,
1489 DefKind::AnonConst
1490 | DefKind::AssocConst
1491 | DefKind::Const
1492 | DefKind::InlineConst
1493 | DefKind::GlobalAsm
1494 ) {
1495 CodegenFnAttrs::EMPTY
1496 } else {
1497 bug!(
1498 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1499 def_id,
1500 def_kind
1501 )
1502 }
1503 }
1504
1505 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1506 self.arena.alloc(Steal::new(thir))
1507 }
1508
1509 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1510 self.arena.alloc(Steal::new(mir))
1511 }
1512
1513 pub fn alloc_steal_promoted(
1514 self,
1515 promoted: IndexVec<Promoted, Body<'tcx>>,
1516 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1517 self.arena.alloc(Steal::new(promoted))
1518 }
1519
1520 pub fn mk_adt_def(
1521 self,
1522 did: DefId,
1523 kind: AdtKind,
1524 variants: IndexVec<VariantIdx, ty::VariantDef>,
1525 repr: ReprOptions,
1526 ) -> ty::AdtDef<'tcx> {
1527 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1528 }
1529
1530 pub fn allocate_bytes_dedup(self, bytes: &[u8], salt: usize) -> interpret::AllocId {
1533 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
1535 let alloc = self.mk_const_alloc(alloc);
1536 self.reserve_and_set_memory_dedup(alloc, salt)
1537 }
1538
1539 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1543 let get = |name| {
1544 let Some(attr) = self.get_attr(def_id, name) else {
1545 return Bound::Unbounded;
1546 };
1547 debug!("layout_scalar_valid_range: attr={:?}", attr);
1548 if let Some(
1549 &[
1550 ast::MetaItemInner::Lit(ast::MetaItemLit {
1551 kind: ast::LitKind::Int(a, _), ..
1552 }),
1553 ],
1554 ) = attr.meta_item_list().as_deref()
1555 {
1556 Bound::Included(a.get())
1557 } else {
1558 self.dcx().span_delayed_bug(
1559 attr.span(),
1560 "invalid rustc_layout_scalar_valid_range attribute",
1561 );
1562 Bound::Unbounded
1563 }
1564 };
1565 (
1566 get(sym::rustc_layout_scalar_valid_range_start),
1567 get(sym::rustc_layout_scalar_valid_range_end),
1568 )
1569 }
1570
1571 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1572 value.lift_to_interner(self)
1573 }
1574
1575 pub fn create_global_ctxt<T>(
1582 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1583 s: &'tcx Session,
1584 crate_types: Vec<CrateType>,
1585 stable_crate_id: StableCrateId,
1586 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1587 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1588 untracked: Untracked,
1589 dep_graph: DepGraph,
1590 query_kinds: &'tcx [DepKindStruct<'tcx>],
1591 query_system: QuerySystem<'tcx>,
1592 hooks: crate::hooks::Providers,
1593 current_gcx: CurrentGcx,
1594 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1595 ) -> T {
1596 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1597 s.dcx().emit_fatal(err);
1598 });
1599 let interners = CtxtInterners::new(arena);
1600 let common_types = CommonTypes::new(&interners, s, &untracked);
1601 let common_lifetimes = CommonLifetimes::new(&interners);
1602 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1603
1604 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1605 sess: s,
1606 crate_types,
1607 stable_crate_id,
1608 arena,
1609 hir_arena,
1610 interners,
1611 dep_graph,
1612 hooks,
1613 prof: s.prof.clone(),
1614 types: common_types,
1615 lifetimes: common_lifetimes,
1616 consts: common_consts,
1617 untracked,
1618 query_system,
1619 query_kinds,
1620 ty_rcache: Default::default(),
1621 selection_cache: Default::default(),
1622 evaluation_cache: Default::default(),
1623 new_solver_evaluation_cache: Default::default(),
1624 canonical_param_env_cache: Default::default(),
1625 data_layout,
1626 alloc_map: interpret::AllocMap::new(),
1627 current_gcx,
1628 });
1629
1630 gcx.enter(f)
1632 }
1633
1634 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1636 self.get_lang_items(())
1637 }
1638
1639 #[track_caller]
1641 pub fn ty_ordering_enum(self, span: Option<Span>) -> Ty<'tcx> {
1642 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1643 self.type_of(ordering_enum).no_bound_vars().unwrap()
1644 }
1645
1646 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1649 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1650 }
1651
1652 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1654 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1655 }
1656
1657 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1659 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1660 }
1661
1662 pub fn is_coroutine(self, def_id: DefId) -> bool {
1663 self.coroutine_kind(def_id).is_some()
1664 }
1665
1666 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1669 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1670 }
1671
1672 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1674 matches!(
1675 self.coroutine_kind(def_id),
1676 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1677 )
1678 }
1679
1680 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1683 matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1684 }
1685
1686 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1689 matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1690 }
1691
1692 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1694 matches!(
1695 self.coroutine_kind(def_id),
1696 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1697 )
1698 }
1699
1700 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1702 matches!(
1703 self.coroutine_kind(def_id),
1704 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1705 )
1706 }
1707
1708 pub fn stability(self) -> &'tcx stability::Index {
1709 self.stability_index(())
1710 }
1711
1712 pub fn features(self) -> &'tcx rustc_feature::Features {
1713 self.features_query(())
1714 }
1715
1716 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1717 let id = id.into_query_param();
1718 if let Some(id) = id.as_local() {
1720 self.definitions_untracked().def_key(id)
1721 } else {
1722 self.cstore_untracked().def_key(id)
1723 }
1724 }
1725
1726 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1732 if let Some(id) = id.as_local() {
1734 self.definitions_untracked().def_path(id)
1735 } else {
1736 self.cstore_untracked().def_path(id)
1737 }
1738 }
1739
1740 #[inline]
1741 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1742 if let Some(def_id) = def_id.as_local() {
1744 self.definitions_untracked().def_path_hash(def_id)
1745 } else {
1746 self.cstore_untracked().def_path_hash(def_id)
1747 }
1748 }
1749
1750 #[inline]
1751 pub fn crate_types(self) -> &'tcx [CrateType] {
1752 &self.crate_types
1753 }
1754
1755 pub fn metadata_kind(self) -> MetadataKind {
1756 self.crate_types()
1757 .iter()
1758 .map(|ty| match *ty {
1759 CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => {
1760 MetadataKind::None
1761 }
1762 CrateType::Rlib => MetadataKind::Uncompressed,
1763 CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
1764 })
1765 .max()
1766 .unwrap_or(MetadataKind::None)
1767 }
1768
1769 pub fn needs_metadata(self) -> bool {
1770 self.metadata_kind() != MetadataKind::None
1771 }
1772
1773 pub fn needs_crate_hash(self) -> bool {
1774 cfg!(debug_assertions)
1782 || self.sess.opts.incremental.is_some()
1783 || self.needs_metadata()
1784 || self.sess.instrument_coverage()
1785 }
1786
1787 #[inline]
1788 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1789 if crate_num == LOCAL_CRATE {
1790 self.stable_crate_id
1791 } else {
1792 self.cstore_untracked().stable_crate_id(crate_num)
1793 }
1794 }
1795
1796 #[inline]
1799 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1800 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1801 LOCAL_CRATE
1802 } else {
1803 *self
1804 .untracked()
1805 .stable_crate_ids
1806 .read()
1807 .get(&stable_crate_id)
1808 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1809 }
1810 }
1811
1812 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1816 debug!("def_path_hash_to_def_id({:?})", hash);
1817
1818 let stable_crate_id = hash.stable_crate_id();
1819
1820 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1823 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1824 } else {
1825 Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
1826 }
1827 }
1828
1829 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1830 let (crate_name, stable_crate_id) = if def_id.is_local() {
1835 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1836 } else {
1837 let cstore = &*self.cstore_untracked();
1838 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1839 };
1840
1841 format!(
1842 "{}[{:04x}]{}",
1843 crate_name,
1844 stable_crate_id.as_u64() >> (8 * 6),
1847 self.def_path(def_id).to_string_no_crate_verbose()
1848 )
1849 }
1850
1851 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1852 self.sess.dcx()
1853 }
1854
1855 pub fn is_target_feature_call_safe(
1856 self,
1857 callee_features: &[TargetFeature],
1858 body_features: &[TargetFeature],
1859 ) -> bool {
1860 self.sess.target.options.is_like_wasm
1865 || callee_features
1866 .iter()
1867 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1868 }
1869
1870 pub fn adjust_target_feature_sig(
1873 self,
1874 fun_def: DefId,
1875 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1876 caller: DefId,
1877 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1878 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1879 let callee_features = &self.codegen_fn_attrs(caller).target_features;
1880 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
1881 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
1882 }
1883 None
1884 }
1885}
1886
1887impl<'tcx> TyCtxtAt<'tcx> {
1888 pub fn create_def(
1890 self,
1891 parent: LocalDefId,
1892 name: Option<Symbol>,
1893 def_kind: DefKind,
1894 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1895 let feed = self.tcx.create_def(parent, name, def_kind);
1896
1897 feed.def_span(self.span);
1898 feed
1899 }
1900}
1901
1902impl<'tcx> TyCtxt<'tcx> {
1903 pub fn create_def(
1905 self,
1906 parent: LocalDefId,
1907 name: Option<Symbol>,
1908 def_kind: DefKind,
1909 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1910 let data = def_kind.def_path_data(name);
1911 let def_id = self.untracked.definitions.write().create_def(parent, data);
1926
1927 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1932
1933 let feed = TyCtxtFeed { tcx: self, key: def_id };
1934 feed.def_kind(def_kind);
1935 if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1940 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1941 feed.visibility(ty::Visibility::Restricted(parent_mod));
1942 }
1943
1944 feed
1945 }
1946
1947 pub fn create_crate_num(
1948 self,
1949 stable_crate_id: StableCrateId,
1950 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1951 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
1952 return Err(existing);
1953 }
1954
1955 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
1956 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
1957 Ok(TyCtxtFeed { key: num, tcx: self })
1958 }
1959
1960 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1961 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1964
1965 let definitions = &self.untracked.definitions;
1966 std::iter::from_coroutine(
1967 #[coroutine]
1968 || {
1969 let mut i = 0;
1970
1971 while i < { definitions.read().num_definitions() } {
1974 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1975 yield LocalDefId { local_def_index };
1976 i += 1;
1977 }
1978
1979 definitions.freeze();
1981 },
1982 )
1983 }
1984
1985 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1986 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1989
1990 self.untracked.definitions.freeze().def_path_table()
1993 }
1994
1995 pub fn def_path_hash_to_def_index_map(
1996 self,
1997 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1998 self.ensure_ok().hir_crate(());
2001 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2004 }
2005
2006 #[inline]
2009 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2010 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2011 }
2012
2013 pub fn untracked(self) -> &'tcx Untracked {
2015 &self.untracked
2016 }
2017 #[inline]
2020 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2021 self.untracked.definitions.read()
2022 }
2023
2024 #[inline]
2027 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2028 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2029 }
2030
2031 #[inline(always)]
2032 pub fn with_stable_hashing_context<R>(
2033 self,
2034 f: impl FnOnce(StableHashingContext<'_>) -> R,
2035 ) -> R {
2036 f(StableHashingContext::new(self.sess, &self.untracked))
2037 }
2038
2039 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2040 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2041 }
2042
2043 #[inline]
2044 pub fn local_crate_exports_generics(self) -> bool {
2045 self.crate_types().iter().any(|crate_type| {
2046 match crate_type {
2047 CrateType::Executable
2048 | CrateType::Staticlib
2049 | CrateType::ProcMacro
2050 | CrateType::Cdylib => false,
2051
2052 CrateType::Dylib => true,
2057
2058 CrateType::Rlib => true,
2059 }
2060 })
2061 }
2062
2063 pub fn is_suitable_region(
2065 self,
2066 generic_param_scope: LocalDefId,
2067 mut region: Region<'tcx>,
2068 ) -> Option<FreeRegionInfo> {
2069 let (suitable_region_binding_scope, region_def_id) = loop {
2070 let def_id =
2071 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2072 let scope = self.local_parent(def_id);
2073 if self.def_kind(scope) == DefKind::OpaqueTy {
2074 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2077 continue;
2078 }
2079 break (scope, def_id.into());
2080 };
2081
2082 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2083 Node::Item(..) | Node::TraitItem(..) => false,
2084 Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2085 _ => false,
2086 };
2087
2088 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2089 }
2090
2091 pub fn return_type_impl_or_dyn_traits(
2093 self,
2094 scope_def_id: LocalDefId,
2095 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2096 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2097 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2098 self.hir_fn_decl_by_hir_id(hir_id)
2099 else {
2100 return vec![];
2101 };
2102
2103 let mut v = TraitObjectVisitor(vec![], self.hir());
2104 v.visit_ty_unambig(hir_output);
2105 v.0
2106 }
2107
2108 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2112 self,
2113 scope_def_id: LocalDefId,
2114 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2115 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2116 let mut v = TraitObjectVisitor(vec![], self.hir());
2117 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2119 && let hir::TyKind::Path(hir::QPath::Resolved(
2120 None,
2121 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2122 && let Some(local_id) = def_id.as_local()
2123 && 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()
2125 {
2126 v.visit_ty_unambig(alias_ty);
2127 if !v.0.is_empty() {
2128 return Some((
2129 v.0,
2130 alias_generics.span,
2131 alias_generics.span_for_lifetime_suggestion(),
2132 ));
2133 }
2134 }
2135 None
2136 }
2137
2138 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2140 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2141 if self.impl_trait_ref(container_id).is_some() {
2142 return true;
2149 }
2150 false
2151 }
2152
2153 pub fn has_strict_asm_symbol_naming(self) -> bool {
2156 self.sess.target.arch.contains("nvptx")
2157 }
2158
2159 pub fn caller_location_ty(self) -> Ty<'tcx> {
2161 Ty::new_imm_ref(
2162 self,
2163 self.lifetimes.re_static,
2164 self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
2165 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2166 )
2167 }
2168
2169 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2171 let kind = self.def_kind(def_id);
2172 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2173 }
2174
2175 pub fn type_length_limit(self) -> Limit {
2176 self.limits(()).type_length_limit
2177 }
2178
2179 pub fn recursion_limit(self) -> Limit {
2180 self.limits(()).recursion_limit
2181 }
2182
2183 pub fn move_size_limit(self) -> Limit {
2184 self.limits(()).move_size_limit
2185 }
2186
2187 pub fn pattern_complexity_limit(self) -> Limit {
2188 self.limits(()).pattern_complexity_limit
2189 }
2190
2191 pub fn all_traits(self) -> impl Iterator<Item = DefId> {
2193 iter::once(LOCAL_CRATE)
2194 .chain(self.crates(()).iter().copied())
2195 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2196 }
2197
2198 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2200 let visible_crates =
2201 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2202
2203 iter::once(LOCAL_CRATE)
2204 .chain(visible_crates)
2205 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2206 }
2207
2208 #[inline]
2209 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2210 self.visibility(def_id).expect_local()
2211 }
2212
2213 #[instrument(skip(self), level = "trace", ret)]
2215 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2216 self.hir_expect_opaque_ty(def_id).origin
2217 }
2218
2219 pub fn finish(self) {
2220 self.alloc_self_profile_query_strings();
2223
2224 self.save_dep_graph();
2225 self.query_key_hash_verify_all();
2226
2227 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2228 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2229 }
2230 }
2231}
2232
2233macro_rules! nop_lift {
2234 ($set:ident; $ty:ty => $lifted:ty) => {
2235 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2236 type Lifted = $lifted;
2237 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2238 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2243 _x: Interned<'tcx, Inner>,
2244 ) -> InternedSet<'tcx, Inner> {
2245 unreachable!()
2246 }
2247 fn _type_eq<T>(_x: &T, _y: &T) {}
2248 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2249 let interner = _intern_set_ty_from_interned_ty(x.0);
2253 _type_eq(&interner, &tcx.interners.$set);
2255 }
2256
2257 tcx.interners
2258 .$set
2259 .contains_pointer_to(&InternedInSet(&*self.0.0))
2260 .then(|| unsafe { mem::transmute(self) })
2263 }
2264 }
2265 };
2266}
2267
2268macro_rules! nop_list_lift {
2269 ($set:ident; $ty:ty => $lifted:ty) => {
2270 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2271 type Lifted = &'tcx List<$lifted>;
2272 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2273 if false {
2275 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2276 }
2277
2278 if self.is_empty() {
2279 return Some(List::empty());
2280 }
2281 tcx.interners
2282 .$set
2283 .contains_pointer_to(&InternedInSet(self))
2284 .then(|| unsafe { mem::transmute(self) })
2285 }
2286 }
2287 };
2288}
2289
2290nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2291nop_lift! { region; Region<'a> => Region<'tcx> }
2292nop_lift! { const_; Const<'a> => Const<'tcx> }
2293nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2294nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2295nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2296nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2297nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2298nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2299
2300nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2301nop_list_lift! {
2302 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2303}
2304nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2305
2306nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2308
2309macro_rules! sty_debug_print {
2310 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2311 #[allow(non_snake_case)]
2314 mod inner {
2315 use crate::ty::{self, TyCtxt};
2316 use crate::ty::context::InternedInSet;
2317
2318 #[derive(Copy, Clone)]
2319 struct DebugStat {
2320 total: usize,
2321 lt_infer: usize,
2322 ty_infer: usize,
2323 ct_infer: usize,
2324 all_infer: usize,
2325 }
2326
2327 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2328 let mut total = DebugStat {
2329 total: 0,
2330 lt_infer: 0,
2331 ty_infer: 0,
2332 ct_infer: 0,
2333 all_infer: 0,
2334 };
2335 $(let mut $variant = total;)*
2336
2337 for shard in tcx.interners.type_.lock_shards() {
2338 let types = shard.iter();
2339 for &(InternedInSet(t), ()) in types {
2340 let variant = match t.internee {
2341 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2342 ty::Float(..) | ty::Str | ty::Never => continue,
2343 ty::Error(_) => continue,
2344 $(ty::$variant(..) => &mut $variant,)*
2345 };
2346 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2347 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2348 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2349
2350 variant.total += 1;
2351 total.total += 1;
2352 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2353 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2354 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2355 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2356 }
2357 }
2358 writeln!(fmt, "Ty interner total ty lt ct all")?;
2359 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2360 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2361 stringify!($variant),
2362 uses = $variant.total,
2363 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2364 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2365 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2366 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2367 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2368 )*
2369 writeln!(fmt, " total {uses:6} \
2370 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2371 uses = total.total,
2372 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2373 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2374 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2375 all = total.all_infer as f64 * 100.0 / total.total as f64)
2376 }
2377 }
2378
2379 inner::go($fmt, $ctxt)
2380 }}
2381}
2382
2383impl<'tcx> TyCtxt<'tcx> {
2384 pub fn debug_stats(self) -> impl fmt::Debug {
2385 fmt::from_fn(move |fmt| {
2386 sty_debug_print!(
2387 fmt,
2388 self,
2389 Adt,
2390 Array,
2391 Slice,
2392 RawPtr,
2393 Ref,
2394 FnDef,
2395 FnPtr,
2396 UnsafeBinder,
2397 Placeholder,
2398 Coroutine,
2399 CoroutineWitness,
2400 Dynamic,
2401 Closure,
2402 CoroutineClosure,
2403 Tuple,
2404 Bound,
2405 Param,
2406 Infer,
2407 Alias,
2408 Pat,
2409 Foreign
2410 )?;
2411
2412 writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2413 writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2414 writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2415 writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2416
2417 Ok(())
2418 })
2419 }
2420}
2421
2422struct InternedInSet<'tcx, T: ?Sized>(&'tcx T);
2427
2428impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> {
2429 fn clone(&self) -> Self {
2430 InternedInSet(self.0)
2431 }
2432}
2433
2434impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {}
2435
2436impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
2437 fn into_pointer(&self) -> *const () {
2438 self.0 as *const _ as *const ()
2439 }
2440}
2441
2442#[allow(rustc::usage_of_ty_tykind)]
2443impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2444 fn borrow(&self) -> &T {
2445 &self.0.internee
2446 }
2447}
2448
2449impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2450 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2451 self.0.internee == other.0.internee
2454 }
2455}
2456
2457impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2458
2459impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2460 fn hash<H: Hasher>(&self, s: &mut H) {
2461 self.0.internee.hash(s)
2463 }
2464}
2465
2466impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2467 fn borrow(&self) -> &[T] {
2468 &self.0[..]
2469 }
2470}
2471
2472impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2473 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2474 self.0[..] == other.0[..]
2477 }
2478}
2479
2480impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2481
2482impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2483 fn hash<H: Hasher>(&self, s: &mut H) {
2484 self.0[..].hash(s)
2486 }
2487}
2488
2489impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2490 fn borrow(&self) -> &[T] {
2491 &self.0[..]
2492 }
2493}
2494
2495impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2496 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2497 self.0[..] == other.0[..]
2500 }
2501}
2502
2503impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2504
2505impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2506 fn hash<H: Hasher>(&self, s: &mut H) {
2507 self.0[..].hash(s)
2509 }
2510}
2511
2512macro_rules! direct_interners {
2513 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2514 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2515 fn borrow<'a>(&'a self) -> &'a $ty {
2516 &self.0
2517 }
2518 }
2519
2520 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2521 fn eq(&self, other: &Self) -> bool {
2522 self.0 == other.0
2525 }
2526 }
2527
2528 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2529
2530 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2531 fn hash<H: Hasher>(&self, s: &mut H) {
2532 self.0.hash(s)
2535 }
2536 }
2537
2538 impl<'tcx> TyCtxt<'tcx> {
2539 $vis fn $method(self, v: $ty) -> $ret_ty {
2540 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2541 InternedInSet(self.interners.arena.alloc(v))
2542 }).0))
2543 }
2544 })+
2545 }
2546}
2547
2548direct_interners! {
2552 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2553 valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2554 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2555 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2556 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2557 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2558 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2559 ExternalConstraints -> ExternalConstraints<'tcx>,
2560 predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2561 PredefinedOpaques -> PredefinedOpaques<'tcx>,
2562}
2563
2564macro_rules! slice_interners {
2565 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2566 impl<'tcx> TyCtxt<'tcx> {
2567 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2568 if v.is_empty() {
2569 List::empty()
2570 } else {
2571 self.interners.$field.intern_ref(v, || {
2572 InternedInSet(List::from_arena(&*self.arena, (), v))
2573 }).0
2574 }
2575 })+
2576 }
2577 );
2578}
2579
2580slice_interners!(
2584 const_lists: pub mk_const_list(Const<'tcx>),
2585 args: pub mk_args(GenericArg<'tcx>),
2586 type_lists: pub mk_type_list(Ty<'tcx>),
2587 canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
2588 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2589 projs: pub mk_projs(ProjectionKind),
2590 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2591 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2592 fields: pub mk_fields(FieldIdx),
2593 local_def_ids: intern_local_def_ids(LocalDefId),
2594 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2595 offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2596);
2597
2598impl<'tcx> TyCtxt<'tcx> {
2599 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2603 assert!(sig.safety().is_safe());
2604 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2605 }
2606
2607 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2610 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2611 self.associated_items(trait_did)
2612 .filter_by_name_unhygienic(assoc_name.name)
2613 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2614 })
2615 }
2616
2617 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2619 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2620 let future_trait = self.require_lang_item(LangItem::Future, None);
2621
2622 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2623 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2624 return false;
2625 };
2626 trait_predicate.trait_ref.def_id == future_trait
2627 && trait_predicate.polarity == PredicatePolarity::Positive
2628 })
2629 }
2630
2631 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2639 sig.map_bound(|s| {
2640 let params = match s.inputs()[0].kind() {
2641 ty::Tuple(params) => *params,
2642 _ => bug!(),
2643 };
2644 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2645 })
2646 }
2647
2648 #[inline]
2649 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2650 self.interners.intern_predicate(
2651 binder,
2652 self.sess,
2653 &self.untracked,
2655 )
2656 }
2657
2658 #[inline]
2659 pub fn reuse_or_mk_predicate(
2660 self,
2661 pred: Predicate<'tcx>,
2662 binder: Binder<'tcx, PredicateKind<'tcx>>,
2663 ) -> Predicate<'tcx> {
2664 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2665 }
2666
2667 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2668 self.check_args_compatible_inner(def_id, args, false)
2669 }
2670
2671 fn check_args_compatible_inner(
2672 self,
2673 def_id: DefId,
2674 args: &'tcx [ty::GenericArg<'tcx>],
2675 nested: bool,
2676 ) -> bool {
2677 let generics = self.generics_of(def_id);
2678
2679 let own_args = if !nested
2682 && let DefKind::AssocTy = self.def_kind(def_id)
2683 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2684 {
2685 if generics.own_params.len() + 1 != args.len() {
2686 return false;
2687 }
2688
2689 if !matches!(args[0].unpack(), ty::GenericArgKind::Type(_)) {
2690 return false;
2691 }
2692
2693 &args[1..]
2694 } else {
2695 if generics.count() != args.len() {
2696 return false;
2697 }
2698
2699 let (parent_args, own_args) = args.split_at(generics.parent_count);
2700
2701 if let Some(parent) = generics.parent
2702 && !self.check_args_compatible_inner(parent, parent_args, true)
2703 {
2704 return false;
2705 }
2706
2707 own_args
2708 };
2709
2710 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2711 match (¶m.kind, arg.unpack()) {
2712 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2713 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2714 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2715 _ => return false,
2716 }
2717 }
2718
2719 true
2720 }
2721
2722 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2725 if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2726 if let DefKind::AssocTy = self.def_kind(def_id)
2727 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2728 {
2729 bug!(
2730 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2731 self.def_path_str(def_id),
2732 args,
2733 self.mk_args_from_iter(
2735 [self.types.self_param.into()].into_iter().chain(
2736 self.generics_of(def_id)
2737 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2738 .iter()
2739 .copied()
2740 )
2741 )
2742 );
2743 } else {
2744 bug!(
2745 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2746 self.def_path_str(def_id),
2747 args,
2748 ty::GenericArgs::identity_for_item(self, def_id)
2749 );
2750 }
2751 }
2752 }
2753
2754 #[inline(always)]
2755 pub(crate) fn check_and_mk_args(
2756 self,
2757 def_id: DefId,
2758 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2759 ) -> GenericArgsRef<'tcx> {
2760 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2761 self.debug_assert_args_compatible(def_id, args);
2762 args
2763 }
2764
2765 #[inline]
2766 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2767 self.interners.intern_const(
2768 kind,
2769 self.sess,
2770 &self.untracked,
2772 )
2773 }
2774
2775 #[allow(rustc::usage_of_ty_tykind)]
2777 #[inline]
2778 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2779 self.interners.intern_ty(
2780 st,
2781 self.sess,
2782 &self.untracked,
2784 )
2785 }
2786
2787 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2788 match param.kind {
2789 GenericParamDefKind::Lifetime => {
2790 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2791 }
2792 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2793 GenericParamDefKind::Const { .. } => {
2794 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2795 .into()
2796 }
2797 }
2798 }
2799
2800 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2801 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2802 }
2803
2804 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2805 self.mk_place_elem(place, PlaceElem::Deref)
2806 }
2807
2808 pub fn mk_place_downcast(
2809 self,
2810 place: Place<'tcx>,
2811 adt_def: AdtDef<'tcx>,
2812 variant_index: VariantIdx,
2813 ) -> Place<'tcx> {
2814 self.mk_place_elem(
2815 place,
2816 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2817 )
2818 }
2819
2820 pub fn mk_place_downcast_unnamed(
2821 self,
2822 place: Place<'tcx>,
2823 variant_index: VariantIdx,
2824 ) -> Place<'tcx> {
2825 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2826 }
2827
2828 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2829 self.mk_place_elem(place, PlaceElem::Index(index))
2830 }
2831
2832 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2836 let mut projection = place.projection.to_vec();
2837 projection.push(elem);
2838
2839 Place { local: place.local, projection: self.mk_place_elems(&projection) }
2840 }
2841
2842 pub fn mk_poly_existential_predicates(
2843 self,
2844 eps: &[PolyExistentialPredicate<'tcx>],
2845 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2846 assert!(!eps.is_empty());
2847 assert!(
2848 eps.array_windows()
2849 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2850 != Ordering::Greater)
2851 );
2852 self.intern_poly_existential_predicates(eps)
2853 }
2854
2855 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2856 self.interners.intern_clauses(clauses)
2860 }
2861
2862 pub fn mk_local_def_ids(self, clauses: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2863 self.intern_local_def_ids(clauses)
2867 }
2868
2869 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2870 where
2871 I: Iterator<Item = T>,
2872 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2873 {
2874 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2875 }
2876
2877 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2878 where
2879 I: Iterator<Item = T>,
2880 T: CollectAndApply<
2881 &'tcx ty::CapturedPlace<'tcx>,
2882 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2883 >,
2884 {
2885 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2886 }
2887
2888 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2889 where
2890 I: Iterator<Item = T>,
2891 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2892 {
2893 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2894 }
2895
2896 pub fn mk_fn_sig<I, T>(
2901 self,
2902 inputs: I,
2903 output: I::Item,
2904 c_variadic: bool,
2905 safety: hir::Safety,
2906 abi: ExternAbi,
2907 ) -> T::Output
2908 where
2909 I: IntoIterator<Item = T>,
2910 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2911 {
2912 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2913 inputs_and_output: self.mk_type_list(xs),
2914 c_variadic,
2915 safety,
2916 abi,
2917 })
2918 }
2919
2920 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2921 where
2922 I: Iterator<Item = T>,
2923 T: CollectAndApply<
2924 PolyExistentialPredicate<'tcx>,
2925 &'tcx List<PolyExistentialPredicate<'tcx>>,
2926 >,
2927 {
2928 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2929 }
2930
2931 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2932 where
2933 I: Iterator<Item = T>,
2934 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2935 {
2936 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2937 }
2938
2939 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2940 where
2941 I: Iterator<Item = T>,
2942 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2943 {
2944 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2945 }
2946
2947 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2948 where
2949 I: Iterator<Item = T>,
2950 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2951 {
2952 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2953 }
2954
2955 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2956 where
2957 I: Iterator<Item = T>,
2958 T: CollectAndApply<CanonicalVarInfo<'tcx>, &'tcx List<CanonicalVarInfo<'tcx>>>,
2959 {
2960 T::collect_and_apply(iter, |xs| self.mk_canonical_var_infos(xs))
2961 }
2962
2963 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2964 where
2965 I: Iterator<Item = T>,
2966 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2967 {
2968 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2969 }
2970
2971 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2972 where
2973 I: Iterator<Item = T>,
2974 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2975 {
2976 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2977 }
2978
2979 pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
2980 where
2981 I: Iterator<Item = T>,
2982 T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
2983 {
2984 T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
2985 }
2986
2987 pub fn mk_args_trait(
2988 self,
2989 self_ty: Ty<'tcx>,
2990 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2991 ) -> GenericArgsRef<'tcx> {
2992 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2993 }
2994
2995 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2996 where
2997 I: Iterator<Item = T>,
2998 T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
2999 {
3000 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3001 }
3002
3003 #[track_caller]
3006 pub fn emit_node_span_lint(
3007 self,
3008 lint: &'static Lint,
3009 hir_id: HirId,
3010 span: impl Into<MultiSpan>,
3011 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3012 ) {
3013 let (level, src) = self.lint_level_at_node(lint, hir_id);
3014 lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
3015 decorator.decorate_lint(lint);
3016 })
3017 }
3018
3019 #[rustc_lint_diagnostics]
3023 #[track_caller]
3024 pub fn node_span_lint(
3025 self,
3026 lint: &'static Lint,
3027 hir_id: HirId,
3028 span: impl Into<MultiSpan>,
3029 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3030 ) {
3031 let (level, src) = self.lint_level_at_node(lint, hir_id);
3032 lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
3033 }
3034
3035 pub fn crate_level_attribute_injection_span(self, hir_id: HirId) -> Option<Span> {
3038 for (_hir_id, node) in self.hir_parent_iter(hir_id) {
3039 if let hir::Node::Crate(m) = node {
3040 return Some(m.spans.inject_use_span.shrink_to_lo());
3041 }
3042 }
3043 None
3044 }
3045
3046 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3047 self,
3048 diag: &mut Diag<'_, E>,
3049 hir_id: Option<HirId>,
3050 features: impl IntoIterator<Item = (String, Symbol)>,
3051 ) {
3052 if !self.sess.is_nightly_build() {
3053 return;
3054 }
3055
3056 let span = hir_id.and_then(|id| self.crate_level_attribute_injection_span(id));
3057 for (desc, feature) in features {
3058 let msg =
3060 format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3061 if let Some(span) = span {
3062 diag.span_suggestion_verbose(
3063 span,
3064 msg,
3065 format!("#![feature({feature})]\n"),
3066 Applicability::MaybeIncorrect,
3067 );
3068 } else {
3069 diag.help(msg);
3070 }
3071 }
3072 }
3073
3074 #[track_caller]
3077 pub fn emit_node_lint(
3078 self,
3079 lint: &'static Lint,
3080 id: HirId,
3081 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3082 ) {
3083 self.node_lint(lint, id, |lint| {
3084 decorator.decorate_lint(lint);
3085 })
3086 }
3087
3088 #[rustc_lint_diagnostics]
3092 #[track_caller]
3093 pub fn node_lint(
3094 self,
3095 lint: &'static Lint,
3096 id: HirId,
3097 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3098 ) {
3099 let (level, src) = self.lint_level_at_node(lint, id);
3100 lint_level(self.sess, lint, level, src, None, decorate);
3101 }
3102
3103 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3104 let map = self.in_scope_traits_map(id.owner)?;
3105 let candidates = map.get(&id.local_id)?;
3106 Some(candidates)
3107 }
3108
3109 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3110 debug!(?id, "named_region");
3111 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3112 }
3113
3114 pub fn is_late_bound(self, id: HirId) -> bool {
3115 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3116 }
3117
3118 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3119 self.mk_bound_variable_kinds(
3120 &self
3121 .late_bound_vars_map(id.owner)
3122 .get(&id.local_id)
3123 .cloned()
3124 .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3125 )
3126 }
3127
3128 pub fn map_opaque_lifetime_to_parent_lifetime(
3136 self,
3137 mut opaque_lifetime_param_def_id: LocalDefId,
3138 ) -> ty::Region<'tcx> {
3139 debug_assert!(
3140 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3141 "{opaque_lifetime_param_def_id:?} is a {}",
3142 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3143 );
3144
3145 loop {
3146 let parent = self.local_parent(opaque_lifetime_param_def_id);
3147 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3148
3149 let Some((lifetime, _)) = lifetime_mapping
3150 .iter()
3151 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3152 else {
3153 bug!("duplicated lifetime param should be present");
3154 };
3155
3156 match *lifetime {
3157 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3158 let new_parent = self.local_parent(ebv);
3159
3160 if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3163 debug_assert_eq!(self.local_parent(parent), new_parent);
3164 opaque_lifetime_param_def_id = ebv;
3165 continue;
3166 }
3167
3168 let generics = self.generics_of(new_parent);
3169 return ty::Region::new_early_param(
3170 self,
3171 ty::EarlyParamRegion {
3172 index: generics
3173 .param_def_id_to_index(self, ebv.to_def_id())
3174 .expect("early-bound var should be present in fn generics"),
3175 name: self.item_name(ebv.to_def_id()),
3176 },
3177 );
3178 }
3179 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3180 let new_parent = self.local_parent(lbv);
3181 return ty::Region::new_late_param(
3182 self,
3183 new_parent.to_def_id(),
3184 ty::LateParamRegionKind::Named(
3185 lbv.to_def_id(),
3186 self.item_name(lbv.to_def_id()),
3187 ),
3188 );
3189 }
3190 resolve_bound_vars::ResolvedArg::Error(guar) => {
3191 return ty::Region::new_error(self, guar);
3192 }
3193 _ => {
3194 return ty::Region::new_error_with_message(
3195 self,
3196 self.def_span(opaque_lifetime_param_def_id),
3197 "cannot resolve lifetime",
3198 );
3199 }
3200 }
3201 }
3202 }
3203
3204 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3209 self.is_const_fn(def_id)
3210 && match self.lookup_const_stability(def_id) {
3211 None => true, Some(stability) if stability.is_const_stable() => true,
3213 _ => false,
3214 }
3215 }
3216
3217 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3219 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3220 && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3221 }
3222
3223 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3224 match self.def_kind(def_id) {
3225 DefKind::Fn | DefKind::AssocFn => {}
3226 _ => return None,
3227 }
3228 self.intrinsic_raw(def_id)
3229 }
3230
3231 pub fn next_trait_solver_globally(self) -> bool {
3232 self.sess.opts.unstable_opts.next_solver.globally
3233 }
3234
3235 pub fn next_trait_solver_in_coherence(self) -> bool {
3236 self.sess.opts.unstable_opts.next_solver.coherence
3237 }
3238
3239 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3240 self.opt_rpitit_info(def_id).is_some()
3241 }
3242
3243 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3253 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3254 }
3255
3256 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3257 self.resolver_for_lowering_raw(()).0
3258 }
3259
3260 pub fn impl_trait_ref(
3263 self,
3264 def_id: impl IntoQueryParam<DefId>,
3265 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3266 Some(self.impl_trait_header(def_id)?.trait_ref)
3267 }
3268
3269 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3270 self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3271 }
3272
3273 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3274 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3275 self.coroutine_kind(def_id)
3276 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3277 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3278 {
3279 true
3280 } else {
3281 false
3282 }
3283 }
3284
3285 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3287 self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3288 }
3289}
3290
3291#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3300pub struct DeducedParamAttrs {
3301 pub read_only: bool,
3304}
3305
3306pub fn provide(providers: &mut Providers) {
3307 providers.maybe_unused_trait_imports =
3308 |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
3309 providers.names_imported_by_glob_use = |tcx, id| {
3310 tcx.arena.alloc(UnordSet::from(
3311 tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default(),
3312 ))
3313 };
3314
3315 providers.extern_mod_stmt_cnum =
3316 |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
3317 providers.is_panic_runtime =
3318 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3319 providers.is_compiler_builtins =
3320 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3321 providers.has_panic_handler = |tcx, LocalCrate| {
3322 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3324 };
3325 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3326}
3327
3328pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3329 attrs.iter().any(|x| x.has_name(name))
3330}