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