1#![allow(rustc::usage_of_ty_tykind)]
4
5pub mod tls;
6
7use std::assert_matches::debug_assert_matches;
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::{PhantomData, PointeeSized};
14use std::ops::{Bound, Deref};
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::fingerprint::Fingerprint;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::jobserver::Proxy;
25use rustc_data_structures::profiling::SelfProfilerRef;
26use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
27use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
28use rustc_data_structures::steal::Steal;
29use rustc_data_structures::sync::{
30 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
31};
32use rustc_errors::{
33 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, LintEmitter, MultiSpan,
34};
35use rustc_hir::attrs::AttributeKind;
36use rustc_hir::def::{CtorKind, CtorOf, DefKind};
37use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
38use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
39use rustc_hir::intravisit::VisitorExt;
40use rustc_hir::lang_items::LangItem;
41use rustc_hir::limit::Limit;
42use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate, find_attr};
43use rustc_index::IndexVec;
44use rustc_macros::{HashStable, TyDecodable, TyEncodable};
45use rustc_query_system::cache::WithDepNode;
46use rustc_query_system::dep_graph::DepNodeIndex;
47use rustc_query_system::ich::StableHashingContext;
48use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
49use rustc_session::Session;
50use rustc_session::config::CrateType;
51use rustc_session::cstore::{CrateStoreDyn, Untracked};
52use rustc_session::lint::Lint;
53use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
54use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
55use rustc_type_ir::TyKind::*;
56use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem};
57pub use rustc_type_ir::lift::Lift;
58use rustc_type_ir::{
59 CollectAndApply, Interner, TypeFlags, TypeFoldable, WithCachedTypeInfo, elaborate, search_graph,
60};
61use tracing::{debug, instrument};
62
63use crate::arena::Arena;
64use crate::dep_graph::{DepGraph, DepKindStruct};
65use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind, CanonicalVarKinds};
66use crate::lint::lint_level;
67use crate::metadata::ModChild;
68use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
69use crate::middle::resolve_bound_vars;
70use crate::mir::interpret::{self, Allocation, ConstAllocation};
71use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
72use crate::query::plumbing::QuerySystem;
73use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
74use crate::thir::Thir;
75use crate::traits;
76use crate::traits::solve::{
77 self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, PredefinedOpaques,
78 PredefinedOpaquesData, QueryResult, inspect,
79};
80use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
81use crate::ty::{
82 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
83 GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, ParamTy,
84 Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
85 PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
86 ValTree, ValTreeKind, Visibility,
87};
88
89#[allow(rustc::usage_of_ty_tykind)]
90impl<'tcx> Interner for TyCtxt<'tcx> {
91 fn next_trait_solver_globally(self) -> bool {
92 self.next_trait_solver_globally()
93 }
94
95 type DefId = DefId;
96 type LocalDefId = LocalDefId;
97 type TraitId = DefId;
98 type ForeignId = DefId;
99 type FunctionId = DefId;
100 type ClosureId = DefId;
101 type CoroutineClosureId = DefId;
102 type CoroutineId = DefId;
103 type AdtId = DefId;
104 type ImplId = DefId;
105 type Span = Span;
106
107 type GenericArgs = ty::GenericArgsRef<'tcx>;
108
109 type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
110 type GenericArg = ty::GenericArg<'tcx>;
111 type Term = ty::Term<'tcx>;
112 type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
113
114 type BoundVarKind = ty::BoundVariableKind;
115 type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
116
117 fn mk_predefined_opaques_in_body(
118 self,
119 data: PredefinedOpaquesData<Self>,
120 ) -> Self::PredefinedOpaques {
121 self.mk_predefined_opaques_in_body(data)
122 }
123 type LocalDefIds = &'tcx ty::List<LocalDefId>;
124 type CanonicalVarKinds = CanonicalVarKinds<'tcx>;
125 fn mk_canonical_var_kinds(
126 self,
127 kinds: &[ty::CanonicalVarKind<Self>],
128 ) -> Self::CanonicalVarKinds {
129 self.mk_canonical_var_kinds(kinds)
130 }
131
132 type ExternalConstraints = ExternalConstraints<'tcx>;
133 fn mk_external_constraints(
134 self,
135 data: ExternalConstraintsData<Self>,
136 ) -> ExternalConstraints<'tcx> {
137 self.mk_external_constraints(data)
138 }
139 type DepNodeIndex = DepNodeIndex;
140 fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
141 self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
142 }
143 type Ty = Ty<'tcx>;
144 type Tys = &'tcx List<Ty<'tcx>>;
145
146 type FnInputTys = &'tcx [Ty<'tcx>];
147 type ParamTy = ParamTy;
148 type BoundTy = ty::BoundTy;
149 type Symbol = Symbol;
150
151 type PlaceholderTy = ty::PlaceholderType;
152 type ErrorGuaranteed = ErrorGuaranteed;
153 type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
154
155 type AllocId = crate::mir::interpret::AllocId;
156 type Pat = Pattern<'tcx>;
157 type PatList = &'tcx List<Pattern<'tcx>>;
158 type Safety = hir::Safety;
159 type Abi = ExternAbi;
160 type Const = ty::Const<'tcx>;
161 type PlaceholderConst = ty::PlaceholderConst;
162
163 type ParamConst = ty::ParamConst;
164 type BoundConst = ty::BoundConst;
165 type ValueConst = ty::Value<'tcx>;
166 type ExprConst = ty::Expr<'tcx>;
167 type ValTree = ty::ValTree<'tcx>;
168
169 type Region = Region<'tcx>;
170 type EarlyParamRegion = ty::EarlyParamRegion;
171 type LateParamRegion = ty::LateParamRegion;
172 type BoundRegion = ty::BoundRegion;
173 type PlaceholderRegion = ty::PlaceholderRegion;
174
175 type RegionAssumptions = &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>;
176
177 type ParamEnv = ty::ParamEnv<'tcx>;
178 type Predicate = Predicate<'tcx>;
179
180 type Clause = Clause<'tcx>;
181 type Clauses = ty::Clauses<'tcx>;
182
183 type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
184 fn mk_tracked<T: fmt::Debug + Clone>(
185 self,
186 data: T,
187 dep_node: DepNodeIndex,
188 ) -> Self::Tracked<T> {
189 WithDepNode::new(dep_node, data)
190 }
191 fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
192 tracked.get(self)
193 }
194
195 fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
196 f(&mut *self.new_solver_evaluation_cache.lock())
197 }
198
199 fn canonical_param_env_cache_get_or_insert<R>(
200 self,
201 param_env: ty::ParamEnv<'tcx>,
202 f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry<Self>,
203 from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry<Self>) -> R,
204 ) -> R {
205 let mut cache = self.new_solver_canonical_param_env_cache.lock();
206 let entry = cache.entry(param_env).or_insert_with(f);
207 from_entry(entry)
208 }
209
210 fn evaluation_is_concurrent(&self) -> bool {
211 self.sess.threads() > 1
212 }
213
214 fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
215 self.expand_abstract_consts(t)
216 }
217
218 type GenericsOf = &'tcx ty::Generics;
219
220 fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
221 self.generics_of(def_id)
222 }
223
224 type VariancesOf = &'tcx [ty::Variance];
225
226 fn variances_of(self, def_id: DefId) -> Self::VariancesOf {
227 self.variances_of(def_id)
228 }
229
230 fn opt_alias_variances(
231 self,
232 kind: impl Into<ty::AliasTermKind>,
233 def_id: DefId,
234 ) -> Option<&'tcx [ty::Variance]> {
235 self.opt_alias_variances(kind, def_id)
236 }
237
238 fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
239 self.type_of(def_id)
240 }
241 fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
242 self.type_of_opaque_hir_typeck(def_id)
243 }
244
245 type AdtDef = ty::AdtDef<'tcx>;
246 fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
247 self.adt_def(adt_def_id)
248 }
249
250 fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
251 match self.def_kind(alias.def_id) {
252 DefKind::AssocTy => {
253 if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
254 {
255 ty::Inherent
256 } else {
257 ty::Projection
258 }
259 }
260 DefKind::OpaqueTy => ty::Opaque,
261 DefKind::TyAlias => ty::Free,
262 kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
263 }
264 }
265
266 fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind {
267 match self.def_kind(alias.def_id) {
268 DefKind::AssocTy => {
269 if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
270 {
271 ty::AliasTermKind::InherentTy
272 } else {
273 ty::AliasTermKind::ProjectionTy
274 }
275 }
276 DefKind::AssocConst => {
277 if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
278 {
279 ty::AliasTermKind::InherentConst
280 } else {
281 ty::AliasTermKind::ProjectionConst
282 }
283 }
284 DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
285 DefKind::TyAlias => ty::AliasTermKind::FreeTy,
286 DefKind::Const => ty::AliasTermKind::FreeConst,
287 DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
288 ty::AliasTermKind::UnevaluatedConst
289 }
290 kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
291 }
292 }
293
294 fn trait_ref_and_own_args_for_alias(
295 self,
296 def_id: DefId,
297 args: ty::GenericArgsRef<'tcx>,
298 ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
299 debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
300 let trait_def_id = self.parent(def_id);
301 debug_assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
302 let trait_ref = ty::TraitRef::from_assoc(self, trait_def_id, args);
303 (trait_ref, &args[trait_ref.args.len()..])
304 }
305
306 fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
307 self.mk_args(args)
308 }
309
310 fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
311 where
312 I: Iterator<Item = T>,
313 T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
314 {
315 self.mk_args_from_iter(args)
316 }
317
318 fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
319 self.check_args_compatible(def_id, args)
320 }
321
322 fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
323 self.debug_assert_args_compatible(def_id, args);
324 }
325
326 fn debug_assert_existential_args_compatible(
330 self,
331 def_id: Self::DefId,
332 args: Self::GenericArgs,
333 ) {
334 if cfg!(debug_assertions) {
337 self.debug_assert_args_compatible(
338 def_id,
339 self.mk_args_from_iter(
340 [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
341 ),
342 );
343 }
344 }
345
346 fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
347 where
348 I: Iterator<Item = T>,
349 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
350 {
351 self.mk_type_list_from_iter(args)
352 }
353
354 fn parent(self, def_id: DefId) -> DefId {
355 self.parent(def_id)
356 }
357
358 fn recursion_limit(self) -> usize {
359 self.recursion_limit().0
360 }
361
362 type Features = &'tcx rustc_feature::Features;
363
364 fn features(self) -> Self::Features {
365 self.features()
366 }
367
368 fn coroutine_hidden_types(
369 self,
370 def_id: DefId,
371 ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> {
372 self.coroutine_hidden_types(def_id)
373 }
374
375 fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
376 self.fn_sig(def_id)
377 }
378
379 fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
380 self.coroutine_movability(def_id)
381 }
382
383 fn coroutine_for_closure(self, def_id: DefId) -> DefId {
384 self.coroutine_for_closure(def_id)
385 }
386
387 fn generics_require_sized_self(self, def_id: DefId) -> bool {
388 self.generics_require_sized_self(def_id)
389 }
390
391 fn item_bounds(
392 self,
393 def_id: DefId,
394 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
395 self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
396 }
397
398 fn item_self_bounds(
399 self,
400 def_id: DefId,
401 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
402 self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
403 }
404
405 fn item_non_self_bounds(
406 self,
407 def_id: DefId,
408 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
409 self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
410 }
411
412 fn predicates_of(
413 self,
414 def_id: DefId,
415 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
416 ty::EarlyBinder::bind(
417 self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
418 )
419 }
420
421 fn own_predicates_of(
422 self,
423 def_id: DefId,
424 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
425 ty::EarlyBinder::bind(
426 self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
427 )
428 }
429
430 fn explicit_super_predicates_of(
431 self,
432 def_id: DefId,
433 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
434 self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
435 }
436
437 fn explicit_implied_predicates_of(
438 self,
439 def_id: DefId,
440 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
441 self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
442 }
443
444 fn impl_super_outlives(
445 self,
446 impl_def_id: DefId,
447 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
448 self.impl_super_outlives(impl_def_id)
449 }
450
451 fn impl_is_const(self, def_id: DefId) -> bool {
452 debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
453 self.is_conditionally_const(def_id)
454 }
455
456 fn fn_is_const(self, def_id: DefId) -> bool {
457 debug_assert_matches!(
458 self.def_kind(def_id),
459 DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
460 );
461 self.is_conditionally_const(def_id)
462 }
463
464 fn alias_has_const_conditions(self, def_id: DefId) -> bool {
465 debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
466 self.is_conditionally_const(def_id)
467 }
468
469 fn const_conditions(
470 self,
471 def_id: DefId,
472 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
473 ty::EarlyBinder::bind(
474 self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
475 )
476 }
477
478 fn explicit_implied_const_bounds(
479 self,
480 def_id: DefId,
481 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
482 ty::EarlyBinder::bind(
483 self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
484 )
485 }
486
487 fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
488 self.impl_self_is_guaranteed_unsized(impl_def_id)
489 }
490
491 fn has_target_features(self, def_id: DefId) -> bool {
492 !self.codegen_fn_attrs(def_id).target_features.is_empty()
493 }
494
495 fn require_lang_item(self, lang_item: SolverLangItem) -> DefId {
496 self.require_lang_item(solver_lang_item_to_lang_item(lang_item), DUMMY_SP)
497 }
498
499 fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> DefId {
500 self.require_lang_item(solver_trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
501 }
502
503 fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> DefId {
504 self.require_lang_item(solver_adt_lang_item_to_lang_item(lang_item), DUMMY_SP)
505 }
506
507 fn is_lang_item(self, def_id: DefId, lang_item: SolverLangItem) -> bool {
508 self.is_lang_item(def_id, solver_lang_item_to_lang_item(lang_item))
509 }
510
511 fn is_trait_lang_item(self, def_id: DefId, lang_item: SolverTraitLangItem) -> bool {
512 self.is_lang_item(def_id, solver_trait_lang_item_to_lang_item(lang_item))
513 }
514
515 fn is_adt_lang_item(self, def_id: DefId, lang_item: SolverAdtLangItem) -> bool {
516 self.is_lang_item(def_id, solver_adt_lang_item_to_lang_item(lang_item))
517 }
518
519 fn is_default_trait(self, def_id: DefId) -> bool {
520 self.is_default_trait(def_id)
521 }
522
523 fn as_lang_item(self, def_id: DefId) -> Option<SolverLangItem> {
524 lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?)
525 }
526
527 fn as_trait_lang_item(self, def_id: DefId) -> Option<SolverTraitLangItem> {
528 lang_item_to_solver_trait_lang_item(self.lang_items().from_def_id(def_id)?)
529 }
530
531 fn as_adt_lang_item(self, def_id: DefId) -> Option<SolverAdtLangItem> {
532 lang_item_to_solver_adt_lang_item(self.lang_items().from_def_id(def_id)?)
533 }
534
535 fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
536 self.associated_items(def_id)
537 .in_definition_order()
538 .filter(|assoc_item| assoc_item.is_type())
539 .map(|assoc_item| assoc_item.def_id)
540 }
541
542 fn for_each_relevant_impl(
546 self,
547 trait_def_id: DefId,
548 self_ty: Ty<'tcx>,
549 mut f: impl FnMut(DefId),
550 ) {
551 let tcx = self;
552 let trait_impls = tcx.trait_impls_of(trait_def_id);
553 let mut consider_impls_for_simplified_type = |simp| {
554 if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
555 for &impl_def_id in impls_for_type {
556 f(impl_def_id);
557 }
558 }
559 };
560
561 match self_ty.kind() {
562 ty::Bool
563 | ty::Char
564 | ty::Int(_)
565 | ty::Uint(_)
566 | ty::Float(_)
567 | ty::Adt(_, _)
568 | ty::Foreign(_)
569 | ty::Str
570 | ty::Array(_, _)
571 | ty::Pat(_, _)
572 | ty::Slice(_)
573 | ty::RawPtr(_, _)
574 | ty::Ref(_, _, _)
575 | ty::FnDef(_, _)
576 | ty::FnPtr(..)
577 | ty::Dynamic(_, _)
578 | ty::Closure(..)
579 | ty::CoroutineClosure(..)
580 | ty::Coroutine(_, _)
581 | ty::Never
582 | ty::Tuple(_)
583 | ty::UnsafeBinder(_) => {
584 let simp = ty::fast_reject::simplify_type(
585 tcx,
586 self_ty,
587 ty::fast_reject::TreatParams::AsRigid,
588 )
589 .unwrap();
590 consider_impls_for_simplified_type(simp);
591 }
592
593 ty::Infer(ty::IntVar(_)) => {
596 use ty::IntTy::*;
597 use ty::UintTy::*;
598 let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
600 let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
601 let possible_integers = [
602 ty::SimplifiedType::Int(I8),
604 ty::SimplifiedType::Int(I16),
605 ty::SimplifiedType::Int(I32),
606 ty::SimplifiedType::Int(I64),
607 ty::SimplifiedType::Int(I128),
608 ty::SimplifiedType::Int(Isize),
609 ty::SimplifiedType::Uint(U8),
611 ty::SimplifiedType::Uint(U16),
612 ty::SimplifiedType::Uint(U32),
613 ty::SimplifiedType::Uint(U64),
614 ty::SimplifiedType::Uint(U128),
615 ty::SimplifiedType::Uint(Usize),
616 ];
617 for simp in possible_integers {
618 consider_impls_for_simplified_type(simp);
619 }
620 }
621
622 ty::Infer(ty::FloatVar(_)) => {
623 let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
625 let possible_floats = [
626 ty::SimplifiedType::Float(ty::FloatTy::F16),
627 ty::SimplifiedType::Float(ty::FloatTy::F32),
628 ty::SimplifiedType::Float(ty::FloatTy::F64),
629 ty::SimplifiedType::Float(ty::FloatTy::F128),
630 ];
631
632 for simp in possible_floats {
633 consider_impls_for_simplified_type(simp);
634 }
635 }
636
637 ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
642
643 ty::CoroutineWitness(..) => (),
647
648 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
650 | ty::Param(_)
651 | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
652 }
653
654 #[allow(rustc::usage_of_type_ir_traits)]
655 self.for_each_blanket_impl(trait_def_id, f)
656 }
657 fn for_each_blanket_impl(self, trait_def_id: DefId, mut f: impl FnMut(DefId)) {
658 let trait_impls = self.trait_impls_of(trait_def_id);
659 for &impl_def_id in trait_impls.blanket_impls() {
660 f(impl_def_id);
661 }
662 }
663
664 fn has_item_definition(self, def_id: DefId) -> bool {
665 self.defaultness(def_id).has_value()
666 }
667
668 fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
669 self.specializes((impl_def_id, victim_def_id))
670 }
671
672 fn impl_is_default(self, impl_def_id: DefId) -> bool {
673 self.defaultness(impl_def_id).is_default()
674 }
675
676 fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
677 self.impl_trait_ref(impl_def_id).unwrap()
678 }
679
680 fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
681 self.impl_polarity(impl_def_id)
682 }
683
684 fn trait_is_auto(self, trait_def_id: DefId) -> bool {
685 self.trait_is_auto(trait_def_id)
686 }
687
688 fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
689 self.trait_is_coinductive(trait_def_id)
690 }
691
692 fn trait_is_alias(self, trait_def_id: DefId) -> bool {
693 self.trait_is_alias(trait_def_id)
694 }
695
696 fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
697 self.is_dyn_compatible(trait_def_id)
698 }
699
700 fn trait_is_fundamental(self, def_id: DefId) -> bool {
701 self.trait_def(def_id).is_fundamental
702 }
703
704 fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
705 self.trait_def(trait_def_id).implement_via_object
706 }
707
708 fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
709 self.trait_def(trait_def_id).safety.is_unsafe()
710 }
711
712 fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
713 self.is_impl_trait_in_trait(def_id)
714 }
715
716 fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
717 self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
718 }
719
720 fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
721 self.is_general_coroutine(coroutine_def_id)
722 }
723
724 fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
725 self.coroutine_is_async(coroutine_def_id)
726 }
727
728 fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
729 self.coroutine_is_gen(coroutine_def_id)
730 }
731
732 fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
733 self.coroutine_is_async_gen(coroutine_def_id)
734 }
735
736 type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
737 fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
738 self.unsizing_params_for_adt(adt_def_id)
739 }
740
741 fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
742 self,
743 binder: ty::Binder<'tcx, T>,
744 ) -> ty::Binder<'tcx, T> {
745 self.anonymize_bound_vars(binder)
746 }
747
748 fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
749 self.opaque_types_defined_by(defining_anchor)
750 }
751
752 fn opaque_types_and_coroutines_defined_by(
753 self,
754 defining_anchor: Self::LocalDefId,
755 ) -> Self::LocalDefIds {
756 let coroutines_defined_by = self
757 .nested_bodies_within(defining_anchor)
758 .iter()
759 .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
760 self.mk_local_def_ids_from_iter(
761 self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
762 )
763 }
764
765 type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
766 fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
767 self.arena.alloc(probe)
768 }
769 fn evaluate_root_goal_for_proof_tree_raw(
770 self,
771 canonical_goal: CanonicalInput<'tcx>,
772 ) -> (QueryResult<'tcx>, &'tcx inspect::Probe<TyCtxt<'tcx>>) {
773 self.evaluate_root_goal_for_proof_tree_raw(canonical_goal)
774 }
775}
776
777macro_rules! bidirectional_lang_item_map {
778 (
779 $solver_ty:ident, $to_solver:ident, $from_solver:ident;
780 $($name:ident),+ $(,)?
781 ) => {
782 fn $from_solver(lang_item: $solver_ty) -> LangItem {
783 match lang_item {
784 $($solver_ty::$name => LangItem::$name,)+
785 }
786 }
787
788 fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> {
789 Some(match lang_item {
790 $(LangItem::$name => $solver_ty::$name,)+
791 _ => return None,
792 })
793 }
794 }
795}
796
797bidirectional_lang_item_map! {
798 SolverLangItem, lang_item_to_solver_lang_item, solver_lang_item_to_lang_item;
799
800AsyncFnKindUpvars,
802 AsyncFnOnceOutput,
803 CallOnceFuture,
804 CallRefFuture,
805 CoroutineReturn,
806 CoroutineYield,
807 DynMetadata,
808 FutureOutput,
809 Metadata,
810}
812
813bidirectional_lang_item_map! {
814 SolverAdtLangItem, lang_item_to_solver_adt_lang_item, solver_adt_lang_item_to_lang_item;
815
816Option,
818 Poll,
819}
821
822bidirectional_lang_item_map! {
823 SolverTraitLangItem, lang_item_to_solver_trait_lang_item, solver_trait_lang_item_to_lang_item;
824
825AsyncFn,
827 AsyncFnKindHelper,
828 AsyncFnMut,
829 AsyncFnOnce,
830 AsyncFnOnceOutput,
831 AsyncIterator,
832 BikeshedGuaranteedNoDrop,
833 Clone,
834 Copy,
835 Coroutine,
836 Destruct,
837 DiscriminantKind,
838 Drop,
839 Fn,
840 FnMut,
841 FnOnce,
842 FnPtrTrait,
843 FusedIterator,
844 Future,
845 Iterator,
846 MetaSized,
847 PointeeSized,
848 PointeeTrait,
849 Sized,
850 TransmuteTrait,
851 Tuple,
852 Unpin,
853 Unsize,
854}
856
857impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
858 fn is_local(self) -> bool {
859 self.is_local()
860 }
861
862 fn as_local(self) -> Option<LocalDefId> {
863 self.as_local()
864 }
865}
866
867impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
868 fn rust() -> Self {
869 ExternAbi::Rust
870 }
871
872 fn is_rust(self) -> bool {
873 matches!(self, ExternAbi::Rust)
874 }
875}
876
877impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
878 fn safe() -> Self {
879 hir::Safety::Safe
880 }
881
882 fn is_safe(self) -> bool {
883 self.is_safe()
884 }
885
886 fn prefix_str(self) -> &'static str {
887 self.prefix_str()
888 }
889}
890
891impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
892 fn generic_const_exprs(self) -> bool {
893 self.generic_const_exprs()
894 }
895
896 fn coroutine_clone(self) -> bool {
897 self.coroutine_clone()
898 }
899
900 fn associated_const_equality(self) -> bool {
901 self.associated_const_equality()
902 }
903
904 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
905 !self.staged_api() && self.enabled(symbol)
909 }
910}
911
912impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
913 fn dummy() -> Self {
914 DUMMY_SP
915 }
916}
917
918type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
919
920pub struct CtxtInterners<'tcx> {
921 arena: &'tcx WorkerLocal<Arena<'tcx>>,
923
924 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
927 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
928 args: InternedSet<'tcx, GenericArgs<'tcx>>,
929 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
930 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
931 region: InternedSet<'tcx, RegionKind<'tcx>>,
932 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
933 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
934 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
935 projs: InternedSet<'tcx, List<ProjectionKind>>,
936 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
937 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
938 pat: InternedSet<'tcx, PatternKind<'tcx>>,
939 const_allocation: InternedSet<'tcx, Allocation>,
940 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
941 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
942 adt_def: InternedSet<'tcx, AdtDefData>,
943 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
944 predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
945 fields: InternedSet<'tcx, List<FieldIdx>>,
946 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
947 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
948 offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
949 valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
950 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
951 outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
952}
953
954impl<'tcx> CtxtInterners<'tcx> {
955 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
956 const N: usize = 2048;
959 CtxtInterners {
960 arena,
961 type_: InternedSet::with_capacity(N * 16),
965 const_lists: InternedSet::with_capacity(N * 4),
966 args: InternedSet::with_capacity(N * 4),
967 type_lists: InternedSet::with_capacity(N * 4),
968 region: InternedSet::with_capacity(N * 4),
969 poly_existential_predicates: InternedSet::with_capacity(N / 4),
970 canonical_var_kinds: InternedSet::with_capacity(N / 2),
971 predicate: InternedSet::with_capacity(N),
972 clauses: InternedSet::with_capacity(N),
973 projs: InternedSet::with_capacity(N * 4),
974 place_elems: InternedSet::with_capacity(N * 2),
975 const_: InternedSet::with_capacity(N * 2),
976 pat: InternedSet::with_capacity(N),
977 const_allocation: InternedSet::with_capacity(N),
978 bound_variable_kinds: InternedSet::with_capacity(N * 2),
979 layout: InternedSet::with_capacity(N),
980 adt_def: InternedSet::with_capacity(N),
981 external_constraints: InternedSet::with_capacity(N),
982 predefined_opaques_in_body: InternedSet::with_capacity(N),
983 fields: InternedSet::with_capacity(N * 4),
984 local_def_ids: InternedSet::with_capacity(N),
985 captures: InternedSet::with_capacity(N),
986 offset_of: InternedSet::with_capacity(N),
987 valtree: InternedSet::with_capacity(N),
988 patterns: InternedSet::with_capacity(N),
989 outlives: InternedSet::with_capacity(N),
990 }
991 }
992
993 #[allow(rustc::usage_of_ty_tykind)]
995 #[inline(never)]
996 fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
997 Ty(Interned::new_unchecked(
998 self.type_
999 .intern(kind, |kind| {
1000 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
1001 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1002
1003 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1004 internee: kind,
1005 stable_hash,
1006 flags: flags.flags,
1007 outer_exclusive_binder: flags.outer_exclusive_binder,
1008 }))
1009 })
1010 .0,
1011 ))
1012 }
1013
1014 #[allow(rustc::usage_of_ty_tykind)]
1016 #[inline(never)]
1017 fn intern_const(
1018 &self,
1019 kind: ty::ConstKind<'tcx>,
1020 sess: &Session,
1021 untracked: &Untracked,
1022 ) -> Const<'tcx> {
1023 Const(Interned::new_unchecked(
1024 self.const_
1025 .intern(kind, |kind: ty::ConstKind<'_>| {
1026 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
1027 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1028
1029 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1030 internee: kind,
1031 stable_hash,
1032 flags: flags.flags,
1033 outer_exclusive_binder: flags.outer_exclusive_binder,
1034 }))
1035 })
1036 .0,
1037 ))
1038 }
1039
1040 fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
1041 &self,
1042 flags: &ty::FlagComputation<TyCtxt<'tcx>>,
1043 sess: &'a Session,
1044 untracked: &'a Untracked,
1045 val: &T,
1046 ) -> Fingerprint {
1047 if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
1050 Fingerprint::ZERO
1051 } else {
1052 let mut hasher = StableHasher::new();
1053 let mut hcx = StableHashingContext::new(sess, untracked);
1054 val.hash_stable(&mut hcx, &mut hasher);
1055 hasher.finish()
1056 }
1057 }
1058
1059 #[inline(never)]
1061 fn intern_predicate(
1062 &self,
1063 kind: Binder<'tcx, PredicateKind<'tcx>>,
1064 sess: &Session,
1065 untracked: &Untracked,
1066 ) -> Predicate<'tcx> {
1067 Predicate(Interned::new_unchecked(
1068 self.predicate
1069 .intern(kind, |kind| {
1070 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
1071
1072 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1073
1074 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1075 internee: kind,
1076 stable_hash,
1077 flags: flags.flags,
1078 outer_exclusive_binder: flags.outer_exclusive_binder,
1079 }))
1080 })
1081 .0,
1082 ))
1083 }
1084
1085 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
1086 if clauses.is_empty() {
1087 ListWithCachedTypeInfo::empty()
1088 } else {
1089 self.clauses
1090 .intern_ref(clauses, || {
1091 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
1092
1093 InternedInSet(ListWithCachedTypeInfo::from_arena(
1094 &*self.arena,
1095 flags.into(),
1096 clauses,
1097 ))
1098 })
1099 .0
1100 }
1101 }
1102}
1103
1104const NUM_PREINTERNED_TY_VARS: u32 = 100;
1109const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
1110const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
1111const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
1112const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
1113const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
1114
1115const NUM_PREINTERNED_RE_VARS: u32 = 500;
1117const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
1118const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
1119
1120pub struct CommonTypes<'tcx> {
1121 pub unit: Ty<'tcx>,
1122 pub bool: Ty<'tcx>,
1123 pub char: Ty<'tcx>,
1124 pub isize: Ty<'tcx>,
1125 pub i8: Ty<'tcx>,
1126 pub i16: Ty<'tcx>,
1127 pub i32: Ty<'tcx>,
1128 pub i64: Ty<'tcx>,
1129 pub i128: Ty<'tcx>,
1130 pub usize: Ty<'tcx>,
1131 pub u8: Ty<'tcx>,
1132 pub u16: Ty<'tcx>,
1133 pub u32: Ty<'tcx>,
1134 pub u64: Ty<'tcx>,
1135 pub u128: Ty<'tcx>,
1136 pub f16: Ty<'tcx>,
1137 pub f32: Ty<'tcx>,
1138 pub f64: Ty<'tcx>,
1139 pub f128: Ty<'tcx>,
1140 pub str_: Ty<'tcx>,
1141 pub never: Ty<'tcx>,
1142 pub self_param: Ty<'tcx>,
1143
1144 pub trait_object_dummy_self: Ty<'tcx>,
1149
1150 pub ty_vars: Vec<Ty<'tcx>>,
1152
1153 pub fresh_tys: Vec<Ty<'tcx>>,
1155
1156 pub fresh_int_tys: Vec<Ty<'tcx>>,
1158
1159 pub fresh_float_tys: Vec<Ty<'tcx>>,
1161
1162 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
1166}
1167
1168pub struct CommonLifetimes<'tcx> {
1169 pub re_static: Region<'tcx>,
1171
1172 pub re_erased: Region<'tcx>,
1174
1175 pub re_vars: Vec<Region<'tcx>>,
1177
1178 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
1182}
1183
1184pub struct CommonConsts<'tcx> {
1185 pub unit: Const<'tcx>,
1186 pub true_: Const<'tcx>,
1187 pub false_: Const<'tcx>,
1188 pub(crate) valtree_zst: ValTree<'tcx>,
1190}
1191
1192impl<'tcx> CommonTypes<'tcx> {
1193 fn new(
1194 interners: &CtxtInterners<'tcx>,
1195 sess: &Session,
1196 untracked: &Untracked,
1197 ) -> CommonTypes<'tcx> {
1198 let mk = |ty| interners.intern_ty(ty, sess, untracked);
1199
1200 let ty_vars =
1201 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1202 let fresh_tys: Vec<_> =
1203 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1204 let fresh_int_tys: Vec<_> =
1205 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1206 let fresh_float_tys: Vec<_> =
1207 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1208
1209 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
1210 .map(|i| {
1211 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
1212 .map(|v| {
1213 mk(ty::Bound(
1214 ty::DebruijnIndex::from(i),
1215 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
1216 ))
1217 })
1218 .collect()
1219 })
1220 .collect();
1221
1222 CommonTypes {
1223 unit: mk(Tuple(List::empty())),
1224 bool: mk(Bool),
1225 char: mk(Char),
1226 never: mk(Never),
1227 isize: mk(Int(ty::IntTy::Isize)),
1228 i8: mk(Int(ty::IntTy::I8)),
1229 i16: mk(Int(ty::IntTy::I16)),
1230 i32: mk(Int(ty::IntTy::I32)),
1231 i64: mk(Int(ty::IntTy::I64)),
1232 i128: mk(Int(ty::IntTy::I128)),
1233 usize: mk(Uint(ty::UintTy::Usize)),
1234 u8: mk(Uint(ty::UintTy::U8)),
1235 u16: mk(Uint(ty::UintTy::U16)),
1236 u32: mk(Uint(ty::UintTy::U32)),
1237 u64: mk(Uint(ty::UintTy::U64)),
1238 u128: mk(Uint(ty::UintTy::U128)),
1239 f16: mk(Float(ty::FloatTy::F16)),
1240 f32: mk(Float(ty::FloatTy::F32)),
1241 f64: mk(Float(ty::FloatTy::F64)),
1242 f128: mk(Float(ty::FloatTy::F128)),
1243 str_: mk(Str),
1244 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1245
1246 trait_object_dummy_self: fresh_tys[0],
1247
1248 ty_vars,
1249 fresh_tys,
1250 fresh_int_tys,
1251 fresh_float_tys,
1252 anon_bound_tys,
1253 }
1254 }
1255}
1256
1257impl<'tcx> CommonLifetimes<'tcx> {
1258 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1259 let mk = |r| {
1260 Region(Interned::new_unchecked(
1261 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1262 ))
1263 };
1264
1265 let re_vars =
1266 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1267
1268 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
1269 .map(|i| {
1270 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
1271 .map(|v| {
1272 mk(ty::ReBound(
1273 ty::DebruijnIndex::from(i),
1274 ty::BoundRegion {
1275 var: ty::BoundVar::from(v),
1276 kind: ty::BoundRegionKind::Anon,
1277 },
1278 ))
1279 })
1280 .collect()
1281 })
1282 .collect();
1283
1284 CommonLifetimes {
1285 re_static: mk(ty::ReStatic),
1286 re_erased: mk(ty::ReErased),
1287 re_vars,
1288 anon_re_bounds,
1289 }
1290 }
1291}
1292
1293impl<'tcx> CommonConsts<'tcx> {
1294 fn new(
1295 interners: &CtxtInterners<'tcx>,
1296 types: &CommonTypes<'tcx>,
1297 sess: &Session,
1298 untracked: &Untracked,
1299 ) -> CommonConsts<'tcx> {
1300 let mk_const = |c| {
1301 interners.intern_const(
1302 c, sess, untracked,
1304 )
1305 };
1306
1307 let mk_valtree = |v| {
1308 ty::ValTree(Interned::new_unchecked(
1309 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1310 ))
1311 };
1312
1313 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1314 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1315 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1316
1317 CommonConsts {
1318 unit: mk_const(ty::ConstKind::Value(ty::Value {
1319 ty: types.unit,
1320 valtree: valtree_zst,
1321 })),
1322 true_: mk_const(ty::ConstKind::Value(ty::Value {
1323 ty: types.bool,
1324 valtree: valtree_true,
1325 })),
1326 false_: mk_const(ty::ConstKind::Value(ty::Value {
1327 ty: types.bool,
1328 valtree: valtree_false,
1329 })),
1330 valtree_zst,
1331 }
1332 }
1333}
1334
1335#[derive(Debug)]
1338pub struct FreeRegionInfo {
1339 pub scope: LocalDefId,
1341 pub region_def_id: DefId,
1343 pub is_impl_item: bool,
1345}
1346
1347#[derive(Copy, Clone)]
1349pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1350 pub tcx: TyCtxt<'tcx>,
1351 key: KEY,
1353}
1354
1355impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1358
1359#[derive(Copy, Clone)]
1364pub struct Feed<'tcx, KEY: Copy> {
1365 _tcx: PhantomData<TyCtxt<'tcx>>,
1366 key: KEY,
1368}
1369
1370impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1373
1374impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1375 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1376 self.key.fmt(f)
1377 }
1378}
1379
1380impl<'tcx> TyCtxt<'tcx> {
1385 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1388 self.dep_graph.assert_ignored();
1389 TyCtxtFeed { tcx: self, key: () }
1390 }
1391
1392 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1395 let key = self.untracked().source_span.push(span);
1396 assert_eq!(key, CRATE_DEF_ID);
1397 TyCtxtFeed { tcx: self, key }
1398 }
1399
1400 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1404 debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1405 TyCtxtFeed { tcx: self, key }.type_of(value)
1406 }
1407}
1408
1409impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1410 #[inline(always)]
1411 pub fn key(&self) -> KEY {
1412 self.key
1413 }
1414
1415 #[inline(always)]
1416 pub fn downgrade(self) -> Feed<'tcx, KEY> {
1417 Feed { _tcx: PhantomData, key: self.key }
1418 }
1419}
1420
1421impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1422 #[inline(always)]
1423 pub fn key(&self) -> KEY {
1424 self.key
1425 }
1426
1427 #[inline(always)]
1428 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1429 TyCtxtFeed { tcx, key: self.key }
1430 }
1431}
1432
1433impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1434 #[inline(always)]
1435 pub fn def_id(&self) -> LocalDefId {
1436 self.key
1437 }
1438
1439 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1441 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1442 }
1443
1444 pub fn feed_hir(&self) {
1446 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1447
1448 let node = hir::OwnerNode::Synthetic;
1449 let bodies = Default::default();
1450 let attrs = hir::AttributeMap::EMPTY;
1451
1452 let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
1453 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
1454 let node = node.into();
1455 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1456 opt_hash_including_bodies,
1457 nodes: IndexVec::from_elem_n(
1458 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1459 1,
1460 ),
1461 bodies,
1462 })));
1463 self.feed_owner_id().hir_attr_map(attrs);
1464 }
1465}
1466
1467#[derive(Copy, Clone)]
1485#[rustc_diagnostic_item = "TyCtxt"]
1486#[rustc_pass_by_value]
1487pub struct TyCtxt<'tcx> {
1488 gcx: &'tcx GlobalCtxt<'tcx>,
1489}
1490
1491impl<'tcx> LintEmitter for TyCtxt<'tcx> {
1492 type Id = HirId;
1493
1494 fn emit_node_span_lint(
1495 self,
1496 lint: &'static Lint,
1497 hir_id: HirId,
1498 span: impl Into<MultiSpan>,
1499 decorator: impl for<'a> LintDiagnostic<'a, ()>,
1500 ) {
1501 self.emit_node_span_lint(lint, hir_id, span, decorator);
1502 }
1503}
1504
1505unsafe impl DynSend for TyCtxt<'_> {}
1509unsafe impl DynSync for TyCtxt<'_> {}
1510fn _assert_tcx_fields() {
1511 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1512 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1513}
1514
1515impl<'tcx> Deref for TyCtxt<'tcx> {
1516 type Target = &'tcx GlobalCtxt<'tcx>;
1517 #[inline(always)]
1518 fn deref(&self) -> &Self::Target {
1519 &self.gcx
1520 }
1521}
1522
1523pub struct GlobalCtxt<'tcx> {
1525 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1526 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1527
1528 interners: CtxtInterners<'tcx>,
1529
1530 pub sess: &'tcx Session,
1531 crate_types: Vec<CrateType>,
1532 stable_crate_id: StableCrateId,
1538
1539 pub dep_graph: DepGraph,
1540
1541 pub prof: SelfProfilerRef,
1542
1543 pub types: CommonTypes<'tcx>,
1545
1546 pub lifetimes: CommonLifetimes<'tcx>,
1548
1549 pub consts: CommonConsts<'tcx>,
1551
1552 pub(crate) hooks: crate::hooks::Providers,
1555
1556 untracked: Untracked,
1557
1558 pub query_system: QuerySystem<'tcx>,
1559 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1560
1561 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1563
1564 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1567
1568 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1572
1573 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1575 pub new_solver_canonical_param_env_cache:
1576 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
1577
1578 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1579
1580 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
1582 pub clauses_cache:
1584 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
1585
1586 pub data_layout: TargetDataLayout,
1588
1589 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1591
1592 current_gcx: CurrentGcx,
1593
1594 pub jobserver_proxy: Arc<Proxy>,
1596}
1597
1598impl<'tcx> GlobalCtxt<'tcx> {
1599 pub fn enter<F, R>(&'tcx self, f: F) -> R
1602 where
1603 F: FnOnce(TyCtxt<'tcx>) -> R,
1604 {
1605 let icx = tls::ImplicitCtxt::new(self);
1606
1607 let _on_drop = defer(move || {
1609 *self.current_gcx.value.write() = None;
1610 });
1611
1612 {
1614 let mut guard = self.current_gcx.value.write();
1615 assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1616 *guard = Some(self as *const _ as *const ());
1617 }
1618
1619 tls::enter_context(&icx, || f(icx.tcx))
1620 }
1621}
1622
1623#[derive(Clone)]
1630pub struct CurrentGcx {
1631 value: Arc<RwLock<Option<*const ()>>>,
1634}
1635
1636unsafe impl DynSend for CurrentGcx {}
1637unsafe impl DynSync for CurrentGcx {}
1638
1639impl CurrentGcx {
1640 pub fn new() -> Self {
1641 Self { value: Arc::new(RwLock::new(None)) }
1642 }
1643
1644 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1645 let read_guard = self.value.read();
1646 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1647 f(unsafe { &*gcx })
1651 }
1652}
1653
1654impl<'tcx> TyCtxt<'tcx> {
1655 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1656 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1659 if typeck_root_def_id != def_id.to_def_id() {
1660 return self.has_typeck_results(typeck_root_def_id.expect_local());
1661 }
1662
1663 self.hir_node_by_def_id(def_id).body_id().is_some()
1664 }
1665
1666 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1671 let def_kind = self.def_kind(def_id);
1672 if def_kind.has_codegen_attrs() {
1673 self.codegen_fn_attrs(def_id)
1674 } else if matches!(
1675 def_kind,
1676 DefKind::AnonConst
1677 | DefKind::AssocConst
1678 | DefKind::Const
1679 | DefKind::InlineConst
1680 | DefKind::GlobalAsm
1681 ) {
1682 CodegenFnAttrs::EMPTY
1683 } else {
1684 bug!(
1685 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1686 def_id,
1687 def_kind
1688 )
1689 }
1690 }
1691
1692 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1693 self.arena.alloc(Steal::new(thir))
1694 }
1695
1696 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1697 self.arena.alloc(Steal::new(mir))
1698 }
1699
1700 pub fn alloc_steal_promoted(
1701 self,
1702 promoted: IndexVec<Promoted, Body<'tcx>>,
1703 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1704 self.arena.alloc(Steal::new(promoted))
1705 }
1706
1707 pub fn mk_adt_def(
1708 self,
1709 did: DefId,
1710 kind: AdtKind,
1711 variants: IndexVec<VariantIdx, ty::VariantDef>,
1712 repr: ReprOptions,
1713 ) -> ty::AdtDef<'tcx> {
1714 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1715 }
1716
1717 pub fn allocate_bytes_dedup<'a>(
1720 self,
1721 bytes: impl Into<Cow<'a, [u8]>>,
1722 salt: usize,
1723 ) -> interpret::AllocId {
1724 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
1726 let alloc = self.mk_const_alloc(alloc);
1727 self.reserve_and_set_memory_dedup(alloc, salt)
1728 }
1729
1730 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1732 if self.sess.opts.unstable_opts.experimental_default_bounds {
1733 &[
1734 LangItem::DefaultTrait1,
1735 LangItem::DefaultTrait2,
1736 LangItem::DefaultTrait3,
1737 LangItem::DefaultTrait4,
1738 ]
1739 } else {
1740 &[]
1741 }
1742 }
1743
1744 pub fn is_default_trait(self, def_id: DefId) -> bool {
1745 self.default_traits()
1746 .iter()
1747 .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
1748 }
1749
1750 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1754 let start = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1755 let end = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1756 (start, end)
1757 }
1758
1759 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1760 value.lift_to_interner(self)
1761 }
1762
1763 pub fn create_global_ctxt<T>(
1770 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1771 s: &'tcx Session,
1772 crate_types: Vec<CrateType>,
1773 stable_crate_id: StableCrateId,
1774 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1775 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1776 untracked: Untracked,
1777 dep_graph: DepGraph,
1778 query_kinds: &'tcx [DepKindStruct<'tcx>],
1779 query_system: QuerySystem<'tcx>,
1780 hooks: crate::hooks::Providers,
1781 current_gcx: CurrentGcx,
1782 jobserver_proxy: Arc<Proxy>,
1783 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1784 ) -> T {
1785 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1786 s.dcx().emit_fatal(err);
1787 });
1788 let interners = CtxtInterners::new(arena);
1789 let common_types = CommonTypes::new(&interners, s, &untracked);
1790 let common_lifetimes = CommonLifetimes::new(&interners);
1791 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1792
1793 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1794 sess: s,
1795 crate_types,
1796 stable_crate_id,
1797 arena,
1798 hir_arena,
1799 interners,
1800 dep_graph,
1801 hooks,
1802 prof: s.prof.clone(),
1803 types: common_types,
1804 lifetimes: common_lifetimes,
1805 consts: common_consts,
1806 untracked,
1807 query_system,
1808 query_kinds,
1809 ty_rcache: Default::default(),
1810 selection_cache: Default::default(),
1811 evaluation_cache: Default::default(),
1812 new_solver_evaluation_cache: Default::default(),
1813 new_solver_canonical_param_env_cache: Default::default(),
1814 canonical_param_env_cache: Default::default(),
1815 highest_var_in_clauses_cache: Default::default(),
1816 clauses_cache: Default::default(),
1817 data_layout,
1818 alloc_map: interpret::AllocMap::new(),
1819 current_gcx,
1820 jobserver_proxy,
1821 });
1822
1823 gcx.enter(f)
1825 }
1826
1827 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1829 self.get_lang_items(())
1830 }
1831
1832 #[track_caller]
1834 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1835 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1836 self.type_of(ordering_enum).no_bound_vars().unwrap()
1837 }
1838
1839 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1842 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1843 }
1844
1845 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1847 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1848 }
1849
1850 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1852 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1853 }
1854
1855 pub fn is_coroutine(self, def_id: DefId) -> bool {
1856 self.coroutine_kind(def_id).is_some()
1857 }
1858
1859 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1860 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1861 }
1862
1863 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1866 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1867 }
1868
1869 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1871 matches!(
1872 self.coroutine_kind(def_id),
1873 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1874 )
1875 }
1876
1877 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1880 matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1881 }
1882
1883 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1886 matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1887 }
1888
1889 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1891 matches!(
1892 self.coroutine_kind(def_id),
1893 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1894 )
1895 }
1896
1897 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1899 matches!(
1900 self.coroutine_kind(def_id),
1901 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1902 )
1903 }
1904
1905 pub fn features(self) -> &'tcx rustc_feature::Features {
1906 self.features_query(())
1907 }
1908
1909 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1910 let id = id.into_query_param();
1911 if let Some(id) = id.as_local() {
1913 self.definitions_untracked().def_key(id)
1914 } else {
1915 self.cstore_untracked().def_key(id)
1916 }
1917 }
1918
1919 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1925 if let Some(id) = id.as_local() {
1927 self.definitions_untracked().def_path(id)
1928 } else {
1929 self.cstore_untracked().def_path(id)
1930 }
1931 }
1932
1933 #[inline]
1934 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1935 if let Some(def_id) = def_id.as_local() {
1937 self.definitions_untracked().def_path_hash(def_id)
1938 } else {
1939 self.cstore_untracked().def_path_hash(def_id)
1940 }
1941 }
1942
1943 #[inline]
1944 pub fn crate_types(self) -> &'tcx [CrateType] {
1945 &self.crate_types
1946 }
1947
1948 pub fn needs_metadata(self) -> bool {
1949 self.crate_types().iter().any(|ty| match *ty {
1950 CrateType::Executable
1951 | CrateType::Staticlib
1952 | CrateType::Cdylib
1953 | CrateType::Sdylib => false,
1954 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1955 })
1956 }
1957
1958 pub fn needs_crate_hash(self) -> bool {
1959 cfg!(debug_assertions)
1971 || self.sess.opts.incremental.is_some()
1972 || self.needs_metadata()
1973 || self.sess.instrument_coverage()
1974 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1975 }
1976
1977 #[inline]
1978 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1979 if crate_num == LOCAL_CRATE {
1980 self.stable_crate_id
1981 } else {
1982 self.cstore_untracked().stable_crate_id(crate_num)
1983 }
1984 }
1985
1986 #[inline]
1989 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1990 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1991 LOCAL_CRATE
1992 } else {
1993 *self
1994 .untracked()
1995 .stable_crate_ids
1996 .read()
1997 .get(&stable_crate_id)
1998 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1999 }
2000 }
2001
2002 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
2006 debug!("def_path_hash_to_def_id({:?})", hash);
2007
2008 let stable_crate_id = hash.stable_crate_id();
2009
2010 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
2013 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
2014 } else {
2015 Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
2016 }
2017 }
2018
2019 pub fn def_path_debug_str(self, def_id: DefId) -> String {
2020 let (crate_name, stable_crate_id) = if def_id.is_local() {
2025 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
2026 } else {
2027 let cstore = &*self.cstore_untracked();
2028 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
2029 };
2030
2031 format!(
2032 "{}[{:04x}]{}",
2033 crate_name,
2034 stable_crate_id.as_u64() >> (8 * 6),
2037 self.def_path(def_id).to_string_no_crate_verbose()
2038 )
2039 }
2040
2041 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
2042 self.sess.dcx()
2043 }
2044
2045 pub fn is_target_feature_call_safe(
2046 self,
2047 callee_features: &[TargetFeature],
2048 body_features: &[TargetFeature],
2049 ) -> bool {
2050 self.sess.target.options.is_like_wasm
2055 || callee_features
2056 .iter()
2057 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
2058 }
2059
2060 pub fn adjust_target_feature_sig(
2063 self,
2064 fun_def: DefId,
2065 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
2066 caller: DefId,
2067 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
2068 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
2069 let callee_features = &self.codegen_fn_attrs(caller).target_features;
2070 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
2071 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
2072 }
2073 None
2074 }
2075
2076 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
2079 match self.env_var_os(key.as_ref()) {
2080 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
2081 None => Err(VarError::NotPresent),
2082 }
2083 }
2084}
2085
2086impl<'tcx> TyCtxtAt<'tcx> {
2087 pub fn create_def(
2089 self,
2090 parent: LocalDefId,
2091 name: Option<Symbol>,
2092 def_kind: DefKind,
2093 override_def_path_data: Option<DefPathData>,
2094 disambiguator: &mut DisambiguatorState,
2095 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2096 let feed =
2097 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
2098
2099 feed.def_span(self.span);
2100 feed
2101 }
2102}
2103
2104impl<'tcx> TyCtxt<'tcx> {
2105 pub fn create_def(
2107 self,
2108 parent: LocalDefId,
2109 name: Option<Symbol>,
2110 def_kind: DefKind,
2111 override_def_path_data: Option<DefPathData>,
2112 disambiguator: &mut DisambiguatorState,
2113 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2114 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2115 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2125
2126 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2131
2132 let feed = TyCtxtFeed { tcx: self, key: def_id };
2133 feed.def_kind(def_kind);
2134 if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2139 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2140 feed.visibility(ty::Visibility::Restricted(parent_mod));
2141 }
2142
2143 feed
2144 }
2145
2146 pub fn create_crate_num(
2147 self,
2148 stable_crate_id: StableCrateId,
2149 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2150 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2151 return Err(existing);
2152 }
2153
2154 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2155 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2156 Ok(TyCtxtFeed { key: num, tcx: self })
2157 }
2158
2159 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2160 self.ensure_ok().analysis(());
2162
2163 let definitions = &self.untracked.definitions;
2164 gen {
2165 let mut i = 0;
2166
2167 while i < { definitions.read().num_definitions() } {
2170 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2171 yield LocalDefId { local_def_index };
2172 i += 1;
2173 }
2174
2175 definitions.freeze();
2177 }
2178 }
2179
2180 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2181 self.ensure_ok().analysis(());
2183
2184 self.untracked.definitions.freeze().def_path_table()
2187 }
2188
2189 pub fn def_path_hash_to_def_index_map(
2190 self,
2191 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2192 self.ensure_ok().hir_crate_items(());
2195 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2198 }
2199
2200 #[inline]
2203 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2204 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2205 }
2206
2207 pub fn untracked(self) -> &'tcx Untracked {
2209 &self.untracked
2210 }
2211 #[inline]
2214 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2215 self.untracked.definitions.read()
2216 }
2217
2218 #[inline]
2221 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2222 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2223 }
2224
2225 #[inline(always)]
2226 pub fn with_stable_hashing_context<R>(
2227 self,
2228 f: impl FnOnce(StableHashingContext<'_>) -> R,
2229 ) -> R {
2230 f(StableHashingContext::new(self.sess, &self.untracked))
2231 }
2232
2233 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2234 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2235 }
2236
2237 #[inline]
2238 pub fn local_crate_exports_generics(self) -> bool {
2239 self.crate_types().iter().any(|crate_type| {
2240 match crate_type {
2241 CrateType::Executable
2242 | CrateType::Staticlib
2243 | CrateType::ProcMacro
2244 | CrateType::Cdylib
2245 | CrateType::Sdylib => false,
2246
2247 CrateType::Dylib => true,
2252
2253 CrateType::Rlib => true,
2254 }
2255 })
2256 }
2257
2258 pub fn is_suitable_region(
2260 self,
2261 generic_param_scope: LocalDefId,
2262 mut region: Region<'tcx>,
2263 ) -> Option<FreeRegionInfo> {
2264 let (suitable_region_binding_scope, region_def_id) = loop {
2265 let def_id =
2266 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2267 let scope = self.local_parent(def_id);
2268 if self.def_kind(scope) == DefKind::OpaqueTy {
2269 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2272 continue;
2273 }
2274 break (scope, def_id.into());
2275 };
2276
2277 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2278 Node::Item(..) | Node::TraitItem(..) => false,
2279 Node::ImplItem(impl_item) => match impl_item.impl_kind {
2280 hir::ImplItemImplKind::Trait { .. } => true,
2287 _ => false,
2288 },
2289 _ => false,
2290 };
2291
2292 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2293 }
2294
2295 pub fn return_type_impl_or_dyn_traits(
2297 self,
2298 scope_def_id: LocalDefId,
2299 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2300 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2301 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2302 self.hir_fn_decl_by_hir_id(hir_id)
2303 else {
2304 return vec![];
2305 };
2306
2307 let mut v = TraitObjectVisitor(vec![]);
2308 v.visit_ty_unambig(hir_output);
2309 v.0
2310 }
2311
2312 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2316 self,
2317 scope_def_id: LocalDefId,
2318 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2319 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2320 let mut v = TraitObjectVisitor(vec![]);
2321 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2323 && let hir::TyKind::Path(hir::QPath::Resolved(
2324 None,
2325 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2326 && let Some(local_id) = def_id.as_local()
2327 && 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()
2329 {
2330 v.visit_ty_unambig(alias_ty);
2331 if !v.0.is_empty() {
2332 return Some((
2333 v.0,
2334 alias_generics.span,
2335 alias_generics.span_for_lifetime_suggestion(),
2336 ));
2337 }
2338 }
2339 None
2340 }
2341
2342 pub fn has_strict_asm_symbol_naming(self) -> bool {
2345 self.sess.target.arch.contains("nvptx")
2346 }
2347
2348 pub fn caller_location_ty(self) -> Ty<'tcx> {
2350 Ty::new_imm_ref(
2351 self,
2352 self.lifetimes.re_static,
2353 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2354 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2355 )
2356 }
2357
2358 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2360 let kind = self.def_kind(def_id);
2361 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2362 }
2363
2364 pub fn type_length_limit(self) -> Limit {
2365 self.limits(()).type_length_limit
2366 }
2367
2368 pub fn recursion_limit(self) -> Limit {
2369 self.limits(()).recursion_limit
2370 }
2371
2372 pub fn move_size_limit(self) -> Limit {
2373 self.limits(()).move_size_limit
2374 }
2375
2376 pub fn pattern_complexity_limit(self) -> Limit {
2377 self.limits(()).pattern_complexity_limit
2378 }
2379
2380 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
2382 iter::once(LOCAL_CRATE)
2383 .chain(self.crates(()).iter().copied())
2384 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2385 }
2386
2387 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2389 let visible_crates =
2390 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2391
2392 iter::once(LOCAL_CRATE)
2393 .chain(visible_crates)
2394 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2395 }
2396
2397 #[inline]
2398 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2399 self.visibility(def_id).expect_local()
2400 }
2401
2402 #[instrument(skip(self), level = "trace", ret)]
2404 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2405 self.hir_expect_opaque_ty(def_id).origin
2406 }
2407
2408 pub fn finish(self) {
2409 self.alloc_self_profile_query_strings();
2412
2413 self.save_dep_graph();
2414 self.query_key_hash_verify_all();
2415
2416 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2417 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2418 }
2419 }
2420}
2421
2422macro_rules! nop_lift {
2423 ($set:ident; $ty:ty => $lifted:ty) => {
2424 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2425 type Lifted = $lifted;
2426 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2427 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2432 _x: Interned<'tcx, Inner>,
2433 ) -> InternedSet<'tcx, Inner> {
2434 unreachable!()
2435 }
2436 fn _type_eq<T>(_x: &T, _y: &T) {}
2437 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2438 let interner = _intern_set_ty_from_interned_ty(x.0);
2442 _type_eq(&interner, &tcx.interners.$set);
2444 }
2445
2446 tcx.interners
2447 .$set
2448 .contains_pointer_to(&InternedInSet(&*self.0.0))
2449 .then(|| unsafe { mem::transmute(self) })
2452 }
2453 }
2454 };
2455}
2456
2457macro_rules! nop_list_lift {
2458 ($set:ident; $ty:ty => $lifted:ty) => {
2459 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2460 type Lifted = &'tcx List<$lifted>;
2461 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2462 if false {
2464 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2465 }
2466
2467 if self.is_empty() {
2468 return Some(List::empty());
2469 }
2470 tcx.interners
2471 .$set
2472 .contains_pointer_to(&InternedInSet(self))
2473 .then(|| unsafe { mem::transmute(self) })
2474 }
2475 }
2476 };
2477}
2478
2479nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2480nop_lift! { region; Region<'a> => Region<'tcx> }
2481nop_lift! { const_; Const<'a> => Const<'tcx> }
2482nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2483nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2484nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2485nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2486nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2487nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2488
2489nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2490nop_list_lift! {
2491 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2492}
2493nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2494
2495nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2497
2498macro_rules! sty_debug_print {
2499 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2500 #[allow(non_snake_case)]
2503 mod inner {
2504 use crate::ty::{self, TyCtxt};
2505 use crate::ty::context::InternedInSet;
2506
2507 #[derive(Copy, Clone)]
2508 struct DebugStat {
2509 total: usize,
2510 lt_infer: usize,
2511 ty_infer: usize,
2512 ct_infer: usize,
2513 all_infer: usize,
2514 }
2515
2516 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2517 let mut total = DebugStat {
2518 total: 0,
2519 lt_infer: 0,
2520 ty_infer: 0,
2521 ct_infer: 0,
2522 all_infer: 0,
2523 };
2524 $(let mut $variant = total;)*
2525
2526 for shard in tcx.interners.type_.lock_shards() {
2527 #[allow(rustc::potential_query_instability)]
2529 let types = shard.iter();
2530 for &(InternedInSet(t), ()) in types {
2531 let variant = match t.internee {
2532 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2533 ty::Float(..) | ty::Str | ty::Never => continue,
2534 ty::Error(_) => continue,
2535 $(ty::$variant(..) => &mut $variant,)*
2536 };
2537 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2538 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2539 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2540
2541 variant.total += 1;
2542 total.total += 1;
2543 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2544 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2545 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2546 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2547 }
2548 }
2549 writeln!(fmt, "Ty interner total ty lt ct all")?;
2550 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2551 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2552 stringify!($variant),
2553 uses = $variant.total,
2554 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2555 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2556 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2557 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2558 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2559 )*
2560 writeln!(fmt, " total {uses:6} \
2561 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2562 uses = total.total,
2563 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2564 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2565 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2566 all = total.all_infer as f64 * 100.0 / total.total as f64)
2567 }
2568 }
2569
2570 inner::go($fmt, $ctxt)
2571 }}
2572}
2573
2574impl<'tcx> TyCtxt<'tcx> {
2575 pub fn debug_stats(self) -> impl fmt::Debug {
2576 fmt::from_fn(move |fmt| {
2577 sty_debug_print!(
2578 fmt,
2579 self,
2580 Adt,
2581 Array,
2582 Slice,
2583 RawPtr,
2584 Ref,
2585 FnDef,
2586 FnPtr,
2587 UnsafeBinder,
2588 Placeholder,
2589 Coroutine,
2590 CoroutineWitness,
2591 Dynamic,
2592 Closure,
2593 CoroutineClosure,
2594 Tuple,
2595 Bound,
2596 Param,
2597 Infer,
2598 Alias,
2599 Pat,
2600 Foreign
2601 )?;
2602
2603 writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2604 writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2605 writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2606 writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2607
2608 Ok(())
2609 })
2610 }
2611}
2612
2613struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2618
2619impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2620 fn clone(&self) -> Self {
2621 InternedInSet(self.0)
2622 }
2623}
2624
2625impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2626
2627impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2628 fn into_pointer(&self) -> *const () {
2629 self.0 as *const _ as *const ()
2630 }
2631}
2632
2633#[allow(rustc::usage_of_ty_tykind)]
2634impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2635 fn borrow(&self) -> &T {
2636 &self.0.internee
2637 }
2638}
2639
2640impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2641 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2642 self.0.internee == other.0.internee
2645 }
2646}
2647
2648impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2649
2650impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2651 fn hash<H: Hasher>(&self, s: &mut H) {
2652 self.0.internee.hash(s)
2654 }
2655}
2656
2657impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2658 fn borrow(&self) -> &[T] {
2659 &self.0[..]
2660 }
2661}
2662
2663impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2664 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2665 self.0[..] == other.0[..]
2668 }
2669}
2670
2671impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2672
2673impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2674 fn hash<H: Hasher>(&self, s: &mut H) {
2675 self.0[..].hash(s)
2677 }
2678}
2679
2680impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2681 fn borrow(&self) -> &[T] {
2682 &self.0[..]
2683 }
2684}
2685
2686impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2687 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2688 self.0[..] == other.0[..]
2691 }
2692}
2693
2694impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2695
2696impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2697 fn hash<H: Hasher>(&self, s: &mut H) {
2698 self.0[..].hash(s)
2700 }
2701}
2702
2703macro_rules! direct_interners {
2704 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2705 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2706 fn borrow<'a>(&'a self) -> &'a $ty {
2707 &self.0
2708 }
2709 }
2710
2711 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2712 fn eq(&self, other: &Self) -> bool {
2713 self.0 == other.0
2716 }
2717 }
2718
2719 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2720
2721 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2722 fn hash<H: Hasher>(&self, s: &mut H) {
2723 self.0.hash(s)
2726 }
2727 }
2728
2729 impl<'tcx> TyCtxt<'tcx> {
2730 $vis fn $method(self, v: $ty) -> $ret_ty {
2731 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2732 InternedInSet(self.interners.arena.alloc(v))
2733 }).0))
2734 }
2735 })+
2736 }
2737}
2738
2739direct_interners! {
2743 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2744 valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2745 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2746 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2747 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2748 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2749 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2750 ExternalConstraints -> ExternalConstraints<'tcx>,
2751 predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2752 PredefinedOpaques -> PredefinedOpaques<'tcx>,
2753}
2754
2755macro_rules! slice_interners {
2756 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2757 impl<'tcx> TyCtxt<'tcx> {
2758 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2759 if v.is_empty() {
2760 List::empty()
2761 } else {
2762 self.interners.$field.intern_ref(v, || {
2763 InternedInSet(List::from_arena(&*self.arena, (), v))
2764 }).0
2765 }
2766 })+
2767 }
2768 );
2769}
2770
2771slice_interners!(
2775 const_lists: pub mk_const_list(Const<'tcx>),
2776 args: pub mk_args(GenericArg<'tcx>),
2777 type_lists: pub mk_type_list(Ty<'tcx>),
2778 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2779 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2780 projs: pub mk_projs(ProjectionKind),
2781 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2782 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2783 fields: pub mk_fields(FieldIdx),
2784 local_def_ids: intern_local_def_ids(LocalDefId),
2785 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2786 offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2787 patterns: pub mk_patterns(Pattern<'tcx>),
2788 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2789);
2790
2791impl<'tcx> TyCtxt<'tcx> {
2792 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2796 assert!(sig.safety().is_safe());
2797 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2798 }
2799
2800 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2803 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2804 self.associated_items(trait_did)
2805 .filter_by_name_unhygienic(assoc_name.name)
2806 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2807 })
2808 }
2809
2810 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2812 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2813 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2814
2815 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2816 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2817 return false;
2818 };
2819 trait_predicate.trait_ref.def_id == future_trait
2820 && trait_predicate.polarity == PredicatePolarity::Positive
2821 })
2822 }
2823
2824 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2832 sig.map_bound(|s| {
2833 let params = match s.inputs()[0].kind() {
2834 ty::Tuple(params) => *params,
2835 _ => bug!(),
2836 };
2837 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2838 })
2839 }
2840
2841 #[inline]
2842 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2843 self.interners.intern_predicate(
2844 binder,
2845 self.sess,
2846 &self.untracked,
2848 )
2849 }
2850
2851 #[inline]
2852 pub fn reuse_or_mk_predicate(
2853 self,
2854 pred: Predicate<'tcx>,
2855 binder: Binder<'tcx, PredicateKind<'tcx>>,
2856 ) -> Predicate<'tcx> {
2857 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2858 }
2859
2860 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2861 self.check_args_compatible_inner(def_id, args, false)
2862 }
2863
2864 fn check_args_compatible_inner(
2865 self,
2866 def_id: DefId,
2867 args: &'tcx [ty::GenericArg<'tcx>],
2868 nested: bool,
2869 ) -> bool {
2870 let generics = self.generics_of(def_id);
2871
2872 let own_args = if !nested
2875 && let DefKind::AssocTy = self.def_kind(def_id)
2876 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2877 {
2878 if generics.own_params.len() + 1 != args.len() {
2879 return false;
2880 }
2881
2882 if !matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2883 return false;
2884 }
2885
2886 &args[1..]
2887 } else {
2888 if generics.count() != args.len() {
2889 return false;
2890 }
2891
2892 let (parent_args, own_args) = args.split_at(generics.parent_count);
2893
2894 if let Some(parent) = generics.parent
2895 && !self.check_args_compatible_inner(parent, parent_args, true)
2896 {
2897 return false;
2898 }
2899
2900 own_args
2901 };
2902
2903 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2904 match (¶m.kind, arg.kind()) {
2905 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2906 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2907 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2908 _ => return false,
2909 }
2910 }
2911
2912 true
2913 }
2914
2915 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2918 if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2919 if let DefKind::AssocTy = self.def_kind(def_id)
2920 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2921 {
2922 bug!(
2923 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2924 self.def_path_str(def_id),
2925 args,
2926 self.mk_args_from_iter(
2928 [self.types.self_param.into()].into_iter().chain(
2929 self.generics_of(def_id)
2930 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2931 .iter()
2932 .copied()
2933 )
2934 )
2935 );
2936 } else {
2937 bug!(
2938 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2939 self.def_path_str(def_id),
2940 args,
2941 ty::GenericArgs::identity_for_item(self, def_id)
2942 );
2943 }
2944 }
2945 }
2946
2947 #[inline(always)]
2948 pub(crate) fn check_and_mk_args(
2949 self,
2950 def_id: DefId,
2951 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2952 ) -> GenericArgsRef<'tcx> {
2953 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2954 self.debug_assert_args_compatible(def_id, args);
2955 args
2956 }
2957
2958 #[inline]
2959 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2960 self.interners.intern_const(
2961 kind,
2962 self.sess,
2963 &self.untracked,
2965 )
2966 }
2967
2968 #[allow(rustc::usage_of_ty_tykind)]
2970 #[inline]
2971 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2972 self.interners.intern_ty(
2973 st,
2974 self.sess,
2975 &self.untracked,
2977 )
2978 }
2979
2980 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2981 match param.kind {
2982 GenericParamDefKind::Lifetime => {
2983 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2984 }
2985 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2986 GenericParamDefKind::Const { .. } => {
2987 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2988 .into()
2989 }
2990 }
2991 }
2992
2993 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2994 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2995 }
2996
2997 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2998 self.mk_place_elem(place, PlaceElem::Deref)
2999 }
3000
3001 pub fn mk_place_downcast(
3002 self,
3003 place: Place<'tcx>,
3004 adt_def: AdtDef<'tcx>,
3005 variant_index: VariantIdx,
3006 ) -> Place<'tcx> {
3007 self.mk_place_elem(
3008 place,
3009 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
3010 )
3011 }
3012
3013 pub fn mk_place_downcast_unnamed(
3014 self,
3015 place: Place<'tcx>,
3016 variant_index: VariantIdx,
3017 ) -> Place<'tcx> {
3018 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
3019 }
3020
3021 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
3022 self.mk_place_elem(place, PlaceElem::Index(index))
3023 }
3024
3025 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
3029 let mut projection = place.projection.to_vec();
3030 projection.push(elem);
3031
3032 Place { local: place.local, projection: self.mk_place_elems(&projection) }
3033 }
3034
3035 pub fn mk_poly_existential_predicates(
3036 self,
3037 eps: &[PolyExistentialPredicate<'tcx>],
3038 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
3039 assert!(!eps.is_empty());
3040 assert!(
3041 eps.array_windows()
3042 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
3043 != Ordering::Greater)
3044 );
3045 self.intern_poly_existential_predicates(eps)
3046 }
3047
3048 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
3049 self.interners.intern_clauses(clauses)
3053 }
3054
3055 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
3056 self.intern_local_def_ids(def_ids)
3060 }
3061
3062 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
3063 where
3064 I: Iterator<Item = T>,
3065 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
3066 {
3067 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
3068 }
3069
3070 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
3071 where
3072 I: Iterator<Item = T>,
3073 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
3074 {
3075 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
3076 }
3077
3078 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
3079 where
3080 I: Iterator<Item = T>,
3081 T: CollectAndApply<
3082 &'tcx ty::CapturedPlace<'tcx>,
3083 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
3084 >,
3085 {
3086 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
3087 }
3088
3089 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
3090 where
3091 I: Iterator<Item = T>,
3092 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
3093 {
3094 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3095 }
3096
3097 pub fn mk_fn_sig<I, T>(
3102 self,
3103 inputs: I,
3104 output: I::Item,
3105 c_variadic: bool,
3106 safety: hir::Safety,
3107 abi: ExternAbi,
3108 ) -> T::Output
3109 where
3110 I: IntoIterator<Item = T>,
3111 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3112 {
3113 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3114 inputs_and_output: self.mk_type_list(xs),
3115 c_variadic,
3116 safety,
3117 abi,
3118 })
3119 }
3120
3121 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3122 where
3123 I: Iterator<Item = T>,
3124 T: CollectAndApply<
3125 PolyExistentialPredicate<'tcx>,
3126 &'tcx List<PolyExistentialPredicate<'tcx>>,
3127 >,
3128 {
3129 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3130 }
3131
3132 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3133 where
3134 I: Iterator<Item = T>,
3135 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3136 {
3137 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3138 }
3139
3140 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3141 where
3142 I: Iterator<Item = T>,
3143 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3144 {
3145 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3146 }
3147
3148 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3149 where
3150 I: Iterator<Item = T>,
3151 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3152 {
3153 T::collect_and_apply(iter, |xs| self.mk_args(xs))
3154 }
3155
3156 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3157 where
3158 I: Iterator<Item = T>,
3159 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3160 {
3161 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3162 }
3163
3164 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3165 where
3166 I: Iterator<Item = T>,
3167 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3168 {
3169 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3170 }
3171
3172 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3173 where
3174 I: Iterator<Item = T>,
3175 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3176 {
3177 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3178 }
3179
3180 pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
3181 where
3182 I: Iterator<Item = T>,
3183 T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
3184 {
3185 T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
3186 }
3187
3188 pub fn mk_args_trait(
3189 self,
3190 self_ty: Ty<'tcx>,
3191 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3192 ) -> GenericArgsRef<'tcx> {
3193 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3194 }
3195
3196 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3197 where
3198 I: Iterator<Item = T>,
3199 T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3200 {
3201 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3202 }
3203
3204 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
3205 where
3206 I: Iterator<Item = T>,
3207 T: CollectAndApply<
3208 ty::ArgOutlivesPredicate<'tcx>,
3209 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
3210 >,
3211 {
3212 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
3213 }
3214
3215 #[track_caller]
3218 pub fn emit_node_span_lint(
3219 self,
3220 lint: &'static Lint,
3221 hir_id: HirId,
3222 span: impl Into<MultiSpan>,
3223 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3224 ) {
3225 let level = self.lint_level_at_node(lint, hir_id);
3226 lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3227 decorator.decorate_lint(lint);
3228 })
3229 }
3230
3231 #[rustc_lint_diagnostics]
3235 #[track_caller]
3236 pub fn node_span_lint(
3237 self,
3238 lint: &'static Lint,
3239 hir_id: HirId,
3240 span: impl Into<MultiSpan>,
3241 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3242 ) {
3243 let level = self.lint_level_at_node(lint, hir_id);
3244 lint_level(self.sess, lint, level, Some(span.into()), decorate);
3245 }
3246
3247 pub fn crate_level_attribute_injection_span(self) -> Span {
3249 let node = self.hir_node(hir::CRATE_HIR_ID);
3250 let hir::Node::Crate(m) = node else { bug!() };
3251 m.spans.inject_use_span.shrink_to_lo()
3252 }
3253
3254 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3255 self,
3256 diag: &mut Diag<'_, E>,
3257 features: impl IntoIterator<Item = (String, Symbol)>,
3258 ) {
3259 if !self.sess.is_nightly_build() {
3260 return;
3261 }
3262
3263 let span = self.crate_level_attribute_injection_span();
3264 for (desc, feature) in features {
3265 let msg =
3267 format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3268 diag.span_suggestion_verbose(
3269 span,
3270 msg,
3271 format!("#![feature({feature})]\n"),
3272 Applicability::MaybeIncorrect,
3273 );
3274 }
3275 }
3276
3277 #[track_caller]
3280 pub fn emit_node_lint(
3281 self,
3282 lint: &'static Lint,
3283 id: HirId,
3284 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3285 ) {
3286 self.node_lint(lint, id, |lint| {
3287 decorator.decorate_lint(lint);
3288 })
3289 }
3290
3291 #[rustc_lint_diagnostics]
3295 #[track_caller]
3296 pub fn node_lint(
3297 self,
3298 lint: &'static Lint,
3299 id: HirId,
3300 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3301 ) {
3302 let level = self.lint_level_at_node(lint, id);
3303 lint_level(self.sess, lint, level, None, decorate);
3304 }
3305
3306 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3307 let map = self.in_scope_traits_map(id.owner)?;
3308 let candidates = map.get(&id.local_id)?;
3309 Some(candidates)
3310 }
3311
3312 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3313 debug!(?id, "named_region");
3314 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3315 }
3316
3317 pub fn is_late_bound(self, id: HirId) -> bool {
3318 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3319 }
3320
3321 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3322 self.mk_bound_variable_kinds(
3323 &self
3324 .late_bound_vars_map(id.owner)
3325 .get(&id.local_id)
3326 .cloned()
3327 .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3328 )
3329 }
3330
3331 pub fn map_opaque_lifetime_to_parent_lifetime(
3339 self,
3340 mut opaque_lifetime_param_def_id: LocalDefId,
3341 ) -> ty::Region<'tcx> {
3342 debug_assert!(
3343 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3344 "{opaque_lifetime_param_def_id:?} is a {}",
3345 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3346 );
3347
3348 loop {
3349 let parent = self.local_parent(opaque_lifetime_param_def_id);
3350 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3351
3352 let Some((lifetime, _)) = lifetime_mapping
3353 .iter()
3354 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3355 else {
3356 bug!("duplicated lifetime param should be present");
3357 };
3358
3359 match *lifetime {
3360 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3361 let new_parent = self.local_parent(ebv);
3362
3363 if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3366 debug_assert_eq!(self.local_parent(parent), new_parent);
3367 opaque_lifetime_param_def_id = ebv;
3368 continue;
3369 }
3370
3371 let generics = self.generics_of(new_parent);
3372 return ty::Region::new_early_param(
3373 self,
3374 ty::EarlyParamRegion {
3375 index: generics
3376 .param_def_id_to_index(self, ebv.to_def_id())
3377 .expect("early-bound var should be present in fn generics"),
3378 name: self.item_name(ebv.to_def_id()),
3379 },
3380 );
3381 }
3382 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3383 let new_parent = self.local_parent(lbv);
3384 return ty::Region::new_late_param(
3385 self,
3386 new_parent.to_def_id(),
3387 ty::LateParamRegionKind::Named(lbv.to_def_id()),
3388 );
3389 }
3390 resolve_bound_vars::ResolvedArg::Error(guar) => {
3391 return ty::Region::new_error(self, guar);
3392 }
3393 _ => {
3394 return ty::Region::new_error_with_message(
3395 self,
3396 self.def_span(opaque_lifetime_param_def_id),
3397 "cannot resolve lifetime",
3398 );
3399 }
3400 }
3401 }
3402 }
3403
3404 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3409 self.is_const_fn(def_id)
3410 && match self.lookup_const_stability(def_id) {
3411 None => true, Some(stability) if stability.is_const_stable() => true,
3413 _ => false,
3414 }
3415 }
3416
3417 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3419 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3420 && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3421 }
3422
3423 pub fn is_sdylib_interface_build(self) -> bool {
3424 self.sess.opts.unstable_opts.build_sdylib_interface
3425 }
3426
3427 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3428 match self.def_kind(def_id) {
3429 DefKind::Fn | DefKind::AssocFn => {}
3430 _ => return None,
3431 }
3432 self.intrinsic_raw(def_id)
3433 }
3434
3435 pub fn next_trait_solver_globally(self) -> bool {
3436 self.sess.opts.unstable_opts.next_solver.globally
3437 }
3438
3439 pub fn next_trait_solver_in_coherence(self) -> bool {
3440 self.sess.opts.unstable_opts.next_solver.coherence
3441 }
3442
3443 #[allow(rustc::bad_opt_access)]
3444 pub fn use_typing_mode_borrowck(self) -> bool {
3445 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3446 }
3447
3448 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3449 self.opt_rpitit_info(def_id).is_some()
3450 }
3451
3452 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3462 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3463 }
3464
3465 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
3467 self.resolutions(()).extern_crate_map.get(&def_id).copied()
3468 }
3469
3470 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3471 self.resolver_for_lowering_raw(()).0
3472 }
3473
3474 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
3475 crate::dep_graph::make_metadata(self)
3476 }
3477
3478 pub fn impl_trait_ref(
3481 self,
3482 def_id: impl IntoQueryParam<DefId>,
3483 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3484 Some(self.impl_trait_header(def_id)?.trait_ref)
3485 }
3486
3487 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3488 self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3489 }
3490
3491 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3492 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3493 self.coroutine_kind(def_id)
3494 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3495 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3496 {
3497 true
3498 } else {
3499 false
3500 }
3501 }
3502
3503 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3505 self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3506 }
3507
3508 pub fn is_entrypoint(self, def_id: DefId) -> bool {
3511 if self.is_lang_item(def_id, LangItem::Start) {
3512 return true;
3513 }
3514 if let Some((entry_def_id, _)) = self.entry_fn(())
3515 && entry_def_id == def_id
3516 {
3517 return true;
3518 }
3519 false
3520 }
3521}
3522
3523#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3532pub struct DeducedParamAttrs {
3533 pub read_only: bool,
3536}
3537
3538pub fn provide(providers: &mut Providers) {
3539 providers.is_panic_runtime =
3540 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3541 providers.is_compiler_builtins =
3542 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3543 providers.has_panic_handler = |tcx, LocalCrate| {
3544 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3546 };
3547 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3548}
3549
3550pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3551 attrs.iter().any(|x| x.has_name(name))
3552}