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, PointeeSized};
14use std::ops::{Bound, Deref};
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_attr_data_structures::{AttributeKind, find_attr};
21use rustc_data_structures::defer;
22use rustc_data_structures::fingerprint::Fingerprint;
23use rustc_data_structures::fx::FxHashMap;
24use rustc_data_structures::intern::Interned;
25use rustc_data_structures::jobserver::Proxy;
26use rustc_data_structures::profiling::SelfProfilerRef;
27use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
28use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
29use rustc_data_structures::steal::Steal;
30use rustc_data_structures::sync::{
31 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
32};
33use rustc_errors::{
34 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, LintEmitter, MultiSpan,
35};
36use rustc_hir::def::{CtorKind, DefKind};
37use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
38use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
39use rustc_hir::intravisit::VisitorExt;
40use rustc_hir::lang_items::LangItem;
41use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
42use rustc_index::IndexVec;
43use rustc_macros::{HashStable, TyDecodable, TyEncodable};
44use rustc_query_system::cache::WithDepNode;
45use rustc_query_system::dep_graph::DepNodeIndex;
46use rustc_query_system::ich::StableHashingContext;
47use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
48use rustc_session::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_super_outlives(
436 self,
437 impl_def_id: DefId,
438 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
439 self.impl_super_outlives(impl_def_id)
440 }
441
442 fn impl_is_const(self, def_id: DefId) -> bool {
443 debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
444 self.is_conditionally_const(def_id)
445 }
446
447 fn fn_is_const(self, def_id: DefId) -> bool {
448 debug_assert_matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
449 self.is_conditionally_const(def_id)
450 }
451
452 fn alias_has_const_conditions(self, def_id: DefId) -> bool {
453 debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
454 self.is_conditionally_const(def_id)
455 }
456
457 fn const_conditions(
458 self,
459 def_id: DefId,
460 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
461 ty::EarlyBinder::bind(
462 self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
463 )
464 }
465
466 fn explicit_implied_const_bounds(
467 self,
468 def_id: DefId,
469 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
470 ty::EarlyBinder::bind(
471 self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
472 )
473 }
474
475 fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
476 self.impl_self_is_guaranteed_unsized(impl_def_id)
477 }
478
479 fn has_target_features(self, def_id: DefId) -> bool {
480 !self.codegen_fn_attrs(def_id).target_features.is_empty()
481 }
482
483 fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
484 self.require_lang_item(trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
485 }
486
487 fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
488 self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
489 }
490
491 fn is_default_trait(self, def_id: DefId) -> bool {
492 self.is_default_trait(def_id)
493 }
494
495 fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
496 lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
497 }
498
499 fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
500 self.associated_items(def_id)
501 .in_definition_order()
502 .filter(|assoc_item| assoc_item.is_type())
503 .map(|assoc_item| assoc_item.def_id)
504 }
505
506 fn for_each_relevant_impl(
510 self,
511 trait_def_id: DefId,
512 self_ty: Ty<'tcx>,
513 mut f: impl FnMut(DefId),
514 ) {
515 let tcx = self;
516 let trait_impls = tcx.trait_impls_of(trait_def_id);
517 let mut consider_impls_for_simplified_type = |simp| {
518 if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
519 for &impl_def_id in impls_for_type {
520 f(impl_def_id);
521 }
522 }
523 };
524
525 match self_ty.kind() {
526 ty::Bool
527 | ty::Char
528 | ty::Int(_)
529 | ty::Uint(_)
530 | ty::Float(_)
531 | ty::Adt(_, _)
532 | ty::Foreign(_)
533 | ty::Str
534 | ty::Array(_, _)
535 | ty::Pat(_, _)
536 | ty::Slice(_)
537 | ty::RawPtr(_, _)
538 | ty::Ref(_, _, _)
539 | ty::FnDef(_, _)
540 | ty::FnPtr(..)
541 | ty::Dynamic(_, _, _)
542 | ty::Closure(..)
543 | ty::CoroutineClosure(..)
544 | ty::Coroutine(_, _)
545 | ty::Never
546 | ty::Tuple(_)
547 | ty::UnsafeBinder(_) => {
548 let simp = ty::fast_reject::simplify_type(
549 tcx,
550 self_ty,
551 ty::fast_reject::TreatParams::AsRigid,
552 )
553 .unwrap();
554 consider_impls_for_simplified_type(simp);
555 }
556
557 ty::Infer(ty::IntVar(_)) => {
560 use ty::IntTy::*;
561 use ty::UintTy::*;
562 let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
564 let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
565 let possible_integers = [
566 ty::SimplifiedType::Int(I8),
568 ty::SimplifiedType::Int(I16),
569 ty::SimplifiedType::Int(I32),
570 ty::SimplifiedType::Int(I64),
571 ty::SimplifiedType::Int(I128),
572 ty::SimplifiedType::Int(Isize),
573 ty::SimplifiedType::Uint(U8),
575 ty::SimplifiedType::Uint(U16),
576 ty::SimplifiedType::Uint(U32),
577 ty::SimplifiedType::Uint(U64),
578 ty::SimplifiedType::Uint(U128),
579 ty::SimplifiedType::Uint(Usize),
580 ];
581 for simp in possible_integers {
582 consider_impls_for_simplified_type(simp);
583 }
584 }
585
586 ty::Infer(ty::FloatVar(_)) => {
587 let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
589 let possible_floats = [
590 ty::SimplifiedType::Float(ty::FloatTy::F16),
591 ty::SimplifiedType::Float(ty::FloatTy::F32),
592 ty::SimplifiedType::Float(ty::FloatTy::F64),
593 ty::SimplifiedType::Float(ty::FloatTy::F128),
594 ];
595
596 for simp in possible_floats {
597 consider_impls_for_simplified_type(simp);
598 }
599 }
600
601 ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
606
607 ty::CoroutineWitness(..) => (),
611
612 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
614 | ty::Param(_)
615 | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
616 }
617
618 let trait_impls = tcx.trait_impls_of(trait_def_id);
619 for &impl_def_id in trait_impls.blanket_impls() {
620 f(impl_def_id);
621 }
622 }
623
624 fn has_item_definition(self, def_id: DefId) -> bool {
625 self.defaultness(def_id).has_value()
626 }
627
628 fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
629 self.specializes((impl_def_id, victim_def_id))
630 }
631
632 fn impl_is_default(self, impl_def_id: DefId) -> bool {
633 self.defaultness(impl_def_id).is_default()
634 }
635
636 fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
637 self.impl_trait_ref(impl_def_id).unwrap()
638 }
639
640 fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
641 self.impl_polarity(impl_def_id)
642 }
643
644 fn trait_is_auto(self, trait_def_id: DefId) -> bool {
645 self.trait_is_auto(trait_def_id)
646 }
647
648 fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
649 self.trait_is_coinductive(trait_def_id)
650 }
651
652 fn trait_is_alias(self, trait_def_id: DefId) -> bool {
653 self.trait_is_alias(trait_def_id)
654 }
655
656 fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
657 self.is_dyn_compatible(trait_def_id)
658 }
659
660 fn trait_is_fundamental(self, def_id: DefId) -> bool {
661 self.trait_def(def_id).is_fundamental
662 }
663
664 fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
665 self.trait_def(trait_def_id).implement_via_object
666 }
667
668 fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
669 self.trait_def(trait_def_id).safety.is_unsafe()
670 }
671
672 fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
673 self.is_impl_trait_in_trait(def_id)
674 }
675
676 fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
677 self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
678 }
679
680 fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
681 self.is_general_coroutine(coroutine_def_id)
682 }
683
684 fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
685 self.coroutine_is_async(coroutine_def_id)
686 }
687
688 fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
689 self.coroutine_is_gen(coroutine_def_id)
690 }
691
692 fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
693 self.coroutine_is_async_gen(coroutine_def_id)
694 }
695
696 type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
697 fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
698 self.unsizing_params_for_adt(adt_def_id)
699 }
700
701 fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
702 self,
703 binder: ty::Binder<'tcx, T>,
704 ) -> ty::Binder<'tcx, T> {
705 self.anonymize_bound_vars(binder)
706 }
707
708 fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
709 self.opaque_types_defined_by(defining_anchor)
710 }
711
712 fn opaque_types_and_coroutines_defined_by(
713 self,
714 defining_anchor: Self::LocalDefId,
715 ) -> Self::LocalDefIds {
716 if self.next_trait_solver_globally() {
717 let coroutines_defined_by = self
718 .nested_bodies_within(defining_anchor)
719 .iter()
720 .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
721 self.mk_local_def_ids_from_iter(
722 self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
723 )
724 } else {
725 self.opaque_types_defined_by(defining_anchor)
726 }
727 }
728}
729
730macro_rules! bidirectional_lang_item_map {
731 ($($name:ident),+ $(,)?) => {
732 fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
733 match lang_item {
734 $(TraitSolverLangItem::$name => LangItem::$name,)+
735 }
736 }
737
738 fn lang_item_to_trait_lang_item(lang_item: LangItem) -> Option<TraitSolverLangItem> {
739 Some(match lang_item {
740 $(LangItem::$name => TraitSolverLangItem::$name,)+
741 _ => return None,
742 })
743 }
744 }
745}
746
747bidirectional_lang_item_map! {
748AsyncFn,
750 AsyncFnKindHelper,
751 AsyncFnKindUpvars,
752 AsyncFnMut,
753 AsyncFnOnce,
754 AsyncFnOnceOutput,
755 AsyncIterator,
756 BikeshedGuaranteedNoDrop,
757 CallOnceFuture,
758 CallRefFuture,
759 Clone,
760 Copy,
761 Coroutine,
762 CoroutineReturn,
763 CoroutineYield,
764 Destruct,
765 DiscriminantKind,
766 Drop,
767 DynMetadata,
768 Fn,
769 FnMut,
770 FnOnce,
771 FnPtrTrait,
772 FusedIterator,
773 Future,
774 FutureOutput,
775 Iterator,
776 MetaSized,
777 Metadata,
778 Option,
779 PointeeSized,
780 PointeeTrait,
781 Poll,
782 Sized,
783 TransmuteTrait,
784 Tuple,
785 Unpin,
786 Unsize,
787}
789
790impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
791 fn is_local(self) -> bool {
792 self.is_local()
793 }
794
795 fn as_local(self) -> Option<LocalDefId> {
796 self.as_local()
797 }
798}
799
800impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
801 fn rust() -> Self {
802 ExternAbi::Rust
803 }
804
805 fn is_rust(self) -> bool {
806 matches!(self, ExternAbi::Rust)
807 }
808}
809
810impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
811 fn safe() -> Self {
812 hir::Safety::Safe
813 }
814
815 fn is_safe(self) -> bool {
816 self.is_safe()
817 }
818
819 fn prefix_str(self) -> &'static str {
820 self.prefix_str()
821 }
822}
823
824impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
825 fn generic_const_exprs(self) -> bool {
826 self.generic_const_exprs()
827 }
828
829 fn coroutine_clone(self) -> bool {
830 self.coroutine_clone()
831 }
832
833 fn associated_const_equality(self) -> bool {
834 self.associated_const_equality()
835 }
836}
837
838impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
839 fn dummy() -> Self {
840 DUMMY_SP
841 }
842}
843
844type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
845
846pub struct CtxtInterners<'tcx> {
847 arena: &'tcx WorkerLocal<Arena<'tcx>>,
849
850 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
853 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
854 args: InternedSet<'tcx, GenericArgs<'tcx>>,
855 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
856 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
857 region: InternedSet<'tcx, RegionKind<'tcx>>,
858 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
859 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
860 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
861 projs: InternedSet<'tcx, List<ProjectionKind>>,
862 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
863 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
864 pat: InternedSet<'tcx, PatternKind<'tcx>>,
865 const_allocation: InternedSet<'tcx, Allocation>,
866 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
867 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
868 adt_def: InternedSet<'tcx, AdtDefData>,
869 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
870 predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
871 fields: InternedSet<'tcx, List<FieldIdx>>,
872 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
873 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
874 offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
875 valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
876 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
877}
878
879impl<'tcx> CtxtInterners<'tcx> {
880 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
881 const N: usize = 2048;
884 CtxtInterners {
885 arena,
886 type_: InternedSet::with_capacity(N * 16),
890 const_lists: InternedSet::with_capacity(N * 4),
891 args: InternedSet::with_capacity(N * 4),
892 type_lists: InternedSet::with_capacity(N * 4),
893 region: InternedSet::with_capacity(N * 4),
894 poly_existential_predicates: InternedSet::with_capacity(N / 4),
895 canonical_var_kinds: InternedSet::with_capacity(N / 2),
896 predicate: InternedSet::with_capacity(N),
897 clauses: InternedSet::with_capacity(N),
898 projs: InternedSet::with_capacity(N * 4),
899 place_elems: InternedSet::with_capacity(N * 2),
900 const_: InternedSet::with_capacity(N * 2),
901 pat: InternedSet::with_capacity(N),
902 const_allocation: InternedSet::with_capacity(N),
903 bound_variable_kinds: InternedSet::with_capacity(N * 2),
904 layout: InternedSet::with_capacity(N),
905 adt_def: InternedSet::with_capacity(N),
906 external_constraints: InternedSet::with_capacity(N),
907 predefined_opaques_in_body: InternedSet::with_capacity(N),
908 fields: InternedSet::with_capacity(N * 4),
909 local_def_ids: InternedSet::with_capacity(N),
910 captures: InternedSet::with_capacity(N),
911 offset_of: InternedSet::with_capacity(N),
912 valtree: InternedSet::with_capacity(N),
913 patterns: InternedSet::with_capacity(N),
914 }
915 }
916
917 #[allow(rustc::usage_of_ty_tykind)]
919 #[inline(never)]
920 fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
921 Ty(Interned::new_unchecked(
922 self.type_
923 .intern(kind, |kind| {
924 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
925 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
926
927 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
928 internee: kind,
929 stable_hash,
930 flags: flags.flags,
931 outer_exclusive_binder: flags.outer_exclusive_binder,
932 }))
933 })
934 .0,
935 ))
936 }
937
938 #[allow(rustc::usage_of_ty_tykind)]
940 #[inline(never)]
941 fn intern_const(
942 &self,
943 kind: ty::ConstKind<'tcx>,
944 sess: &Session,
945 untracked: &Untracked,
946 ) -> Const<'tcx> {
947 Const(Interned::new_unchecked(
948 self.const_
949 .intern(kind, |kind: ty::ConstKind<'_>| {
950 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
951 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
952
953 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
954 internee: kind,
955 stable_hash,
956 flags: flags.flags,
957 outer_exclusive_binder: flags.outer_exclusive_binder,
958 }))
959 })
960 .0,
961 ))
962 }
963
964 fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
965 &self,
966 flags: &ty::FlagComputation<TyCtxt<'tcx>>,
967 sess: &'a Session,
968 untracked: &'a Untracked,
969 val: &T,
970 ) -> Fingerprint {
971 if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
974 Fingerprint::ZERO
975 } else {
976 let mut hasher = StableHasher::new();
977 let mut hcx = StableHashingContext::new(sess, untracked);
978 val.hash_stable(&mut hcx, &mut hasher);
979 hasher.finish()
980 }
981 }
982
983 #[inline(never)]
985 fn intern_predicate(
986 &self,
987 kind: Binder<'tcx, PredicateKind<'tcx>>,
988 sess: &Session,
989 untracked: &Untracked,
990 ) -> Predicate<'tcx> {
991 Predicate(Interned::new_unchecked(
992 self.predicate
993 .intern(kind, |kind| {
994 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
995
996 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
997
998 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
999 internee: kind,
1000 stable_hash,
1001 flags: flags.flags,
1002 outer_exclusive_binder: flags.outer_exclusive_binder,
1003 }))
1004 })
1005 .0,
1006 ))
1007 }
1008
1009 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
1010 if clauses.is_empty() {
1011 ListWithCachedTypeInfo::empty()
1012 } else {
1013 self.clauses
1014 .intern_ref(clauses, || {
1015 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
1016
1017 InternedInSet(ListWithCachedTypeInfo::from_arena(
1018 &*self.arena,
1019 flags.into(),
1020 clauses,
1021 ))
1022 })
1023 .0
1024 }
1025 }
1026}
1027
1028const NUM_PREINTERNED_TY_VARS: u32 = 100;
1033const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
1034const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
1035const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
1036
1037const NUM_PREINTERNED_RE_VARS: u32 = 500;
1039const NUM_PREINTERNED_RE_LATE_BOUNDS_I: u32 = 2;
1040const NUM_PREINTERNED_RE_LATE_BOUNDS_V: u32 = 20;
1041
1042pub struct CommonTypes<'tcx> {
1043 pub unit: Ty<'tcx>,
1044 pub bool: Ty<'tcx>,
1045 pub char: Ty<'tcx>,
1046 pub isize: Ty<'tcx>,
1047 pub i8: Ty<'tcx>,
1048 pub i16: Ty<'tcx>,
1049 pub i32: Ty<'tcx>,
1050 pub i64: Ty<'tcx>,
1051 pub i128: Ty<'tcx>,
1052 pub usize: Ty<'tcx>,
1053 pub u8: Ty<'tcx>,
1054 pub u16: Ty<'tcx>,
1055 pub u32: Ty<'tcx>,
1056 pub u64: Ty<'tcx>,
1057 pub u128: Ty<'tcx>,
1058 pub f16: Ty<'tcx>,
1059 pub f32: Ty<'tcx>,
1060 pub f64: Ty<'tcx>,
1061 pub f128: Ty<'tcx>,
1062 pub str_: Ty<'tcx>,
1063 pub never: Ty<'tcx>,
1064 pub self_param: Ty<'tcx>,
1065
1066 pub trait_object_dummy_self: Ty<'tcx>,
1071
1072 pub ty_vars: Vec<Ty<'tcx>>,
1074
1075 pub fresh_tys: Vec<Ty<'tcx>>,
1077
1078 pub fresh_int_tys: Vec<Ty<'tcx>>,
1080
1081 pub fresh_float_tys: Vec<Ty<'tcx>>,
1083}
1084
1085pub struct CommonLifetimes<'tcx> {
1086 pub re_static: Region<'tcx>,
1088
1089 pub re_erased: Region<'tcx>,
1091
1092 pub re_vars: Vec<Region<'tcx>>,
1094
1095 pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
1099}
1100
1101pub struct CommonConsts<'tcx> {
1102 pub unit: Const<'tcx>,
1103 pub true_: Const<'tcx>,
1104 pub false_: Const<'tcx>,
1105 pub(crate) valtree_zst: ValTree<'tcx>,
1107}
1108
1109impl<'tcx> CommonTypes<'tcx> {
1110 fn new(
1111 interners: &CtxtInterners<'tcx>,
1112 sess: &Session,
1113 untracked: &Untracked,
1114 ) -> CommonTypes<'tcx> {
1115 let mk = |ty| interners.intern_ty(ty, sess, untracked);
1116
1117 let ty_vars =
1118 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1119 let fresh_tys: Vec<_> =
1120 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1121 let fresh_int_tys: Vec<_> =
1122 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1123 let fresh_float_tys: Vec<_> =
1124 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1125
1126 CommonTypes {
1127 unit: mk(Tuple(List::empty())),
1128 bool: mk(Bool),
1129 char: mk(Char),
1130 never: mk(Never),
1131 isize: mk(Int(ty::IntTy::Isize)),
1132 i8: mk(Int(ty::IntTy::I8)),
1133 i16: mk(Int(ty::IntTy::I16)),
1134 i32: mk(Int(ty::IntTy::I32)),
1135 i64: mk(Int(ty::IntTy::I64)),
1136 i128: mk(Int(ty::IntTy::I128)),
1137 usize: mk(Uint(ty::UintTy::Usize)),
1138 u8: mk(Uint(ty::UintTy::U8)),
1139 u16: mk(Uint(ty::UintTy::U16)),
1140 u32: mk(Uint(ty::UintTy::U32)),
1141 u64: mk(Uint(ty::UintTy::U64)),
1142 u128: mk(Uint(ty::UintTy::U128)),
1143 f16: mk(Float(ty::FloatTy::F16)),
1144 f32: mk(Float(ty::FloatTy::F32)),
1145 f64: mk(Float(ty::FloatTy::F64)),
1146 f128: mk(Float(ty::FloatTy::F128)),
1147 str_: mk(Str),
1148 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1149
1150 trait_object_dummy_self: fresh_tys[0],
1151
1152 ty_vars,
1153 fresh_tys,
1154 fresh_int_tys,
1155 fresh_float_tys,
1156 }
1157 }
1158}
1159
1160impl<'tcx> CommonLifetimes<'tcx> {
1161 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1162 let mk = |r| {
1163 Region(Interned::new_unchecked(
1164 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1165 ))
1166 };
1167
1168 let re_vars =
1169 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1170
1171 let re_late_bounds = (0..NUM_PREINTERNED_RE_LATE_BOUNDS_I)
1172 .map(|i| {
1173 (0..NUM_PREINTERNED_RE_LATE_BOUNDS_V)
1174 .map(|v| {
1175 mk(ty::ReBound(
1176 ty::DebruijnIndex::from(i),
1177 ty::BoundRegion {
1178 var: ty::BoundVar::from(v),
1179 kind: ty::BoundRegionKind::Anon,
1180 },
1181 ))
1182 })
1183 .collect()
1184 })
1185 .collect();
1186
1187 CommonLifetimes {
1188 re_static: mk(ty::ReStatic),
1189 re_erased: mk(ty::ReErased),
1190 re_vars,
1191 re_late_bounds,
1192 }
1193 }
1194}
1195
1196impl<'tcx> CommonConsts<'tcx> {
1197 fn new(
1198 interners: &CtxtInterners<'tcx>,
1199 types: &CommonTypes<'tcx>,
1200 sess: &Session,
1201 untracked: &Untracked,
1202 ) -> CommonConsts<'tcx> {
1203 let mk_const = |c| {
1204 interners.intern_const(
1205 c, sess, untracked,
1207 )
1208 };
1209
1210 let mk_valtree = |v| {
1211 ty::ValTree(Interned::new_unchecked(
1212 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1213 ))
1214 };
1215
1216 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1217 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1218 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1219
1220 CommonConsts {
1221 unit: mk_const(ty::ConstKind::Value(ty::Value {
1222 ty: types.unit,
1223 valtree: valtree_zst,
1224 })),
1225 true_: mk_const(ty::ConstKind::Value(ty::Value {
1226 ty: types.bool,
1227 valtree: valtree_true,
1228 })),
1229 false_: mk_const(ty::ConstKind::Value(ty::Value {
1230 ty: types.bool,
1231 valtree: valtree_false,
1232 })),
1233 valtree_zst,
1234 }
1235 }
1236}
1237
1238#[derive(Debug)]
1241pub struct FreeRegionInfo {
1242 pub scope: LocalDefId,
1244 pub region_def_id: DefId,
1246 pub is_impl_item: bool,
1248}
1249
1250#[derive(Copy, Clone)]
1252pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1253 pub tcx: TyCtxt<'tcx>,
1254 key: KEY,
1256}
1257
1258impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1261
1262#[derive(Copy, Clone)]
1267pub struct Feed<'tcx, KEY: Copy> {
1268 _tcx: PhantomData<TyCtxt<'tcx>>,
1269 key: KEY,
1271}
1272
1273impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1276
1277impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1278 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1279 self.key.fmt(f)
1280 }
1281}
1282
1283impl<'tcx> TyCtxt<'tcx> {
1288 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1291 self.dep_graph.assert_ignored();
1292 TyCtxtFeed { tcx: self, key: () }
1293 }
1294
1295 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1298 let key = self.untracked().source_span.push(span);
1299 assert_eq!(key, CRATE_DEF_ID);
1300 TyCtxtFeed { tcx: self, key }
1301 }
1302
1303 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1307 debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1308 TyCtxtFeed { tcx: self, key }.type_of(value)
1309 }
1310}
1311
1312impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1313 #[inline(always)]
1314 pub fn key(&self) -> KEY {
1315 self.key
1316 }
1317
1318 #[inline(always)]
1319 pub fn downgrade(self) -> Feed<'tcx, KEY> {
1320 Feed { _tcx: PhantomData, key: self.key }
1321 }
1322}
1323
1324impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1325 #[inline(always)]
1326 pub fn key(&self) -> KEY {
1327 self.key
1328 }
1329
1330 #[inline(always)]
1331 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1332 TyCtxtFeed { tcx, key: self.key }
1333 }
1334}
1335
1336impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1337 #[inline(always)]
1338 pub fn def_id(&self) -> LocalDefId {
1339 self.key
1340 }
1341
1342 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1344 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1345 }
1346
1347 pub fn feed_hir(&self) {
1349 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1350
1351 let node = hir::OwnerNode::Synthetic;
1352 let bodies = Default::default();
1353 let attrs = hir::AttributeMap::EMPTY;
1354
1355 let (opt_hash_including_bodies, _, _) =
1356 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
1357 let node = node.into();
1358 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1359 opt_hash_including_bodies,
1360 nodes: IndexVec::from_elem_n(
1361 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1362 1,
1363 ),
1364 bodies,
1365 })));
1366 self.feed_owner_id().hir_attr_map(attrs);
1367 }
1368}
1369
1370#[derive(Copy, Clone)]
1388#[rustc_diagnostic_item = "TyCtxt"]
1389#[rustc_pass_by_value]
1390pub struct TyCtxt<'tcx> {
1391 gcx: &'tcx GlobalCtxt<'tcx>,
1392}
1393
1394impl<'tcx> LintEmitter for TyCtxt<'tcx> {
1395 fn emit_node_span_lint(
1396 self,
1397 lint: &'static Lint,
1398 hir_id: HirId,
1399 span: impl Into<MultiSpan>,
1400 decorator: impl for<'a> LintDiagnostic<'a, ()>,
1401 ) {
1402 self.emit_node_span_lint(lint, hir_id, span, decorator);
1403 }
1404}
1405
1406unsafe impl DynSend for TyCtxt<'_> {}
1410unsafe impl DynSync for TyCtxt<'_> {}
1411fn _assert_tcx_fields() {
1412 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1413 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1414}
1415
1416impl<'tcx> Deref for TyCtxt<'tcx> {
1417 type Target = &'tcx GlobalCtxt<'tcx>;
1418 #[inline(always)]
1419 fn deref(&self) -> &Self::Target {
1420 &self.gcx
1421 }
1422}
1423
1424pub struct GlobalCtxt<'tcx> {
1426 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1427 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1428
1429 interners: CtxtInterners<'tcx>,
1430
1431 pub sess: &'tcx Session,
1432 crate_types: Vec<CrateType>,
1433 stable_crate_id: StableCrateId,
1439
1440 pub dep_graph: DepGraph,
1441
1442 pub prof: SelfProfilerRef,
1443
1444 pub types: CommonTypes<'tcx>,
1446
1447 pub lifetimes: CommonLifetimes<'tcx>,
1449
1450 pub consts: CommonConsts<'tcx>,
1452
1453 pub(crate) hooks: crate::hooks::Providers,
1456
1457 untracked: Untracked,
1458
1459 pub query_system: QuerySystem<'tcx>,
1460 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1461
1462 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1464
1465 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1468
1469 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1473
1474 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1476 pub new_solver_canonical_param_env_cache:
1477 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
1478
1479 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1480
1481 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
1483 pub clauses_cache:
1485 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
1486
1487 pub data_layout: TargetDataLayout,
1489
1490 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1492
1493 current_gcx: CurrentGcx,
1494
1495 pub jobserver_proxy: Arc<Proxy>,
1497}
1498
1499impl<'tcx> GlobalCtxt<'tcx> {
1500 pub fn enter<F, R>(&'tcx self, f: F) -> R
1503 where
1504 F: FnOnce(TyCtxt<'tcx>) -> R,
1505 {
1506 let icx = tls::ImplicitCtxt::new(self);
1507
1508 let _on_drop = defer(move || {
1510 *self.current_gcx.value.write() = None;
1511 });
1512
1513 {
1515 let mut guard = self.current_gcx.value.write();
1516 assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1517 *guard = Some(self as *const _ as *const ());
1518 }
1519
1520 tls::enter_context(&icx, || f(icx.tcx))
1521 }
1522}
1523
1524#[derive(Clone)]
1531pub struct CurrentGcx {
1532 value: Arc<RwLock<Option<*const ()>>>,
1535}
1536
1537unsafe impl DynSend for CurrentGcx {}
1538unsafe impl DynSync for CurrentGcx {}
1539
1540impl CurrentGcx {
1541 pub fn new() -> Self {
1542 Self { value: Arc::new(RwLock::new(None)) }
1543 }
1544
1545 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1546 let read_guard = self.value.read();
1547 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1548 f(unsafe { &*gcx })
1552 }
1553}
1554
1555impl<'tcx> TyCtxt<'tcx> {
1556 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1557 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1560 if typeck_root_def_id != def_id.to_def_id() {
1561 return self.has_typeck_results(typeck_root_def_id.expect_local());
1562 }
1563
1564 self.hir_node_by_def_id(def_id).body_id().is_some()
1565 }
1566
1567 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1572 let def_kind = self.def_kind(def_id);
1573 if def_kind.has_codegen_attrs() {
1574 self.codegen_fn_attrs(def_id)
1575 } else if matches!(
1576 def_kind,
1577 DefKind::AnonConst
1578 | DefKind::AssocConst
1579 | DefKind::Const
1580 | DefKind::InlineConst
1581 | DefKind::GlobalAsm
1582 ) {
1583 CodegenFnAttrs::EMPTY
1584 } else {
1585 bug!(
1586 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1587 def_id,
1588 def_kind
1589 )
1590 }
1591 }
1592
1593 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1594 self.arena.alloc(Steal::new(thir))
1595 }
1596
1597 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1598 self.arena.alloc(Steal::new(mir))
1599 }
1600
1601 pub fn alloc_steal_promoted(
1602 self,
1603 promoted: IndexVec<Promoted, Body<'tcx>>,
1604 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1605 self.arena.alloc(Steal::new(promoted))
1606 }
1607
1608 pub fn mk_adt_def(
1609 self,
1610 did: DefId,
1611 kind: AdtKind,
1612 variants: IndexVec<VariantIdx, ty::VariantDef>,
1613 repr: ReprOptions,
1614 ) -> ty::AdtDef<'tcx> {
1615 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1616 }
1617
1618 pub fn allocate_bytes_dedup(self, bytes: &[u8], salt: usize) -> interpret::AllocId {
1621 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
1623 let alloc = self.mk_const_alloc(alloc);
1624 self.reserve_and_set_memory_dedup(alloc, salt)
1625 }
1626
1627 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1629 if self.sess.opts.unstable_opts.experimental_default_bounds {
1630 &[
1631 LangItem::DefaultTrait1,
1632 LangItem::DefaultTrait2,
1633 LangItem::DefaultTrait3,
1634 LangItem::DefaultTrait4,
1635 ]
1636 } else {
1637 &[]
1638 }
1639 }
1640
1641 pub fn is_default_trait(self, def_id: DefId) -> bool {
1642 self.default_traits()
1643 .iter()
1644 .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
1645 }
1646
1647 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1651 let start = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1652 let end = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1653 (start, end)
1654 }
1655
1656 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1657 value.lift_to_interner(self)
1658 }
1659
1660 pub fn create_global_ctxt<T>(
1667 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1668 s: &'tcx Session,
1669 crate_types: Vec<CrateType>,
1670 stable_crate_id: StableCrateId,
1671 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1672 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1673 untracked: Untracked,
1674 dep_graph: DepGraph,
1675 query_kinds: &'tcx [DepKindStruct<'tcx>],
1676 query_system: QuerySystem<'tcx>,
1677 hooks: crate::hooks::Providers,
1678 current_gcx: CurrentGcx,
1679 jobserver_proxy: Arc<Proxy>,
1680 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1681 ) -> T {
1682 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1683 s.dcx().emit_fatal(err);
1684 });
1685 let interners = CtxtInterners::new(arena);
1686 let common_types = CommonTypes::new(&interners, s, &untracked);
1687 let common_lifetimes = CommonLifetimes::new(&interners);
1688 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1689
1690 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1691 sess: s,
1692 crate_types,
1693 stable_crate_id,
1694 arena,
1695 hir_arena,
1696 interners,
1697 dep_graph,
1698 hooks,
1699 prof: s.prof.clone(),
1700 types: common_types,
1701 lifetimes: common_lifetimes,
1702 consts: common_consts,
1703 untracked,
1704 query_system,
1705 query_kinds,
1706 ty_rcache: Default::default(),
1707 selection_cache: Default::default(),
1708 evaluation_cache: Default::default(),
1709 new_solver_evaluation_cache: Default::default(),
1710 new_solver_canonical_param_env_cache: Default::default(),
1711 canonical_param_env_cache: Default::default(),
1712 highest_var_in_clauses_cache: Default::default(),
1713 clauses_cache: Default::default(),
1714 data_layout,
1715 alloc_map: interpret::AllocMap::new(),
1716 current_gcx,
1717 jobserver_proxy,
1718 });
1719
1720 gcx.enter(f)
1722 }
1723
1724 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1726 self.get_lang_items(())
1727 }
1728
1729 #[track_caller]
1731 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1732 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1733 self.type_of(ordering_enum).no_bound_vars().unwrap()
1734 }
1735
1736 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1739 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1740 }
1741
1742 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1744 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1745 }
1746
1747 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1749 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1750 }
1751
1752 pub fn is_coroutine(self, def_id: DefId) -> bool {
1753 self.coroutine_kind(def_id).is_some()
1754 }
1755
1756 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1757 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1758 }
1759
1760 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1763 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1764 }
1765
1766 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1768 matches!(
1769 self.coroutine_kind(def_id),
1770 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1771 )
1772 }
1773
1774 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1777 matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1778 }
1779
1780 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1783 matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1784 }
1785
1786 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1788 matches!(
1789 self.coroutine_kind(def_id),
1790 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1791 )
1792 }
1793
1794 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1796 matches!(
1797 self.coroutine_kind(def_id),
1798 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1799 )
1800 }
1801
1802 pub fn stability(self) -> &'tcx stability::Index {
1803 self.stability_index(())
1804 }
1805
1806 pub fn features(self) -> &'tcx rustc_feature::Features {
1807 self.features_query(())
1808 }
1809
1810 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1811 let id = id.into_query_param();
1812 if let Some(id) = id.as_local() {
1814 self.definitions_untracked().def_key(id)
1815 } else {
1816 self.cstore_untracked().def_key(id)
1817 }
1818 }
1819
1820 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1826 if let Some(id) = id.as_local() {
1828 self.definitions_untracked().def_path(id)
1829 } else {
1830 self.cstore_untracked().def_path(id)
1831 }
1832 }
1833
1834 #[inline]
1835 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1836 if let Some(def_id) = def_id.as_local() {
1838 self.definitions_untracked().def_path_hash(def_id)
1839 } else {
1840 self.cstore_untracked().def_path_hash(def_id)
1841 }
1842 }
1843
1844 #[inline]
1845 pub fn crate_types(self) -> &'tcx [CrateType] {
1846 &self.crate_types
1847 }
1848
1849 pub fn needs_metadata(self) -> bool {
1850 self.crate_types().iter().any(|ty| match *ty {
1851 CrateType::Executable
1852 | CrateType::Staticlib
1853 | CrateType::Cdylib
1854 | CrateType::Sdylib => false,
1855 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1856 })
1857 }
1858
1859 pub fn needs_crate_hash(self) -> bool {
1860 cfg!(debug_assertions)
1872 || self.sess.opts.incremental.is_some()
1873 || self.needs_metadata()
1874 || self.sess.instrument_coverage()
1875 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1876 }
1877
1878 #[inline]
1879 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1880 if crate_num == LOCAL_CRATE {
1881 self.stable_crate_id
1882 } else {
1883 self.cstore_untracked().stable_crate_id(crate_num)
1884 }
1885 }
1886
1887 #[inline]
1890 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1891 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1892 LOCAL_CRATE
1893 } else {
1894 *self
1895 .untracked()
1896 .stable_crate_ids
1897 .read()
1898 .get(&stable_crate_id)
1899 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1900 }
1901 }
1902
1903 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1907 debug!("def_path_hash_to_def_id({:?})", hash);
1908
1909 let stable_crate_id = hash.stable_crate_id();
1910
1911 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1914 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1915 } else {
1916 Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
1917 }
1918 }
1919
1920 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1921 let (crate_name, stable_crate_id) = if def_id.is_local() {
1926 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1927 } else {
1928 let cstore = &*self.cstore_untracked();
1929 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1930 };
1931
1932 format!(
1933 "{}[{:04x}]{}",
1934 crate_name,
1935 stable_crate_id.as_u64() >> (8 * 6),
1938 self.def_path(def_id).to_string_no_crate_verbose()
1939 )
1940 }
1941
1942 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1943 self.sess.dcx()
1944 }
1945
1946 pub fn is_target_feature_call_safe(
1947 self,
1948 callee_features: &[TargetFeature],
1949 body_features: &[TargetFeature],
1950 ) -> bool {
1951 self.sess.target.options.is_like_wasm
1956 || callee_features
1957 .iter()
1958 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1959 }
1960
1961 pub fn adjust_target_feature_sig(
1964 self,
1965 fun_def: DefId,
1966 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1967 caller: DefId,
1968 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1969 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1970 let callee_features = &self.codegen_fn_attrs(caller).target_features;
1971 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
1972 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
1973 }
1974 None
1975 }
1976
1977 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1980 match self.env_var_os(key.as_ref()) {
1981 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1982 None => Err(VarError::NotPresent),
1983 }
1984 }
1985}
1986
1987impl<'tcx> TyCtxtAt<'tcx> {
1988 pub fn create_def(
1990 self,
1991 parent: LocalDefId,
1992 name: Option<Symbol>,
1993 def_kind: DefKind,
1994 override_def_path_data: Option<DefPathData>,
1995 disambiguator: &mut DisambiguatorState,
1996 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1997 let feed =
1998 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1999
2000 feed.def_span(self.span);
2001 feed
2002 }
2003}
2004
2005impl<'tcx> TyCtxt<'tcx> {
2006 pub fn create_def(
2008 self,
2009 parent: LocalDefId,
2010 name: Option<Symbol>,
2011 def_kind: DefKind,
2012 override_def_path_data: Option<DefPathData>,
2013 disambiguator: &mut DisambiguatorState,
2014 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2015 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2016 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2026
2027 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2032
2033 let feed = TyCtxtFeed { tcx: self, key: def_id };
2034 feed.def_kind(def_kind);
2035 if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2040 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2041 feed.visibility(ty::Visibility::Restricted(parent_mod));
2042 }
2043
2044 feed
2045 }
2046
2047 pub fn create_crate_num(
2048 self,
2049 stable_crate_id: StableCrateId,
2050 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2051 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2052 return Err(existing);
2053 }
2054
2055 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2056 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2057 Ok(TyCtxtFeed { key: num, tcx: self })
2058 }
2059
2060 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2061 self.ensure_ok().analysis(());
2063
2064 let definitions = &self.untracked.definitions;
2065 gen {
2066 let mut i = 0;
2067
2068 while i < { definitions.read().num_definitions() } {
2071 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2072 yield LocalDefId { local_def_index };
2073 i += 1;
2074 }
2075
2076 definitions.freeze();
2078 }
2079 }
2080
2081 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2082 self.ensure_ok().analysis(());
2084
2085 self.untracked.definitions.freeze().def_path_table()
2088 }
2089
2090 pub fn def_path_hash_to_def_index_map(
2091 self,
2092 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2093 self.ensure_ok().hir_crate_items(());
2096 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2099 }
2100
2101 #[inline]
2104 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2105 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2106 }
2107
2108 pub fn untracked(self) -> &'tcx Untracked {
2110 &self.untracked
2111 }
2112 #[inline]
2115 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2116 self.untracked.definitions.read()
2117 }
2118
2119 #[inline]
2122 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2123 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2124 }
2125
2126 #[inline(always)]
2127 pub fn with_stable_hashing_context<R>(
2128 self,
2129 f: impl FnOnce(StableHashingContext<'_>) -> R,
2130 ) -> R {
2131 f(StableHashingContext::new(self.sess, &self.untracked))
2132 }
2133
2134 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2135 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2136 }
2137
2138 #[inline]
2139 pub fn local_crate_exports_generics(self) -> bool {
2140 self.crate_types().iter().any(|crate_type| {
2141 match crate_type {
2142 CrateType::Executable
2143 | CrateType::Staticlib
2144 | CrateType::ProcMacro
2145 | CrateType::Cdylib
2146 | CrateType::Sdylib => false,
2147
2148 CrateType::Dylib => true,
2153
2154 CrateType::Rlib => true,
2155 }
2156 })
2157 }
2158
2159 pub fn is_suitable_region(
2161 self,
2162 generic_param_scope: LocalDefId,
2163 mut region: Region<'tcx>,
2164 ) -> Option<FreeRegionInfo> {
2165 let (suitable_region_binding_scope, region_def_id) = loop {
2166 let def_id =
2167 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2168 let scope = self.local_parent(def_id);
2169 if self.def_kind(scope) == DefKind::OpaqueTy {
2170 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2173 continue;
2174 }
2175 break (scope, def_id.into());
2176 };
2177
2178 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2179 Node::Item(..) | Node::TraitItem(..) => false,
2180 Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2181 _ => false,
2182 };
2183
2184 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2185 }
2186
2187 pub fn return_type_impl_or_dyn_traits(
2189 self,
2190 scope_def_id: LocalDefId,
2191 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2192 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2193 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2194 self.hir_fn_decl_by_hir_id(hir_id)
2195 else {
2196 return vec![];
2197 };
2198
2199 let mut v = TraitObjectVisitor(vec![]);
2200 v.visit_ty_unambig(hir_output);
2201 v.0
2202 }
2203
2204 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2208 self,
2209 scope_def_id: LocalDefId,
2210 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2211 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2212 let mut v = TraitObjectVisitor(vec![]);
2213 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2215 && let hir::TyKind::Path(hir::QPath::Resolved(
2216 None,
2217 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2218 && let Some(local_id) = def_id.as_local()
2219 && 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()
2221 {
2222 v.visit_ty_unambig(alias_ty);
2223 if !v.0.is_empty() {
2224 return Some((
2225 v.0,
2226 alias_generics.span,
2227 alias_generics.span_for_lifetime_suggestion(),
2228 ));
2229 }
2230 }
2231 None
2232 }
2233
2234 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2236 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2237 if self.impl_trait_ref(container_id).is_some() {
2238 return true;
2245 }
2246 false
2247 }
2248
2249 pub fn has_strict_asm_symbol_naming(self) -> bool {
2252 self.sess.target.arch.contains("nvptx")
2253 }
2254
2255 pub fn caller_location_ty(self) -> Ty<'tcx> {
2257 Ty::new_imm_ref(
2258 self,
2259 self.lifetimes.re_static,
2260 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2261 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2262 )
2263 }
2264
2265 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2267 let kind = self.def_kind(def_id);
2268 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2269 }
2270
2271 pub fn type_length_limit(self) -> Limit {
2272 self.limits(()).type_length_limit
2273 }
2274
2275 pub fn recursion_limit(self) -> Limit {
2276 self.limits(()).recursion_limit
2277 }
2278
2279 pub fn move_size_limit(self) -> Limit {
2280 self.limits(()).move_size_limit
2281 }
2282
2283 pub fn pattern_complexity_limit(self) -> Limit {
2284 self.limits(()).pattern_complexity_limit
2285 }
2286
2287 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
2289 iter::once(LOCAL_CRATE)
2290 .chain(self.crates(()).iter().copied())
2291 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2292 }
2293
2294 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2296 let visible_crates =
2297 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2298
2299 iter::once(LOCAL_CRATE)
2300 .chain(visible_crates)
2301 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2302 }
2303
2304 #[inline]
2305 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2306 self.visibility(def_id).expect_local()
2307 }
2308
2309 #[instrument(skip(self), level = "trace", ret)]
2311 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2312 self.hir_expect_opaque_ty(def_id).origin
2313 }
2314
2315 pub fn finish(self) {
2316 self.alloc_self_profile_query_strings();
2319
2320 self.save_dep_graph();
2321 self.query_key_hash_verify_all();
2322
2323 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2324 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2325 }
2326 }
2327}
2328
2329macro_rules! nop_lift {
2330 ($set:ident; $ty:ty => $lifted:ty) => {
2331 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2332 type Lifted = $lifted;
2333 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2334 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2339 _x: Interned<'tcx, Inner>,
2340 ) -> InternedSet<'tcx, Inner> {
2341 unreachable!()
2342 }
2343 fn _type_eq<T>(_x: &T, _y: &T) {}
2344 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2345 let interner = _intern_set_ty_from_interned_ty(x.0);
2349 _type_eq(&interner, &tcx.interners.$set);
2351 }
2352
2353 tcx.interners
2354 .$set
2355 .contains_pointer_to(&InternedInSet(&*self.0.0))
2356 .then(|| unsafe { mem::transmute(self) })
2359 }
2360 }
2361 };
2362}
2363
2364macro_rules! nop_list_lift {
2365 ($set:ident; $ty:ty => $lifted:ty) => {
2366 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2367 type Lifted = &'tcx List<$lifted>;
2368 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2369 if false {
2371 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2372 }
2373
2374 if self.is_empty() {
2375 return Some(List::empty());
2376 }
2377 tcx.interners
2378 .$set
2379 .contains_pointer_to(&InternedInSet(self))
2380 .then(|| unsafe { mem::transmute(self) })
2381 }
2382 }
2383 };
2384}
2385
2386nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2387nop_lift! { region; Region<'a> => Region<'tcx> }
2388nop_lift! { const_; Const<'a> => Const<'tcx> }
2389nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2390nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2391nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2392nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2393nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2394nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2395
2396nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2397nop_list_lift! {
2398 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2399}
2400nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2401
2402nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2404
2405macro_rules! sty_debug_print {
2406 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2407 #[allow(non_snake_case)]
2410 mod inner {
2411 use crate::ty::{self, TyCtxt};
2412 use crate::ty::context::InternedInSet;
2413
2414 #[derive(Copy, Clone)]
2415 struct DebugStat {
2416 total: usize,
2417 lt_infer: usize,
2418 ty_infer: usize,
2419 ct_infer: usize,
2420 all_infer: usize,
2421 }
2422
2423 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2424 let mut total = DebugStat {
2425 total: 0,
2426 lt_infer: 0,
2427 ty_infer: 0,
2428 ct_infer: 0,
2429 all_infer: 0,
2430 };
2431 $(let mut $variant = total;)*
2432
2433 for shard in tcx.interners.type_.lock_shards() {
2434 #[allow(rustc::potential_query_instability)]
2436 let types = shard.iter();
2437 for &(InternedInSet(t), ()) in types {
2438 let variant = match t.internee {
2439 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2440 ty::Float(..) | ty::Str | ty::Never => continue,
2441 ty::Error(_) => continue,
2442 $(ty::$variant(..) => &mut $variant,)*
2443 };
2444 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2445 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2446 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2447
2448 variant.total += 1;
2449 total.total += 1;
2450 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2451 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2452 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2453 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2454 }
2455 }
2456 writeln!(fmt, "Ty interner total ty lt ct all")?;
2457 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2458 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2459 stringify!($variant),
2460 uses = $variant.total,
2461 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2462 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2463 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2464 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2465 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2466 )*
2467 writeln!(fmt, " total {uses:6} \
2468 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2469 uses = total.total,
2470 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2471 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2472 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2473 all = total.all_infer as f64 * 100.0 / total.total as f64)
2474 }
2475 }
2476
2477 inner::go($fmt, $ctxt)
2478 }}
2479}
2480
2481impl<'tcx> TyCtxt<'tcx> {
2482 pub fn debug_stats(self) -> impl fmt::Debug {
2483 fmt::from_fn(move |fmt| {
2484 sty_debug_print!(
2485 fmt,
2486 self,
2487 Adt,
2488 Array,
2489 Slice,
2490 RawPtr,
2491 Ref,
2492 FnDef,
2493 FnPtr,
2494 UnsafeBinder,
2495 Placeholder,
2496 Coroutine,
2497 CoroutineWitness,
2498 Dynamic,
2499 Closure,
2500 CoroutineClosure,
2501 Tuple,
2502 Bound,
2503 Param,
2504 Infer,
2505 Alias,
2506 Pat,
2507 Foreign
2508 )?;
2509
2510 writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2511 writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2512 writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2513 writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2514
2515 Ok(())
2516 })
2517 }
2518}
2519
2520struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2525
2526impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2527 fn clone(&self) -> Self {
2528 InternedInSet(self.0)
2529 }
2530}
2531
2532impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2533
2534impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2535 fn into_pointer(&self) -> *const () {
2536 self.0 as *const _ as *const ()
2537 }
2538}
2539
2540#[allow(rustc::usage_of_ty_tykind)]
2541impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2542 fn borrow(&self) -> &T {
2543 &self.0.internee
2544 }
2545}
2546
2547impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2548 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2549 self.0.internee == other.0.internee
2552 }
2553}
2554
2555impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2556
2557impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2558 fn hash<H: Hasher>(&self, s: &mut H) {
2559 self.0.internee.hash(s)
2561 }
2562}
2563
2564impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2565 fn borrow(&self) -> &[T] {
2566 &self.0[..]
2567 }
2568}
2569
2570impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2571 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2572 self.0[..] == other.0[..]
2575 }
2576}
2577
2578impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2579
2580impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2581 fn hash<H: Hasher>(&self, s: &mut H) {
2582 self.0[..].hash(s)
2584 }
2585}
2586
2587impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2588 fn borrow(&self) -> &[T] {
2589 &self.0[..]
2590 }
2591}
2592
2593impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2594 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2595 self.0[..] == other.0[..]
2598 }
2599}
2600
2601impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2602
2603impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2604 fn hash<H: Hasher>(&self, s: &mut H) {
2605 self.0[..].hash(s)
2607 }
2608}
2609
2610macro_rules! direct_interners {
2611 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2612 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2613 fn borrow<'a>(&'a self) -> &'a $ty {
2614 &self.0
2615 }
2616 }
2617
2618 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2619 fn eq(&self, other: &Self) -> bool {
2620 self.0 == other.0
2623 }
2624 }
2625
2626 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2627
2628 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2629 fn hash<H: Hasher>(&self, s: &mut H) {
2630 self.0.hash(s)
2633 }
2634 }
2635
2636 impl<'tcx> TyCtxt<'tcx> {
2637 $vis fn $method(self, v: $ty) -> $ret_ty {
2638 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2639 InternedInSet(self.interners.arena.alloc(v))
2640 }).0))
2641 }
2642 })+
2643 }
2644}
2645
2646direct_interners! {
2650 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2651 valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2652 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2653 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2654 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2655 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2656 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2657 ExternalConstraints -> ExternalConstraints<'tcx>,
2658 predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2659 PredefinedOpaques -> PredefinedOpaques<'tcx>,
2660}
2661
2662macro_rules! slice_interners {
2663 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2664 impl<'tcx> TyCtxt<'tcx> {
2665 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2666 if v.is_empty() {
2667 List::empty()
2668 } else {
2669 self.interners.$field.intern_ref(v, || {
2670 InternedInSet(List::from_arena(&*self.arena, (), v))
2671 }).0
2672 }
2673 })+
2674 }
2675 );
2676}
2677
2678slice_interners!(
2682 const_lists: pub mk_const_list(Const<'tcx>),
2683 args: pub mk_args(GenericArg<'tcx>),
2684 type_lists: pub mk_type_list(Ty<'tcx>),
2685 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2686 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2687 projs: pub mk_projs(ProjectionKind),
2688 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2689 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2690 fields: pub mk_fields(FieldIdx),
2691 local_def_ids: intern_local_def_ids(LocalDefId),
2692 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2693 offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2694 patterns: pub mk_patterns(Pattern<'tcx>),
2695);
2696
2697impl<'tcx> TyCtxt<'tcx> {
2698 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2702 assert!(sig.safety().is_safe());
2703 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2704 }
2705
2706 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2709 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2710 self.associated_items(trait_did)
2711 .filter_by_name_unhygienic(assoc_name.name)
2712 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2713 })
2714 }
2715
2716 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2718 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2719 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2720
2721 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2722 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2723 return false;
2724 };
2725 trait_predicate.trait_ref.def_id == future_trait
2726 && trait_predicate.polarity == PredicatePolarity::Positive
2727 })
2728 }
2729
2730 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2738 sig.map_bound(|s| {
2739 let params = match s.inputs()[0].kind() {
2740 ty::Tuple(params) => *params,
2741 _ => bug!(),
2742 };
2743 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2744 })
2745 }
2746
2747 #[inline]
2748 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2749 self.interners.intern_predicate(
2750 binder,
2751 self.sess,
2752 &self.untracked,
2754 )
2755 }
2756
2757 #[inline]
2758 pub fn reuse_or_mk_predicate(
2759 self,
2760 pred: Predicate<'tcx>,
2761 binder: Binder<'tcx, PredicateKind<'tcx>>,
2762 ) -> Predicate<'tcx> {
2763 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2764 }
2765
2766 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2767 self.check_args_compatible_inner(def_id, args, false)
2768 }
2769
2770 fn check_args_compatible_inner(
2771 self,
2772 def_id: DefId,
2773 args: &'tcx [ty::GenericArg<'tcx>],
2774 nested: bool,
2775 ) -> bool {
2776 let generics = self.generics_of(def_id);
2777
2778 let own_args = if !nested
2781 && let DefKind::AssocTy = self.def_kind(def_id)
2782 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2783 {
2784 if generics.own_params.len() + 1 != args.len() {
2785 return false;
2786 }
2787
2788 if !matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2789 return false;
2790 }
2791
2792 &args[1..]
2793 } else {
2794 if generics.count() != args.len() {
2795 return false;
2796 }
2797
2798 let (parent_args, own_args) = args.split_at(generics.parent_count);
2799
2800 if let Some(parent) = generics.parent
2801 && !self.check_args_compatible_inner(parent, parent_args, true)
2802 {
2803 return false;
2804 }
2805
2806 own_args
2807 };
2808
2809 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2810 match (¶m.kind, arg.kind()) {
2811 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2812 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2813 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2814 _ => return false,
2815 }
2816 }
2817
2818 true
2819 }
2820
2821 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2824 if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2825 if let DefKind::AssocTy = self.def_kind(def_id)
2826 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2827 {
2828 bug!(
2829 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2830 self.def_path_str(def_id),
2831 args,
2832 self.mk_args_from_iter(
2834 [self.types.self_param.into()].into_iter().chain(
2835 self.generics_of(def_id)
2836 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2837 .iter()
2838 .copied()
2839 )
2840 )
2841 );
2842 } else {
2843 bug!(
2844 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2845 self.def_path_str(def_id),
2846 args,
2847 ty::GenericArgs::identity_for_item(self, def_id)
2848 );
2849 }
2850 }
2851 }
2852
2853 #[inline(always)]
2854 pub(crate) fn check_and_mk_args(
2855 self,
2856 def_id: DefId,
2857 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2858 ) -> GenericArgsRef<'tcx> {
2859 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2860 self.debug_assert_args_compatible(def_id, args);
2861 args
2862 }
2863
2864 #[inline]
2865 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2866 self.interners.intern_const(
2867 kind,
2868 self.sess,
2869 &self.untracked,
2871 )
2872 }
2873
2874 #[allow(rustc::usage_of_ty_tykind)]
2876 #[inline]
2877 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2878 self.interners.intern_ty(
2879 st,
2880 self.sess,
2881 &self.untracked,
2883 )
2884 }
2885
2886 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2887 match param.kind {
2888 GenericParamDefKind::Lifetime => {
2889 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2890 }
2891 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2892 GenericParamDefKind::Const { .. } => {
2893 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2894 .into()
2895 }
2896 }
2897 }
2898
2899 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2900 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2901 }
2902
2903 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2904 self.mk_place_elem(place, PlaceElem::Deref)
2905 }
2906
2907 pub fn mk_place_downcast(
2908 self,
2909 place: Place<'tcx>,
2910 adt_def: AdtDef<'tcx>,
2911 variant_index: VariantIdx,
2912 ) -> Place<'tcx> {
2913 self.mk_place_elem(
2914 place,
2915 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2916 )
2917 }
2918
2919 pub fn mk_place_downcast_unnamed(
2920 self,
2921 place: Place<'tcx>,
2922 variant_index: VariantIdx,
2923 ) -> Place<'tcx> {
2924 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2925 }
2926
2927 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2928 self.mk_place_elem(place, PlaceElem::Index(index))
2929 }
2930
2931 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2935 let mut projection = place.projection.to_vec();
2936 projection.push(elem);
2937
2938 Place { local: place.local, projection: self.mk_place_elems(&projection) }
2939 }
2940
2941 pub fn mk_poly_existential_predicates(
2942 self,
2943 eps: &[PolyExistentialPredicate<'tcx>],
2944 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2945 assert!(!eps.is_empty());
2946 assert!(
2947 eps.array_windows()
2948 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2949 != Ordering::Greater)
2950 );
2951 self.intern_poly_existential_predicates(eps)
2952 }
2953
2954 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2955 self.interners.intern_clauses(clauses)
2959 }
2960
2961 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2962 self.intern_local_def_ids(def_ids)
2966 }
2967
2968 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2969 where
2970 I: Iterator<Item = T>,
2971 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2972 {
2973 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2974 }
2975
2976 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2977 where
2978 I: Iterator<Item = T>,
2979 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2980 {
2981 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2982 }
2983
2984 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2985 where
2986 I: Iterator<Item = T>,
2987 T: CollectAndApply<
2988 &'tcx ty::CapturedPlace<'tcx>,
2989 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2990 >,
2991 {
2992 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2993 }
2994
2995 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2996 where
2997 I: Iterator<Item = T>,
2998 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2999 {
3000 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3001 }
3002
3003 pub fn mk_fn_sig<I, T>(
3008 self,
3009 inputs: I,
3010 output: I::Item,
3011 c_variadic: bool,
3012 safety: hir::Safety,
3013 abi: ExternAbi,
3014 ) -> T::Output
3015 where
3016 I: IntoIterator<Item = T>,
3017 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3018 {
3019 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3020 inputs_and_output: self.mk_type_list(xs),
3021 c_variadic,
3022 safety,
3023 abi,
3024 })
3025 }
3026
3027 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3028 where
3029 I: Iterator<Item = T>,
3030 T: CollectAndApply<
3031 PolyExistentialPredicate<'tcx>,
3032 &'tcx List<PolyExistentialPredicate<'tcx>>,
3033 >,
3034 {
3035 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3036 }
3037
3038 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3039 where
3040 I: Iterator<Item = T>,
3041 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3042 {
3043 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3044 }
3045
3046 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3047 where
3048 I: Iterator<Item = T>,
3049 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3050 {
3051 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3052 }
3053
3054 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3055 where
3056 I: Iterator<Item = T>,
3057 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3058 {
3059 T::collect_and_apply(iter, |xs| self.mk_args(xs))
3060 }
3061
3062 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3063 where
3064 I: Iterator<Item = T>,
3065 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3066 {
3067 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3068 }
3069
3070 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3071 where
3072 I: Iterator<Item = T>,
3073 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3074 {
3075 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3076 }
3077
3078 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3079 where
3080 I: Iterator<Item = T>,
3081 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3082 {
3083 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3084 }
3085
3086 pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
3087 where
3088 I: Iterator<Item = T>,
3089 T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
3090 {
3091 T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
3092 }
3093
3094 pub fn mk_args_trait(
3095 self,
3096 self_ty: Ty<'tcx>,
3097 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3098 ) -> GenericArgsRef<'tcx> {
3099 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3100 }
3101
3102 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3103 where
3104 I: Iterator<Item = T>,
3105 T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3106 {
3107 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3108 }
3109
3110 #[track_caller]
3113 pub fn emit_node_span_lint(
3114 self,
3115 lint: &'static Lint,
3116 hir_id: HirId,
3117 span: impl Into<MultiSpan>,
3118 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3119 ) {
3120 let level = self.lint_level_at_node(lint, hir_id);
3121 lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3122 decorator.decorate_lint(lint);
3123 })
3124 }
3125
3126 #[rustc_lint_diagnostics]
3130 #[track_caller]
3131 pub fn node_span_lint(
3132 self,
3133 lint: &'static Lint,
3134 hir_id: HirId,
3135 span: impl Into<MultiSpan>,
3136 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3137 ) {
3138 let level = self.lint_level_at_node(lint, hir_id);
3139 lint_level(self.sess, lint, level, Some(span.into()), decorate);
3140 }
3141
3142 pub fn crate_level_attribute_injection_span(self) -> Span {
3144 let node = self.hir_node(hir::CRATE_HIR_ID);
3145 let hir::Node::Crate(m) = node else { bug!() };
3146 m.spans.inject_use_span.shrink_to_lo()
3147 }
3148
3149 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3150 self,
3151 diag: &mut Diag<'_, E>,
3152 features: impl IntoIterator<Item = (String, Symbol)>,
3153 ) {
3154 if !self.sess.is_nightly_build() {
3155 return;
3156 }
3157
3158 let span = self.crate_level_attribute_injection_span();
3159 for (desc, feature) in features {
3160 let msg =
3162 format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3163 diag.span_suggestion_verbose(
3164 span,
3165 msg,
3166 format!("#![feature({feature})]\n"),
3167 Applicability::MaybeIncorrect,
3168 );
3169 }
3170 }
3171
3172 #[track_caller]
3175 pub fn emit_node_lint(
3176 self,
3177 lint: &'static Lint,
3178 id: HirId,
3179 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3180 ) {
3181 self.node_lint(lint, id, |lint| {
3182 decorator.decorate_lint(lint);
3183 })
3184 }
3185
3186 #[rustc_lint_diagnostics]
3190 #[track_caller]
3191 pub fn node_lint(
3192 self,
3193 lint: &'static Lint,
3194 id: HirId,
3195 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3196 ) {
3197 let level = self.lint_level_at_node(lint, id);
3198 lint_level(self.sess, lint, level, None, decorate);
3199 }
3200
3201 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3202 let map = self.in_scope_traits_map(id.owner)?;
3203 let candidates = map.get(&id.local_id)?;
3204 Some(candidates)
3205 }
3206
3207 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3208 debug!(?id, "named_region");
3209 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3210 }
3211
3212 pub fn is_late_bound(self, id: HirId) -> bool {
3213 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3214 }
3215
3216 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3217 self.mk_bound_variable_kinds(
3218 &self
3219 .late_bound_vars_map(id.owner)
3220 .get(&id.local_id)
3221 .cloned()
3222 .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3223 )
3224 }
3225
3226 pub fn map_opaque_lifetime_to_parent_lifetime(
3234 self,
3235 mut opaque_lifetime_param_def_id: LocalDefId,
3236 ) -> ty::Region<'tcx> {
3237 debug_assert!(
3238 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3239 "{opaque_lifetime_param_def_id:?} is a {}",
3240 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3241 );
3242
3243 loop {
3244 let parent = self.local_parent(opaque_lifetime_param_def_id);
3245 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3246
3247 let Some((lifetime, _)) = lifetime_mapping
3248 .iter()
3249 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3250 else {
3251 bug!("duplicated lifetime param should be present");
3252 };
3253
3254 match *lifetime {
3255 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3256 let new_parent = self.local_parent(ebv);
3257
3258 if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3261 debug_assert_eq!(self.local_parent(parent), new_parent);
3262 opaque_lifetime_param_def_id = ebv;
3263 continue;
3264 }
3265
3266 let generics = self.generics_of(new_parent);
3267 return ty::Region::new_early_param(
3268 self,
3269 ty::EarlyParamRegion {
3270 index: generics
3271 .param_def_id_to_index(self, ebv.to_def_id())
3272 .expect("early-bound var should be present in fn generics"),
3273 name: self.item_name(ebv.to_def_id()),
3274 },
3275 );
3276 }
3277 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3278 let new_parent = self.local_parent(lbv);
3279 return ty::Region::new_late_param(
3280 self,
3281 new_parent.to_def_id(),
3282 ty::LateParamRegionKind::Named(lbv.to_def_id()),
3283 );
3284 }
3285 resolve_bound_vars::ResolvedArg::Error(guar) => {
3286 return ty::Region::new_error(self, guar);
3287 }
3288 _ => {
3289 return ty::Region::new_error_with_message(
3290 self,
3291 self.def_span(opaque_lifetime_param_def_id),
3292 "cannot resolve lifetime",
3293 );
3294 }
3295 }
3296 }
3297 }
3298
3299 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3304 self.is_const_fn(def_id)
3305 && match self.lookup_const_stability(def_id) {
3306 None => true, Some(stability) if stability.is_const_stable() => true,
3308 _ => false,
3309 }
3310 }
3311
3312 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3314 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3315 && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3316 }
3317
3318 pub fn is_sdylib_interface_build(self) -> bool {
3319 self.sess.opts.unstable_opts.build_sdylib_interface
3320 }
3321
3322 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3323 match self.def_kind(def_id) {
3324 DefKind::Fn | DefKind::AssocFn => {}
3325 _ => return None,
3326 }
3327 self.intrinsic_raw(def_id)
3328 }
3329
3330 pub fn next_trait_solver_globally(self) -> bool {
3331 self.sess.opts.unstable_opts.next_solver.globally
3332 }
3333
3334 pub fn next_trait_solver_in_coherence(self) -> bool {
3335 self.sess.opts.unstable_opts.next_solver.coherence
3336 }
3337
3338 #[allow(rustc::bad_opt_access)]
3339 pub fn use_typing_mode_borrowck(self) -> bool {
3340 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3341 }
3342
3343 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3344 self.opt_rpitit_info(def_id).is_some()
3345 }
3346
3347 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3357 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3358 }
3359
3360 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3361 self.resolver_for_lowering_raw(()).0
3362 }
3363
3364 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
3365 crate::dep_graph::make_metadata(self)
3366 }
3367
3368 pub fn impl_trait_ref(
3371 self,
3372 def_id: impl IntoQueryParam<DefId>,
3373 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3374 Some(self.impl_trait_header(def_id)?.trait_ref)
3375 }
3376
3377 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3378 self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3379 }
3380
3381 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3382 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3383 self.coroutine_kind(def_id)
3384 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3385 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3386 {
3387 true
3388 } else {
3389 false
3390 }
3391 }
3392
3393 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3395 self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3396 }
3397}
3398
3399#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3408pub struct DeducedParamAttrs {
3409 pub read_only: bool,
3412}
3413
3414pub fn provide(providers: &mut Providers) {
3415 providers.maybe_unused_trait_imports =
3416 |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
3417 providers.extern_mod_stmt_cnum =
3418 |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
3419 providers.is_panic_runtime =
3420 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3421 providers.is_compiler_builtins =
3422 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3423 providers.has_panic_handler = |tcx, LocalCrate| {
3424 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3426 };
3427 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3428}
3429
3430pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3431 attrs.iter().any(|x| x.has_name(name))
3432}