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