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