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