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