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