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