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