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