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