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