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 let trait_impls = tcx.trait_impls_of(trait_def_id);
655 for &impl_def_id in trait_impls.blanket_impls() {
656 f(impl_def_id);
657 }
658 }
659
660 fn has_item_definition(self, def_id: DefId) -> bool {
661 self.defaultness(def_id).has_value()
662 }
663
664 fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
665 self.specializes((impl_def_id, victim_def_id))
666 }
667
668 fn impl_is_default(self, impl_def_id: DefId) -> bool {
669 self.defaultness(impl_def_id).is_default()
670 }
671
672 fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
673 self.impl_trait_ref(impl_def_id).unwrap()
674 }
675
676 fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
677 self.impl_polarity(impl_def_id)
678 }
679
680 fn trait_is_auto(self, trait_def_id: DefId) -> bool {
681 self.trait_is_auto(trait_def_id)
682 }
683
684 fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
685 self.trait_is_coinductive(trait_def_id)
686 }
687
688 fn trait_is_alias(self, trait_def_id: DefId) -> bool {
689 self.trait_is_alias(trait_def_id)
690 }
691
692 fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
693 self.is_dyn_compatible(trait_def_id)
694 }
695
696 fn trait_is_fundamental(self, def_id: DefId) -> bool {
697 self.trait_def(def_id).is_fundamental
698 }
699
700 fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
701 self.trait_def(trait_def_id).implement_via_object
702 }
703
704 fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
705 self.trait_def(trait_def_id).safety.is_unsafe()
706 }
707
708 fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
709 self.is_impl_trait_in_trait(def_id)
710 }
711
712 fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
713 self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
714 }
715
716 fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
717 self.is_general_coroutine(coroutine_def_id)
718 }
719
720 fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
721 self.coroutine_is_async(coroutine_def_id)
722 }
723
724 fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
725 self.coroutine_is_gen(coroutine_def_id)
726 }
727
728 fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
729 self.coroutine_is_async_gen(coroutine_def_id)
730 }
731
732 type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
733 fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
734 self.unsizing_params_for_adt(adt_def_id)
735 }
736
737 fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
738 self,
739 binder: ty::Binder<'tcx, T>,
740 ) -> ty::Binder<'tcx, T> {
741 self.anonymize_bound_vars(binder)
742 }
743
744 fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
745 self.opaque_types_defined_by(defining_anchor)
746 }
747
748 fn opaque_types_and_coroutines_defined_by(
749 self,
750 defining_anchor: Self::LocalDefId,
751 ) -> Self::LocalDefIds {
752 let coroutines_defined_by = self
753 .nested_bodies_within(defining_anchor)
754 .iter()
755 .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
756 self.mk_local_def_ids_from_iter(
757 self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
758 )
759 }
760
761 type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
762 fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
763 self.arena.alloc(probe)
764 }
765 fn evaluate_root_goal_for_proof_tree_raw(
766 self,
767 canonical_goal: CanonicalInput<'tcx>,
768 ) -> (QueryResult<'tcx>, &'tcx inspect::Probe<TyCtxt<'tcx>>) {
769 self.evaluate_root_goal_for_proof_tree_raw(canonical_goal)
770 }
771}
772
773macro_rules! bidirectional_lang_item_map {
774 (
775 $solver_ty:ident, $to_solver:ident, $from_solver:ident;
776 $($name:ident),+ $(,)?
777 ) => {
778 fn $from_solver(lang_item: $solver_ty) -> LangItem {
779 match lang_item {
780 $($solver_ty::$name => LangItem::$name,)+
781 }
782 }
783
784 fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> {
785 Some(match lang_item {
786 $(LangItem::$name => $solver_ty::$name,)+
787 _ => return None,
788 })
789 }
790 }
791}
792
793bidirectional_lang_item_map! {
794 SolverLangItem, lang_item_to_solver_lang_item, solver_lang_item_to_lang_item;
795
796AsyncFnKindUpvars,
798 AsyncFnOnceOutput,
799 CallOnceFuture,
800 CallRefFuture,
801 CoroutineReturn,
802 CoroutineYield,
803 DynMetadata,
804 FutureOutput,
805 Metadata,
806}
808
809bidirectional_lang_item_map! {
810 SolverAdtLangItem, lang_item_to_solver_adt_lang_item, solver_adt_lang_item_to_lang_item;
811
812Option,
814 Poll,
815}
817
818bidirectional_lang_item_map! {
819 SolverTraitLangItem, lang_item_to_solver_trait_lang_item, solver_trait_lang_item_to_lang_item;
820
821AsyncFn,
823 AsyncFnKindHelper,
824 AsyncFnMut,
825 AsyncFnOnce,
826 AsyncFnOnceOutput,
827 AsyncIterator,
828 BikeshedGuaranteedNoDrop,
829 Clone,
830 Copy,
831 Coroutine,
832 Destruct,
833 DiscriminantKind,
834 Drop,
835 Fn,
836 FnMut,
837 FnOnce,
838 FnPtrTrait,
839 FusedIterator,
840 Future,
841 Iterator,
842 MetaSized,
843 PointeeSized,
844 PointeeTrait,
845 Sized,
846 TransmuteTrait,
847 Tuple,
848 Unpin,
849 Unsize,
850}
852
853impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
854 fn is_local(self) -> bool {
855 self.is_local()
856 }
857
858 fn as_local(self) -> Option<LocalDefId> {
859 self.as_local()
860 }
861}
862
863impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
864 fn rust() -> Self {
865 ExternAbi::Rust
866 }
867
868 fn is_rust(self) -> bool {
869 matches!(self, ExternAbi::Rust)
870 }
871}
872
873impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
874 fn safe() -> Self {
875 hir::Safety::Safe
876 }
877
878 fn is_safe(self) -> bool {
879 self.is_safe()
880 }
881
882 fn prefix_str(self) -> &'static str {
883 self.prefix_str()
884 }
885}
886
887impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
888 fn generic_const_exprs(self) -> bool {
889 self.generic_const_exprs()
890 }
891
892 fn coroutine_clone(self) -> bool {
893 self.coroutine_clone()
894 }
895
896 fn associated_const_equality(self) -> bool {
897 self.associated_const_equality()
898 }
899
900 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
901 !self.staged_api() && self.enabled(symbol)
905 }
906}
907
908impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
909 fn dummy() -> Self {
910 DUMMY_SP
911 }
912}
913
914type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
915
916pub struct CtxtInterners<'tcx> {
917 arena: &'tcx WorkerLocal<Arena<'tcx>>,
919
920 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
923 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
924 args: InternedSet<'tcx, GenericArgs<'tcx>>,
925 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
926 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
927 region: InternedSet<'tcx, RegionKind<'tcx>>,
928 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
929 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
930 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
931 projs: InternedSet<'tcx, List<ProjectionKind>>,
932 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
933 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
934 pat: InternedSet<'tcx, PatternKind<'tcx>>,
935 const_allocation: InternedSet<'tcx, Allocation>,
936 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
937 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
938 adt_def: InternedSet<'tcx, AdtDefData>,
939 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
940 predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
941 fields: InternedSet<'tcx, List<FieldIdx>>,
942 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
943 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
944 offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
945 valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
946 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
947 outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
948}
949
950impl<'tcx> CtxtInterners<'tcx> {
951 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
952 const N: usize = 2048;
955 CtxtInterners {
956 arena,
957 type_: InternedSet::with_capacity(N * 16),
961 const_lists: InternedSet::with_capacity(N * 4),
962 args: InternedSet::with_capacity(N * 4),
963 type_lists: InternedSet::with_capacity(N * 4),
964 region: InternedSet::with_capacity(N * 4),
965 poly_existential_predicates: InternedSet::with_capacity(N / 4),
966 canonical_var_kinds: InternedSet::with_capacity(N / 2),
967 predicate: InternedSet::with_capacity(N),
968 clauses: InternedSet::with_capacity(N),
969 projs: InternedSet::with_capacity(N * 4),
970 place_elems: InternedSet::with_capacity(N * 2),
971 const_: InternedSet::with_capacity(N * 2),
972 pat: InternedSet::with_capacity(N),
973 const_allocation: InternedSet::with_capacity(N),
974 bound_variable_kinds: InternedSet::with_capacity(N * 2),
975 layout: InternedSet::with_capacity(N),
976 adt_def: InternedSet::with_capacity(N),
977 external_constraints: InternedSet::with_capacity(N),
978 predefined_opaques_in_body: InternedSet::with_capacity(N),
979 fields: InternedSet::with_capacity(N * 4),
980 local_def_ids: InternedSet::with_capacity(N),
981 captures: InternedSet::with_capacity(N),
982 offset_of: InternedSet::with_capacity(N),
983 valtree: InternedSet::with_capacity(N),
984 patterns: InternedSet::with_capacity(N),
985 outlives: InternedSet::with_capacity(N),
986 }
987 }
988
989 #[allow(rustc::usage_of_ty_tykind)]
991 #[inline(never)]
992 fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
993 Ty(Interned::new_unchecked(
994 self.type_
995 .intern(kind, |kind| {
996 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
997 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
998
999 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1000 internee: kind,
1001 stable_hash,
1002 flags: flags.flags,
1003 outer_exclusive_binder: flags.outer_exclusive_binder,
1004 }))
1005 })
1006 .0,
1007 ))
1008 }
1009
1010 #[allow(rustc::usage_of_ty_tykind)]
1012 #[inline(never)]
1013 fn intern_const(
1014 &self,
1015 kind: ty::ConstKind<'tcx>,
1016 sess: &Session,
1017 untracked: &Untracked,
1018 ) -> Const<'tcx> {
1019 Const(Interned::new_unchecked(
1020 self.const_
1021 .intern(kind, |kind: ty::ConstKind<'_>| {
1022 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
1023 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1024
1025 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1026 internee: kind,
1027 stable_hash,
1028 flags: flags.flags,
1029 outer_exclusive_binder: flags.outer_exclusive_binder,
1030 }))
1031 })
1032 .0,
1033 ))
1034 }
1035
1036 fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
1037 &self,
1038 flags: &ty::FlagComputation<TyCtxt<'tcx>>,
1039 sess: &'a Session,
1040 untracked: &'a Untracked,
1041 val: &T,
1042 ) -> Fingerprint {
1043 if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
1046 Fingerprint::ZERO
1047 } else {
1048 let mut hasher = StableHasher::new();
1049 let mut hcx = StableHashingContext::new(sess, untracked);
1050 val.hash_stable(&mut hcx, &mut hasher);
1051 hasher.finish()
1052 }
1053 }
1054
1055 #[inline(never)]
1057 fn intern_predicate(
1058 &self,
1059 kind: Binder<'tcx, PredicateKind<'tcx>>,
1060 sess: &Session,
1061 untracked: &Untracked,
1062 ) -> Predicate<'tcx> {
1063 Predicate(Interned::new_unchecked(
1064 self.predicate
1065 .intern(kind, |kind| {
1066 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
1067
1068 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1069
1070 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1071 internee: kind,
1072 stable_hash,
1073 flags: flags.flags,
1074 outer_exclusive_binder: flags.outer_exclusive_binder,
1075 }))
1076 })
1077 .0,
1078 ))
1079 }
1080
1081 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
1082 if clauses.is_empty() {
1083 ListWithCachedTypeInfo::empty()
1084 } else {
1085 self.clauses
1086 .intern_ref(clauses, || {
1087 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
1088
1089 InternedInSet(ListWithCachedTypeInfo::from_arena(
1090 &*self.arena,
1091 flags.into(),
1092 clauses,
1093 ))
1094 })
1095 .0
1096 }
1097 }
1098}
1099
1100const NUM_PREINTERNED_TY_VARS: u32 = 100;
1105const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
1106const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
1107const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
1108const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
1109const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
1110
1111const NUM_PREINTERNED_RE_VARS: u32 = 500;
1113const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
1114const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
1115
1116pub struct CommonTypes<'tcx> {
1117 pub unit: Ty<'tcx>,
1118 pub bool: Ty<'tcx>,
1119 pub char: Ty<'tcx>,
1120 pub isize: Ty<'tcx>,
1121 pub i8: Ty<'tcx>,
1122 pub i16: Ty<'tcx>,
1123 pub i32: Ty<'tcx>,
1124 pub i64: Ty<'tcx>,
1125 pub i128: Ty<'tcx>,
1126 pub usize: Ty<'tcx>,
1127 pub u8: Ty<'tcx>,
1128 pub u16: Ty<'tcx>,
1129 pub u32: Ty<'tcx>,
1130 pub u64: Ty<'tcx>,
1131 pub u128: Ty<'tcx>,
1132 pub f16: Ty<'tcx>,
1133 pub f32: Ty<'tcx>,
1134 pub f64: Ty<'tcx>,
1135 pub f128: Ty<'tcx>,
1136 pub str_: Ty<'tcx>,
1137 pub never: Ty<'tcx>,
1138 pub self_param: Ty<'tcx>,
1139
1140 pub trait_object_dummy_self: Ty<'tcx>,
1145
1146 pub ty_vars: Vec<Ty<'tcx>>,
1148
1149 pub fresh_tys: Vec<Ty<'tcx>>,
1151
1152 pub fresh_int_tys: Vec<Ty<'tcx>>,
1154
1155 pub fresh_float_tys: Vec<Ty<'tcx>>,
1157
1158 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
1162}
1163
1164pub struct CommonLifetimes<'tcx> {
1165 pub re_static: Region<'tcx>,
1167
1168 pub re_erased: Region<'tcx>,
1170
1171 pub re_vars: Vec<Region<'tcx>>,
1173
1174 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
1178}
1179
1180pub struct CommonConsts<'tcx> {
1181 pub unit: Const<'tcx>,
1182 pub true_: Const<'tcx>,
1183 pub false_: Const<'tcx>,
1184 pub(crate) valtree_zst: ValTree<'tcx>,
1186}
1187
1188impl<'tcx> CommonTypes<'tcx> {
1189 fn new(
1190 interners: &CtxtInterners<'tcx>,
1191 sess: &Session,
1192 untracked: &Untracked,
1193 ) -> CommonTypes<'tcx> {
1194 let mk = |ty| interners.intern_ty(ty, sess, untracked);
1195
1196 let ty_vars =
1197 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1198 let fresh_tys: Vec<_> =
1199 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1200 let fresh_int_tys: Vec<_> =
1201 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1202 let fresh_float_tys: Vec<_> =
1203 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1204
1205 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
1206 .map(|i| {
1207 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
1208 .map(|v| {
1209 mk(ty::Bound(
1210 ty::DebruijnIndex::from(i),
1211 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
1212 ))
1213 })
1214 .collect()
1215 })
1216 .collect();
1217
1218 CommonTypes {
1219 unit: mk(Tuple(List::empty())),
1220 bool: mk(Bool),
1221 char: mk(Char),
1222 never: mk(Never),
1223 isize: mk(Int(ty::IntTy::Isize)),
1224 i8: mk(Int(ty::IntTy::I8)),
1225 i16: mk(Int(ty::IntTy::I16)),
1226 i32: mk(Int(ty::IntTy::I32)),
1227 i64: mk(Int(ty::IntTy::I64)),
1228 i128: mk(Int(ty::IntTy::I128)),
1229 usize: mk(Uint(ty::UintTy::Usize)),
1230 u8: mk(Uint(ty::UintTy::U8)),
1231 u16: mk(Uint(ty::UintTy::U16)),
1232 u32: mk(Uint(ty::UintTy::U32)),
1233 u64: mk(Uint(ty::UintTy::U64)),
1234 u128: mk(Uint(ty::UintTy::U128)),
1235 f16: mk(Float(ty::FloatTy::F16)),
1236 f32: mk(Float(ty::FloatTy::F32)),
1237 f64: mk(Float(ty::FloatTy::F64)),
1238 f128: mk(Float(ty::FloatTy::F128)),
1239 str_: mk(Str),
1240 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1241
1242 trait_object_dummy_self: fresh_tys[0],
1243
1244 ty_vars,
1245 fresh_tys,
1246 fresh_int_tys,
1247 fresh_float_tys,
1248 anon_bound_tys,
1249 }
1250 }
1251}
1252
1253impl<'tcx> CommonLifetimes<'tcx> {
1254 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1255 let mk = |r| {
1256 Region(Interned::new_unchecked(
1257 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1258 ))
1259 };
1260
1261 let re_vars =
1262 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1263
1264 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
1265 .map(|i| {
1266 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
1267 .map(|v| {
1268 mk(ty::ReBound(
1269 ty::DebruijnIndex::from(i),
1270 ty::BoundRegion {
1271 var: ty::BoundVar::from(v),
1272 kind: ty::BoundRegionKind::Anon,
1273 },
1274 ))
1275 })
1276 .collect()
1277 })
1278 .collect();
1279
1280 CommonLifetimes {
1281 re_static: mk(ty::ReStatic),
1282 re_erased: mk(ty::ReErased),
1283 re_vars,
1284 anon_re_bounds,
1285 }
1286 }
1287}
1288
1289impl<'tcx> CommonConsts<'tcx> {
1290 fn new(
1291 interners: &CtxtInterners<'tcx>,
1292 types: &CommonTypes<'tcx>,
1293 sess: &Session,
1294 untracked: &Untracked,
1295 ) -> CommonConsts<'tcx> {
1296 let mk_const = |c| {
1297 interners.intern_const(
1298 c, sess, untracked,
1300 )
1301 };
1302
1303 let mk_valtree = |v| {
1304 ty::ValTree(Interned::new_unchecked(
1305 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1306 ))
1307 };
1308
1309 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1310 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1311 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1312
1313 CommonConsts {
1314 unit: mk_const(ty::ConstKind::Value(ty::Value {
1315 ty: types.unit,
1316 valtree: valtree_zst,
1317 })),
1318 true_: mk_const(ty::ConstKind::Value(ty::Value {
1319 ty: types.bool,
1320 valtree: valtree_true,
1321 })),
1322 false_: mk_const(ty::ConstKind::Value(ty::Value {
1323 ty: types.bool,
1324 valtree: valtree_false,
1325 })),
1326 valtree_zst,
1327 }
1328 }
1329}
1330
1331#[derive(Debug)]
1334pub struct FreeRegionInfo {
1335 pub scope: LocalDefId,
1337 pub region_def_id: DefId,
1339 pub is_impl_item: bool,
1341}
1342
1343#[derive(Copy, Clone)]
1345pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1346 pub tcx: TyCtxt<'tcx>,
1347 key: KEY,
1349}
1350
1351impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1354
1355#[derive(Copy, Clone)]
1360pub struct Feed<'tcx, KEY: Copy> {
1361 _tcx: PhantomData<TyCtxt<'tcx>>,
1362 key: KEY,
1364}
1365
1366impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1369
1370impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1371 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1372 self.key.fmt(f)
1373 }
1374}
1375
1376impl<'tcx> TyCtxt<'tcx> {
1381 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1384 self.dep_graph.assert_ignored();
1385 TyCtxtFeed { tcx: self, key: () }
1386 }
1387
1388 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1391 let key = self.untracked().source_span.push(span);
1392 assert_eq!(key, CRATE_DEF_ID);
1393 TyCtxtFeed { tcx: self, key }
1394 }
1395
1396 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1400 debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1401 TyCtxtFeed { tcx: self, key }.type_of(value)
1402 }
1403}
1404
1405impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1406 #[inline(always)]
1407 pub fn key(&self) -> KEY {
1408 self.key
1409 }
1410
1411 #[inline(always)]
1412 pub fn downgrade(self) -> Feed<'tcx, KEY> {
1413 Feed { _tcx: PhantomData, key: self.key }
1414 }
1415}
1416
1417impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1418 #[inline(always)]
1419 pub fn key(&self) -> KEY {
1420 self.key
1421 }
1422
1423 #[inline(always)]
1424 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1425 TyCtxtFeed { tcx, key: self.key }
1426 }
1427}
1428
1429impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1430 #[inline(always)]
1431 pub fn def_id(&self) -> LocalDefId {
1432 self.key
1433 }
1434
1435 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1437 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1438 }
1439
1440 pub fn feed_hir(&self) {
1442 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1443
1444 let node = hir::OwnerNode::Synthetic;
1445 let bodies = Default::default();
1446 let attrs = hir::AttributeMap::EMPTY;
1447
1448 let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
1449 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
1450 let node = node.into();
1451 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1452 opt_hash_including_bodies,
1453 nodes: IndexVec::from_elem_n(
1454 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1455 1,
1456 ),
1457 bodies,
1458 })));
1459 self.feed_owner_id().hir_attr_map(attrs);
1460 }
1461}
1462
1463#[derive(Copy, Clone)]
1481#[rustc_diagnostic_item = "TyCtxt"]
1482#[rustc_pass_by_value]
1483pub struct TyCtxt<'tcx> {
1484 gcx: &'tcx GlobalCtxt<'tcx>,
1485}
1486
1487impl<'tcx> LintEmitter for TyCtxt<'tcx> {
1488 type Id = HirId;
1489
1490 fn emit_node_span_lint(
1491 self,
1492 lint: &'static Lint,
1493 hir_id: HirId,
1494 span: impl Into<MultiSpan>,
1495 decorator: impl for<'a> LintDiagnostic<'a, ()>,
1496 ) {
1497 self.emit_node_span_lint(lint, hir_id, span, decorator);
1498 }
1499}
1500
1501unsafe impl DynSend for TyCtxt<'_> {}
1505unsafe impl DynSync for TyCtxt<'_> {}
1506fn _assert_tcx_fields() {
1507 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1508 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1509}
1510
1511impl<'tcx> Deref for TyCtxt<'tcx> {
1512 type Target = &'tcx GlobalCtxt<'tcx>;
1513 #[inline(always)]
1514 fn deref(&self) -> &Self::Target {
1515 &self.gcx
1516 }
1517}
1518
1519pub struct GlobalCtxt<'tcx> {
1521 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1522 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1523
1524 interners: CtxtInterners<'tcx>,
1525
1526 pub sess: &'tcx Session,
1527 crate_types: Vec<CrateType>,
1528 stable_crate_id: StableCrateId,
1534
1535 pub dep_graph: DepGraph,
1536
1537 pub prof: SelfProfilerRef,
1538
1539 pub types: CommonTypes<'tcx>,
1541
1542 pub lifetimes: CommonLifetimes<'tcx>,
1544
1545 pub consts: CommonConsts<'tcx>,
1547
1548 pub(crate) hooks: crate::hooks::Providers,
1551
1552 untracked: Untracked,
1553
1554 pub query_system: QuerySystem<'tcx>,
1555 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1556
1557 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1559
1560 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1563
1564 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1568
1569 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1571 pub new_solver_canonical_param_env_cache:
1572 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
1573
1574 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1575
1576 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
1578 pub clauses_cache:
1580 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
1581
1582 pub data_layout: TargetDataLayout,
1584
1585 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1587
1588 current_gcx: CurrentGcx,
1589
1590 pub jobserver_proxy: Arc<Proxy>,
1592}
1593
1594impl<'tcx> GlobalCtxt<'tcx> {
1595 pub fn enter<F, R>(&'tcx self, f: F) -> R
1598 where
1599 F: FnOnce(TyCtxt<'tcx>) -> R,
1600 {
1601 let icx = tls::ImplicitCtxt::new(self);
1602
1603 let _on_drop = defer(move || {
1605 *self.current_gcx.value.write() = None;
1606 });
1607
1608 {
1610 let mut guard = self.current_gcx.value.write();
1611 assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1612 *guard = Some(self as *const _ as *const ());
1613 }
1614
1615 tls::enter_context(&icx, || f(icx.tcx))
1616 }
1617}
1618
1619#[derive(Clone)]
1626pub struct CurrentGcx {
1627 value: Arc<RwLock<Option<*const ()>>>,
1630}
1631
1632unsafe impl DynSend for CurrentGcx {}
1633unsafe impl DynSync for CurrentGcx {}
1634
1635impl CurrentGcx {
1636 pub fn new() -> Self {
1637 Self { value: Arc::new(RwLock::new(None)) }
1638 }
1639
1640 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1641 let read_guard = self.value.read();
1642 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1643 f(unsafe { &*gcx })
1647 }
1648}
1649
1650impl<'tcx> TyCtxt<'tcx> {
1651 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1652 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1655 if typeck_root_def_id != def_id.to_def_id() {
1656 return self.has_typeck_results(typeck_root_def_id.expect_local());
1657 }
1658
1659 self.hir_node_by_def_id(def_id).body_id().is_some()
1660 }
1661
1662 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1667 let def_kind = self.def_kind(def_id);
1668 if def_kind.has_codegen_attrs() {
1669 self.codegen_fn_attrs(def_id)
1670 } else if matches!(
1671 def_kind,
1672 DefKind::AnonConst
1673 | DefKind::AssocConst
1674 | DefKind::Const
1675 | DefKind::InlineConst
1676 | DefKind::GlobalAsm
1677 ) {
1678 CodegenFnAttrs::EMPTY
1679 } else {
1680 bug!(
1681 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1682 def_id,
1683 def_kind
1684 )
1685 }
1686 }
1687
1688 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1689 self.arena.alloc(Steal::new(thir))
1690 }
1691
1692 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1693 self.arena.alloc(Steal::new(mir))
1694 }
1695
1696 pub fn alloc_steal_promoted(
1697 self,
1698 promoted: IndexVec<Promoted, Body<'tcx>>,
1699 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1700 self.arena.alloc(Steal::new(promoted))
1701 }
1702
1703 pub fn mk_adt_def(
1704 self,
1705 did: DefId,
1706 kind: AdtKind,
1707 variants: IndexVec<VariantIdx, ty::VariantDef>,
1708 repr: ReprOptions,
1709 ) -> ty::AdtDef<'tcx> {
1710 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1711 }
1712
1713 pub fn allocate_bytes_dedup<'a>(
1716 self,
1717 bytes: impl Into<Cow<'a, [u8]>>,
1718 salt: usize,
1719 ) -> interpret::AllocId {
1720 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
1722 let alloc = self.mk_const_alloc(alloc);
1723 self.reserve_and_set_memory_dedup(alloc, salt)
1724 }
1725
1726 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1728 if self.sess.opts.unstable_opts.experimental_default_bounds {
1729 &[
1730 LangItem::DefaultTrait1,
1731 LangItem::DefaultTrait2,
1732 LangItem::DefaultTrait3,
1733 LangItem::DefaultTrait4,
1734 ]
1735 } else {
1736 &[]
1737 }
1738 }
1739
1740 pub fn is_default_trait(self, def_id: DefId) -> bool {
1741 self.default_traits()
1742 .iter()
1743 .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
1744 }
1745
1746 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1750 let start = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1751 let end = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1752 (start, end)
1753 }
1754
1755 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1756 value.lift_to_interner(self)
1757 }
1758
1759 pub fn create_global_ctxt<T>(
1766 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1767 s: &'tcx Session,
1768 crate_types: Vec<CrateType>,
1769 stable_crate_id: StableCrateId,
1770 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1771 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1772 untracked: Untracked,
1773 dep_graph: DepGraph,
1774 query_kinds: &'tcx [DepKindStruct<'tcx>],
1775 query_system: QuerySystem<'tcx>,
1776 hooks: crate::hooks::Providers,
1777 current_gcx: CurrentGcx,
1778 jobserver_proxy: Arc<Proxy>,
1779 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1780 ) -> T {
1781 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1782 s.dcx().emit_fatal(err);
1783 });
1784 let interners = CtxtInterners::new(arena);
1785 let common_types = CommonTypes::new(&interners, s, &untracked);
1786 let common_lifetimes = CommonLifetimes::new(&interners);
1787 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1788
1789 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1790 sess: s,
1791 crate_types,
1792 stable_crate_id,
1793 arena,
1794 hir_arena,
1795 interners,
1796 dep_graph,
1797 hooks,
1798 prof: s.prof.clone(),
1799 types: common_types,
1800 lifetimes: common_lifetimes,
1801 consts: common_consts,
1802 untracked,
1803 query_system,
1804 query_kinds,
1805 ty_rcache: Default::default(),
1806 selection_cache: Default::default(),
1807 evaluation_cache: Default::default(),
1808 new_solver_evaluation_cache: Default::default(),
1809 new_solver_canonical_param_env_cache: Default::default(),
1810 canonical_param_env_cache: Default::default(),
1811 highest_var_in_clauses_cache: Default::default(),
1812 clauses_cache: Default::default(),
1813 data_layout,
1814 alloc_map: interpret::AllocMap::new(),
1815 current_gcx,
1816 jobserver_proxy,
1817 });
1818
1819 gcx.enter(f)
1821 }
1822
1823 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1825 self.get_lang_items(())
1826 }
1827
1828 #[track_caller]
1830 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1831 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1832 self.type_of(ordering_enum).no_bound_vars().unwrap()
1833 }
1834
1835 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1838 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1839 }
1840
1841 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1843 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1844 }
1845
1846 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1848 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1849 }
1850
1851 pub fn is_coroutine(self, def_id: DefId) -> bool {
1852 self.coroutine_kind(def_id).is_some()
1853 }
1854
1855 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1856 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1857 }
1858
1859 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1862 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1863 }
1864
1865 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1867 matches!(
1868 self.coroutine_kind(def_id),
1869 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1870 )
1871 }
1872
1873 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1876 matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1877 }
1878
1879 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1882 matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1883 }
1884
1885 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1887 matches!(
1888 self.coroutine_kind(def_id),
1889 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1890 )
1891 }
1892
1893 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1895 matches!(
1896 self.coroutine_kind(def_id),
1897 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1898 )
1899 }
1900
1901 pub fn features(self) -> &'tcx rustc_feature::Features {
1902 self.features_query(())
1903 }
1904
1905 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1906 let id = id.into_query_param();
1907 if let Some(id) = id.as_local() {
1909 self.definitions_untracked().def_key(id)
1910 } else {
1911 self.cstore_untracked().def_key(id)
1912 }
1913 }
1914
1915 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1921 if let Some(id) = id.as_local() {
1923 self.definitions_untracked().def_path(id)
1924 } else {
1925 self.cstore_untracked().def_path(id)
1926 }
1927 }
1928
1929 #[inline]
1930 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1931 if let Some(def_id) = def_id.as_local() {
1933 self.definitions_untracked().def_path_hash(def_id)
1934 } else {
1935 self.cstore_untracked().def_path_hash(def_id)
1936 }
1937 }
1938
1939 #[inline]
1940 pub fn crate_types(self) -> &'tcx [CrateType] {
1941 &self.crate_types
1942 }
1943
1944 pub fn needs_metadata(self) -> bool {
1945 self.crate_types().iter().any(|ty| match *ty {
1946 CrateType::Executable
1947 | CrateType::Staticlib
1948 | CrateType::Cdylib
1949 | CrateType::Sdylib => false,
1950 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1951 })
1952 }
1953
1954 pub fn needs_crate_hash(self) -> bool {
1955 cfg!(debug_assertions)
1967 || self.sess.opts.incremental.is_some()
1968 || self.needs_metadata()
1969 || self.sess.instrument_coverage()
1970 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1971 }
1972
1973 #[inline]
1974 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1975 if crate_num == LOCAL_CRATE {
1976 self.stable_crate_id
1977 } else {
1978 self.cstore_untracked().stable_crate_id(crate_num)
1979 }
1980 }
1981
1982 #[inline]
1985 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1986 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1987 LOCAL_CRATE
1988 } else {
1989 *self
1990 .untracked()
1991 .stable_crate_ids
1992 .read()
1993 .get(&stable_crate_id)
1994 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1995 }
1996 }
1997
1998 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
2002 debug!("def_path_hash_to_def_id({:?})", hash);
2003
2004 let stable_crate_id = hash.stable_crate_id();
2005
2006 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
2009 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
2010 } else {
2011 Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
2012 }
2013 }
2014
2015 pub fn def_path_debug_str(self, def_id: DefId) -> String {
2016 let (crate_name, stable_crate_id) = if def_id.is_local() {
2021 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
2022 } else {
2023 let cstore = &*self.cstore_untracked();
2024 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
2025 };
2026
2027 format!(
2028 "{}[{:04x}]{}",
2029 crate_name,
2030 stable_crate_id.as_u64() >> (8 * 6),
2033 self.def_path(def_id).to_string_no_crate_verbose()
2034 )
2035 }
2036
2037 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
2038 self.sess.dcx()
2039 }
2040
2041 pub fn is_target_feature_call_safe(
2042 self,
2043 callee_features: &[TargetFeature],
2044 body_features: &[TargetFeature],
2045 ) -> bool {
2046 self.sess.target.options.is_like_wasm
2051 || callee_features
2052 .iter()
2053 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
2054 }
2055
2056 pub fn adjust_target_feature_sig(
2059 self,
2060 fun_def: DefId,
2061 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
2062 caller: DefId,
2063 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
2064 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
2065 let callee_features = &self.codegen_fn_attrs(caller).target_features;
2066 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
2067 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
2068 }
2069 None
2070 }
2071
2072 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
2075 match self.env_var_os(key.as_ref()) {
2076 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
2077 None => Err(VarError::NotPresent),
2078 }
2079 }
2080}
2081
2082impl<'tcx> TyCtxtAt<'tcx> {
2083 pub fn create_def(
2085 self,
2086 parent: LocalDefId,
2087 name: Option<Symbol>,
2088 def_kind: DefKind,
2089 override_def_path_data: Option<DefPathData>,
2090 disambiguator: &mut DisambiguatorState,
2091 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2092 let feed =
2093 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
2094
2095 feed.def_span(self.span);
2096 feed
2097 }
2098}
2099
2100impl<'tcx> TyCtxt<'tcx> {
2101 pub fn create_def(
2103 self,
2104 parent: LocalDefId,
2105 name: Option<Symbol>,
2106 def_kind: DefKind,
2107 override_def_path_data: Option<DefPathData>,
2108 disambiguator: &mut DisambiguatorState,
2109 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2110 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2111 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2121
2122 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2127
2128 let feed = TyCtxtFeed { tcx: self, key: def_id };
2129 feed.def_kind(def_kind);
2130 if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2135 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2136 feed.visibility(ty::Visibility::Restricted(parent_mod));
2137 }
2138
2139 feed
2140 }
2141
2142 pub fn create_crate_num(
2143 self,
2144 stable_crate_id: StableCrateId,
2145 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2146 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2147 return Err(existing);
2148 }
2149
2150 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2151 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2152 Ok(TyCtxtFeed { key: num, tcx: self })
2153 }
2154
2155 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2156 self.ensure_ok().analysis(());
2158
2159 let definitions = &self.untracked.definitions;
2160 gen {
2161 let mut i = 0;
2162
2163 while i < { definitions.read().num_definitions() } {
2166 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2167 yield LocalDefId { local_def_index };
2168 i += 1;
2169 }
2170
2171 definitions.freeze();
2173 }
2174 }
2175
2176 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2177 self.ensure_ok().analysis(());
2179
2180 self.untracked.definitions.freeze().def_path_table()
2183 }
2184
2185 pub fn def_path_hash_to_def_index_map(
2186 self,
2187 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2188 self.ensure_ok().hir_crate_items(());
2191 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2194 }
2195
2196 #[inline]
2199 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2200 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2201 }
2202
2203 pub fn untracked(self) -> &'tcx Untracked {
2205 &self.untracked
2206 }
2207 #[inline]
2210 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2211 self.untracked.definitions.read()
2212 }
2213
2214 #[inline]
2217 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2218 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2219 }
2220
2221 #[inline(always)]
2222 pub fn with_stable_hashing_context<R>(
2223 self,
2224 f: impl FnOnce(StableHashingContext<'_>) -> R,
2225 ) -> R {
2226 f(StableHashingContext::new(self.sess, &self.untracked))
2227 }
2228
2229 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2230 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2231 }
2232
2233 #[inline]
2234 pub fn local_crate_exports_generics(self) -> bool {
2235 self.crate_types().iter().any(|crate_type| {
2236 match crate_type {
2237 CrateType::Executable
2238 | CrateType::Staticlib
2239 | CrateType::ProcMacro
2240 | CrateType::Cdylib
2241 | CrateType::Sdylib => false,
2242
2243 CrateType::Dylib => true,
2248
2249 CrateType::Rlib => true,
2250 }
2251 })
2252 }
2253
2254 pub fn is_suitable_region(
2256 self,
2257 generic_param_scope: LocalDefId,
2258 mut region: Region<'tcx>,
2259 ) -> Option<FreeRegionInfo> {
2260 let (suitable_region_binding_scope, region_def_id) = loop {
2261 let def_id =
2262 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2263 let scope = self.local_parent(def_id);
2264 if self.def_kind(scope) == DefKind::OpaqueTy {
2265 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2268 continue;
2269 }
2270 break (scope, def_id.into());
2271 };
2272
2273 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2274 Node::Item(..) | Node::TraitItem(..) => false,
2275 Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2276 _ => false,
2277 };
2278
2279 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2280 }
2281
2282 pub fn return_type_impl_or_dyn_traits(
2284 self,
2285 scope_def_id: LocalDefId,
2286 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2287 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2288 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2289 self.hir_fn_decl_by_hir_id(hir_id)
2290 else {
2291 return vec![];
2292 };
2293
2294 let mut v = TraitObjectVisitor(vec![]);
2295 v.visit_ty_unambig(hir_output);
2296 v.0
2297 }
2298
2299 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2303 self,
2304 scope_def_id: LocalDefId,
2305 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2306 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2307 let mut v = TraitObjectVisitor(vec![]);
2308 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2310 && let hir::TyKind::Path(hir::QPath::Resolved(
2311 None,
2312 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2313 && let Some(local_id) = def_id.as_local()
2314 && 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()
2316 {
2317 v.visit_ty_unambig(alias_ty);
2318 if !v.0.is_empty() {
2319 return Some((
2320 v.0,
2321 alias_generics.span,
2322 alias_generics.span_for_lifetime_suggestion(),
2323 ));
2324 }
2325 }
2326 None
2327 }
2328
2329 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2331 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2332 if self.impl_trait_ref(container_id).is_some() {
2333 return true;
2340 }
2341 false
2342 }
2343
2344 pub fn has_strict_asm_symbol_naming(self) -> bool {
2347 self.sess.target.arch.contains("nvptx")
2348 }
2349
2350 pub fn caller_location_ty(self) -> Ty<'tcx> {
2352 Ty::new_imm_ref(
2353 self,
2354 self.lifetimes.re_static,
2355 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2356 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2357 )
2358 }
2359
2360 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2362 let kind = self.def_kind(def_id);
2363 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2364 }
2365
2366 pub fn type_length_limit(self) -> Limit {
2367 self.limits(()).type_length_limit
2368 }
2369
2370 pub fn recursion_limit(self) -> Limit {
2371 self.limits(()).recursion_limit
2372 }
2373
2374 pub fn move_size_limit(self) -> Limit {
2375 self.limits(()).move_size_limit
2376 }
2377
2378 pub fn pattern_complexity_limit(self) -> Limit {
2379 self.limits(()).pattern_complexity_limit
2380 }
2381
2382 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
2384 iter::once(LOCAL_CRATE)
2385 .chain(self.crates(()).iter().copied())
2386 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2387 }
2388
2389 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2391 let visible_crates =
2392 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2393
2394 iter::once(LOCAL_CRATE)
2395 .chain(visible_crates)
2396 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2397 }
2398
2399 #[inline]
2400 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2401 self.visibility(def_id).expect_local()
2402 }
2403
2404 #[instrument(skip(self), level = "trace", ret)]
2406 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2407 self.hir_expect_opaque_ty(def_id).origin
2408 }
2409
2410 pub fn finish(self) {
2411 self.alloc_self_profile_query_strings();
2414
2415 self.save_dep_graph();
2416 self.query_key_hash_verify_all();
2417
2418 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2419 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2420 }
2421 }
2422}
2423
2424macro_rules! nop_lift {
2425 ($set:ident; $ty:ty => $lifted:ty) => {
2426 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2427 type Lifted = $lifted;
2428 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2429 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2434 _x: Interned<'tcx, Inner>,
2435 ) -> InternedSet<'tcx, Inner> {
2436 unreachable!()
2437 }
2438 fn _type_eq<T>(_x: &T, _y: &T) {}
2439 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2440 let interner = _intern_set_ty_from_interned_ty(x.0);
2444 _type_eq(&interner, &tcx.interners.$set);
2446 }
2447
2448 tcx.interners
2449 .$set
2450 .contains_pointer_to(&InternedInSet(&*self.0.0))
2451 .then(|| unsafe { mem::transmute(self) })
2454 }
2455 }
2456 };
2457}
2458
2459macro_rules! nop_list_lift {
2460 ($set:ident; $ty:ty => $lifted:ty) => {
2461 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2462 type Lifted = &'tcx List<$lifted>;
2463 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2464 if false {
2466 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2467 }
2468
2469 if self.is_empty() {
2470 return Some(List::empty());
2471 }
2472 tcx.interners
2473 .$set
2474 .contains_pointer_to(&InternedInSet(self))
2475 .then(|| unsafe { mem::transmute(self) })
2476 }
2477 }
2478 };
2479}
2480
2481nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2482nop_lift! { region; Region<'a> => Region<'tcx> }
2483nop_lift! { const_; Const<'a> => Const<'tcx> }
2484nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2485nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2486nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2487nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2488nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2489nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2490
2491nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2492nop_list_lift! {
2493 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2494}
2495nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2496
2497nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2499
2500macro_rules! sty_debug_print {
2501 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2502 #[allow(non_snake_case)]
2505 mod inner {
2506 use crate::ty::{self, TyCtxt};
2507 use crate::ty::context::InternedInSet;
2508
2509 #[derive(Copy, Clone)]
2510 struct DebugStat {
2511 total: usize,
2512 lt_infer: usize,
2513 ty_infer: usize,
2514 ct_infer: usize,
2515 all_infer: usize,
2516 }
2517
2518 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2519 let mut total = DebugStat {
2520 total: 0,
2521 lt_infer: 0,
2522 ty_infer: 0,
2523 ct_infer: 0,
2524 all_infer: 0,
2525 };
2526 $(let mut $variant = total;)*
2527
2528 for shard in tcx.interners.type_.lock_shards() {
2529 #[allow(rustc::potential_query_instability)]
2531 let types = shard.iter();
2532 for &(InternedInSet(t), ()) in types {
2533 let variant = match t.internee {
2534 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2535 ty::Float(..) | ty::Str | ty::Never => continue,
2536 ty::Error(_) => continue,
2537 $(ty::$variant(..) => &mut $variant,)*
2538 };
2539 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2540 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2541 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2542
2543 variant.total += 1;
2544 total.total += 1;
2545 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2546 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2547 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2548 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2549 }
2550 }
2551 writeln!(fmt, "Ty interner total ty lt ct all")?;
2552 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2553 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2554 stringify!($variant),
2555 uses = $variant.total,
2556 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2557 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2558 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2559 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2560 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2561 )*
2562 writeln!(fmt, " total {uses:6} \
2563 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2564 uses = total.total,
2565 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2566 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2567 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2568 all = total.all_infer as f64 * 100.0 / total.total as f64)
2569 }
2570 }
2571
2572 inner::go($fmt, $ctxt)
2573 }}
2574}
2575
2576impl<'tcx> TyCtxt<'tcx> {
2577 pub fn debug_stats(self) -> impl fmt::Debug {
2578 fmt::from_fn(move |fmt| {
2579 sty_debug_print!(
2580 fmt,
2581 self,
2582 Adt,
2583 Array,
2584 Slice,
2585 RawPtr,
2586 Ref,
2587 FnDef,
2588 FnPtr,
2589 UnsafeBinder,
2590 Placeholder,
2591 Coroutine,
2592 CoroutineWitness,
2593 Dynamic,
2594 Closure,
2595 CoroutineClosure,
2596 Tuple,
2597 Bound,
2598 Param,
2599 Infer,
2600 Alias,
2601 Pat,
2602 Foreign
2603 )?;
2604
2605 writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2606 writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2607 writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2608 writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2609
2610 Ok(())
2611 })
2612 }
2613}
2614
2615struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2620
2621impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2622 fn clone(&self) -> Self {
2623 InternedInSet(self.0)
2624 }
2625}
2626
2627impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2628
2629impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2630 fn into_pointer(&self) -> *const () {
2631 self.0 as *const _ as *const ()
2632 }
2633}
2634
2635#[allow(rustc::usage_of_ty_tykind)]
2636impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2637 fn borrow(&self) -> &T {
2638 &self.0.internee
2639 }
2640}
2641
2642impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2643 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2644 self.0.internee == other.0.internee
2647 }
2648}
2649
2650impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2651
2652impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2653 fn hash<H: Hasher>(&self, s: &mut H) {
2654 self.0.internee.hash(s)
2656 }
2657}
2658
2659impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2660 fn borrow(&self) -> &[T] {
2661 &self.0[..]
2662 }
2663}
2664
2665impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2666 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2667 self.0[..] == other.0[..]
2670 }
2671}
2672
2673impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2674
2675impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2676 fn hash<H: Hasher>(&self, s: &mut H) {
2677 self.0[..].hash(s)
2679 }
2680}
2681
2682impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2683 fn borrow(&self) -> &[T] {
2684 &self.0[..]
2685 }
2686}
2687
2688impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2689 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2690 self.0[..] == other.0[..]
2693 }
2694}
2695
2696impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2697
2698impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2699 fn hash<H: Hasher>(&self, s: &mut H) {
2700 self.0[..].hash(s)
2702 }
2703}
2704
2705macro_rules! direct_interners {
2706 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2707 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2708 fn borrow<'a>(&'a self) -> &'a $ty {
2709 &self.0
2710 }
2711 }
2712
2713 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2714 fn eq(&self, other: &Self) -> bool {
2715 self.0 == other.0
2718 }
2719 }
2720
2721 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2722
2723 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2724 fn hash<H: Hasher>(&self, s: &mut H) {
2725 self.0.hash(s)
2728 }
2729 }
2730
2731 impl<'tcx> TyCtxt<'tcx> {
2732 $vis fn $method(self, v: $ty) -> $ret_ty {
2733 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2734 InternedInSet(self.interners.arena.alloc(v))
2735 }).0))
2736 }
2737 })+
2738 }
2739}
2740
2741direct_interners! {
2745 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2746 valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2747 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2748 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2749 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2750 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2751 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2752 ExternalConstraints -> ExternalConstraints<'tcx>,
2753 predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2754 PredefinedOpaques -> PredefinedOpaques<'tcx>,
2755}
2756
2757macro_rules! slice_interners {
2758 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2759 impl<'tcx> TyCtxt<'tcx> {
2760 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2761 if v.is_empty() {
2762 List::empty()
2763 } else {
2764 self.interners.$field.intern_ref(v, || {
2765 InternedInSet(List::from_arena(&*self.arena, (), v))
2766 }).0
2767 }
2768 })+
2769 }
2770 );
2771}
2772
2773slice_interners!(
2777 const_lists: pub mk_const_list(Const<'tcx>),
2778 args: pub mk_args(GenericArg<'tcx>),
2779 type_lists: pub mk_type_list(Ty<'tcx>),
2780 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2781 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2782 projs: pub mk_projs(ProjectionKind),
2783 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2784 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2785 fields: pub mk_fields(FieldIdx),
2786 local_def_ids: intern_local_def_ids(LocalDefId),
2787 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2788 offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2789 patterns: pub mk_patterns(Pattern<'tcx>),
2790 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2791);
2792
2793impl<'tcx> TyCtxt<'tcx> {
2794 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2798 assert!(sig.safety().is_safe());
2799 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2800 }
2801
2802 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2805 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2806 self.associated_items(trait_did)
2807 .filter_by_name_unhygienic(assoc_name.name)
2808 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2809 })
2810 }
2811
2812 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2814 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2815 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2816
2817 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2818 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2819 return false;
2820 };
2821 trait_predicate.trait_ref.def_id == future_trait
2822 && trait_predicate.polarity == PredicatePolarity::Positive
2823 })
2824 }
2825
2826 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2834 sig.map_bound(|s| {
2835 let params = match s.inputs()[0].kind() {
2836 ty::Tuple(params) => *params,
2837 _ => bug!(),
2838 };
2839 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2840 })
2841 }
2842
2843 #[inline]
2844 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2845 self.interners.intern_predicate(
2846 binder,
2847 self.sess,
2848 &self.untracked,
2850 )
2851 }
2852
2853 #[inline]
2854 pub fn reuse_or_mk_predicate(
2855 self,
2856 pred: Predicate<'tcx>,
2857 binder: Binder<'tcx, PredicateKind<'tcx>>,
2858 ) -> Predicate<'tcx> {
2859 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2860 }
2861
2862 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2863 self.check_args_compatible_inner(def_id, args, false)
2864 }
2865
2866 fn check_args_compatible_inner(
2867 self,
2868 def_id: DefId,
2869 args: &'tcx [ty::GenericArg<'tcx>],
2870 nested: bool,
2871 ) -> bool {
2872 let generics = self.generics_of(def_id);
2873
2874 let own_args = if !nested
2877 && let DefKind::AssocTy = self.def_kind(def_id)
2878 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2879 {
2880 if generics.own_params.len() + 1 != args.len() {
2881 return false;
2882 }
2883
2884 if !matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2885 return false;
2886 }
2887
2888 &args[1..]
2889 } else {
2890 if generics.count() != args.len() {
2891 return false;
2892 }
2893
2894 let (parent_args, own_args) = args.split_at(generics.parent_count);
2895
2896 if let Some(parent) = generics.parent
2897 && !self.check_args_compatible_inner(parent, parent_args, true)
2898 {
2899 return false;
2900 }
2901
2902 own_args
2903 };
2904
2905 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2906 match (¶m.kind, arg.kind()) {
2907 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2908 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2909 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2910 _ => return false,
2911 }
2912 }
2913
2914 true
2915 }
2916
2917 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2920 if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2921 if let DefKind::AssocTy = self.def_kind(def_id)
2922 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2923 {
2924 bug!(
2925 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2926 self.def_path_str(def_id),
2927 args,
2928 self.mk_args_from_iter(
2930 [self.types.self_param.into()].into_iter().chain(
2931 self.generics_of(def_id)
2932 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2933 .iter()
2934 .copied()
2935 )
2936 )
2937 );
2938 } else {
2939 bug!(
2940 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2941 self.def_path_str(def_id),
2942 args,
2943 ty::GenericArgs::identity_for_item(self, def_id)
2944 );
2945 }
2946 }
2947 }
2948
2949 #[inline(always)]
2950 pub(crate) fn check_and_mk_args(
2951 self,
2952 def_id: DefId,
2953 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2954 ) -> GenericArgsRef<'tcx> {
2955 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2956 self.debug_assert_args_compatible(def_id, args);
2957 args
2958 }
2959
2960 #[inline]
2961 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2962 self.interners.intern_const(
2963 kind,
2964 self.sess,
2965 &self.untracked,
2967 )
2968 }
2969
2970 #[allow(rustc::usage_of_ty_tykind)]
2972 #[inline]
2973 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2974 self.interners.intern_ty(
2975 st,
2976 self.sess,
2977 &self.untracked,
2979 )
2980 }
2981
2982 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2983 match param.kind {
2984 GenericParamDefKind::Lifetime => {
2985 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2986 }
2987 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2988 GenericParamDefKind::Const { .. } => {
2989 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2990 .into()
2991 }
2992 }
2993 }
2994
2995 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2996 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2997 }
2998
2999 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
3000 self.mk_place_elem(place, PlaceElem::Deref)
3001 }
3002
3003 pub fn mk_place_downcast(
3004 self,
3005 place: Place<'tcx>,
3006 adt_def: AdtDef<'tcx>,
3007 variant_index: VariantIdx,
3008 ) -> Place<'tcx> {
3009 self.mk_place_elem(
3010 place,
3011 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
3012 )
3013 }
3014
3015 pub fn mk_place_downcast_unnamed(
3016 self,
3017 place: Place<'tcx>,
3018 variant_index: VariantIdx,
3019 ) -> Place<'tcx> {
3020 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
3021 }
3022
3023 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
3024 self.mk_place_elem(place, PlaceElem::Index(index))
3025 }
3026
3027 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
3031 let mut projection = place.projection.to_vec();
3032 projection.push(elem);
3033
3034 Place { local: place.local, projection: self.mk_place_elems(&projection) }
3035 }
3036
3037 pub fn mk_poly_existential_predicates(
3038 self,
3039 eps: &[PolyExistentialPredicate<'tcx>],
3040 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
3041 assert!(!eps.is_empty());
3042 assert!(
3043 eps.array_windows()
3044 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
3045 != Ordering::Greater)
3046 );
3047 self.intern_poly_existential_predicates(eps)
3048 }
3049
3050 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
3051 self.interners.intern_clauses(clauses)
3055 }
3056
3057 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
3058 self.intern_local_def_ids(def_ids)
3062 }
3063
3064 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
3065 where
3066 I: Iterator<Item = T>,
3067 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
3068 {
3069 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
3070 }
3071
3072 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
3073 where
3074 I: Iterator<Item = T>,
3075 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
3076 {
3077 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
3078 }
3079
3080 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
3081 where
3082 I: Iterator<Item = T>,
3083 T: CollectAndApply<
3084 &'tcx ty::CapturedPlace<'tcx>,
3085 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
3086 >,
3087 {
3088 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
3089 }
3090
3091 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
3092 where
3093 I: Iterator<Item = T>,
3094 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
3095 {
3096 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3097 }
3098
3099 pub fn mk_fn_sig<I, T>(
3104 self,
3105 inputs: I,
3106 output: I::Item,
3107 c_variadic: bool,
3108 safety: hir::Safety,
3109 abi: ExternAbi,
3110 ) -> T::Output
3111 where
3112 I: IntoIterator<Item = T>,
3113 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3114 {
3115 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3116 inputs_and_output: self.mk_type_list(xs),
3117 c_variadic,
3118 safety,
3119 abi,
3120 })
3121 }
3122
3123 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3124 where
3125 I: Iterator<Item = T>,
3126 T: CollectAndApply<
3127 PolyExistentialPredicate<'tcx>,
3128 &'tcx List<PolyExistentialPredicate<'tcx>>,
3129 >,
3130 {
3131 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3132 }
3133
3134 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3135 where
3136 I: Iterator<Item = T>,
3137 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3138 {
3139 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3140 }
3141
3142 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3143 where
3144 I: Iterator<Item = T>,
3145 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3146 {
3147 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3148 }
3149
3150 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3151 where
3152 I: Iterator<Item = T>,
3153 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3154 {
3155 T::collect_and_apply(iter, |xs| self.mk_args(xs))
3156 }
3157
3158 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3159 where
3160 I: Iterator<Item = T>,
3161 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3162 {
3163 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3164 }
3165
3166 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3167 where
3168 I: Iterator<Item = T>,
3169 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3170 {
3171 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3172 }
3173
3174 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3175 where
3176 I: Iterator<Item = T>,
3177 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3178 {
3179 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3180 }
3181
3182 pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
3183 where
3184 I: Iterator<Item = T>,
3185 T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
3186 {
3187 T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
3188 }
3189
3190 pub fn mk_args_trait(
3191 self,
3192 self_ty: Ty<'tcx>,
3193 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3194 ) -> GenericArgsRef<'tcx> {
3195 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3196 }
3197
3198 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3199 where
3200 I: Iterator<Item = T>,
3201 T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3202 {
3203 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3204 }
3205
3206 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
3207 where
3208 I: Iterator<Item = T>,
3209 T: CollectAndApply<
3210 ty::ArgOutlivesPredicate<'tcx>,
3211 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
3212 >,
3213 {
3214 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
3215 }
3216
3217 #[track_caller]
3220 pub fn emit_node_span_lint(
3221 self,
3222 lint: &'static Lint,
3223 hir_id: HirId,
3224 span: impl Into<MultiSpan>,
3225 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3226 ) {
3227 let level = self.lint_level_at_node(lint, hir_id);
3228 lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3229 decorator.decorate_lint(lint);
3230 })
3231 }
3232
3233 #[rustc_lint_diagnostics]
3237 #[track_caller]
3238 pub fn node_span_lint(
3239 self,
3240 lint: &'static Lint,
3241 hir_id: HirId,
3242 span: impl Into<MultiSpan>,
3243 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3244 ) {
3245 let level = self.lint_level_at_node(lint, hir_id);
3246 lint_level(self.sess, lint, level, Some(span.into()), decorate);
3247 }
3248
3249 pub fn crate_level_attribute_injection_span(self) -> Span {
3251 let node = self.hir_node(hir::CRATE_HIR_ID);
3252 let hir::Node::Crate(m) = node else { bug!() };
3253 m.spans.inject_use_span.shrink_to_lo()
3254 }
3255
3256 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3257 self,
3258 diag: &mut Diag<'_, E>,
3259 features: impl IntoIterator<Item = (String, Symbol)>,
3260 ) {
3261 if !self.sess.is_nightly_build() {
3262 return;
3263 }
3264
3265 let span = self.crate_level_attribute_injection_span();
3266 for (desc, feature) in features {
3267 let msg =
3269 format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3270 diag.span_suggestion_verbose(
3271 span,
3272 msg,
3273 format!("#![feature({feature})]\n"),
3274 Applicability::MaybeIncorrect,
3275 );
3276 }
3277 }
3278
3279 #[track_caller]
3282 pub fn emit_node_lint(
3283 self,
3284 lint: &'static Lint,
3285 id: HirId,
3286 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3287 ) {
3288 self.node_lint(lint, id, |lint| {
3289 decorator.decorate_lint(lint);
3290 })
3291 }
3292
3293 #[rustc_lint_diagnostics]
3297 #[track_caller]
3298 pub fn node_lint(
3299 self,
3300 lint: &'static Lint,
3301 id: HirId,
3302 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3303 ) {
3304 let level = self.lint_level_at_node(lint, id);
3305 lint_level(self.sess, lint, level, None, decorate);
3306 }
3307
3308 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3309 let map = self.in_scope_traits_map(id.owner)?;
3310 let candidates = map.get(&id.local_id)?;
3311 Some(candidates)
3312 }
3313
3314 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3315 debug!(?id, "named_region");
3316 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3317 }
3318
3319 pub fn is_late_bound(self, id: HirId) -> bool {
3320 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3321 }
3322
3323 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3324 self.mk_bound_variable_kinds(
3325 &self
3326 .late_bound_vars_map(id.owner)
3327 .get(&id.local_id)
3328 .cloned()
3329 .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3330 )
3331 }
3332
3333 pub fn map_opaque_lifetime_to_parent_lifetime(
3341 self,
3342 mut opaque_lifetime_param_def_id: LocalDefId,
3343 ) -> ty::Region<'tcx> {
3344 debug_assert!(
3345 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3346 "{opaque_lifetime_param_def_id:?} is a {}",
3347 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3348 );
3349
3350 loop {
3351 let parent = self.local_parent(opaque_lifetime_param_def_id);
3352 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3353
3354 let Some((lifetime, _)) = lifetime_mapping
3355 .iter()
3356 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3357 else {
3358 bug!("duplicated lifetime param should be present");
3359 };
3360
3361 match *lifetime {
3362 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3363 let new_parent = self.local_parent(ebv);
3364
3365 if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3368 debug_assert_eq!(self.local_parent(parent), new_parent);
3369 opaque_lifetime_param_def_id = ebv;
3370 continue;
3371 }
3372
3373 let generics = self.generics_of(new_parent);
3374 return ty::Region::new_early_param(
3375 self,
3376 ty::EarlyParamRegion {
3377 index: generics
3378 .param_def_id_to_index(self, ebv.to_def_id())
3379 .expect("early-bound var should be present in fn generics"),
3380 name: self.item_name(ebv.to_def_id()),
3381 },
3382 );
3383 }
3384 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3385 let new_parent = self.local_parent(lbv);
3386 return ty::Region::new_late_param(
3387 self,
3388 new_parent.to_def_id(),
3389 ty::LateParamRegionKind::Named(lbv.to_def_id()),
3390 );
3391 }
3392 resolve_bound_vars::ResolvedArg::Error(guar) => {
3393 return ty::Region::new_error(self, guar);
3394 }
3395 _ => {
3396 return ty::Region::new_error_with_message(
3397 self,
3398 self.def_span(opaque_lifetime_param_def_id),
3399 "cannot resolve lifetime",
3400 );
3401 }
3402 }
3403 }
3404 }
3405
3406 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3411 self.is_const_fn(def_id)
3412 && match self.lookup_const_stability(def_id) {
3413 None => true, Some(stability) if stability.is_const_stable() => true,
3415 _ => false,
3416 }
3417 }
3418
3419 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3421 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3422 && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3423 }
3424
3425 pub fn is_sdylib_interface_build(self) -> bool {
3426 self.sess.opts.unstable_opts.build_sdylib_interface
3427 }
3428
3429 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3430 match self.def_kind(def_id) {
3431 DefKind::Fn | DefKind::AssocFn => {}
3432 _ => return None,
3433 }
3434 self.intrinsic_raw(def_id)
3435 }
3436
3437 pub fn next_trait_solver_globally(self) -> bool {
3438 self.sess.opts.unstable_opts.next_solver.globally
3439 }
3440
3441 pub fn next_trait_solver_in_coherence(self) -> bool {
3442 self.sess.opts.unstable_opts.next_solver.coherence
3443 }
3444
3445 #[allow(rustc::bad_opt_access)]
3446 pub fn use_typing_mode_borrowck(self) -> bool {
3447 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3448 }
3449
3450 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3451 self.opt_rpitit_info(def_id).is_some()
3452 }
3453
3454 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3464 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3465 }
3466
3467 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
3469 self.resolutions(()).extern_crate_map.get(&def_id).copied()
3470 }
3471
3472 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3473 self.resolver_for_lowering_raw(()).0
3474 }
3475
3476 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
3477 crate::dep_graph::make_metadata(self)
3478 }
3479
3480 pub fn impl_trait_ref(
3483 self,
3484 def_id: impl IntoQueryParam<DefId>,
3485 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3486 Some(self.impl_trait_header(def_id)?.trait_ref)
3487 }
3488
3489 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3490 self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3491 }
3492
3493 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3494 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3495 self.coroutine_kind(def_id)
3496 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3497 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3498 {
3499 true
3500 } else {
3501 false
3502 }
3503 }
3504
3505 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3507 self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3508 }
3509
3510 pub fn is_entrypoint(self, def_id: DefId) -> bool {
3513 if self.is_lang_item(def_id, LangItem::Start) {
3514 return true;
3515 }
3516 if let Some((entry_def_id, _)) = self.entry_fn(())
3517 && entry_def_id == def_id
3518 {
3519 return true;
3520 }
3521 false
3522 }
3523}
3524
3525#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3534pub struct DeducedParamAttrs {
3535 pub read_only: bool,
3538}
3539
3540pub fn provide(providers: &mut Providers) {
3541 providers.is_panic_runtime =
3542 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3543 providers.is_compiler_builtins =
3544 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3545 providers.has_panic_handler = |tcx, LocalCrate| {
3546 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3548 };
3549 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3550}
3551
3552pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3553 attrs.iter().any(|x| x.has_name(name))
3554}