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