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