1#![allow(rustc::usage_of_ty_tykind)]
4
5pub mod tls;
6
7use std::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::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::def::{CtorKind, DefKind};
36use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
37use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
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::PointeeSized;
47use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
48use rustc_session::config::CrateType;
49use rustc_session::cstore::{CrateStoreDyn, Untracked};
50use rustc_session::lint::Lint;
51use rustc_session::{Limit, Session};
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::TraitSolverLangItem;
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, stability};
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;
76use crate::traits::solve::{
77 ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData,
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 Span = Span;
97
98 type GenericArgs = ty::GenericArgsRef<'tcx>;
99
100 type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
101 type GenericArg = ty::GenericArg<'tcx>;
102 type Term = ty::Term<'tcx>;
103 type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
104
105 type BoundVarKind = ty::BoundVariableKind;
106 type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
107
108 fn mk_predefined_opaques_in_body(
109 self,
110 data: PredefinedOpaquesData<Self>,
111 ) -> Self::PredefinedOpaques {
112 self.mk_predefined_opaques_in_body(data)
113 }
114 type LocalDefIds = &'tcx ty::List<LocalDefId>;
115 type CanonicalVarKinds = CanonicalVarKinds<'tcx>;
116 fn mk_canonical_var_kinds(
117 self,
118 kinds: &[ty::CanonicalVarKind<Self>],
119 ) -> Self::CanonicalVarKinds {
120 self.mk_canonical_var_kinds(kinds)
121 }
122
123 type ExternalConstraints = ExternalConstraints<'tcx>;
124 fn mk_external_constraints(
125 self,
126 data: ExternalConstraintsData<Self>,
127 ) -> ExternalConstraints<'tcx> {
128 self.mk_external_constraints(data)
129 }
130 type DepNodeIndex = DepNodeIndex;
131 fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
132 self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
133 }
134 type Ty = Ty<'tcx>;
135 type Tys = &'tcx List<Ty<'tcx>>;
136
137 type FnInputTys = &'tcx [Ty<'tcx>];
138 type ParamTy = ParamTy;
139 type BoundTy = ty::BoundTy;
140
141 type PlaceholderTy = ty::PlaceholderType;
142 type ErrorGuaranteed = ErrorGuaranteed;
143 type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
144
145 type AllocId = crate::mir::interpret::AllocId;
146 type Pat = Pattern<'tcx>;
147 type PatList = &'tcx List<Pattern<'tcx>>;
148 type Safety = hir::Safety;
149 type Abi = ExternAbi;
150 type Const = ty::Const<'tcx>;
151 type PlaceholderConst = ty::PlaceholderConst;
152
153 type ParamConst = ty::ParamConst;
154 type BoundConst = ty::BoundVar;
155 type ValueConst = ty::Value<'tcx>;
156 type ExprConst = ty::Expr<'tcx>;
157 type ValTree = ty::ValTree<'tcx>;
158
159 type Region = Region<'tcx>;
160 type EarlyParamRegion = ty::EarlyParamRegion;
161 type LateParamRegion = ty::LateParamRegion;
162 type BoundRegion = ty::BoundRegion;
163 type PlaceholderRegion = ty::PlaceholderRegion;
164
165 type ParamEnv = ty::ParamEnv<'tcx>;
166 type Predicate = Predicate<'tcx>;
167
168 type Clause = Clause<'tcx>;
169 type Clauses = ty::Clauses<'tcx>;
170
171 type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
172 fn mk_tracked<T: fmt::Debug + Clone>(
173 self,
174 data: T,
175 dep_node: DepNodeIndex,
176 ) -> Self::Tracked<T> {
177 WithDepNode::new(dep_node, data)
178 }
179 fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
180 tracked.get(self)
181 }
182
183 fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
184 f(&mut *self.new_solver_evaluation_cache.lock())
185 }
186
187 fn canonical_param_env_cache_get_or_insert<R>(
188 self,
189 param_env: ty::ParamEnv<'tcx>,
190 f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry<Self>,
191 from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry<Self>) -> R,
192 ) -> R {
193 let mut cache = self.new_solver_canonical_param_env_cache.lock();
194 let entry = cache.entry(param_env).or_insert_with(f);
195 from_entry(entry)
196 }
197
198 fn evaluation_is_concurrent(&self) -> bool {
199 self.sess.threads() > 1
200 }
201
202 fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
203 self.expand_abstract_consts(t)
204 }
205
206 type GenericsOf = &'tcx ty::Generics;
207
208 fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
209 self.generics_of(def_id)
210 }
211
212 type VariancesOf = &'tcx [ty::Variance];
213
214 fn variances_of(self, def_id: DefId) -> Self::VariancesOf {
215 self.variances_of(def_id)
216 }
217
218 fn opt_alias_variances(
219 self,
220 kind: impl Into<ty::AliasTermKind>,
221 def_id: DefId,
222 ) -> Option<&'tcx [ty::Variance]> {
223 self.opt_alias_variances(kind, def_id)
224 }
225
226 fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
227 self.type_of(def_id)
228 }
229 fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
230 self.type_of_opaque_hir_typeck(def_id)
231 }
232
233 type AdtDef = ty::AdtDef<'tcx>;
234 fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
235 self.adt_def(adt_def_id)
236 }
237
238 fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
239 match self.def_kind(alias.def_id) {
240 DefKind::AssocTy => {
241 if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
242 {
243 ty::Inherent
244 } else {
245 ty::Projection
246 }
247 }
248 DefKind::OpaqueTy => ty::Opaque,
249 DefKind::TyAlias => ty::Free,
250 kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
251 }
252 }
253
254 fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind {
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::AliasTermKind::InherentTy
260 } else {
261 ty::AliasTermKind::ProjectionTy
262 }
263 }
264 DefKind::AssocConst => {
265 if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
266 {
267 ty::AliasTermKind::InherentConst
268 } else {
269 ty::AliasTermKind::ProjectionConst
270 }
271 }
272 DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
273 DefKind::TyAlias => ty::AliasTermKind::FreeTy,
274 DefKind::Const => ty::AliasTermKind::FreeConst,
275 DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
276 ty::AliasTermKind::UnevaluatedConst
277 }
278 kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
279 }
280 }
281
282 fn trait_ref_and_own_args_for_alias(
283 self,
284 def_id: DefId,
285 args: ty::GenericArgsRef<'tcx>,
286 ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
287 debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
288 let trait_def_id = self.parent(def_id);
289 debug_assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
290 let trait_generics = self.generics_of(trait_def_id);
291 (
292 ty::TraitRef::new_from_args(self, trait_def_id, args.truncate_to(self, trait_generics)),
293 &args[trait_generics.count()..],
294 )
295 }
296
297 fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
298 self.mk_args(args)
299 }
300
301 fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
302 where
303 I: Iterator<Item = T>,
304 T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
305 {
306 self.mk_args_from_iter(args)
307 }
308
309 fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
310 self.check_args_compatible(def_id, args)
311 }
312
313 fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
314 self.debug_assert_args_compatible(def_id, args);
315 }
316
317 fn debug_assert_existential_args_compatible(
321 self,
322 def_id: Self::DefId,
323 args: Self::GenericArgs,
324 ) {
325 if cfg!(debug_assertions) {
328 self.debug_assert_args_compatible(
329 def_id,
330 self.mk_args_from_iter(
331 [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
332 ),
333 );
334 }
335 }
336
337 fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
338 where
339 I: Iterator<Item = T>,
340 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
341 {
342 self.mk_type_list_from_iter(args)
343 }
344
345 fn parent(self, def_id: DefId) -> DefId {
346 self.parent(def_id)
347 }
348
349 fn recursion_limit(self) -> usize {
350 self.recursion_limit().0
351 }
352
353 type Features = &'tcx rustc_feature::Features;
354
355 fn features(self) -> Self::Features {
356 self.features()
357 }
358
359 fn coroutine_hidden_types(
360 self,
361 def_id: DefId,
362 ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> {
363 self.coroutine_hidden_types(def_id)
364 }
365
366 fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
367 self.fn_sig(def_id)
368 }
369
370 fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
371 self.coroutine_movability(def_id)
372 }
373
374 fn coroutine_for_closure(self, def_id: DefId) -> DefId {
375 self.coroutine_for_closure(def_id)
376 }
377
378 fn generics_require_sized_self(self, def_id: DefId) -> bool {
379 self.generics_require_sized_self(def_id)
380 }
381
382 fn item_bounds(
383 self,
384 def_id: DefId,
385 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
386 self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
387 }
388
389 fn item_self_bounds(
390 self,
391 def_id: DefId,
392 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
393 self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
394 }
395
396 fn item_non_self_bounds(
397 self,
398 def_id: DefId,
399 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
400 self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
401 }
402
403 fn predicates_of(
404 self,
405 def_id: DefId,
406 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
407 ty::EarlyBinder::bind(
408 self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
409 )
410 }
411
412 fn own_predicates_of(
413 self,
414 def_id: DefId,
415 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
416 ty::EarlyBinder::bind(
417 self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
418 )
419 }
420
421 fn explicit_super_predicates_of(
422 self,
423 def_id: DefId,
424 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
425 self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
426 }
427
428 fn explicit_implied_predicates_of(
429 self,
430 def_id: DefId,
431 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
432 self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
433 }
434
435 fn impl_is_const(self, def_id: DefId) -> bool {
436 debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
437 self.is_conditionally_const(def_id)
438 }
439
440 fn fn_is_const(self, def_id: DefId) -> bool {
441 debug_assert_matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
442 self.is_conditionally_const(def_id)
443 }
444
445 fn alias_has_const_conditions(self, def_id: DefId) -> bool {
446 debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
447 self.is_conditionally_const(def_id)
448 }
449
450 fn const_conditions(
451 self,
452 def_id: DefId,
453 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
454 ty::EarlyBinder::bind(
455 self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
456 )
457 }
458
459 fn explicit_implied_const_bounds(
460 self,
461 def_id: DefId,
462 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
463 ty::EarlyBinder::bind(
464 self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
465 )
466 }
467
468 fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
469 self.impl_self_is_guaranteed_unsized(impl_def_id)
470 }
471
472 fn has_target_features(self, def_id: DefId) -> bool {
473 !self.codegen_fn_attrs(def_id).target_features.is_empty()
474 }
475
476 fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
477 self.require_lang_item(trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
478 }
479
480 fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
481 self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
482 }
483
484 fn is_default_trait(self, def_id: DefId) -> bool {
485 self.is_default_trait(def_id)
486 }
487
488 fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
489 lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
490 }
491
492 fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
493 self.associated_items(def_id)
494 .in_definition_order()
495 .filter(|assoc_item| assoc_item.is_type())
496 .map(|assoc_item| assoc_item.def_id)
497 }
498
499 fn for_each_relevant_impl(
503 self,
504 trait_def_id: DefId,
505 self_ty: Ty<'tcx>,
506 mut f: impl FnMut(DefId),
507 ) {
508 let tcx = self;
509 let trait_impls = tcx.trait_impls_of(trait_def_id);
510 let mut consider_impls_for_simplified_type = |simp| {
511 if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
512 for &impl_def_id in impls_for_type {
513 f(impl_def_id);
514 }
515 }
516 };
517
518 match self_ty.kind() {
519 ty::Bool
520 | ty::Char
521 | ty::Int(_)
522 | ty::Uint(_)
523 | ty::Float(_)
524 | ty::Adt(_, _)
525 | ty::Foreign(_)
526 | ty::Str
527 | ty::Array(_, _)
528 | ty::Pat(_, _)
529 | ty::Slice(_)
530 | ty::RawPtr(_, _)
531 | ty::Ref(_, _, _)
532 | ty::FnDef(_, _)
533 | ty::FnPtr(..)
534 | ty::Dynamic(_, _, _)
535 | ty::Closure(..)
536 | ty::CoroutineClosure(..)
537 | ty::Coroutine(_, _)
538 | ty::Never
539 | ty::Tuple(_)
540 | ty::UnsafeBinder(_) => {
541 let simp = ty::fast_reject::simplify_type(
542 tcx,
543 self_ty,
544 ty::fast_reject::TreatParams::AsRigid,
545 )
546 .unwrap();
547 consider_impls_for_simplified_type(simp);
548 }
549
550 ty::Infer(ty::IntVar(_)) => {
553 use ty::IntTy::*;
554 use ty::UintTy::*;
555 let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
557 let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
558 let possible_integers = [
559 ty::SimplifiedType::Int(I8),
561 ty::SimplifiedType::Int(I16),
562 ty::SimplifiedType::Int(I32),
563 ty::SimplifiedType::Int(I64),
564 ty::SimplifiedType::Int(I128),
565 ty::SimplifiedType::Int(Isize),
566 ty::SimplifiedType::Uint(U8),
568 ty::SimplifiedType::Uint(U16),
569 ty::SimplifiedType::Uint(U32),
570 ty::SimplifiedType::Uint(U64),
571 ty::SimplifiedType::Uint(U128),
572 ty::SimplifiedType::Uint(Usize),
573 ];
574 for simp in possible_integers {
575 consider_impls_for_simplified_type(simp);
576 }
577 }
578
579 ty::Infer(ty::FloatVar(_)) => {
580 let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
582 let possible_floats = [
583 ty::SimplifiedType::Float(ty::FloatTy::F16),
584 ty::SimplifiedType::Float(ty::FloatTy::F32),
585 ty::SimplifiedType::Float(ty::FloatTy::F64),
586 ty::SimplifiedType::Float(ty::FloatTy::F128),
587 ];
588
589 for simp in possible_floats {
590 consider_impls_for_simplified_type(simp);
591 }
592 }
593
594 ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
599
600 ty::CoroutineWitness(..) => (),
604
605 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
607 | ty::Param(_)
608 | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
609 }
610
611 let trait_impls = tcx.trait_impls_of(trait_def_id);
612 for &impl_def_id in trait_impls.blanket_impls() {
613 f(impl_def_id);
614 }
615 }
616
617 fn has_item_definition(self, def_id: DefId) -> bool {
618 self.defaultness(def_id).has_value()
619 }
620
621 fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
622 self.specializes((impl_def_id, victim_def_id))
623 }
624
625 fn impl_is_default(self, impl_def_id: DefId) -> bool {
626 self.defaultness(impl_def_id).is_default()
627 }
628
629 fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
630 self.impl_trait_ref(impl_def_id).unwrap()
631 }
632
633 fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
634 self.impl_polarity(impl_def_id)
635 }
636
637 fn trait_is_auto(self, trait_def_id: DefId) -> bool {
638 self.trait_is_auto(trait_def_id)
639 }
640
641 fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
642 self.trait_is_coinductive(trait_def_id)
643 }
644
645 fn trait_is_alias(self, trait_def_id: DefId) -> bool {
646 self.trait_is_alias(trait_def_id)
647 }
648
649 fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
650 self.is_dyn_compatible(trait_def_id)
651 }
652
653 fn trait_is_fundamental(self, def_id: DefId) -> bool {
654 self.trait_def(def_id).is_fundamental
655 }
656
657 fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
658 self.trait_def(trait_def_id).implement_via_object
659 }
660
661 fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
662 self.trait_def(trait_def_id).safety.is_unsafe()
663 }
664
665 fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
666 self.is_impl_trait_in_trait(def_id)
667 }
668
669 fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
670 self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
671 }
672
673 fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
674 self.is_general_coroutine(coroutine_def_id)
675 }
676
677 fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
678 self.coroutine_is_async(coroutine_def_id)
679 }
680
681 fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
682 self.coroutine_is_gen(coroutine_def_id)
683 }
684
685 fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
686 self.coroutine_is_async_gen(coroutine_def_id)
687 }
688
689 type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
690 fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
691 self.unsizing_params_for_adt(adt_def_id)
692 }
693
694 fn find_const_ty_from_env(
695 self,
696 param_env: ty::ParamEnv<'tcx>,
697 placeholder: Self::PlaceholderConst,
698 ) -> Ty<'tcx> {
699 placeholder.find_const_ty_from_env(param_env)
700 }
701
702 fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
703 self,
704 binder: ty::Binder<'tcx, T>,
705 ) -> ty::Binder<'tcx, T> {
706 self.anonymize_bound_vars(binder)
707 }
708
709 fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
710 self.opaque_types_defined_by(defining_anchor)
711 }
712
713 fn opaque_types_and_coroutines_defined_by(
714 self,
715 defining_anchor: Self::LocalDefId,
716 ) -> Self::LocalDefIds {
717 if self.next_trait_solver_globally() {
718 let coroutines_defined_by = self
719 .nested_bodies_within(defining_anchor)
720 .iter()
721 .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
722 self.mk_local_def_ids_from_iter(
723 self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
724 )
725 } else {
726 self.opaque_types_defined_by(defining_anchor)
727 }
728 }
729}
730
731macro_rules! bidirectional_lang_item_map {
732 ($($name:ident),+ $(,)?) => {
733 fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
734 match lang_item {
735 $(TraitSolverLangItem::$name => LangItem::$name,)+
736 }
737 }
738
739 fn lang_item_to_trait_lang_item(lang_item: LangItem) -> Option<TraitSolverLangItem> {
740 Some(match lang_item {
741 $(LangItem::$name => TraitSolverLangItem::$name,)+
742 _ => return None,
743 })
744 }
745 }
746}
747
748bidirectional_lang_item_map! {
749AsyncFn,
751 AsyncFnKindHelper,
752 AsyncFnKindUpvars,
753 AsyncFnMut,
754 AsyncFnOnce,
755 AsyncFnOnceOutput,
756 AsyncIterator,
757 BikeshedGuaranteedNoDrop,
758 CallOnceFuture,
759 CallRefFuture,
760 Clone,
761 Copy,
762 Coroutine,
763 CoroutineReturn,
764 CoroutineYield,
765 Destruct,
766 DiscriminantKind,
767 Drop,
768 DynMetadata,
769 Fn,
770 FnMut,
771 FnOnce,
772 FnPtrTrait,
773 FusedIterator,
774 Future,
775 FutureOutput,
776 Iterator,
777 Metadata,
778 MetaSized,
779 Option,
780 PointeeSized,
781 PointeeTrait,
782 Poll,
783 Sized,
784 TransmuteTrait,
785 Tuple,
786 Unpin,
787 Unsize,
788}
790
791impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
792 fn is_local(self) -> bool {
793 self.is_local()
794 }
795
796 fn as_local(self) -> Option<LocalDefId> {
797 self.as_local()
798 }
799}
800
801impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
802 fn rust() -> Self {
803 ExternAbi::Rust
804 }
805
806 fn is_rust(self) -> bool {
807 matches!(self, ExternAbi::Rust)
808 }
809}
810
811impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
812 fn safe() -> Self {
813 hir::Safety::Safe
814 }
815
816 fn is_safe(self) -> bool {
817 self.is_safe()
818 }
819
820 fn prefix_str(self) -> &'static str {
821 self.prefix_str()
822 }
823}
824
825impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
826 fn generic_const_exprs(self) -> bool {
827 self.generic_const_exprs()
828 }
829
830 fn coroutine_clone(self) -> bool {
831 self.coroutine_clone()
832 }
833
834 fn associated_const_equality(self) -> bool {
835 self.associated_const_equality()
836 }
837}
838
839impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
840 fn dummy() -> Self {
841 DUMMY_SP
842 }
843}
844
845type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
846
847pub struct CtxtInterners<'tcx> {
848 arena: &'tcx WorkerLocal<Arena<'tcx>>,
850
851 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
854 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
855 args: InternedSet<'tcx, GenericArgs<'tcx>>,
856 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
857 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
858 region: InternedSet<'tcx, RegionKind<'tcx>>,
859 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
860 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
861 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
862 projs: InternedSet<'tcx, List<ProjectionKind>>,
863 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
864 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
865 pat: InternedSet<'tcx, PatternKind<'tcx>>,
866 const_allocation: InternedSet<'tcx, Allocation>,
867 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
868 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
869 adt_def: InternedSet<'tcx, AdtDefData>,
870 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
871 predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
872 fields: InternedSet<'tcx, List<FieldIdx>>,
873 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
874 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
875 offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
876 valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
877 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
878}
879
880impl<'tcx> CtxtInterners<'tcx> {
881 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
882 const N: usize = 2048;
885 CtxtInterners {
886 arena,
887 type_: InternedSet::with_capacity(N * 16),
891 const_lists: InternedSet::with_capacity(N * 4),
892 args: InternedSet::with_capacity(N * 4),
893 type_lists: InternedSet::with_capacity(N * 4),
894 region: InternedSet::with_capacity(N * 4),
895 poly_existential_predicates: InternedSet::with_capacity(N / 4),
896 canonical_var_kinds: InternedSet::with_capacity(N / 2),
897 predicate: InternedSet::with_capacity(N),
898 clauses: InternedSet::with_capacity(N),
899 projs: InternedSet::with_capacity(N * 4),
900 place_elems: InternedSet::with_capacity(N * 2),
901 const_: InternedSet::with_capacity(N * 2),
902 pat: InternedSet::with_capacity(N),
903 const_allocation: InternedSet::with_capacity(N),
904 bound_variable_kinds: InternedSet::with_capacity(N * 2),
905 layout: InternedSet::with_capacity(N),
906 adt_def: InternedSet::with_capacity(N),
907 external_constraints: InternedSet::with_capacity(N),
908 predefined_opaques_in_body: InternedSet::with_capacity(N),
909 fields: InternedSet::with_capacity(N * 4),
910 local_def_ids: InternedSet::with_capacity(N),
911 captures: InternedSet::with_capacity(N),
912 offset_of: InternedSet::with_capacity(N),
913 valtree: InternedSet::with_capacity(N),
914 patterns: InternedSet::with_capacity(N),
915 }
916 }
917
918 #[allow(rustc::usage_of_ty_tykind)]
920 #[inline(never)]
921 fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
922 Ty(Interned::new_unchecked(
923 self.type_
924 .intern(kind, |kind| {
925 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
926 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
927
928 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
929 internee: kind,
930 stable_hash,
931 flags: flags.flags,
932 outer_exclusive_binder: flags.outer_exclusive_binder,
933 }))
934 })
935 .0,
936 ))
937 }
938
939 #[allow(rustc::usage_of_ty_tykind)]
941 #[inline(never)]
942 fn intern_const(
943 &self,
944 kind: ty::ConstKind<'tcx>,
945 sess: &Session,
946 untracked: &Untracked,
947 ) -> Const<'tcx> {
948 Const(Interned::new_unchecked(
949 self.const_
950 .intern(kind, |kind: ty::ConstKind<'_>| {
951 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
952 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
953
954 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
955 internee: kind,
956 stable_hash,
957 flags: flags.flags,
958 outer_exclusive_binder: flags.outer_exclusive_binder,
959 }))
960 })
961 .0,
962 ))
963 }
964
965 fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
966 &self,
967 flags: &ty::FlagComputation<TyCtxt<'tcx>>,
968 sess: &'a Session,
969 untracked: &'a Untracked,
970 val: &T,
971 ) -> Fingerprint {
972 if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
975 Fingerprint::ZERO
976 } else {
977 let mut hasher = StableHasher::new();
978 let mut hcx = StableHashingContext::new(sess, untracked);
979 val.hash_stable(&mut hcx, &mut hasher);
980 hasher.finish()
981 }
982 }
983
984 #[inline(never)]
986 fn intern_predicate(
987 &self,
988 kind: Binder<'tcx, PredicateKind<'tcx>>,
989 sess: &Session,
990 untracked: &Untracked,
991 ) -> Predicate<'tcx> {
992 Predicate(Interned::new_unchecked(
993 self.predicate
994 .intern(kind, |kind| {
995 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
996
997 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
998
999 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1000 internee: kind,
1001 stable_hash,
1002 flags: flags.flags,
1003 outer_exclusive_binder: flags.outer_exclusive_binder,
1004 }))
1005 })
1006 .0,
1007 ))
1008 }
1009
1010 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
1011 if clauses.is_empty() {
1012 ListWithCachedTypeInfo::empty()
1013 } else {
1014 self.clauses
1015 .intern_ref(clauses, || {
1016 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
1017
1018 InternedInSet(ListWithCachedTypeInfo::from_arena(
1019 &*self.arena,
1020 flags.into(),
1021 clauses,
1022 ))
1023 })
1024 .0
1025 }
1026 }
1027}
1028
1029const NUM_PREINTERNED_TY_VARS: u32 = 100;
1034const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
1035const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
1036const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
1037
1038const NUM_PREINTERNED_RE_VARS: u32 = 500;
1040const NUM_PREINTERNED_RE_LATE_BOUNDS_I: u32 = 2;
1041const NUM_PREINTERNED_RE_LATE_BOUNDS_V: u32 = 20;
1042
1043pub struct CommonTypes<'tcx> {
1044 pub unit: Ty<'tcx>,
1045 pub bool: Ty<'tcx>,
1046 pub char: Ty<'tcx>,
1047 pub isize: Ty<'tcx>,
1048 pub i8: Ty<'tcx>,
1049 pub i16: Ty<'tcx>,
1050 pub i32: Ty<'tcx>,
1051 pub i64: Ty<'tcx>,
1052 pub i128: Ty<'tcx>,
1053 pub usize: Ty<'tcx>,
1054 pub u8: Ty<'tcx>,
1055 pub u16: Ty<'tcx>,
1056 pub u32: Ty<'tcx>,
1057 pub u64: Ty<'tcx>,
1058 pub u128: Ty<'tcx>,
1059 pub f16: Ty<'tcx>,
1060 pub f32: Ty<'tcx>,
1061 pub f64: Ty<'tcx>,
1062 pub f128: Ty<'tcx>,
1063 pub str_: Ty<'tcx>,
1064 pub never: Ty<'tcx>,
1065 pub self_param: Ty<'tcx>,
1066
1067 pub trait_object_dummy_self: Ty<'tcx>,
1072
1073 pub ty_vars: Vec<Ty<'tcx>>,
1075
1076 pub fresh_tys: Vec<Ty<'tcx>>,
1078
1079 pub fresh_int_tys: Vec<Ty<'tcx>>,
1081
1082 pub fresh_float_tys: Vec<Ty<'tcx>>,
1084}
1085
1086pub struct CommonLifetimes<'tcx> {
1087 pub re_static: Region<'tcx>,
1089
1090 pub re_erased: Region<'tcx>,
1092
1093 pub re_vars: Vec<Region<'tcx>>,
1095
1096 pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
1100}
1101
1102pub struct CommonConsts<'tcx> {
1103 pub unit: Const<'tcx>,
1104 pub true_: Const<'tcx>,
1105 pub false_: Const<'tcx>,
1106 pub(crate) valtree_zst: ValTree<'tcx>,
1108}
1109
1110impl<'tcx> CommonTypes<'tcx> {
1111 fn new(
1112 interners: &CtxtInterners<'tcx>,
1113 sess: &Session,
1114 untracked: &Untracked,
1115 ) -> CommonTypes<'tcx> {
1116 let mk = |ty| interners.intern_ty(ty, sess, untracked);
1117
1118 let ty_vars =
1119 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1120 let fresh_tys: Vec<_> =
1121 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1122 let fresh_int_tys: Vec<_> =
1123 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1124 let fresh_float_tys: Vec<_> =
1125 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1126
1127 CommonTypes {
1128 unit: mk(Tuple(List::empty())),
1129 bool: mk(Bool),
1130 char: mk(Char),
1131 never: mk(Never),
1132 isize: mk(Int(ty::IntTy::Isize)),
1133 i8: mk(Int(ty::IntTy::I8)),
1134 i16: mk(Int(ty::IntTy::I16)),
1135 i32: mk(Int(ty::IntTy::I32)),
1136 i64: mk(Int(ty::IntTy::I64)),
1137 i128: mk(Int(ty::IntTy::I128)),
1138 usize: mk(Uint(ty::UintTy::Usize)),
1139 u8: mk(Uint(ty::UintTy::U8)),
1140 u16: mk(Uint(ty::UintTy::U16)),
1141 u32: mk(Uint(ty::UintTy::U32)),
1142 u64: mk(Uint(ty::UintTy::U64)),
1143 u128: mk(Uint(ty::UintTy::U128)),
1144 f16: mk(Float(ty::FloatTy::F16)),
1145 f32: mk(Float(ty::FloatTy::F32)),
1146 f64: mk(Float(ty::FloatTy::F64)),
1147 f128: mk(Float(ty::FloatTy::F128)),
1148 str_: mk(Str),
1149 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1150
1151 trait_object_dummy_self: fresh_tys[0],
1152
1153 ty_vars,
1154 fresh_tys,
1155 fresh_int_tys,
1156 fresh_float_tys,
1157 }
1158 }
1159}
1160
1161impl<'tcx> CommonLifetimes<'tcx> {
1162 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1163 let mk = |r| {
1164 Region(Interned::new_unchecked(
1165 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1166 ))
1167 };
1168
1169 let re_vars =
1170 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1171
1172 let re_late_bounds = (0..NUM_PREINTERNED_RE_LATE_BOUNDS_I)
1173 .map(|i| {
1174 (0..NUM_PREINTERNED_RE_LATE_BOUNDS_V)
1175 .map(|v| {
1176 mk(ty::ReBound(
1177 ty::DebruijnIndex::from(i),
1178 ty::BoundRegion {
1179 var: ty::BoundVar::from(v),
1180 kind: ty::BoundRegionKind::Anon,
1181 },
1182 ))
1183 })
1184 .collect()
1185 })
1186 .collect();
1187
1188 CommonLifetimes {
1189 re_static: mk(ty::ReStatic),
1190 re_erased: mk(ty::ReErased),
1191 re_vars,
1192 re_late_bounds,
1193 }
1194 }
1195}
1196
1197impl<'tcx> CommonConsts<'tcx> {
1198 fn new(
1199 interners: &CtxtInterners<'tcx>,
1200 types: &CommonTypes<'tcx>,
1201 sess: &Session,
1202 untracked: &Untracked,
1203 ) -> CommonConsts<'tcx> {
1204 let mk_const = |c| {
1205 interners.intern_const(
1206 c, sess, untracked,
1208 )
1209 };
1210
1211 let mk_valtree = |v| {
1212 ty::ValTree(Interned::new_unchecked(
1213 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1214 ))
1215 };
1216
1217 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1218 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1219 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1220
1221 CommonConsts {
1222 unit: mk_const(ty::ConstKind::Value(ty::Value {
1223 ty: types.unit,
1224 valtree: valtree_zst,
1225 })),
1226 true_: mk_const(ty::ConstKind::Value(ty::Value {
1227 ty: types.bool,
1228 valtree: valtree_true,
1229 })),
1230 false_: mk_const(ty::ConstKind::Value(ty::Value {
1231 ty: types.bool,
1232 valtree: valtree_false,
1233 })),
1234 valtree_zst,
1235 }
1236 }
1237}
1238
1239#[derive(Debug)]
1242pub struct FreeRegionInfo {
1243 pub scope: LocalDefId,
1245 pub region_def_id: DefId,
1247 pub is_impl_item: bool,
1249}
1250
1251#[derive(Copy, Clone)]
1253pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1254 pub tcx: TyCtxt<'tcx>,
1255 key: KEY,
1257}
1258
1259impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1262
1263#[derive(Copy, Clone)]
1268pub struct Feed<'tcx, KEY: Copy> {
1269 _tcx: PhantomData<TyCtxt<'tcx>>,
1270 key: KEY,
1272}
1273
1274impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1277
1278impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1279 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1280 self.key.fmt(f)
1281 }
1282}
1283
1284impl<'tcx> TyCtxt<'tcx> {
1289 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1292 self.dep_graph.assert_ignored();
1293 TyCtxtFeed { tcx: self, key: () }
1294 }
1295
1296 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1299 let key = self.untracked().source_span.push(span);
1300 assert_eq!(key, CRATE_DEF_ID);
1301 TyCtxtFeed { tcx: self, key }
1302 }
1303
1304 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1308 debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1309 TyCtxtFeed { tcx: self, key }.type_of(value)
1310 }
1311}
1312
1313impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1314 #[inline(always)]
1315 pub fn key(&self) -> KEY {
1316 self.key
1317 }
1318
1319 #[inline(always)]
1320 pub fn downgrade(self) -> Feed<'tcx, KEY> {
1321 Feed { _tcx: PhantomData, key: self.key }
1322 }
1323}
1324
1325impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1326 #[inline(always)]
1327 pub fn key(&self) -> KEY {
1328 self.key
1329 }
1330
1331 #[inline(always)]
1332 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1333 TyCtxtFeed { tcx, key: self.key }
1334 }
1335}
1336
1337impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1338 #[inline(always)]
1339 pub fn def_id(&self) -> LocalDefId {
1340 self.key
1341 }
1342
1343 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1345 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1346 }
1347
1348 pub fn feed_hir(&self) {
1350 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1351
1352 let node = hir::OwnerNode::Synthetic;
1353 let bodies = Default::default();
1354 let attrs = hir::AttributeMap::EMPTY;
1355
1356 let (opt_hash_including_bodies, _, _) =
1357 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
1358 let node = node.into();
1359 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1360 opt_hash_including_bodies,
1361 nodes: IndexVec::from_elem_n(
1362 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1363 1,
1364 ),
1365 bodies,
1366 })));
1367 self.feed_owner_id().hir_attr_map(attrs);
1368 }
1369}
1370
1371#[derive(Copy, Clone)]
1389#[rustc_diagnostic_item = "TyCtxt"]
1390#[rustc_pass_by_value]
1391pub struct TyCtxt<'tcx> {
1392 gcx: &'tcx GlobalCtxt<'tcx>,
1393}
1394
1395impl<'tcx> LintEmitter for TyCtxt<'tcx> {
1396 fn emit_node_span_lint(
1397 self,
1398 lint: &'static Lint,
1399 hir_id: HirId,
1400 span: impl Into<MultiSpan>,
1401 decorator: impl for<'a> LintDiagnostic<'a, ()>,
1402 ) {
1403 self.emit_node_span_lint(lint, hir_id, span, decorator);
1404 }
1405}
1406
1407unsafe impl DynSend for TyCtxt<'_> {}
1411unsafe impl DynSync for TyCtxt<'_> {}
1412fn _assert_tcx_fields() {
1413 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1414 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1415}
1416
1417impl<'tcx> Deref for TyCtxt<'tcx> {
1418 type Target = &'tcx GlobalCtxt<'tcx>;
1419 #[inline(always)]
1420 fn deref(&self) -> &Self::Target {
1421 &self.gcx
1422 }
1423}
1424
1425pub struct GlobalCtxt<'tcx> {
1427 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1428 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1429
1430 interners: CtxtInterners<'tcx>,
1431
1432 pub sess: &'tcx Session,
1433 crate_types: Vec<CrateType>,
1434 stable_crate_id: StableCrateId,
1440
1441 pub dep_graph: DepGraph,
1442
1443 pub prof: SelfProfilerRef,
1444
1445 pub types: CommonTypes<'tcx>,
1447
1448 pub lifetimes: CommonLifetimes<'tcx>,
1450
1451 pub consts: CommonConsts<'tcx>,
1453
1454 pub(crate) hooks: crate::hooks::Providers,
1457
1458 untracked: Untracked,
1459
1460 pub query_system: QuerySystem<'tcx>,
1461 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1462
1463 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1465
1466 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1469
1470 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1474
1475 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1477 pub new_solver_canonical_param_env_cache:
1478 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
1479
1480 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1481
1482 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
1484 pub clauses_cache:
1486 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
1487
1488 pub data_layout: TargetDataLayout,
1490
1491 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1493
1494 current_gcx: CurrentGcx,
1495
1496 pub jobserver_proxy: Arc<Proxy>,
1498}
1499
1500impl<'tcx> GlobalCtxt<'tcx> {
1501 pub fn enter<F, R>(&'tcx self, f: F) -> R
1504 where
1505 F: FnOnce(TyCtxt<'tcx>) -> R,
1506 {
1507 let icx = tls::ImplicitCtxt::new(self);
1508
1509 let _on_drop = defer(move || {
1511 *self.current_gcx.value.write() = None;
1512 });
1513
1514 {
1516 let mut guard = self.current_gcx.value.write();
1517 assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1518 *guard = Some(self as *const _ as *const ());
1519 }
1520
1521 tls::enter_context(&icx, || f(icx.tcx))
1522 }
1523}
1524
1525#[derive(Clone)]
1532pub struct CurrentGcx {
1533 value: Arc<RwLock<Option<*const ()>>>,
1536}
1537
1538unsafe impl DynSend for CurrentGcx {}
1539unsafe impl DynSync for CurrentGcx {}
1540
1541impl CurrentGcx {
1542 pub fn new() -> Self {
1543 Self { value: Arc::new(RwLock::new(None)) }
1544 }
1545
1546 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1547 let read_guard = self.value.read();
1548 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1549 f(unsafe { &*gcx })
1553 }
1554}
1555
1556impl<'tcx> TyCtxt<'tcx> {
1557 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1558 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1561 if typeck_root_def_id != def_id.to_def_id() {
1562 return self.has_typeck_results(typeck_root_def_id.expect_local());
1563 }
1564
1565 self.hir_node_by_def_id(def_id).body_id().is_some()
1566 }
1567
1568 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1573 let def_kind = self.def_kind(def_id);
1574 if def_kind.has_codegen_attrs() {
1575 self.codegen_fn_attrs(def_id)
1576 } else if matches!(
1577 def_kind,
1578 DefKind::AnonConst
1579 | DefKind::AssocConst
1580 | DefKind::Const
1581 | DefKind::InlineConst
1582 | DefKind::GlobalAsm
1583 ) {
1584 CodegenFnAttrs::EMPTY
1585 } else {
1586 bug!(
1587 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1588 def_id,
1589 def_kind
1590 )
1591 }
1592 }
1593
1594 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1595 self.arena.alloc(Steal::new(thir))
1596 }
1597
1598 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1599 self.arena.alloc(Steal::new(mir))
1600 }
1601
1602 pub fn alloc_steal_promoted(
1603 self,
1604 promoted: IndexVec<Promoted, Body<'tcx>>,
1605 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1606 self.arena.alloc(Steal::new(promoted))
1607 }
1608
1609 pub fn mk_adt_def(
1610 self,
1611 did: DefId,
1612 kind: AdtKind,
1613 variants: IndexVec<VariantIdx, ty::VariantDef>,
1614 repr: ReprOptions,
1615 ) -> ty::AdtDef<'tcx> {
1616 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1617 }
1618
1619 pub fn allocate_bytes_dedup(self, bytes: &[u8], salt: usize) -> interpret::AllocId {
1622 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
1624 let alloc = self.mk_const_alloc(alloc);
1625 self.reserve_and_set_memory_dedup(alloc, salt)
1626 }
1627
1628 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1630 if self.sess.opts.unstable_opts.experimental_default_bounds {
1631 &[
1632 LangItem::DefaultTrait1,
1633 LangItem::DefaultTrait2,
1634 LangItem::DefaultTrait3,
1635 LangItem::DefaultTrait4,
1636 ]
1637 } else {
1638 &[]
1639 }
1640 }
1641
1642 pub fn is_default_trait(self, def_id: DefId) -> bool {
1643 self.default_traits()
1644 .iter()
1645 .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
1646 }
1647
1648 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1652 let get = |name| {
1653 let Some(attr) = self.get_attr(def_id, name) else {
1654 return Bound::Unbounded;
1655 };
1656 debug!("layout_scalar_valid_range: attr={:?}", attr);
1657 if let Some(
1658 &[
1659 ast::MetaItemInner::Lit(ast::MetaItemLit {
1660 kind: ast::LitKind::Int(a, _), ..
1661 }),
1662 ],
1663 ) = attr.meta_item_list().as_deref()
1664 {
1665 Bound::Included(a.get())
1666 } else {
1667 self.dcx().span_delayed_bug(
1668 attr.span(),
1669 "invalid rustc_layout_scalar_valid_range attribute",
1670 );
1671 Bound::Unbounded
1672 }
1673 };
1674 (
1675 get(sym::rustc_layout_scalar_valid_range_start),
1676 get(sym::rustc_layout_scalar_valid_range_end),
1677 )
1678 }
1679
1680 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1681 value.lift_to_interner(self)
1682 }
1683
1684 pub fn create_global_ctxt<T>(
1691 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1692 s: &'tcx Session,
1693 crate_types: Vec<CrateType>,
1694 stable_crate_id: StableCrateId,
1695 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1696 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1697 untracked: Untracked,
1698 dep_graph: DepGraph,
1699 query_kinds: &'tcx [DepKindStruct<'tcx>],
1700 query_system: QuerySystem<'tcx>,
1701 hooks: crate::hooks::Providers,
1702 current_gcx: CurrentGcx,
1703 jobserver_proxy: Arc<Proxy>,
1704 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1705 ) -> T {
1706 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1707 s.dcx().emit_fatal(err);
1708 });
1709 let interners = CtxtInterners::new(arena);
1710 let common_types = CommonTypes::new(&interners, s, &untracked);
1711 let common_lifetimes = CommonLifetimes::new(&interners);
1712 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1713
1714 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1715 sess: s,
1716 crate_types,
1717 stable_crate_id,
1718 arena,
1719 hir_arena,
1720 interners,
1721 dep_graph,
1722 hooks,
1723 prof: s.prof.clone(),
1724 types: common_types,
1725 lifetimes: common_lifetimes,
1726 consts: common_consts,
1727 untracked,
1728 query_system,
1729 query_kinds,
1730 ty_rcache: Default::default(),
1731 selection_cache: Default::default(),
1732 evaluation_cache: Default::default(),
1733 new_solver_evaluation_cache: Default::default(),
1734 new_solver_canonical_param_env_cache: Default::default(),
1735 canonical_param_env_cache: Default::default(),
1736 highest_var_in_clauses_cache: Default::default(),
1737 clauses_cache: Default::default(),
1738 data_layout,
1739 alloc_map: interpret::AllocMap::new(),
1740 current_gcx,
1741 jobserver_proxy,
1742 });
1743
1744 gcx.enter(f)
1746 }
1747
1748 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1750 self.get_lang_items(())
1751 }
1752
1753 #[track_caller]
1755 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1756 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1757 self.type_of(ordering_enum).no_bound_vars().unwrap()
1758 }
1759
1760 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1763 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1764 }
1765
1766 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1768 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1769 }
1770
1771 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1773 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1774 }
1775
1776 pub fn is_coroutine(self, def_id: DefId) -> bool {
1777 self.coroutine_kind(def_id).is_some()
1778 }
1779
1780 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1781 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1782 }
1783
1784 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1787 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1788 }
1789
1790 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1792 matches!(
1793 self.coroutine_kind(def_id),
1794 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1795 )
1796 }
1797
1798 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1801 matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1802 }
1803
1804 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1807 matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1808 }
1809
1810 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1812 matches!(
1813 self.coroutine_kind(def_id),
1814 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1815 )
1816 }
1817
1818 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1820 matches!(
1821 self.coroutine_kind(def_id),
1822 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1823 )
1824 }
1825
1826 pub fn stability(self) -> &'tcx stability::Index {
1827 self.stability_index(())
1828 }
1829
1830 pub fn features(self) -> &'tcx rustc_feature::Features {
1831 self.features_query(())
1832 }
1833
1834 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1835 let id = id.into_query_param();
1836 if let Some(id) = id.as_local() {
1838 self.definitions_untracked().def_key(id)
1839 } else {
1840 self.cstore_untracked().def_key(id)
1841 }
1842 }
1843
1844 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1850 if let Some(id) = id.as_local() {
1852 self.definitions_untracked().def_path(id)
1853 } else {
1854 self.cstore_untracked().def_path(id)
1855 }
1856 }
1857
1858 #[inline]
1859 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1860 if let Some(def_id) = def_id.as_local() {
1862 self.definitions_untracked().def_path_hash(def_id)
1863 } else {
1864 self.cstore_untracked().def_path_hash(def_id)
1865 }
1866 }
1867
1868 #[inline]
1869 pub fn crate_types(self) -> &'tcx [CrateType] {
1870 &self.crate_types
1871 }
1872
1873 pub fn needs_metadata(self) -> bool {
1874 self.crate_types().iter().any(|ty| match *ty {
1875 CrateType::Executable
1876 | CrateType::Staticlib
1877 | CrateType::Cdylib
1878 | CrateType::Sdylib => false,
1879 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1880 })
1881 }
1882
1883 pub fn needs_crate_hash(self) -> bool {
1884 cfg!(debug_assertions)
1896 || self.sess.opts.incremental.is_some()
1897 || self.needs_metadata()
1898 || self.sess.instrument_coverage()
1899 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1900 }
1901
1902 #[inline]
1903 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1904 if crate_num == LOCAL_CRATE {
1905 self.stable_crate_id
1906 } else {
1907 self.cstore_untracked().stable_crate_id(crate_num)
1908 }
1909 }
1910
1911 #[inline]
1914 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1915 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1916 LOCAL_CRATE
1917 } else {
1918 *self
1919 .untracked()
1920 .stable_crate_ids
1921 .read()
1922 .get(&stable_crate_id)
1923 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1924 }
1925 }
1926
1927 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1931 debug!("def_path_hash_to_def_id({:?})", hash);
1932
1933 let stable_crate_id = hash.stable_crate_id();
1934
1935 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1938 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1939 } else {
1940 Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
1941 }
1942 }
1943
1944 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1945 let (crate_name, stable_crate_id) = if def_id.is_local() {
1950 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1951 } else {
1952 let cstore = &*self.cstore_untracked();
1953 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1954 };
1955
1956 format!(
1957 "{}[{:04x}]{}",
1958 crate_name,
1959 stable_crate_id.as_u64() >> (8 * 6),
1962 self.def_path(def_id).to_string_no_crate_verbose()
1963 )
1964 }
1965
1966 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1967 self.sess.dcx()
1968 }
1969
1970 pub fn is_target_feature_call_safe(
1971 self,
1972 callee_features: &[TargetFeature],
1973 body_features: &[TargetFeature],
1974 ) -> bool {
1975 self.sess.target.options.is_like_wasm
1980 || callee_features
1981 .iter()
1982 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1983 }
1984
1985 pub fn adjust_target_feature_sig(
1988 self,
1989 fun_def: DefId,
1990 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1991 caller: DefId,
1992 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1993 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1994 let callee_features = &self.codegen_fn_attrs(caller).target_features;
1995 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
1996 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
1997 }
1998 None
1999 }
2000
2001 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
2004 match self.env_var_os(key.as_ref()) {
2005 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
2006 None => Err(VarError::NotPresent),
2007 }
2008 }
2009}
2010
2011impl<'tcx> TyCtxtAt<'tcx> {
2012 pub fn create_def(
2014 self,
2015 parent: LocalDefId,
2016 name: Option<Symbol>,
2017 def_kind: DefKind,
2018 override_def_path_data: Option<DefPathData>,
2019 disambiguator: &mut DisambiguatorState,
2020 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2021 let feed =
2022 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
2023
2024 feed.def_span(self.span);
2025 feed
2026 }
2027}
2028
2029impl<'tcx> TyCtxt<'tcx> {
2030 pub fn create_def(
2032 self,
2033 parent: LocalDefId,
2034 name: Option<Symbol>,
2035 def_kind: DefKind,
2036 override_def_path_data: Option<DefPathData>,
2037 disambiguator: &mut DisambiguatorState,
2038 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2039 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2040 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2050
2051 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2056
2057 let feed = TyCtxtFeed { tcx: self, key: def_id };
2058 feed.def_kind(def_kind);
2059 if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2064 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2065 feed.visibility(ty::Visibility::Restricted(parent_mod));
2066 }
2067
2068 feed
2069 }
2070
2071 pub fn create_crate_num(
2072 self,
2073 stable_crate_id: StableCrateId,
2074 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2075 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2076 return Err(existing);
2077 }
2078
2079 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2080 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2081 Ok(TyCtxtFeed { key: num, tcx: self })
2082 }
2083
2084 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2085 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2088
2089 let definitions = &self.untracked.definitions;
2090 gen {
2091 let mut i = 0;
2092
2093 while i < { definitions.read().num_definitions() } {
2096 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2097 yield LocalDefId { local_def_index };
2098 i += 1;
2099 }
2100
2101 definitions.freeze();
2103 }
2104 }
2105
2106 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2107 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2110
2111 self.untracked.definitions.freeze().def_path_table()
2114 }
2115
2116 pub fn def_path_hash_to_def_index_map(
2117 self,
2118 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2119 self.ensure_ok().hir_crate_items(());
2122 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2125 }
2126
2127 #[inline]
2130 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2131 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2132 }
2133
2134 pub fn untracked(self) -> &'tcx Untracked {
2136 &self.untracked
2137 }
2138 #[inline]
2141 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2142 self.untracked.definitions.read()
2143 }
2144
2145 #[inline]
2148 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2149 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2150 }
2151
2152 #[inline(always)]
2153 pub fn with_stable_hashing_context<R>(
2154 self,
2155 f: impl FnOnce(StableHashingContext<'_>) -> R,
2156 ) -> R {
2157 f(StableHashingContext::new(self.sess, &self.untracked))
2158 }
2159
2160 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2161 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2162 }
2163
2164 #[inline]
2165 pub fn local_crate_exports_generics(self) -> bool {
2166 self.crate_types().iter().any(|crate_type| {
2167 match crate_type {
2168 CrateType::Executable
2169 | CrateType::Staticlib
2170 | CrateType::ProcMacro
2171 | CrateType::Cdylib
2172 | CrateType::Sdylib => false,
2173
2174 CrateType::Dylib => true,
2179
2180 CrateType::Rlib => true,
2181 }
2182 })
2183 }
2184
2185 pub fn is_suitable_region(
2187 self,
2188 generic_param_scope: LocalDefId,
2189 mut region: Region<'tcx>,
2190 ) -> Option<FreeRegionInfo> {
2191 let (suitable_region_binding_scope, region_def_id) = loop {
2192 let def_id =
2193 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2194 let scope = self.local_parent(def_id);
2195 if self.def_kind(scope) == DefKind::OpaqueTy {
2196 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2199 continue;
2200 }
2201 break (scope, def_id.into());
2202 };
2203
2204 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2205 Node::Item(..) | Node::TraitItem(..) => false,
2206 Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2207 _ => false,
2208 };
2209
2210 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2211 }
2212
2213 pub fn return_type_impl_or_dyn_traits(
2215 self,
2216 scope_def_id: LocalDefId,
2217 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2218 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2219 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2220 self.hir_fn_decl_by_hir_id(hir_id)
2221 else {
2222 return vec![];
2223 };
2224
2225 let mut v = TraitObjectVisitor(vec![]);
2226 v.visit_ty_unambig(hir_output);
2227 v.0
2228 }
2229
2230 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2234 self,
2235 scope_def_id: LocalDefId,
2236 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2237 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2238 let mut v = TraitObjectVisitor(vec![]);
2239 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2241 && let hir::TyKind::Path(hir::QPath::Resolved(
2242 None,
2243 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2244 && let Some(local_id) = def_id.as_local()
2245 && 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()
2247 {
2248 v.visit_ty_unambig(alias_ty);
2249 if !v.0.is_empty() {
2250 return Some((
2251 v.0,
2252 alias_generics.span,
2253 alias_generics.span_for_lifetime_suggestion(),
2254 ));
2255 }
2256 }
2257 None
2258 }
2259
2260 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2262 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2263 if self.impl_trait_ref(container_id).is_some() {
2264 return true;
2271 }
2272 false
2273 }
2274
2275 pub fn has_strict_asm_symbol_naming(self) -> bool {
2278 self.sess.target.arch.contains("nvptx")
2279 }
2280
2281 pub fn caller_location_ty(self) -> Ty<'tcx> {
2283 Ty::new_imm_ref(
2284 self,
2285 self.lifetimes.re_static,
2286 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2287 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2288 )
2289 }
2290
2291 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2293 let kind = self.def_kind(def_id);
2294 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2295 }
2296
2297 pub fn type_length_limit(self) -> Limit {
2298 self.limits(()).type_length_limit
2299 }
2300
2301 pub fn recursion_limit(self) -> Limit {
2302 self.limits(()).recursion_limit
2303 }
2304
2305 pub fn move_size_limit(self) -> Limit {
2306 self.limits(()).move_size_limit
2307 }
2308
2309 pub fn pattern_complexity_limit(self) -> Limit {
2310 self.limits(()).pattern_complexity_limit
2311 }
2312
2313 pub fn all_traits(self) -> impl Iterator<Item = DefId> {
2315 iter::once(LOCAL_CRATE)
2316 .chain(self.crates(()).iter().copied())
2317 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2318 }
2319
2320 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2322 let visible_crates =
2323 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2324
2325 iter::once(LOCAL_CRATE)
2326 .chain(visible_crates)
2327 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2328 }
2329
2330 #[inline]
2331 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2332 self.visibility(def_id).expect_local()
2333 }
2334
2335 #[instrument(skip(self), level = "trace", ret)]
2337 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2338 self.hir_expect_opaque_ty(def_id).origin
2339 }
2340
2341 pub fn finish(self) {
2342 self.alloc_self_profile_query_strings();
2345
2346 self.save_dep_graph();
2347 self.query_key_hash_verify_all();
2348
2349 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2350 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2351 }
2352 }
2353}
2354
2355macro_rules! nop_lift {
2356 ($set:ident; $ty:ty => $lifted:ty) => {
2357 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2358 type Lifted = $lifted;
2359 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2360 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2365 _x: Interned<'tcx, Inner>,
2366 ) -> InternedSet<'tcx, Inner> {
2367 unreachable!()
2368 }
2369 fn _type_eq<T>(_x: &T, _y: &T) {}
2370 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2371 let interner = _intern_set_ty_from_interned_ty(x.0);
2375 _type_eq(&interner, &tcx.interners.$set);
2377 }
2378
2379 tcx.interners
2380 .$set
2381 .contains_pointer_to(&InternedInSet(&*self.0.0))
2382 .then(|| unsafe { mem::transmute(self) })
2385 }
2386 }
2387 };
2388}
2389
2390macro_rules! nop_list_lift {
2391 ($set:ident; $ty:ty => $lifted:ty) => {
2392 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2393 type Lifted = &'tcx List<$lifted>;
2394 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2395 if false {
2397 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2398 }
2399
2400 if self.is_empty() {
2401 return Some(List::empty());
2402 }
2403 tcx.interners
2404 .$set
2405 .contains_pointer_to(&InternedInSet(self))
2406 .then(|| unsafe { mem::transmute(self) })
2407 }
2408 }
2409 };
2410}
2411
2412nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2413nop_lift! { region; Region<'a> => Region<'tcx> }
2414nop_lift! { const_; Const<'a> => Const<'tcx> }
2415nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2416nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2417nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2418nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2419nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2420nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2421
2422nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2423nop_list_lift! {
2424 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2425}
2426nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2427
2428nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2430
2431macro_rules! sty_debug_print {
2432 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2433 #[allow(non_snake_case)]
2436 mod inner {
2437 use crate::ty::{self, TyCtxt};
2438 use crate::ty::context::InternedInSet;
2439
2440 #[derive(Copy, Clone)]
2441 struct DebugStat {
2442 total: usize,
2443 lt_infer: usize,
2444 ty_infer: usize,
2445 ct_infer: usize,
2446 all_infer: usize,
2447 }
2448
2449 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2450 let mut total = DebugStat {
2451 total: 0,
2452 lt_infer: 0,
2453 ty_infer: 0,
2454 ct_infer: 0,
2455 all_infer: 0,
2456 };
2457 $(let mut $variant = total;)*
2458
2459 for shard in tcx.interners.type_.lock_shards() {
2460 #[allow(rustc::potential_query_instability)]
2462 let types = shard.iter();
2463 for &(InternedInSet(t), ()) in types {
2464 let variant = match t.internee {
2465 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2466 ty::Float(..) | ty::Str | ty::Never => continue,
2467 ty::Error(_) => continue,
2468 $(ty::$variant(..) => &mut $variant,)*
2469 };
2470 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2471 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2472 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2473
2474 variant.total += 1;
2475 total.total += 1;
2476 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2477 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2478 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2479 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2480 }
2481 }
2482 writeln!(fmt, "Ty interner total ty lt ct all")?;
2483 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2484 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2485 stringify!($variant),
2486 uses = $variant.total,
2487 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2488 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2489 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2490 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2491 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2492 )*
2493 writeln!(fmt, " total {uses:6} \
2494 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2495 uses = total.total,
2496 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2497 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2498 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2499 all = total.all_infer as f64 * 100.0 / total.total as f64)
2500 }
2501 }
2502
2503 inner::go($fmt, $ctxt)
2504 }}
2505}
2506
2507impl<'tcx> TyCtxt<'tcx> {
2508 pub fn debug_stats(self) -> impl fmt::Debug {
2509 fmt::from_fn(move |fmt| {
2510 sty_debug_print!(
2511 fmt,
2512 self,
2513 Adt,
2514 Array,
2515 Slice,
2516 RawPtr,
2517 Ref,
2518 FnDef,
2519 FnPtr,
2520 UnsafeBinder,
2521 Placeholder,
2522 Coroutine,
2523 CoroutineWitness,
2524 Dynamic,
2525 Closure,
2526 CoroutineClosure,
2527 Tuple,
2528 Bound,
2529 Param,
2530 Infer,
2531 Alias,
2532 Pat,
2533 Foreign
2534 )?;
2535
2536 writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2537 writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2538 writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2539 writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2540
2541 Ok(())
2542 })
2543 }
2544}
2545
2546struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2551
2552impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2553 fn clone(&self) -> Self {
2554 InternedInSet(self.0)
2555 }
2556}
2557
2558impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2559
2560impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2561 fn into_pointer(&self) -> *const () {
2562 self.0 as *const _ as *const ()
2563 }
2564}
2565
2566#[allow(rustc::usage_of_ty_tykind)]
2567impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2568 fn borrow(&self) -> &T {
2569 &self.0.internee
2570 }
2571}
2572
2573impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2574 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2575 self.0.internee == other.0.internee
2578 }
2579}
2580
2581impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2582
2583impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2584 fn hash<H: Hasher>(&self, s: &mut H) {
2585 self.0.internee.hash(s)
2587 }
2588}
2589
2590impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2591 fn borrow(&self) -> &[T] {
2592 &self.0[..]
2593 }
2594}
2595
2596impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2597 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2598 self.0[..] == other.0[..]
2601 }
2602}
2603
2604impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2605
2606impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2607 fn hash<H: Hasher>(&self, s: &mut H) {
2608 self.0[..].hash(s)
2610 }
2611}
2612
2613impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2614 fn borrow(&self) -> &[T] {
2615 &self.0[..]
2616 }
2617}
2618
2619impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2620 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2621 self.0[..] == other.0[..]
2624 }
2625}
2626
2627impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2628
2629impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2630 fn hash<H: Hasher>(&self, s: &mut H) {
2631 self.0[..].hash(s)
2633 }
2634}
2635
2636macro_rules! direct_interners {
2637 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2638 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2639 fn borrow<'a>(&'a self) -> &'a $ty {
2640 &self.0
2641 }
2642 }
2643
2644 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2645 fn eq(&self, other: &Self) -> bool {
2646 self.0 == other.0
2649 }
2650 }
2651
2652 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2653
2654 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2655 fn hash<H: Hasher>(&self, s: &mut H) {
2656 self.0.hash(s)
2659 }
2660 }
2661
2662 impl<'tcx> TyCtxt<'tcx> {
2663 $vis fn $method(self, v: $ty) -> $ret_ty {
2664 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2665 InternedInSet(self.interners.arena.alloc(v))
2666 }).0))
2667 }
2668 })+
2669 }
2670}
2671
2672direct_interners! {
2676 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2677 valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2678 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2679 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2680 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2681 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2682 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2683 ExternalConstraints -> ExternalConstraints<'tcx>,
2684 predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2685 PredefinedOpaques -> PredefinedOpaques<'tcx>,
2686}
2687
2688macro_rules! slice_interners {
2689 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2690 impl<'tcx> TyCtxt<'tcx> {
2691 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2692 if v.is_empty() {
2693 List::empty()
2694 } else {
2695 self.interners.$field.intern_ref(v, || {
2696 InternedInSet(List::from_arena(&*self.arena, (), v))
2697 }).0
2698 }
2699 })+
2700 }
2701 );
2702}
2703
2704slice_interners!(
2708 const_lists: pub mk_const_list(Const<'tcx>),
2709 args: pub mk_args(GenericArg<'tcx>),
2710 type_lists: pub mk_type_list(Ty<'tcx>),
2711 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2712 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2713 projs: pub mk_projs(ProjectionKind),
2714 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2715 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2716 fields: pub mk_fields(FieldIdx),
2717 local_def_ids: intern_local_def_ids(LocalDefId),
2718 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2719 offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2720 patterns: pub mk_patterns(Pattern<'tcx>),
2721);
2722
2723impl<'tcx> TyCtxt<'tcx> {
2724 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2728 assert!(sig.safety().is_safe());
2729 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2730 }
2731
2732 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2735 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2736 self.associated_items(trait_did)
2737 .filter_by_name_unhygienic(assoc_name.name)
2738 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2739 })
2740 }
2741
2742 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2744 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2745 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2746
2747 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2748 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2749 return false;
2750 };
2751 trait_predicate.trait_ref.def_id == future_trait
2752 && trait_predicate.polarity == PredicatePolarity::Positive
2753 })
2754 }
2755
2756 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2764 sig.map_bound(|s| {
2765 let params = match s.inputs()[0].kind() {
2766 ty::Tuple(params) => *params,
2767 _ => bug!(),
2768 };
2769 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2770 })
2771 }
2772
2773 #[inline]
2774 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2775 self.interners.intern_predicate(
2776 binder,
2777 self.sess,
2778 &self.untracked,
2780 )
2781 }
2782
2783 #[inline]
2784 pub fn reuse_or_mk_predicate(
2785 self,
2786 pred: Predicate<'tcx>,
2787 binder: Binder<'tcx, PredicateKind<'tcx>>,
2788 ) -> Predicate<'tcx> {
2789 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2790 }
2791
2792 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2793 self.check_args_compatible_inner(def_id, args, false)
2794 }
2795
2796 fn check_args_compatible_inner(
2797 self,
2798 def_id: DefId,
2799 args: &'tcx [ty::GenericArg<'tcx>],
2800 nested: bool,
2801 ) -> bool {
2802 let generics = self.generics_of(def_id);
2803
2804 let own_args = if !nested
2807 && let DefKind::AssocTy = self.def_kind(def_id)
2808 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2809 {
2810 if generics.own_params.len() + 1 != args.len() {
2811 return false;
2812 }
2813
2814 if !matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2815 return false;
2816 }
2817
2818 &args[1..]
2819 } else {
2820 if generics.count() != args.len() {
2821 return false;
2822 }
2823
2824 let (parent_args, own_args) = args.split_at(generics.parent_count);
2825
2826 if let Some(parent) = generics.parent
2827 && !self.check_args_compatible_inner(parent, parent_args, true)
2828 {
2829 return false;
2830 }
2831
2832 own_args
2833 };
2834
2835 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2836 match (¶m.kind, arg.kind()) {
2837 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2838 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2839 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2840 _ => return false,
2841 }
2842 }
2843
2844 true
2845 }
2846
2847 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2850 if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2851 if let DefKind::AssocTy = self.def_kind(def_id)
2852 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2853 {
2854 bug!(
2855 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2856 self.def_path_str(def_id),
2857 args,
2858 self.mk_args_from_iter(
2860 [self.types.self_param.into()].into_iter().chain(
2861 self.generics_of(def_id)
2862 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2863 .iter()
2864 .copied()
2865 )
2866 )
2867 );
2868 } else {
2869 bug!(
2870 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2871 self.def_path_str(def_id),
2872 args,
2873 ty::GenericArgs::identity_for_item(self, def_id)
2874 );
2875 }
2876 }
2877 }
2878
2879 #[inline(always)]
2880 pub(crate) fn check_and_mk_args(
2881 self,
2882 def_id: DefId,
2883 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2884 ) -> GenericArgsRef<'tcx> {
2885 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2886 self.debug_assert_args_compatible(def_id, args);
2887 args
2888 }
2889
2890 #[inline]
2891 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2892 self.interners.intern_const(
2893 kind,
2894 self.sess,
2895 &self.untracked,
2897 )
2898 }
2899
2900 #[allow(rustc::usage_of_ty_tykind)]
2902 #[inline]
2903 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2904 self.interners.intern_ty(
2905 st,
2906 self.sess,
2907 &self.untracked,
2909 )
2910 }
2911
2912 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2913 match param.kind {
2914 GenericParamDefKind::Lifetime => {
2915 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2916 }
2917 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2918 GenericParamDefKind::Const { .. } => {
2919 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2920 .into()
2921 }
2922 }
2923 }
2924
2925 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2926 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2927 }
2928
2929 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2930 self.mk_place_elem(place, PlaceElem::Deref)
2931 }
2932
2933 pub fn mk_place_downcast(
2934 self,
2935 place: Place<'tcx>,
2936 adt_def: AdtDef<'tcx>,
2937 variant_index: VariantIdx,
2938 ) -> Place<'tcx> {
2939 self.mk_place_elem(
2940 place,
2941 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2942 )
2943 }
2944
2945 pub fn mk_place_downcast_unnamed(
2946 self,
2947 place: Place<'tcx>,
2948 variant_index: VariantIdx,
2949 ) -> Place<'tcx> {
2950 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2951 }
2952
2953 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2954 self.mk_place_elem(place, PlaceElem::Index(index))
2955 }
2956
2957 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2961 let mut projection = place.projection.to_vec();
2962 projection.push(elem);
2963
2964 Place { local: place.local, projection: self.mk_place_elems(&projection) }
2965 }
2966
2967 pub fn mk_poly_existential_predicates(
2968 self,
2969 eps: &[PolyExistentialPredicate<'tcx>],
2970 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2971 assert!(!eps.is_empty());
2972 assert!(
2973 eps.array_windows()
2974 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2975 != Ordering::Greater)
2976 );
2977 self.intern_poly_existential_predicates(eps)
2978 }
2979
2980 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2981 self.interners.intern_clauses(clauses)
2985 }
2986
2987 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2988 self.intern_local_def_ids(def_ids)
2992 }
2993
2994 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2995 where
2996 I: Iterator<Item = T>,
2997 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2998 {
2999 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
3000 }
3001
3002 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
3003 where
3004 I: Iterator<Item = T>,
3005 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
3006 {
3007 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
3008 }
3009
3010 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
3011 where
3012 I: Iterator<Item = T>,
3013 T: CollectAndApply<
3014 &'tcx ty::CapturedPlace<'tcx>,
3015 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
3016 >,
3017 {
3018 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
3019 }
3020
3021 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
3022 where
3023 I: Iterator<Item = T>,
3024 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
3025 {
3026 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3027 }
3028
3029 pub fn mk_fn_sig<I, T>(
3034 self,
3035 inputs: I,
3036 output: I::Item,
3037 c_variadic: bool,
3038 safety: hir::Safety,
3039 abi: ExternAbi,
3040 ) -> T::Output
3041 where
3042 I: IntoIterator<Item = T>,
3043 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3044 {
3045 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3046 inputs_and_output: self.mk_type_list(xs),
3047 c_variadic,
3048 safety,
3049 abi,
3050 })
3051 }
3052
3053 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3054 where
3055 I: Iterator<Item = T>,
3056 T: CollectAndApply<
3057 PolyExistentialPredicate<'tcx>,
3058 &'tcx List<PolyExistentialPredicate<'tcx>>,
3059 >,
3060 {
3061 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3062 }
3063
3064 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3065 where
3066 I: Iterator<Item = T>,
3067 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3068 {
3069 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3070 }
3071
3072 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3073 where
3074 I: Iterator<Item = T>,
3075 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3076 {
3077 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3078 }
3079
3080 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3081 where
3082 I: Iterator<Item = T>,
3083 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3084 {
3085 T::collect_and_apply(iter, |xs| self.mk_args(xs))
3086 }
3087
3088 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3089 where
3090 I: Iterator<Item = T>,
3091 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3092 {
3093 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3094 }
3095
3096 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3097 where
3098 I: Iterator<Item = T>,
3099 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3100 {
3101 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3102 }
3103
3104 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3105 where
3106 I: Iterator<Item = T>,
3107 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3108 {
3109 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3110 }
3111
3112 pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
3113 where
3114 I: Iterator<Item = T>,
3115 T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
3116 {
3117 T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
3118 }
3119
3120 pub fn mk_args_trait(
3121 self,
3122 self_ty: Ty<'tcx>,
3123 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3124 ) -> GenericArgsRef<'tcx> {
3125 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3126 }
3127
3128 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3129 where
3130 I: Iterator<Item = T>,
3131 T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3132 {
3133 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3134 }
3135
3136 #[track_caller]
3139 pub fn emit_node_span_lint(
3140 self,
3141 lint: &'static Lint,
3142 hir_id: HirId,
3143 span: impl Into<MultiSpan>,
3144 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3145 ) {
3146 let level = self.lint_level_at_node(lint, hir_id);
3147 lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3148 decorator.decorate_lint(lint);
3149 })
3150 }
3151
3152 #[rustc_lint_diagnostics]
3156 #[track_caller]
3157 pub fn node_span_lint(
3158 self,
3159 lint: &'static Lint,
3160 hir_id: HirId,
3161 span: impl Into<MultiSpan>,
3162 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3163 ) {
3164 let level = self.lint_level_at_node(lint, hir_id);
3165 lint_level(self.sess, lint, level, Some(span.into()), decorate);
3166 }
3167
3168 pub fn crate_level_attribute_injection_span(self) -> Span {
3170 let node = self.hir_node(hir::CRATE_HIR_ID);
3171 let hir::Node::Crate(m) = node else { bug!() };
3172 m.spans.inject_use_span.shrink_to_lo()
3173 }
3174
3175 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3176 self,
3177 diag: &mut Diag<'_, E>,
3178 features: impl IntoIterator<Item = (String, Symbol)>,
3179 ) {
3180 if !self.sess.is_nightly_build() {
3181 return;
3182 }
3183
3184 let span = self.crate_level_attribute_injection_span();
3185 for (desc, feature) in features {
3186 let msg =
3188 format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3189 diag.span_suggestion_verbose(
3190 span,
3191 msg,
3192 format!("#![feature({feature})]\n"),
3193 Applicability::MaybeIncorrect,
3194 );
3195 }
3196 }
3197
3198 #[track_caller]
3201 pub fn emit_node_lint(
3202 self,
3203 lint: &'static Lint,
3204 id: HirId,
3205 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3206 ) {
3207 self.node_lint(lint, id, |lint| {
3208 decorator.decorate_lint(lint);
3209 })
3210 }
3211
3212 #[rustc_lint_diagnostics]
3216 #[track_caller]
3217 pub fn node_lint(
3218 self,
3219 lint: &'static Lint,
3220 id: HirId,
3221 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3222 ) {
3223 let level = self.lint_level_at_node(lint, id);
3224 lint_level(self.sess, lint, level, None, decorate);
3225 }
3226
3227 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3228 let map = self.in_scope_traits_map(id.owner)?;
3229 let candidates = map.get(&id.local_id)?;
3230 Some(candidates)
3231 }
3232
3233 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3234 debug!(?id, "named_region");
3235 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3236 }
3237
3238 pub fn is_late_bound(self, id: HirId) -> bool {
3239 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3240 }
3241
3242 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3243 self.mk_bound_variable_kinds(
3244 &self
3245 .late_bound_vars_map(id.owner)
3246 .get(&id.local_id)
3247 .cloned()
3248 .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3249 )
3250 }
3251
3252 pub fn map_opaque_lifetime_to_parent_lifetime(
3260 self,
3261 mut opaque_lifetime_param_def_id: LocalDefId,
3262 ) -> ty::Region<'tcx> {
3263 debug_assert!(
3264 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3265 "{opaque_lifetime_param_def_id:?} is a {}",
3266 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3267 );
3268
3269 loop {
3270 let parent = self.local_parent(opaque_lifetime_param_def_id);
3271 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3272
3273 let Some((lifetime, _)) = lifetime_mapping
3274 .iter()
3275 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3276 else {
3277 bug!("duplicated lifetime param should be present");
3278 };
3279
3280 match *lifetime {
3281 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3282 let new_parent = self.local_parent(ebv);
3283
3284 if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3287 debug_assert_eq!(self.local_parent(parent), new_parent);
3288 opaque_lifetime_param_def_id = ebv;
3289 continue;
3290 }
3291
3292 let generics = self.generics_of(new_parent);
3293 return ty::Region::new_early_param(
3294 self,
3295 ty::EarlyParamRegion {
3296 index: generics
3297 .param_def_id_to_index(self, ebv.to_def_id())
3298 .expect("early-bound var should be present in fn generics"),
3299 name: self.item_name(ebv.to_def_id()),
3300 },
3301 );
3302 }
3303 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3304 let new_parent = self.local_parent(lbv);
3305 return ty::Region::new_late_param(
3306 self,
3307 new_parent.to_def_id(),
3308 ty::LateParamRegionKind::Named(
3309 lbv.to_def_id(),
3310 self.item_name(lbv.to_def_id()),
3311 ),
3312 );
3313 }
3314 resolve_bound_vars::ResolvedArg::Error(guar) => {
3315 return ty::Region::new_error(self, guar);
3316 }
3317 _ => {
3318 return ty::Region::new_error_with_message(
3319 self,
3320 self.def_span(opaque_lifetime_param_def_id),
3321 "cannot resolve lifetime",
3322 );
3323 }
3324 }
3325 }
3326 }
3327
3328 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3333 self.is_const_fn(def_id)
3334 && match self.lookup_const_stability(def_id) {
3335 None => true, Some(stability) if stability.is_const_stable() => true,
3337 _ => false,
3338 }
3339 }
3340
3341 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3343 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3344 && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3345 }
3346
3347 pub fn is_sdylib_interface_build(self) -> bool {
3348 self.sess.opts.unstable_opts.build_sdylib_interface
3349 }
3350
3351 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3352 match self.def_kind(def_id) {
3353 DefKind::Fn | DefKind::AssocFn => {}
3354 _ => return None,
3355 }
3356 self.intrinsic_raw(def_id)
3357 }
3358
3359 pub fn next_trait_solver_globally(self) -> bool {
3360 self.sess.opts.unstable_opts.next_solver.globally
3361 }
3362
3363 pub fn next_trait_solver_in_coherence(self) -> bool {
3364 self.sess.opts.unstable_opts.next_solver.coherence
3365 }
3366
3367 #[allow(rustc::bad_opt_access)]
3368 pub fn use_typing_mode_borrowck(self) -> bool {
3369 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3370 }
3371
3372 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3373 self.opt_rpitit_info(def_id).is_some()
3374 }
3375
3376 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3386 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3387 }
3388
3389 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3390 self.resolver_for_lowering_raw(()).0
3391 }
3392
3393 pub fn impl_trait_ref(
3396 self,
3397 def_id: impl IntoQueryParam<DefId>,
3398 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3399 Some(self.impl_trait_header(def_id)?.trait_ref)
3400 }
3401
3402 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3403 self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3404 }
3405
3406 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3407 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3408 self.coroutine_kind(def_id)
3409 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3410 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3411 {
3412 true
3413 } else {
3414 false
3415 }
3416 }
3417
3418 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3420 self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3421 }
3422}
3423
3424#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3433pub struct DeducedParamAttrs {
3434 pub read_only: bool,
3437}
3438
3439pub fn provide(providers: &mut Providers) {
3440 providers.maybe_unused_trait_imports =
3441 |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
3442 providers.names_imported_by_glob_use = |tcx, id| {
3443 tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
3444 };
3445
3446 providers.extern_mod_stmt_cnum =
3447 |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
3448 providers.is_panic_runtime =
3449 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3450 providers.is_compiler_builtins =
3451 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3452 providers.has_panic_handler = |tcx, LocalCrate| {
3453 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3455 };
3456 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3457}
3458
3459pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3460 attrs.iter().any(|x| x.has_name(name))
3461}