1#![allow(rustc::usage_of_ty_tykind)]
4
5pub mod tls;
6
7use std::assert_matches::{assert_matches, debug_assert_matches};
8use std::borrow::Borrow;
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::PhantomData;
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::profiling::SelfProfilerRef;
25use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
26use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
27use rustc_data_structures::steal::Steal;
28use rustc_data_structures::sync::{
29 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
30};
31use rustc_data_structures::unord::UnordSet;
32use rustc_errors::{
33 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan,
34};
35use rustc_hir::def::{CtorKind, DefKind};
36use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
37use rustc_hir::definitions::Definitions;
38use rustc_hir::intravisit::VisitorExt;
39use rustc_hir::lang_items::LangItem;
40use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
41use rustc_index::IndexVec;
42use rustc_macros::{HashStable, TyDecodable, TyEncodable};
43use rustc_query_system::cache::WithDepNode;
44use rustc_query_system::dep_graph::DepNodeIndex;
45use rustc_query_system::ich::StableHashingContext;
46use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
47use rustc_session::config::CrateType;
48use rustc_session::cstore::{CrateStoreDyn, Untracked};
49use rustc_session::lint::Lint;
50use rustc_session::{Limit, MetadataKind, Session};
51use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
52use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
53use rustc_type_ir::TyKind::*;
54use rustc_type_ir::lang_items::TraitSolverLangItem;
55pub use rustc_type_ir::lift::Lift;
56use rustc_type_ir::{
57 CollectAndApply, Interner, TypeFlags, TypeFoldable, WithCachedTypeInfo, elaborate, search_graph,
58};
59use tracing::{debug, instrument};
60
61use crate::arena::Arena;
62use crate::dep_graph::{DepGraph, DepKindStruct};
63use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
64use crate::lint::lint_level;
65use crate::metadata::ModChild;
66use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
67use crate::middle::{resolve_bound_vars, stability};
68use crate::mir::interpret::{self, Allocation, ConstAllocation};
69use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
70use crate::query::plumbing::QuerySystem;
71use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
72use crate::thir::Thir;
73use crate::traits;
74use crate::traits::solve;
75use crate::traits::solve::{
76 ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData,
77};
78use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
79use crate::ty::{
80 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
81 GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, ParamTy,
82 Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
83 PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
84 ValTree, ValTreeKind, Visibility,
85};
86
87#[allow(rustc::usage_of_ty_tykind)]
88impl<'tcx> Interner for TyCtxt<'tcx> {
89 type DefId = DefId;
90 type LocalDefId = LocalDefId;
91 type Span = Span;
92
93 type GenericArgs = ty::GenericArgsRef<'tcx>;
94
95 type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
96 type GenericArg = ty::GenericArg<'tcx>;
97 type Term = ty::Term<'tcx>;
98 type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
99
100 type BoundVarKind = ty::BoundVariableKind;
101 type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
102
103 fn mk_predefined_opaques_in_body(
104 self,
105 data: PredefinedOpaquesData<Self>,
106 ) -> Self::PredefinedOpaques {
107 self.mk_predefined_opaques_in_body(data)
108 }
109 type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
110 type CanonicalVars = CanonicalVarInfos<'tcx>;
111 fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
112 self.mk_canonical_var_infos(infos)
113 }
114
115 type ExternalConstraints = ExternalConstraints<'tcx>;
116 fn mk_external_constraints(
117 self,
118 data: ExternalConstraintsData<Self>,
119 ) -> ExternalConstraints<'tcx> {
120 self.mk_external_constraints(data)
121 }
122 type DepNodeIndex = DepNodeIndex;
123 fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
124 self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
125 }
126 type Ty = Ty<'tcx>;
127 type Tys = &'tcx List<Ty<'tcx>>;
128
129 type FnInputTys = &'tcx [Ty<'tcx>];
130 type ParamTy = ParamTy;
131 type BoundTy = ty::BoundTy;
132
133 type PlaceholderTy = ty::PlaceholderType;
134 type ErrorGuaranteed = ErrorGuaranteed;
135 type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
136
137 type AllocId = crate::mir::interpret::AllocId;
138 type Pat = Pattern<'tcx>;
139 type Safety = hir::Safety;
140 type Abi = ExternAbi;
141 type Const = ty::Const<'tcx>;
142 type PlaceholderConst = ty::PlaceholderConst;
143
144 type ParamConst = ty::ParamConst;
145 type BoundConst = ty::BoundVar;
146 type ValueConst = ty::Value<'tcx>;
147 type ExprConst = ty::Expr<'tcx>;
148 type ValTree = ty::ValTree<'tcx>;
149
150 type Region = Region<'tcx>;
151 type EarlyParamRegion = ty::EarlyParamRegion;
152 type LateParamRegion = ty::LateParamRegion;
153 type BoundRegion = ty::BoundRegion;
154 type PlaceholderRegion = ty::PlaceholderRegion;
155
156 type ParamEnv = ty::ParamEnv<'tcx>;
157 type Predicate = Predicate<'tcx>;
158
159 type Clause = Clause<'tcx>;
160 type Clauses = ty::Clauses<'tcx>;
161
162 type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
163 fn mk_tracked<T: fmt::Debug + Clone>(
164 self,
165 data: T,
166 dep_node: DepNodeIndex,
167 ) -> Self::Tracked<T> {
168 WithDepNode::new(dep_node, data)
169 }
170 fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
171 tracked.get(self)
172 }
173
174 fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
175 f(&mut *self.new_solver_evaluation_cache.lock())
176 }
177
178 fn evaluation_is_concurrent(&self) -> bool {
179 self.sess.threads() > 1
180 }
181
182 fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
183 self.expand_abstract_consts(t)
184 }
185
186 type GenericsOf = &'tcx ty::Generics;
187
188 fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
189 self.generics_of(def_id)
190 }
191
192 type VariancesOf = &'tcx [ty::Variance];
193
194 fn variances_of(self, def_id: DefId) -> Self::VariancesOf {
195 self.variances_of(def_id)
196 }
197
198 fn opt_alias_variances(
199 self,
200 kind: impl Into<ty::AliasTermKind>,
201 def_id: DefId,
202 ) -> Option<&'tcx [ty::Variance]> {
203 self.opt_alias_variances(kind, def_id)
204 }
205
206 fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
207 self.type_of(def_id)
208 }
209
210 type AdtDef = ty::AdtDef<'tcx>;
211 fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
212 self.adt_def(adt_def_id)
213 }
214
215 fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
216 match self.def_kind(alias.def_id) {
217 DefKind::AssocTy => {
218 if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
219 {
220 ty::Inherent
221 } else {
222 ty::Projection
223 }
224 }
225 DefKind::OpaqueTy => ty::Opaque,
226 DefKind::TyAlias => ty::Weak,
227 kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
228 }
229 }
230
231 fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind {
232 match self.def_kind(alias.def_id) {
233 DefKind::AssocTy => {
234 if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
235 {
236 ty::AliasTermKind::InherentTy
237 } else {
238 ty::AliasTermKind::ProjectionTy
239 }
240 }
241 DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
242 DefKind::TyAlias => ty::AliasTermKind::WeakTy,
243 DefKind::AssocConst => ty::AliasTermKind::ProjectionConst,
244 DefKind::AnonConst | DefKind::Const | DefKind::Ctor(_, CtorKind::Const) => {
245 ty::AliasTermKind::UnevaluatedConst
246 }
247 kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
248 }
249 }
250
251 fn trait_ref_and_own_args_for_alias(
252 self,
253 def_id: DefId,
254 args: ty::GenericArgsRef<'tcx>,
255 ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
256 assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
257 let trait_def_id = self.parent(def_id);
258 assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
259 let trait_generics = self.generics_of(trait_def_id);
260 (
261 ty::TraitRef::new_from_args(self, trait_def_id, args.truncate_to(self, trait_generics)),
262 &args[trait_generics.count()..],
263 )
264 }
265
266 fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
267 self.mk_args(args)
268 }
269
270 fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
271 where
272 I: Iterator<Item = T>,
273 T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
274 {
275 self.mk_args_from_iter(args)
276 }
277
278 fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
279 self.check_args_compatible(def_id, args)
280 }
281
282 fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
283 self.debug_assert_args_compatible(def_id, args);
284 }
285
286 fn debug_assert_existential_args_compatible(
290 self,
291 def_id: Self::DefId,
292 args: Self::GenericArgs,
293 ) {
294 if cfg!(debug_assertions) {
297 self.debug_assert_args_compatible(
298 def_id,
299 self.mk_args_from_iter(
300 [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
301 ),
302 );
303 }
304 }
305
306 fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
307 where
308 I: Iterator<Item = T>,
309 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
310 {
311 self.mk_type_list_from_iter(args)
312 }
313
314 fn parent(self, def_id: DefId) -> DefId {
315 self.parent(def_id)
316 }
317
318 fn recursion_limit(self) -> usize {
319 self.recursion_limit().0
320 }
321
322 type Features = &'tcx rustc_feature::Features;
323
324 fn features(self) -> Self::Features {
325 self.features()
326 }
327
328 fn coroutine_hidden_types(
329 self,
330 def_id: DefId,
331 ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> {
332 self.coroutine_hidden_types(def_id)
333 }
334
335 fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
336 self.fn_sig(def_id)
337 }
338
339 fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
340 self.coroutine_movability(def_id)
341 }
342
343 fn coroutine_for_closure(self, def_id: DefId) -> DefId {
344 self.coroutine_for_closure(def_id)
345 }
346
347 fn generics_require_sized_self(self, def_id: DefId) -> bool {
348 self.generics_require_sized_self(def_id)
349 }
350
351 fn item_bounds(
352 self,
353 def_id: DefId,
354 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
355 self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
356 }
357
358 fn item_self_bounds(
359 self,
360 def_id: DefId,
361 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
362 self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
363 }
364
365 fn item_non_self_bounds(
366 self,
367 def_id: DefId,
368 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
369 self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
370 }
371
372 fn predicates_of(
373 self,
374 def_id: DefId,
375 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
376 ty::EarlyBinder::bind(
377 self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
378 )
379 }
380
381 fn own_predicates_of(
382 self,
383 def_id: DefId,
384 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
385 ty::EarlyBinder::bind(
386 self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
387 )
388 }
389
390 fn explicit_super_predicates_of(
391 self,
392 def_id: DefId,
393 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
394 self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
395 }
396
397 fn explicit_implied_predicates_of(
398 self,
399 def_id: DefId,
400 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
401 self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
402 }
403
404 fn impl_is_const(self, def_id: DefId) -> bool {
405 debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
406 self.is_conditionally_const(def_id)
407 }
408
409 fn fn_is_const(self, def_id: DefId) -> bool {
410 debug_assert_matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
411 self.is_conditionally_const(def_id)
412 }
413
414 fn alias_has_const_conditions(self, def_id: DefId) -> bool {
415 debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
416 self.is_conditionally_const(def_id)
417 }
418
419 fn const_conditions(
420 self,
421 def_id: DefId,
422 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
423 ty::EarlyBinder::bind(
424 self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
425 )
426 }
427
428 fn explicit_implied_const_bounds(
429 self,
430 def_id: DefId,
431 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
432 ty::EarlyBinder::bind(
433 self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
434 )
435 }
436
437 fn has_target_features(self, def_id: DefId) -> bool {
438 !self.codegen_fn_attrs(def_id).target_features.is_empty()
439 }
440
441 fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
442 self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None)
443 }
444
445 fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
446 self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
447 }
448
449 fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
450 lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
451 }
452
453 fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
454 self.associated_items(def_id)
455 .in_definition_order()
456 .filter(|assoc_item| matches!(assoc_item.kind, ty::AssocKind::Type))
457 .map(|assoc_item| assoc_item.def_id)
458 }
459
460 fn for_each_relevant_impl(
464 self,
465 trait_def_id: DefId,
466 self_ty: Ty<'tcx>,
467 mut f: impl FnMut(DefId),
468 ) {
469 let tcx = self;
470 let trait_impls = tcx.trait_impls_of(trait_def_id);
471 let mut consider_impls_for_simplified_type = |simp| {
472 if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
473 for &impl_def_id in impls_for_type {
474 f(impl_def_id);
475 }
476 }
477 };
478
479 match self_ty.kind() {
480 ty::Bool
481 | ty::Char
482 | ty::Int(_)
483 | ty::Uint(_)
484 | ty::Float(_)
485 | ty::Adt(_, _)
486 | ty::Foreign(_)
487 | ty::Str
488 | ty::Array(_, _)
489 | ty::Pat(_, _)
490 | ty::Slice(_)
491 | ty::RawPtr(_, _)
492 | ty::Ref(_, _, _)
493 | ty::FnDef(_, _)
494 | ty::FnPtr(..)
495 | ty::Dynamic(_, _, _)
496 | ty::Closure(..)
497 | ty::CoroutineClosure(..)
498 | ty::Coroutine(_, _)
499 | ty::Never
500 | ty::Tuple(_)
501 | ty::UnsafeBinder(_) => {
502 let simp = ty::fast_reject::simplify_type(
503 tcx,
504 self_ty,
505 ty::fast_reject::TreatParams::AsRigid,
506 )
507 .unwrap();
508 consider_impls_for_simplified_type(simp);
509 }
510
511 ty::Infer(ty::IntVar(_)) => {
514 use ty::IntTy::*;
515 use ty::UintTy::*;
516 let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
518 let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
519 let possible_integers = [
520 ty::SimplifiedType::Int(I8),
522 ty::SimplifiedType::Int(I16),
523 ty::SimplifiedType::Int(I32),
524 ty::SimplifiedType::Int(I64),
525 ty::SimplifiedType::Int(I128),
526 ty::SimplifiedType::Int(Isize),
527 ty::SimplifiedType::Uint(U8),
529 ty::SimplifiedType::Uint(U16),
530 ty::SimplifiedType::Uint(U32),
531 ty::SimplifiedType::Uint(U64),
532 ty::SimplifiedType::Uint(U128),
533 ty::SimplifiedType::Uint(Usize),
534 ];
535 for simp in possible_integers {
536 consider_impls_for_simplified_type(simp);
537 }
538 }
539
540 ty::Infer(ty::FloatVar(_)) => {
541 let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
543 let possible_floats = [
544 ty::SimplifiedType::Float(ty::FloatTy::F16),
545 ty::SimplifiedType::Float(ty::FloatTy::F32),
546 ty::SimplifiedType::Float(ty::FloatTy::F64),
547 ty::SimplifiedType::Float(ty::FloatTy::F128),
548 ];
549
550 for simp in possible_floats {
551 consider_impls_for_simplified_type(simp);
552 }
553 }
554
555 ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
560
561 ty::CoroutineWitness(..) => (),
565
566 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
568 | ty::Param(_)
569 | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
570 }
571
572 let trait_impls = tcx.trait_impls_of(trait_def_id);
573 for &impl_def_id in trait_impls.blanket_impls() {
574 f(impl_def_id);
575 }
576 }
577
578 fn has_item_definition(self, def_id: DefId) -> bool {
579 self.defaultness(def_id).has_value()
580 }
581
582 fn impl_is_default(self, impl_def_id: DefId) -> bool {
583 self.defaultness(impl_def_id).is_default()
584 }
585
586 fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
587 self.impl_trait_ref(impl_def_id).unwrap()
588 }
589
590 fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
591 self.impl_polarity(impl_def_id)
592 }
593
594 fn trait_is_auto(self, trait_def_id: DefId) -> bool {
595 self.trait_is_auto(trait_def_id)
596 }
597
598 fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
599 self.trait_is_coinductive(trait_def_id)
600 }
601
602 fn trait_is_alias(self, trait_def_id: DefId) -> bool {
603 self.trait_is_alias(trait_def_id)
604 }
605
606 fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
607 self.is_dyn_compatible(trait_def_id)
608 }
609
610 fn trait_is_fundamental(self, def_id: DefId) -> bool {
611 self.trait_def(def_id).is_fundamental
612 }
613
614 fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
615 self.trait_def(trait_def_id).implement_via_object
616 }
617
618 fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
619 self.trait_def(trait_def_id).safety.is_unsafe()
620 }
621
622 fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
623 self.is_impl_trait_in_trait(def_id)
624 }
625
626 fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
627 self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
628 }
629
630 fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
631 self.is_general_coroutine(coroutine_def_id)
632 }
633
634 fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
635 self.coroutine_is_async(coroutine_def_id)
636 }
637
638 fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
639 self.coroutine_is_gen(coroutine_def_id)
640 }
641
642 fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
643 self.coroutine_is_async_gen(coroutine_def_id)
644 }
645
646 type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
647 fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
648 self.unsizing_params_for_adt(adt_def_id)
649 }
650
651 fn find_const_ty_from_env(
652 self,
653 param_env: ty::ParamEnv<'tcx>,
654 placeholder: Self::PlaceholderConst,
655 ) -> Ty<'tcx> {
656 placeholder.find_const_ty_from_env(param_env)
657 }
658
659 fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
660 self,
661 binder: ty::Binder<'tcx, T>,
662 ) -> ty::Binder<'tcx, T> {
663 self.anonymize_bound_vars(binder)
664 }
665
666 fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::DefiningOpaqueTypes {
667 self.opaque_types_defined_by(defining_anchor)
668 }
669}
670
671macro_rules! bidirectional_lang_item_map {
672 ($($name:ident),+ $(,)?) => {
673 fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
674 match lang_item {
675 $(TraitSolverLangItem::$name => LangItem::$name,)+
676 }
677 }
678
679 fn lang_item_to_trait_lang_item(lang_item: LangItem) -> Option<TraitSolverLangItem> {
680 Some(match lang_item {
681 $(LangItem::$name => TraitSolverLangItem::$name,)+
682 _ => return None,
683 })
684 }
685 }
686}
687
688bidirectional_lang_item_map! {
689AsyncDestruct,
691 AsyncFn,
692 AsyncFnKindHelper,
693 AsyncFnKindUpvars,
694 AsyncFnMut,
695 AsyncFnOnce,
696 AsyncFnOnceOutput,
697 AsyncIterator,
698 BikeshedGuaranteedNoDrop,
699 CallOnceFuture,
700 CallRefFuture,
701 Clone,
702 Copy,
703 Coroutine,
704 CoroutineReturn,
705 CoroutineYield,
706 Destruct,
707 DiscriminantKind,
708 Drop,
709 DynMetadata,
710 Fn,
711 FnMut,
712 FnOnce,
713 FnPtrTrait,
714 FusedIterator,
715 Future,
716 FutureOutput,
717 Iterator,
718 Metadata,
719 Option,
720 PointeeTrait,
721 Poll,
722 Sized,
723 TransmuteTrait,
724 Tuple,
725 Unpin,
726 Unsize,
727}
729
730impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
731 fn is_local(self) -> bool {
732 self.is_local()
733 }
734
735 fn as_local(self) -> Option<LocalDefId> {
736 self.as_local()
737 }
738}
739
740impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
741 fn rust() -> Self {
742 ExternAbi::Rust
743 }
744
745 fn is_rust(self) -> bool {
746 matches!(self, ExternAbi::Rust)
747 }
748}
749
750impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
751 fn safe() -> Self {
752 hir::Safety::Safe
753 }
754
755 fn is_safe(self) -> bool {
756 self.is_safe()
757 }
758
759 fn prefix_str(self) -> &'static str {
760 self.prefix_str()
761 }
762}
763
764impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
765 fn generic_const_exprs(self) -> bool {
766 self.generic_const_exprs()
767 }
768
769 fn coroutine_clone(self) -> bool {
770 self.coroutine_clone()
771 }
772
773 fn associated_const_equality(self) -> bool {
774 self.associated_const_equality()
775 }
776}
777
778impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
779 fn dummy() -> Self {
780 DUMMY_SP
781 }
782}
783
784type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
785
786pub struct CtxtInterners<'tcx> {
787 arena: &'tcx WorkerLocal<Arena<'tcx>>,
789
790 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
793 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
794 args: InternedSet<'tcx, GenericArgs<'tcx>>,
795 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
796 canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
797 region: InternedSet<'tcx, RegionKind<'tcx>>,
798 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
799 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
800 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
801 projs: InternedSet<'tcx, List<ProjectionKind>>,
802 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
803 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
804 pat: InternedSet<'tcx, PatternKind<'tcx>>,
805 const_allocation: InternedSet<'tcx, Allocation>,
806 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
807 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
808 adt_def: InternedSet<'tcx, AdtDefData>,
809 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
810 predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
811 fields: InternedSet<'tcx, List<FieldIdx>>,
812 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
813 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
814 offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
815 valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
816}
817
818impl<'tcx> CtxtInterners<'tcx> {
819 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
820 const N: usize = 2048;
823 CtxtInterners {
824 arena,
825 type_: InternedSet::with_capacity(N * 16),
829 const_lists: InternedSet::with_capacity(N * 4),
830 args: InternedSet::with_capacity(N * 4),
831 type_lists: InternedSet::with_capacity(N * 4),
832 region: InternedSet::with_capacity(N * 4),
833 poly_existential_predicates: InternedSet::with_capacity(N / 4),
834 canonical_var_infos: InternedSet::with_capacity(N / 2),
835 predicate: InternedSet::with_capacity(N),
836 clauses: InternedSet::with_capacity(N),
837 projs: InternedSet::with_capacity(N * 4),
838 place_elems: InternedSet::with_capacity(N * 2),
839 const_: InternedSet::with_capacity(N * 2),
840 pat: InternedSet::with_capacity(N),
841 const_allocation: InternedSet::with_capacity(N),
842 bound_variable_kinds: InternedSet::with_capacity(N * 2),
843 layout: InternedSet::with_capacity(N),
844 adt_def: InternedSet::with_capacity(N),
845 external_constraints: InternedSet::with_capacity(N),
846 predefined_opaques_in_body: InternedSet::with_capacity(N),
847 fields: InternedSet::with_capacity(N * 4),
848 local_def_ids: InternedSet::with_capacity(N),
849 captures: InternedSet::with_capacity(N),
850 offset_of: InternedSet::with_capacity(N),
851 valtree: InternedSet::with_capacity(N),
852 }
853 }
854
855 #[allow(rustc::usage_of_ty_tykind)]
857 #[inline(never)]
858 fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
859 Ty(Interned::new_unchecked(
860 self.type_
861 .intern(kind, |kind| {
862 let flags = super::flags::FlagComputation::for_kind(&kind);
863 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
864
865 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
866 internee: kind,
867 stable_hash,
868 flags: flags.flags,
869 outer_exclusive_binder: flags.outer_exclusive_binder,
870 }))
871 })
872 .0,
873 ))
874 }
875
876 #[allow(rustc::usage_of_ty_tykind)]
878 #[inline(never)]
879 fn intern_const(
880 &self,
881 kind: ty::ConstKind<'tcx>,
882 sess: &Session,
883 untracked: &Untracked,
884 ) -> Const<'tcx> {
885 Const(Interned::new_unchecked(
886 self.const_
887 .intern(kind, |kind: ty::ConstKind<'_>| {
888 let flags = super::flags::FlagComputation::for_const_kind(&kind);
889 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
890
891 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
892 internee: kind,
893 stable_hash,
894 flags: flags.flags,
895 outer_exclusive_binder: flags.outer_exclusive_binder,
896 }))
897 })
898 .0,
899 ))
900 }
901
902 fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
903 &self,
904 flags: &ty::flags::FlagComputation,
905 sess: &'a Session,
906 untracked: &'a Untracked,
907 val: &T,
908 ) -> Fingerprint {
909 if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
912 Fingerprint::ZERO
913 } else {
914 let mut hasher = StableHasher::new();
915 let mut hcx = StableHashingContext::new(sess, untracked);
916 val.hash_stable(&mut hcx, &mut hasher);
917 hasher.finish()
918 }
919 }
920
921 #[inline(never)]
923 fn intern_predicate(
924 &self,
925 kind: Binder<'tcx, PredicateKind<'tcx>>,
926 sess: &Session,
927 untracked: &Untracked,
928 ) -> Predicate<'tcx> {
929 Predicate(Interned::new_unchecked(
930 self.predicate
931 .intern(kind, |kind| {
932 let flags = super::flags::FlagComputation::for_predicate(kind);
933
934 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
935
936 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
937 internee: kind,
938 stable_hash,
939 flags: flags.flags,
940 outer_exclusive_binder: flags.outer_exclusive_binder,
941 }))
942 })
943 .0,
944 ))
945 }
946
947 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
948 if clauses.is_empty() {
949 ListWithCachedTypeInfo::empty()
950 } else {
951 self.clauses
952 .intern_ref(clauses, || {
953 let flags = super::flags::FlagComputation::for_clauses(clauses);
954
955 InternedInSet(ListWithCachedTypeInfo::from_arena(
956 &*self.arena,
957 flags.into(),
958 clauses,
959 ))
960 })
961 .0
962 }
963 }
964}
965
966const NUM_PREINTERNED_TY_VARS: u32 = 100;
971const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
972const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
973const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
974
975const NUM_PREINTERNED_RE_VARS: u32 = 500;
977const NUM_PREINTERNED_RE_LATE_BOUNDS_I: u32 = 2;
978const NUM_PREINTERNED_RE_LATE_BOUNDS_V: u32 = 20;
979
980pub struct CommonTypes<'tcx> {
981 pub unit: Ty<'tcx>,
982 pub bool: Ty<'tcx>,
983 pub char: Ty<'tcx>,
984 pub isize: Ty<'tcx>,
985 pub i8: Ty<'tcx>,
986 pub i16: Ty<'tcx>,
987 pub i32: Ty<'tcx>,
988 pub i64: Ty<'tcx>,
989 pub i128: Ty<'tcx>,
990 pub usize: Ty<'tcx>,
991 pub u8: Ty<'tcx>,
992 pub u16: Ty<'tcx>,
993 pub u32: Ty<'tcx>,
994 pub u64: Ty<'tcx>,
995 pub u128: Ty<'tcx>,
996 pub f16: Ty<'tcx>,
997 pub f32: Ty<'tcx>,
998 pub f64: Ty<'tcx>,
999 pub f128: Ty<'tcx>,
1000 pub str_: Ty<'tcx>,
1001 pub never: Ty<'tcx>,
1002 pub self_param: Ty<'tcx>,
1003
1004 pub trait_object_dummy_self: Ty<'tcx>,
1009
1010 pub ty_vars: Vec<Ty<'tcx>>,
1012
1013 pub fresh_tys: Vec<Ty<'tcx>>,
1015
1016 pub fresh_int_tys: Vec<Ty<'tcx>>,
1018
1019 pub fresh_float_tys: Vec<Ty<'tcx>>,
1021}
1022
1023pub struct CommonLifetimes<'tcx> {
1024 pub re_static: Region<'tcx>,
1026
1027 pub re_erased: Region<'tcx>,
1029
1030 pub re_vars: Vec<Region<'tcx>>,
1032
1033 pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
1037}
1038
1039pub struct CommonConsts<'tcx> {
1040 pub unit: Const<'tcx>,
1041 pub true_: Const<'tcx>,
1042 pub false_: Const<'tcx>,
1043 pub(crate) valtree_zst: ValTree<'tcx>,
1045}
1046
1047impl<'tcx> CommonTypes<'tcx> {
1048 fn new(
1049 interners: &CtxtInterners<'tcx>,
1050 sess: &Session,
1051 untracked: &Untracked,
1052 ) -> CommonTypes<'tcx> {
1053 let mk = |ty| interners.intern_ty(ty, sess, untracked);
1054
1055 let ty_vars =
1056 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1057 let fresh_tys: Vec<_> =
1058 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1059 let fresh_int_tys: Vec<_> =
1060 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1061 let fresh_float_tys: Vec<_> =
1062 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1063
1064 CommonTypes {
1065 unit: mk(Tuple(List::empty())),
1066 bool: mk(Bool),
1067 char: mk(Char),
1068 never: mk(Never),
1069 isize: mk(Int(ty::IntTy::Isize)),
1070 i8: mk(Int(ty::IntTy::I8)),
1071 i16: mk(Int(ty::IntTy::I16)),
1072 i32: mk(Int(ty::IntTy::I32)),
1073 i64: mk(Int(ty::IntTy::I64)),
1074 i128: mk(Int(ty::IntTy::I128)),
1075 usize: mk(Uint(ty::UintTy::Usize)),
1076 u8: mk(Uint(ty::UintTy::U8)),
1077 u16: mk(Uint(ty::UintTy::U16)),
1078 u32: mk(Uint(ty::UintTy::U32)),
1079 u64: mk(Uint(ty::UintTy::U64)),
1080 u128: mk(Uint(ty::UintTy::U128)),
1081 f16: mk(Float(ty::FloatTy::F16)),
1082 f32: mk(Float(ty::FloatTy::F32)),
1083 f64: mk(Float(ty::FloatTy::F64)),
1084 f128: mk(Float(ty::FloatTy::F128)),
1085 str_: mk(Str),
1086 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1087
1088 trait_object_dummy_self: fresh_tys[0],
1089
1090 ty_vars,
1091 fresh_tys,
1092 fresh_int_tys,
1093 fresh_float_tys,
1094 }
1095 }
1096}
1097
1098impl<'tcx> CommonLifetimes<'tcx> {
1099 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1100 let mk = |r| {
1101 Region(Interned::new_unchecked(
1102 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1103 ))
1104 };
1105
1106 let re_vars =
1107 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1108
1109 let re_late_bounds = (0..NUM_PREINTERNED_RE_LATE_BOUNDS_I)
1110 .map(|i| {
1111 (0..NUM_PREINTERNED_RE_LATE_BOUNDS_V)
1112 .map(|v| {
1113 mk(ty::ReBound(
1114 ty::DebruijnIndex::from(i),
1115 ty::BoundRegion {
1116 var: ty::BoundVar::from(v),
1117 kind: ty::BoundRegionKind::Anon,
1118 },
1119 ))
1120 })
1121 .collect()
1122 })
1123 .collect();
1124
1125 CommonLifetimes {
1126 re_static: mk(ty::ReStatic),
1127 re_erased: mk(ty::ReErased),
1128 re_vars,
1129 re_late_bounds,
1130 }
1131 }
1132}
1133
1134impl<'tcx> CommonConsts<'tcx> {
1135 fn new(
1136 interners: &CtxtInterners<'tcx>,
1137 types: &CommonTypes<'tcx>,
1138 sess: &Session,
1139 untracked: &Untracked,
1140 ) -> CommonConsts<'tcx> {
1141 let mk_const = |c| {
1142 interners.intern_const(
1143 c, sess, untracked,
1145 )
1146 };
1147
1148 let mk_valtree = |v| {
1149 ty::ValTree(Interned::new_unchecked(
1150 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1151 ))
1152 };
1153
1154 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1155 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1156 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1157
1158 CommonConsts {
1159 unit: mk_const(ty::ConstKind::Value(ty::Value {
1160 ty: types.unit,
1161 valtree: valtree_zst,
1162 })),
1163 true_: mk_const(ty::ConstKind::Value(ty::Value {
1164 ty: types.bool,
1165 valtree: valtree_true,
1166 })),
1167 false_: mk_const(ty::ConstKind::Value(ty::Value {
1168 ty: types.bool,
1169 valtree: valtree_false,
1170 })),
1171 valtree_zst,
1172 }
1173 }
1174}
1175
1176#[derive(Debug)]
1179pub struct FreeRegionInfo {
1180 pub scope: LocalDefId,
1182 pub region_def_id: DefId,
1184 pub is_impl_item: bool,
1186}
1187
1188#[derive(Copy, Clone)]
1190pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1191 pub tcx: TyCtxt<'tcx>,
1192 key: KEY,
1194}
1195
1196impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1199
1200#[derive(Copy, Clone)]
1205pub struct Feed<'tcx, KEY: Copy> {
1206 _tcx: PhantomData<TyCtxt<'tcx>>,
1207 key: KEY,
1209}
1210
1211impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1214
1215impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1217 self.key.fmt(f)
1218 }
1219}
1220
1221impl<'tcx> TyCtxt<'tcx> {
1226 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1229 self.dep_graph.assert_ignored();
1230 TyCtxtFeed { tcx: self, key: () }
1231 }
1232
1233 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1236 let key = self.untracked().source_span.push(span);
1237 assert_eq!(key, CRATE_DEF_ID);
1238 TyCtxtFeed { tcx: self, key }
1239 }
1240
1241 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1245 debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1246 TyCtxtFeed { tcx: self, key }.type_of(value)
1247 }
1248}
1249
1250impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1251 #[inline(always)]
1252 pub fn key(&self) -> KEY {
1253 self.key
1254 }
1255
1256 #[inline(always)]
1257 pub fn downgrade(self) -> Feed<'tcx, KEY> {
1258 Feed { _tcx: PhantomData, key: self.key }
1259 }
1260}
1261
1262impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1263 #[inline(always)]
1264 pub fn key(&self) -> KEY {
1265 self.key
1266 }
1267
1268 #[inline(always)]
1269 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1270 TyCtxtFeed { tcx, key: self.key }
1271 }
1272}
1273
1274impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1275 #[inline(always)]
1276 pub fn def_id(&self) -> LocalDefId {
1277 self.key
1278 }
1279
1280 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1282 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1283 }
1284
1285 pub fn feed_hir(&self) {
1287 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1288
1289 let node = hir::OwnerNode::Synthetic;
1290 let bodies = Default::default();
1291 let attrs = hir::AttributeMap::EMPTY;
1292
1293 let (opt_hash_including_bodies, _) =
1294 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque);
1295 let node = node.into();
1296 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1297 opt_hash_including_bodies,
1298 nodes: IndexVec::from_elem_n(
1299 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1300 1,
1301 ),
1302 bodies,
1303 })));
1304 self.feed_owner_id().hir_attr_map(attrs);
1305 }
1306}
1307
1308#[derive(Copy, Clone)]
1326#[rustc_diagnostic_item = "TyCtxt"]
1327#[rustc_pass_by_value]
1328pub struct TyCtxt<'tcx> {
1329 gcx: &'tcx GlobalCtxt<'tcx>,
1330}
1331
1332unsafe impl DynSend for TyCtxt<'_> {}
1336unsafe impl DynSync for TyCtxt<'_> {}
1337fn _assert_tcx_fields() {
1338 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1339 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1340}
1341
1342impl<'tcx> Deref for TyCtxt<'tcx> {
1343 type Target = &'tcx GlobalCtxt<'tcx>;
1344 #[inline(always)]
1345 fn deref(&self) -> &Self::Target {
1346 &self.gcx
1347 }
1348}
1349
1350pub struct GlobalCtxt<'tcx> {
1352 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1353 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1354
1355 interners: CtxtInterners<'tcx>,
1356
1357 pub sess: &'tcx Session,
1358 crate_types: Vec<CrateType>,
1359 stable_crate_id: StableCrateId,
1365
1366 pub dep_graph: DepGraph,
1367
1368 pub prof: SelfProfilerRef,
1369
1370 pub types: CommonTypes<'tcx>,
1372
1373 pub lifetimes: CommonLifetimes<'tcx>,
1375
1376 pub consts: CommonConsts<'tcx>,
1378
1379 pub(crate) hooks: crate::hooks::Providers,
1382
1383 untracked: Untracked,
1384
1385 pub query_system: QuerySystem<'tcx>,
1386 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1387
1388 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1390
1391 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1394
1395 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1399
1400 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1402
1403 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1404
1405 pub data_layout: TargetDataLayout,
1407
1408 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1410
1411 current_gcx: CurrentGcx,
1412}
1413
1414impl<'tcx> GlobalCtxt<'tcx> {
1415 pub fn enter<F, R>(&'tcx self, f: F) -> R
1418 where
1419 F: FnOnce(TyCtxt<'tcx>) -> R,
1420 {
1421 let icx = tls::ImplicitCtxt::new(self);
1422
1423 let _on_drop = defer(move || {
1425 *self.current_gcx.value.write() = None;
1426 });
1427
1428 {
1430 let mut guard = self.current_gcx.value.write();
1431 assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1432 *guard = Some(self as *const _ as *const ());
1433 }
1434
1435 tls::enter_context(&icx, || f(icx.tcx))
1436 }
1437}
1438
1439#[derive(Clone)]
1446pub struct CurrentGcx {
1447 value: Arc<RwLock<Option<*const ()>>>,
1450}
1451
1452unsafe impl DynSend for CurrentGcx {}
1453unsafe impl DynSync for CurrentGcx {}
1454
1455impl CurrentGcx {
1456 pub fn new() -> Self {
1457 Self { value: Arc::new(RwLock::new(None)) }
1458 }
1459
1460 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1461 let read_guard = self.value.read();
1462 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1463 f(unsafe { &*gcx })
1467 }
1468}
1469
1470impl<'tcx> TyCtxt<'tcx> {
1471 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1472 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1475 if typeck_root_def_id != def_id.to_def_id() {
1476 return self.has_typeck_results(typeck_root_def_id.expect_local());
1477 }
1478
1479 self.hir_node_by_def_id(def_id).body_id().is_some()
1480 }
1481
1482 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1487 let def_kind = self.def_kind(def_id);
1488 if def_kind.has_codegen_attrs() {
1489 self.codegen_fn_attrs(def_id)
1490 } else if matches!(
1491 def_kind,
1492 DefKind::AnonConst
1493 | DefKind::AssocConst
1494 | DefKind::Const
1495 | DefKind::InlineConst
1496 | DefKind::GlobalAsm
1497 ) {
1498 CodegenFnAttrs::EMPTY
1499 } else {
1500 bug!(
1501 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1502 def_id,
1503 def_kind
1504 )
1505 }
1506 }
1507
1508 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1509 self.arena.alloc(Steal::new(thir))
1510 }
1511
1512 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1513 self.arena.alloc(Steal::new(mir))
1514 }
1515
1516 pub fn alloc_steal_promoted(
1517 self,
1518 promoted: IndexVec<Promoted, Body<'tcx>>,
1519 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1520 self.arena.alloc(Steal::new(promoted))
1521 }
1522
1523 pub fn mk_adt_def(
1524 self,
1525 did: DefId,
1526 kind: AdtKind,
1527 variants: IndexVec<VariantIdx, ty::VariantDef>,
1528 repr: ReprOptions,
1529 ) -> ty::AdtDef<'tcx> {
1530 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1531 }
1532
1533 pub fn allocate_bytes_dedup(self, bytes: &[u8], salt: usize) -> interpret::AllocId {
1536 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
1538 let alloc = self.mk_const_alloc(alloc);
1539 self.reserve_and_set_memory_dedup(alloc, salt)
1540 }
1541
1542 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1546 let get = |name| {
1547 let Some(attr) = self.get_attr(def_id, name) else {
1548 return Bound::Unbounded;
1549 };
1550 debug!("layout_scalar_valid_range: attr={:?}", attr);
1551 if let Some(
1552 &[
1553 ast::MetaItemInner::Lit(ast::MetaItemLit {
1554 kind: ast::LitKind::Int(a, _), ..
1555 }),
1556 ],
1557 ) = attr.meta_item_list().as_deref()
1558 {
1559 Bound::Included(a.get())
1560 } else {
1561 self.dcx().span_delayed_bug(
1562 attr.span(),
1563 "invalid rustc_layout_scalar_valid_range attribute",
1564 );
1565 Bound::Unbounded
1566 }
1567 };
1568 (
1569 get(sym::rustc_layout_scalar_valid_range_start),
1570 get(sym::rustc_layout_scalar_valid_range_end),
1571 )
1572 }
1573
1574 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1575 value.lift_to_interner(self)
1576 }
1577
1578 pub fn create_global_ctxt<T>(
1585 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1586 s: &'tcx Session,
1587 crate_types: Vec<CrateType>,
1588 stable_crate_id: StableCrateId,
1589 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1590 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1591 untracked: Untracked,
1592 dep_graph: DepGraph,
1593 query_kinds: &'tcx [DepKindStruct<'tcx>],
1594 query_system: QuerySystem<'tcx>,
1595 hooks: crate::hooks::Providers,
1596 current_gcx: CurrentGcx,
1597 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1598 ) -> T {
1599 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1600 s.dcx().emit_fatal(err);
1601 });
1602 let interners = CtxtInterners::new(arena);
1603 let common_types = CommonTypes::new(&interners, s, &untracked);
1604 let common_lifetimes = CommonLifetimes::new(&interners);
1605 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1606
1607 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1608 sess: s,
1609 crate_types,
1610 stable_crate_id,
1611 arena,
1612 hir_arena,
1613 interners,
1614 dep_graph,
1615 hooks,
1616 prof: s.prof.clone(),
1617 types: common_types,
1618 lifetimes: common_lifetimes,
1619 consts: common_consts,
1620 untracked,
1621 query_system,
1622 query_kinds,
1623 ty_rcache: Default::default(),
1624 selection_cache: Default::default(),
1625 evaluation_cache: Default::default(),
1626 new_solver_evaluation_cache: Default::default(),
1627 canonical_param_env_cache: Default::default(),
1628 data_layout,
1629 alloc_map: interpret::AllocMap::new(),
1630 current_gcx,
1631 });
1632
1633 gcx.enter(f)
1635 }
1636
1637 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1639 self.get_lang_items(())
1640 }
1641
1642 #[track_caller]
1644 pub fn ty_ordering_enum(self, span: Option<Span>) -> Ty<'tcx> {
1645 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1646 self.type_of(ordering_enum).no_bound_vars().unwrap()
1647 }
1648
1649 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1652 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1653 }
1654
1655 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1657 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1658 }
1659
1660 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1662 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1663 }
1664
1665 pub fn is_coroutine(self, def_id: DefId) -> bool {
1666 self.coroutine_kind(def_id).is_some()
1667 }
1668
1669 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1672 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1673 }
1674
1675 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1677 matches!(
1678 self.coroutine_kind(def_id),
1679 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1680 )
1681 }
1682
1683 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1686 matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1687 }
1688
1689 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1692 matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1693 }
1694
1695 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1697 matches!(
1698 self.coroutine_kind(def_id),
1699 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1700 )
1701 }
1702
1703 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1705 matches!(
1706 self.coroutine_kind(def_id),
1707 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1708 )
1709 }
1710
1711 pub fn stability(self) -> &'tcx stability::Index {
1712 self.stability_index(())
1713 }
1714
1715 pub fn features(self) -> &'tcx rustc_feature::Features {
1716 self.features_query(())
1717 }
1718
1719 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1720 let id = id.into_query_param();
1721 if let Some(id) = id.as_local() {
1723 self.definitions_untracked().def_key(id)
1724 } else {
1725 self.cstore_untracked().def_key(id)
1726 }
1727 }
1728
1729 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1735 if let Some(id) = id.as_local() {
1737 self.definitions_untracked().def_path(id)
1738 } else {
1739 self.cstore_untracked().def_path(id)
1740 }
1741 }
1742
1743 #[inline]
1744 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1745 if let Some(def_id) = def_id.as_local() {
1747 self.definitions_untracked().def_path_hash(def_id)
1748 } else {
1749 self.cstore_untracked().def_path_hash(def_id)
1750 }
1751 }
1752
1753 #[inline]
1754 pub fn crate_types(self) -> &'tcx [CrateType] {
1755 &self.crate_types
1756 }
1757
1758 pub fn metadata_kind(self) -> MetadataKind {
1759 self.crate_types()
1760 .iter()
1761 .map(|ty| match *ty {
1762 CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => {
1763 MetadataKind::None
1764 }
1765 CrateType::Rlib => MetadataKind::Uncompressed,
1766 CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
1767 })
1768 .max()
1769 .unwrap_or(MetadataKind::None)
1770 }
1771
1772 pub fn needs_metadata(self) -> bool {
1773 self.metadata_kind() != MetadataKind::None
1774 }
1775
1776 pub fn needs_crate_hash(self) -> bool {
1777 cfg!(debug_assertions)
1785 || self.sess.opts.incremental.is_some()
1786 || self.needs_metadata()
1787 || self.sess.instrument_coverage()
1788 }
1789
1790 #[inline]
1791 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1792 if crate_num == LOCAL_CRATE {
1793 self.stable_crate_id
1794 } else {
1795 self.cstore_untracked().stable_crate_id(crate_num)
1796 }
1797 }
1798
1799 #[inline]
1802 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1803 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1804 LOCAL_CRATE
1805 } else {
1806 *self
1807 .untracked()
1808 .stable_crate_ids
1809 .read()
1810 .get(&stable_crate_id)
1811 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1812 }
1813 }
1814
1815 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1819 debug!("def_path_hash_to_def_id({:?})", hash);
1820
1821 let stable_crate_id = hash.stable_crate_id();
1822
1823 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1826 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1827 } else {
1828 Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
1829 }
1830 }
1831
1832 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1833 let (crate_name, stable_crate_id) = if def_id.is_local() {
1838 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1839 } else {
1840 let cstore = &*self.cstore_untracked();
1841 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1842 };
1843
1844 format!(
1845 "{}[{:04x}]{}",
1846 crate_name,
1847 stable_crate_id.as_u64() >> (8 * 6),
1850 self.def_path(def_id).to_string_no_crate_verbose()
1851 )
1852 }
1853
1854 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1855 self.sess.dcx()
1856 }
1857
1858 pub fn is_target_feature_call_safe(
1859 self,
1860 callee_features: &[TargetFeature],
1861 body_features: &[TargetFeature],
1862 ) -> bool {
1863 self.sess.target.options.is_like_wasm
1868 || callee_features
1869 .iter()
1870 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1871 }
1872
1873 pub fn adjust_target_feature_sig(
1876 self,
1877 fun_def: DefId,
1878 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1879 caller: DefId,
1880 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1881 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1882 let callee_features = &self.codegen_fn_attrs(caller).target_features;
1883 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
1884 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
1885 }
1886 None
1887 }
1888
1889 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1892 match self.env_var_os(key.as_ref()) {
1893 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1894 None => Err(VarError::NotPresent),
1895 }
1896 }
1897}
1898
1899impl<'tcx> TyCtxtAt<'tcx> {
1900 pub fn create_def(
1902 self,
1903 parent: LocalDefId,
1904 name: Option<Symbol>,
1905 def_kind: DefKind,
1906 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1907 let feed = self.tcx.create_def(parent, name, def_kind);
1908
1909 feed.def_span(self.span);
1910 feed
1911 }
1912}
1913
1914impl<'tcx> TyCtxt<'tcx> {
1915 pub fn create_def(
1917 self,
1918 parent: LocalDefId,
1919 name: Option<Symbol>,
1920 def_kind: DefKind,
1921 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1922 let data = def_kind.def_path_data(name);
1923 let def_id = self.untracked.definitions.write().create_def(parent, data);
1938
1939 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1944
1945 let feed = TyCtxtFeed { tcx: self, key: def_id };
1946 feed.def_kind(def_kind);
1947 if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1952 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1953 feed.visibility(ty::Visibility::Restricted(parent_mod));
1954 }
1955
1956 feed
1957 }
1958
1959 pub fn create_crate_num(
1960 self,
1961 stable_crate_id: StableCrateId,
1962 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1963 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
1964 return Err(existing);
1965 }
1966
1967 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
1968 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
1969 Ok(TyCtxtFeed { key: num, tcx: self })
1970 }
1971
1972 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1973 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1976
1977 let definitions = &self.untracked.definitions;
1978 std::iter::from_coroutine(
1979 #[coroutine]
1980 || {
1981 let mut i = 0;
1982
1983 while i < { definitions.read().num_definitions() } {
1986 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1987 yield LocalDefId { local_def_index };
1988 i += 1;
1989 }
1990
1991 definitions.freeze();
1993 },
1994 )
1995 }
1996
1997 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1998 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2001
2002 self.untracked.definitions.freeze().def_path_table()
2005 }
2006
2007 pub fn def_path_hash_to_def_index_map(
2008 self,
2009 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2010 self.ensure_ok().hir_crate(());
2013 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2016 }
2017
2018 #[inline]
2021 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2022 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2023 }
2024
2025 pub fn untracked(self) -> &'tcx Untracked {
2027 &self.untracked
2028 }
2029 #[inline]
2032 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2033 self.untracked.definitions.read()
2034 }
2035
2036 #[inline]
2039 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2040 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2041 }
2042
2043 #[inline(always)]
2044 pub fn with_stable_hashing_context<R>(
2045 self,
2046 f: impl FnOnce(StableHashingContext<'_>) -> R,
2047 ) -> R {
2048 f(StableHashingContext::new(self.sess, &self.untracked))
2049 }
2050
2051 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2052 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2053 }
2054
2055 #[inline]
2056 pub fn local_crate_exports_generics(self) -> bool {
2057 self.crate_types().iter().any(|crate_type| {
2058 match crate_type {
2059 CrateType::Executable
2060 | CrateType::Staticlib
2061 | CrateType::ProcMacro
2062 | CrateType::Cdylib => false,
2063
2064 CrateType::Dylib => true,
2069
2070 CrateType::Rlib => true,
2071 }
2072 })
2073 }
2074
2075 pub fn is_suitable_region(
2077 self,
2078 generic_param_scope: LocalDefId,
2079 mut region: Region<'tcx>,
2080 ) -> Option<FreeRegionInfo> {
2081 let (suitable_region_binding_scope, region_def_id) = loop {
2082 let def_id =
2083 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2084 let scope = self.local_parent(def_id);
2085 if self.def_kind(scope) == DefKind::OpaqueTy {
2086 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2089 continue;
2090 }
2091 break (scope, def_id.into());
2092 };
2093
2094 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2095 Node::Item(..) | Node::TraitItem(..) => false,
2096 Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2097 _ => false,
2098 };
2099
2100 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2101 }
2102
2103 pub fn return_type_impl_or_dyn_traits(
2105 self,
2106 scope_def_id: LocalDefId,
2107 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2108 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2109 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2110 self.hir_fn_decl_by_hir_id(hir_id)
2111 else {
2112 return vec![];
2113 };
2114
2115 let mut v = TraitObjectVisitor(vec![], self.hir());
2116 v.visit_ty_unambig(hir_output);
2117 v.0
2118 }
2119
2120 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2124 self,
2125 scope_def_id: LocalDefId,
2126 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2127 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2128 let mut v = TraitObjectVisitor(vec![], self.hir());
2129 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2131 && let hir::TyKind::Path(hir::QPath::Resolved(
2132 None,
2133 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2134 && let Some(local_id) = def_id.as_local()
2135 && 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()
2137 {
2138 v.visit_ty_unambig(alias_ty);
2139 if !v.0.is_empty() {
2140 return Some((
2141 v.0,
2142 alias_generics.span,
2143 alias_generics.span_for_lifetime_suggestion(),
2144 ));
2145 }
2146 }
2147 None
2148 }
2149
2150 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2152 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2153 if self.impl_trait_ref(container_id).is_some() {
2154 return true;
2161 }
2162 false
2163 }
2164
2165 pub fn has_strict_asm_symbol_naming(self) -> bool {
2168 self.sess.target.arch.contains("nvptx")
2169 }
2170
2171 pub fn caller_location_ty(self) -> Ty<'tcx> {
2173 Ty::new_imm_ref(
2174 self,
2175 self.lifetimes.re_static,
2176 self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
2177 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2178 )
2179 }
2180
2181 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2183 let kind = self.def_kind(def_id);
2184 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2185 }
2186
2187 pub fn type_length_limit(self) -> Limit {
2188 self.limits(()).type_length_limit
2189 }
2190
2191 pub fn recursion_limit(self) -> Limit {
2192 self.limits(()).recursion_limit
2193 }
2194
2195 pub fn move_size_limit(self) -> Limit {
2196 self.limits(()).move_size_limit
2197 }
2198
2199 pub fn pattern_complexity_limit(self) -> Limit {
2200 self.limits(()).pattern_complexity_limit
2201 }
2202
2203 pub fn all_traits(self) -> impl Iterator<Item = DefId> {
2205 iter::once(LOCAL_CRATE)
2206 .chain(self.crates(()).iter().copied())
2207 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2208 }
2209
2210 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2212 let visible_crates =
2213 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2214
2215 iter::once(LOCAL_CRATE)
2216 .chain(visible_crates)
2217 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2218 }
2219
2220 #[inline]
2221 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2222 self.visibility(def_id).expect_local()
2223 }
2224
2225 #[instrument(skip(self), level = "trace", ret)]
2227 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2228 self.hir_expect_opaque_ty(def_id).origin
2229 }
2230
2231 pub fn finish(self) {
2232 self.alloc_self_profile_query_strings();
2235
2236 self.save_dep_graph();
2237 self.query_key_hash_verify_all();
2238
2239 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2240 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2241 }
2242 }
2243}
2244
2245macro_rules! nop_lift {
2246 ($set:ident; $ty:ty => $lifted:ty) => {
2247 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2248 type Lifted = $lifted;
2249 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2250 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2255 _x: Interned<'tcx, Inner>,
2256 ) -> InternedSet<'tcx, Inner> {
2257 unreachable!()
2258 }
2259 fn _type_eq<T>(_x: &T, _y: &T) {}
2260 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2261 let interner = _intern_set_ty_from_interned_ty(x.0);
2265 _type_eq(&interner, &tcx.interners.$set);
2267 }
2268
2269 tcx.interners
2270 .$set
2271 .contains_pointer_to(&InternedInSet(&*self.0.0))
2272 .then(|| unsafe { mem::transmute(self) })
2275 }
2276 }
2277 };
2278}
2279
2280macro_rules! nop_list_lift {
2281 ($set:ident; $ty:ty => $lifted:ty) => {
2282 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2283 type Lifted = &'tcx List<$lifted>;
2284 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2285 if false {
2287 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2288 }
2289
2290 if self.is_empty() {
2291 return Some(List::empty());
2292 }
2293 tcx.interners
2294 .$set
2295 .contains_pointer_to(&InternedInSet(self))
2296 .then(|| unsafe { mem::transmute(self) })
2297 }
2298 }
2299 };
2300}
2301
2302nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2303nop_lift! { region; Region<'a> => Region<'tcx> }
2304nop_lift! { const_; Const<'a> => Const<'tcx> }
2305nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2306nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2307nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2308nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2309nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2310nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2311
2312nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2313nop_list_lift! {
2314 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2315}
2316nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2317
2318nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2320
2321macro_rules! sty_debug_print {
2322 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2323 #[allow(non_snake_case)]
2326 mod inner {
2327 use crate::ty::{self, TyCtxt};
2328 use crate::ty::context::InternedInSet;
2329
2330 #[derive(Copy, Clone)]
2331 struct DebugStat {
2332 total: usize,
2333 lt_infer: usize,
2334 ty_infer: usize,
2335 ct_infer: usize,
2336 all_infer: usize,
2337 }
2338
2339 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2340 let mut total = DebugStat {
2341 total: 0,
2342 lt_infer: 0,
2343 ty_infer: 0,
2344 ct_infer: 0,
2345 all_infer: 0,
2346 };
2347 $(let mut $variant = total;)*
2348
2349 for shard in tcx.interners.type_.lock_shards() {
2350 let types = shard.iter();
2351 for &(InternedInSet(t), ()) in types {
2352 let variant = match t.internee {
2353 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2354 ty::Float(..) | ty::Str | ty::Never => continue,
2355 ty::Error(_) => continue,
2356 $(ty::$variant(..) => &mut $variant,)*
2357 };
2358 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2359 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2360 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2361
2362 variant.total += 1;
2363 total.total += 1;
2364 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2365 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2366 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2367 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2368 }
2369 }
2370 writeln!(fmt, "Ty interner total ty lt ct all")?;
2371 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2372 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2373 stringify!($variant),
2374 uses = $variant.total,
2375 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2376 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2377 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2378 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2379 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2380 )*
2381 writeln!(fmt, " total {uses:6} \
2382 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2383 uses = total.total,
2384 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2385 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2386 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2387 all = total.all_infer as f64 * 100.0 / total.total as f64)
2388 }
2389 }
2390
2391 inner::go($fmt, $ctxt)
2392 }}
2393}
2394
2395impl<'tcx> TyCtxt<'tcx> {
2396 pub fn debug_stats(self) -> impl fmt::Debug {
2397 fmt::from_fn(move |fmt| {
2398 sty_debug_print!(
2399 fmt,
2400 self,
2401 Adt,
2402 Array,
2403 Slice,
2404 RawPtr,
2405 Ref,
2406 FnDef,
2407 FnPtr,
2408 UnsafeBinder,
2409 Placeholder,
2410 Coroutine,
2411 CoroutineWitness,
2412 Dynamic,
2413 Closure,
2414 CoroutineClosure,
2415 Tuple,
2416 Bound,
2417 Param,
2418 Infer,
2419 Alias,
2420 Pat,
2421 Foreign
2422 )?;
2423
2424 writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2425 writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2426 writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2427 writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2428
2429 Ok(())
2430 })
2431 }
2432}
2433
2434struct InternedInSet<'tcx, T: ?Sized>(&'tcx T);
2439
2440impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> {
2441 fn clone(&self) -> Self {
2442 InternedInSet(self.0)
2443 }
2444}
2445
2446impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {}
2447
2448impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
2449 fn into_pointer(&self) -> *const () {
2450 self.0 as *const _ as *const ()
2451 }
2452}
2453
2454#[allow(rustc::usage_of_ty_tykind)]
2455impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2456 fn borrow(&self) -> &T {
2457 &self.0.internee
2458 }
2459}
2460
2461impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2462 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2463 self.0.internee == other.0.internee
2466 }
2467}
2468
2469impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2470
2471impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2472 fn hash<H: Hasher>(&self, s: &mut H) {
2473 self.0.internee.hash(s)
2475 }
2476}
2477
2478impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2479 fn borrow(&self) -> &[T] {
2480 &self.0[..]
2481 }
2482}
2483
2484impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2485 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2486 self.0[..] == other.0[..]
2489 }
2490}
2491
2492impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2493
2494impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2495 fn hash<H: Hasher>(&self, s: &mut H) {
2496 self.0[..].hash(s)
2498 }
2499}
2500
2501impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2502 fn borrow(&self) -> &[T] {
2503 &self.0[..]
2504 }
2505}
2506
2507impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2508 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2509 self.0[..] == other.0[..]
2512 }
2513}
2514
2515impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2516
2517impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2518 fn hash<H: Hasher>(&self, s: &mut H) {
2519 self.0[..].hash(s)
2521 }
2522}
2523
2524macro_rules! direct_interners {
2525 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2526 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2527 fn borrow<'a>(&'a self) -> &'a $ty {
2528 &self.0
2529 }
2530 }
2531
2532 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2533 fn eq(&self, other: &Self) -> bool {
2534 self.0 == other.0
2537 }
2538 }
2539
2540 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2541
2542 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2543 fn hash<H: Hasher>(&self, s: &mut H) {
2544 self.0.hash(s)
2547 }
2548 }
2549
2550 impl<'tcx> TyCtxt<'tcx> {
2551 $vis fn $method(self, v: $ty) -> $ret_ty {
2552 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2553 InternedInSet(self.interners.arena.alloc(v))
2554 }).0))
2555 }
2556 })+
2557 }
2558}
2559
2560direct_interners! {
2564 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2565 valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2566 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2567 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2568 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2569 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2570 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2571 ExternalConstraints -> ExternalConstraints<'tcx>,
2572 predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2573 PredefinedOpaques -> PredefinedOpaques<'tcx>,
2574}
2575
2576macro_rules! slice_interners {
2577 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2578 impl<'tcx> TyCtxt<'tcx> {
2579 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2580 if v.is_empty() {
2581 List::empty()
2582 } else {
2583 self.interners.$field.intern_ref(v, || {
2584 InternedInSet(List::from_arena(&*self.arena, (), v))
2585 }).0
2586 }
2587 })+
2588 }
2589 );
2590}
2591
2592slice_interners!(
2596 const_lists: pub mk_const_list(Const<'tcx>),
2597 args: pub mk_args(GenericArg<'tcx>),
2598 type_lists: pub mk_type_list(Ty<'tcx>),
2599 canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
2600 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2601 projs: pub mk_projs(ProjectionKind),
2602 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2603 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2604 fields: pub mk_fields(FieldIdx),
2605 local_def_ids: intern_local_def_ids(LocalDefId),
2606 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2607 offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2608);
2609
2610impl<'tcx> TyCtxt<'tcx> {
2611 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2615 assert!(sig.safety().is_safe());
2616 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2617 }
2618
2619 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2622 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2623 self.associated_items(trait_did)
2624 .filter_by_name_unhygienic(assoc_name.name)
2625 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2626 })
2627 }
2628
2629 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2631 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2632 let future_trait = self.require_lang_item(LangItem::Future, None);
2633
2634 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2635 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2636 return false;
2637 };
2638 trait_predicate.trait_ref.def_id == future_trait
2639 && trait_predicate.polarity == PredicatePolarity::Positive
2640 })
2641 }
2642
2643 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2651 sig.map_bound(|s| {
2652 let params = match s.inputs()[0].kind() {
2653 ty::Tuple(params) => *params,
2654 _ => bug!(),
2655 };
2656 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2657 })
2658 }
2659
2660 #[inline]
2661 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2662 self.interners.intern_predicate(
2663 binder,
2664 self.sess,
2665 &self.untracked,
2667 )
2668 }
2669
2670 #[inline]
2671 pub fn reuse_or_mk_predicate(
2672 self,
2673 pred: Predicate<'tcx>,
2674 binder: Binder<'tcx, PredicateKind<'tcx>>,
2675 ) -> Predicate<'tcx> {
2676 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2677 }
2678
2679 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2680 self.check_args_compatible_inner(def_id, args, false)
2681 }
2682
2683 fn check_args_compatible_inner(
2684 self,
2685 def_id: DefId,
2686 args: &'tcx [ty::GenericArg<'tcx>],
2687 nested: bool,
2688 ) -> bool {
2689 let generics = self.generics_of(def_id);
2690
2691 let own_args = if !nested
2694 && let DefKind::AssocTy = self.def_kind(def_id)
2695 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2696 {
2697 if generics.own_params.len() + 1 != args.len() {
2698 return false;
2699 }
2700
2701 if !matches!(args[0].unpack(), ty::GenericArgKind::Type(_)) {
2702 return false;
2703 }
2704
2705 &args[1..]
2706 } else {
2707 if generics.count() != args.len() {
2708 return false;
2709 }
2710
2711 let (parent_args, own_args) = args.split_at(generics.parent_count);
2712
2713 if let Some(parent) = generics.parent
2714 && !self.check_args_compatible_inner(parent, parent_args, true)
2715 {
2716 return false;
2717 }
2718
2719 own_args
2720 };
2721
2722 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2723 match (¶m.kind, arg.unpack()) {
2724 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2725 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2726 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2727 _ => return false,
2728 }
2729 }
2730
2731 true
2732 }
2733
2734 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2737 if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2738 if let DefKind::AssocTy = self.def_kind(def_id)
2739 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2740 {
2741 bug!(
2742 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2743 self.def_path_str(def_id),
2744 args,
2745 self.mk_args_from_iter(
2747 [self.types.self_param.into()].into_iter().chain(
2748 self.generics_of(def_id)
2749 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2750 .iter()
2751 .copied()
2752 )
2753 )
2754 );
2755 } else {
2756 bug!(
2757 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2758 self.def_path_str(def_id),
2759 args,
2760 ty::GenericArgs::identity_for_item(self, def_id)
2761 );
2762 }
2763 }
2764 }
2765
2766 #[inline(always)]
2767 pub(crate) fn check_and_mk_args(
2768 self,
2769 def_id: DefId,
2770 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2771 ) -> GenericArgsRef<'tcx> {
2772 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2773 self.debug_assert_args_compatible(def_id, args);
2774 args
2775 }
2776
2777 #[inline]
2778 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2779 self.interners.intern_const(
2780 kind,
2781 self.sess,
2782 &self.untracked,
2784 )
2785 }
2786
2787 #[allow(rustc::usage_of_ty_tykind)]
2789 #[inline]
2790 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2791 self.interners.intern_ty(
2792 st,
2793 self.sess,
2794 &self.untracked,
2796 )
2797 }
2798
2799 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2800 match param.kind {
2801 GenericParamDefKind::Lifetime => {
2802 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2803 }
2804 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2805 GenericParamDefKind::Const { .. } => {
2806 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2807 .into()
2808 }
2809 }
2810 }
2811
2812 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2813 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2814 }
2815
2816 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2817 self.mk_place_elem(place, PlaceElem::Deref)
2818 }
2819
2820 pub fn mk_place_downcast(
2821 self,
2822 place: Place<'tcx>,
2823 adt_def: AdtDef<'tcx>,
2824 variant_index: VariantIdx,
2825 ) -> Place<'tcx> {
2826 self.mk_place_elem(
2827 place,
2828 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2829 )
2830 }
2831
2832 pub fn mk_place_downcast_unnamed(
2833 self,
2834 place: Place<'tcx>,
2835 variant_index: VariantIdx,
2836 ) -> Place<'tcx> {
2837 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2838 }
2839
2840 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2841 self.mk_place_elem(place, PlaceElem::Index(index))
2842 }
2843
2844 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2848 let mut projection = place.projection.to_vec();
2849 projection.push(elem);
2850
2851 Place { local: place.local, projection: self.mk_place_elems(&projection) }
2852 }
2853
2854 pub fn mk_poly_existential_predicates(
2855 self,
2856 eps: &[PolyExistentialPredicate<'tcx>],
2857 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2858 assert!(!eps.is_empty());
2859 assert!(
2860 eps.array_windows()
2861 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2862 != Ordering::Greater)
2863 );
2864 self.intern_poly_existential_predicates(eps)
2865 }
2866
2867 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2868 self.interners.intern_clauses(clauses)
2872 }
2873
2874 pub fn mk_local_def_ids(self, clauses: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2875 self.intern_local_def_ids(clauses)
2879 }
2880
2881 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2882 where
2883 I: Iterator<Item = T>,
2884 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2885 {
2886 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2887 }
2888
2889 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2890 where
2891 I: Iterator<Item = T>,
2892 T: CollectAndApply<
2893 &'tcx ty::CapturedPlace<'tcx>,
2894 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2895 >,
2896 {
2897 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2898 }
2899
2900 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2901 where
2902 I: Iterator<Item = T>,
2903 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2904 {
2905 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2906 }
2907
2908 pub fn mk_fn_sig<I, T>(
2913 self,
2914 inputs: I,
2915 output: I::Item,
2916 c_variadic: bool,
2917 safety: hir::Safety,
2918 abi: ExternAbi,
2919 ) -> T::Output
2920 where
2921 I: IntoIterator<Item = T>,
2922 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2923 {
2924 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2925 inputs_and_output: self.mk_type_list(xs),
2926 c_variadic,
2927 safety,
2928 abi,
2929 })
2930 }
2931
2932 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2933 where
2934 I: Iterator<Item = T>,
2935 T: CollectAndApply<
2936 PolyExistentialPredicate<'tcx>,
2937 &'tcx List<PolyExistentialPredicate<'tcx>>,
2938 >,
2939 {
2940 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2941 }
2942
2943 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2944 where
2945 I: Iterator<Item = T>,
2946 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2947 {
2948 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2949 }
2950
2951 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2952 where
2953 I: Iterator<Item = T>,
2954 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2955 {
2956 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2957 }
2958
2959 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2960 where
2961 I: Iterator<Item = T>,
2962 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2963 {
2964 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2965 }
2966
2967 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2968 where
2969 I: Iterator<Item = T>,
2970 T: CollectAndApply<CanonicalVarInfo<'tcx>, &'tcx List<CanonicalVarInfo<'tcx>>>,
2971 {
2972 T::collect_and_apply(iter, |xs| self.mk_canonical_var_infos(xs))
2973 }
2974
2975 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2976 where
2977 I: Iterator<Item = T>,
2978 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2979 {
2980 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2981 }
2982
2983 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2984 where
2985 I: Iterator<Item = T>,
2986 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2987 {
2988 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2989 }
2990
2991 pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
2992 where
2993 I: Iterator<Item = T>,
2994 T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
2995 {
2996 T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
2997 }
2998
2999 pub fn mk_args_trait(
3000 self,
3001 self_ty: Ty<'tcx>,
3002 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3003 ) -> GenericArgsRef<'tcx> {
3004 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3005 }
3006
3007 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3008 where
3009 I: Iterator<Item = T>,
3010 T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3011 {
3012 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3013 }
3014
3015 #[track_caller]
3018 pub fn emit_node_span_lint(
3019 self,
3020 lint: &'static Lint,
3021 hir_id: HirId,
3022 span: impl Into<MultiSpan>,
3023 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3024 ) {
3025 let (level, src) = self.lint_level_at_node(lint, hir_id);
3026 lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
3027 decorator.decorate_lint(lint);
3028 })
3029 }
3030
3031 #[rustc_lint_diagnostics]
3035 #[track_caller]
3036 pub fn node_span_lint(
3037 self,
3038 lint: &'static Lint,
3039 hir_id: HirId,
3040 span: impl Into<MultiSpan>,
3041 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3042 ) {
3043 let (level, src) = self.lint_level_at_node(lint, hir_id);
3044 lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
3045 }
3046
3047 pub fn crate_level_attribute_injection_span(self, hir_id: HirId) -> Option<Span> {
3050 for (_hir_id, node) in self.hir_parent_iter(hir_id) {
3051 if let hir::Node::Crate(m) = node {
3052 return Some(m.spans.inject_use_span.shrink_to_lo());
3053 }
3054 }
3055 None
3056 }
3057
3058 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3059 self,
3060 diag: &mut Diag<'_, E>,
3061 hir_id: Option<HirId>,
3062 features: impl IntoIterator<Item = (String, Symbol)>,
3063 ) {
3064 if !self.sess.is_nightly_build() {
3065 return;
3066 }
3067
3068 let span = hir_id.and_then(|id| self.crate_level_attribute_injection_span(id));
3069 for (desc, feature) in features {
3070 let msg =
3072 format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3073 if let Some(span) = span {
3074 diag.span_suggestion_verbose(
3075 span,
3076 msg,
3077 format!("#![feature({feature})]\n"),
3078 Applicability::MaybeIncorrect,
3079 );
3080 } else {
3081 diag.help(msg);
3082 }
3083 }
3084 }
3085
3086 #[track_caller]
3089 pub fn emit_node_lint(
3090 self,
3091 lint: &'static Lint,
3092 id: HirId,
3093 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3094 ) {
3095 self.node_lint(lint, id, |lint| {
3096 decorator.decorate_lint(lint);
3097 })
3098 }
3099
3100 #[rustc_lint_diagnostics]
3104 #[track_caller]
3105 pub fn node_lint(
3106 self,
3107 lint: &'static Lint,
3108 id: HirId,
3109 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3110 ) {
3111 let (level, src) = self.lint_level_at_node(lint, id);
3112 lint_level(self.sess, lint, level, src, None, decorate);
3113 }
3114
3115 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3116 let map = self.in_scope_traits_map(id.owner)?;
3117 let candidates = map.get(&id.local_id)?;
3118 Some(candidates)
3119 }
3120
3121 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3122 debug!(?id, "named_region");
3123 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3124 }
3125
3126 pub fn is_late_bound(self, id: HirId) -> bool {
3127 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3128 }
3129
3130 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3131 self.mk_bound_variable_kinds(
3132 &self
3133 .late_bound_vars_map(id.owner)
3134 .get(&id.local_id)
3135 .cloned()
3136 .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3137 )
3138 }
3139
3140 pub fn map_opaque_lifetime_to_parent_lifetime(
3148 self,
3149 mut opaque_lifetime_param_def_id: LocalDefId,
3150 ) -> ty::Region<'tcx> {
3151 debug_assert!(
3152 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3153 "{opaque_lifetime_param_def_id:?} is a {}",
3154 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3155 );
3156
3157 loop {
3158 let parent = self.local_parent(opaque_lifetime_param_def_id);
3159 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3160
3161 let Some((lifetime, _)) = lifetime_mapping
3162 .iter()
3163 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3164 else {
3165 bug!("duplicated lifetime param should be present");
3166 };
3167
3168 match *lifetime {
3169 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3170 let new_parent = self.local_parent(ebv);
3171
3172 if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3175 debug_assert_eq!(self.local_parent(parent), new_parent);
3176 opaque_lifetime_param_def_id = ebv;
3177 continue;
3178 }
3179
3180 let generics = self.generics_of(new_parent);
3181 return ty::Region::new_early_param(
3182 self,
3183 ty::EarlyParamRegion {
3184 index: generics
3185 .param_def_id_to_index(self, ebv.to_def_id())
3186 .expect("early-bound var should be present in fn generics"),
3187 name: self.item_name(ebv.to_def_id()),
3188 },
3189 );
3190 }
3191 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3192 let new_parent = self.local_parent(lbv);
3193 return ty::Region::new_late_param(
3194 self,
3195 new_parent.to_def_id(),
3196 ty::LateParamRegionKind::Named(
3197 lbv.to_def_id(),
3198 self.item_name(lbv.to_def_id()),
3199 ),
3200 );
3201 }
3202 resolve_bound_vars::ResolvedArg::Error(guar) => {
3203 return ty::Region::new_error(self, guar);
3204 }
3205 _ => {
3206 return ty::Region::new_error_with_message(
3207 self,
3208 self.def_span(opaque_lifetime_param_def_id),
3209 "cannot resolve lifetime",
3210 );
3211 }
3212 }
3213 }
3214 }
3215
3216 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3221 self.is_const_fn(def_id)
3222 && match self.lookup_const_stability(def_id) {
3223 None => true, Some(stability) if stability.is_const_stable() => true,
3225 _ => false,
3226 }
3227 }
3228
3229 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3231 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3232 && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3233 }
3234
3235 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3236 match self.def_kind(def_id) {
3237 DefKind::Fn | DefKind::AssocFn => {}
3238 _ => return None,
3239 }
3240 self.intrinsic_raw(def_id)
3241 }
3242
3243 pub fn next_trait_solver_globally(self) -> bool {
3244 self.sess.opts.unstable_opts.next_solver.globally
3245 }
3246
3247 pub fn next_trait_solver_in_coherence(self) -> bool {
3248 self.sess.opts.unstable_opts.next_solver.coherence
3249 }
3250
3251 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3252 self.opt_rpitit_info(def_id).is_some()
3253 }
3254
3255 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3265 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3266 }
3267
3268 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3269 self.resolver_for_lowering_raw(()).0
3270 }
3271
3272 pub fn impl_trait_ref(
3275 self,
3276 def_id: impl IntoQueryParam<DefId>,
3277 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3278 Some(self.impl_trait_header(def_id)?.trait_ref)
3279 }
3280
3281 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3282 self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3283 }
3284
3285 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3286 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3287 self.coroutine_kind(def_id)
3288 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3289 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3290 {
3291 true
3292 } else {
3293 false
3294 }
3295 }
3296
3297 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3299 self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3300 }
3301}
3302
3303#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3312pub struct DeducedParamAttrs {
3313 pub read_only: bool,
3316}
3317
3318pub fn provide(providers: &mut Providers) {
3319 providers.maybe_unused_trait_imports =
3320 |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
3321 providers.names_imported_by_glob_use = |tcx, id| {
3322 tcx.arena.alloc(UnordSet::from(
3323 tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default(),
3324 ))
3325 };
3326
3327 providers.extern_mod_stmt_cnum =
3328 |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
3329 providers.is_panic_runtime =
3330 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3331 providers.is_compiler_builtins =
3332 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3333 providers.has_panic_handler = |tcx, LocalCrate| {
3334 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3336 };
3337 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3338}
3339
3340pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3341 attrs.iter().any(|x| x.has_name(name))
3342}