1#![allow(rustc::usage_of_ty_tykind)]
4
5pub mod tls;
6
7use std::assert_matches::debug_assert_matches;
8use std::borrow::{Borrow, Cow};
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_data_structures::defer;
21use rustc_data_structures::fingerprint::Fingerprint;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::jobserver::Proxy;
25use rustc_data_structures::profiling::SelfProfilerRef;
26use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
27use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
28use rustc_data_structures::steal::Steal;
29use rustc_data_structures::sync::{
30 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
31};
32use rustc_errors::{
33 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, LintEmitter, MultiSpan,
34};
35use rustc_hir::attrs::AttributeKind;
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, find_attr};
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;
1044const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
1045const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
1046
1047const NUM_PREINTERNED_RE_VARS: u32 = 500;
1049const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
1050const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
1051
1052pub struct CommonTypes<'tcx> {
1053 pub unit: Ty<'tcx>,
1054 pub bool: Ty<'tcx>,
1055 pub char: Ty<'tcx>,
1056 pub isize: Ty<'tcx>,
1057 pub i8: Ty<'tcx>,
1058 pub i16: Ty<'tcx>,
1059 pub i32: Ty<'tcx>,
1060 pub i64: Ty<'tcx>,
1061 pub i128: Ty<'tcx>,
1062 pub usize: Ty<'tcx>,
1063 pub u8: Ty<'tcx>,
1064 pub u16: Ty<'tcx>,
1065 pub u32: Ty<'tcx>,
1066 pub u64: Ty<'tcx>,
1067 pub u128: Ty<'tcx>,
1068 pub f16: Ty<'tcx>,
1069 pub f32: Ty<'tcx>,
1070 pub f64: Ty<'tcx>,
1071 pub f128: Ty<'tcx>,
1072 pub str_: Ty<'tcx>,
1073 pub never: Ty<'tcx>,
1074 pub self_param: Ty<'tcx>,
1075
1076 pub trait_object_dummy_self: Ty<'tcx>,
1081
1082 pub ty_vars: Vec<Ty<'tcx>>,
1084
1085 pub fresh_tys: Vec<Ty<'tcx>>,
1087
1088 pub fresh_int_tys: Vec<Ty<'tcx>>,
1090
1091 pub fresh_float_tys: Vec<Ty<'tcx>>,
1093
1094 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
1098}
1099
1100pub struct CommonLifetimes<'tcx> {
1101 pub re_static: Region<'tcx>,
1103
1104 pub re_erased: Region<'tcx>,
1106
1107 pub re_vars: Vec<Region<'tcx>>,
1109
1110 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
1114}
1115
1116pub struct CommonConsts<'tcx> {
1117 pub unit: Const<'tcx>,
1118 pub true_: Const<'tcx>,
1119 pub false_: Const<'tcx>,
1120 pub(crate) valtree_zst: ValTree<'tcx>,
1122}
1123
1124impl<'tcx> CommonTypes<'tcx> {
1125 fn new(
1126 interners: &CtxtInterners<'tcx>,
1127 sess: &Session,
1128 untracked: &Untracked,
1129 ) -> CommonTypes<'tcx> {
1130 let mk = |ty| interners.intern_ty(ty, sess, untracked);
1131
1132 let ty_vars =
1133 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1134 let fresh_tys: Vec<_> =
1135 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1136 let fresh_int_tys: Vec<_> =
1137 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1138 let fresh_float_tys: Vec<_> =
1139 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1140
1141 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
1142 .map(|i| {
1143 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
1144 .map(|v| {
1145 mk(ty::Bound(
1146 ty::DebruijnIndex::from(i),
1147 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
1148 ))
1149 })
1150 .collect()
1151 })
1152 .collect();
1153
1154 CommonTypes {
1155 unit: mk(Tuple(List::empty())),
1156 bool: mk(Bool),
1157 char: mk(Char),
1158 never: mk(Never),
1159 isize: mk(Int(ty::IntTy::Isize)),
1160 i8: mk(Int(ty::IntTy::I8)),
1161 i16: mk(Int(ty::IntTy::I16)),
1162 i32: mk(Int(ty::IntTy::I32)),
1163 i64: mk(Int(ty::IntTy::I64)),
1164 i128: mk(Int(ty::IntTy::I128)),
1165 usize: mk(Uint(ty::UintTy::Usize)),
1166 u8: mk(Uint(ty::UintTy::U8)),
1167 u16: mk(Uint(ty::UintTy::U16)),
1168 u32: mk(Uint(ty::UintTy::U32)),
1169 u64: mk(Uint(ty::UintTy::U64)),
1170 u128: mk(Uint(ty::UintTy::U128)),
1171 f16: mk(Float(ty::FloatTy::F16)),
1172 f32: mk(Float(ty::FloatTy::F32)),
1173 f64: mk(Float(ty::FloatTy::F64)),
1174 f128: mk(Float(ty::FloatTy::F128)),
1175 str_: mk(Str),
1176 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1177
1178 trait_object_dummy_self: fresh_tys[0],
1179
1180 ty_vars,
1181 fresh_tys,
1182 fresh_int_tys,
1183 fresh_float_tys,
1184 anon_bound_tys,
1185 }
1186 }
1187}
1188
1189impl<'tcx> CommonLifetimes<'tcx> {
1190 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1191 let mk = |r| {
1192 Region(Interned::new_unchecked(
1193 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1194 ))
1195 };
1196
1197 let re_vars =
1198 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1199
1200 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
1201 .map(|i| {
1202 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
1203 .map(|v| {
1204 mk(ty::ReBound(
1205 ty::DebruijnIndex::from(i),
1206 ty::BoundRegion {
1207 var: ty::BoundVar::from(v),
1208 kind: ty::BoundRegionKind::Anon,
1209 },
1210 ))
1211 })
1212 .collect()
1213 })
1214 .collect();
1215
1216 CommonLifetimes {
1217 re_static: mk(ty::ReStatic),
1218 re_erased: mk(ty::ReErased),
1219 re_vars,
1220 anon_re_bounds,
1221 }
1222 }
1223}
1224
1225impl<'tcx> CommonConsts<'tcx> {
1226 fn new(
1227 interners: &CtxtInterners<'tcx>,
1228 types: &CommonTypes<'tcx>,
1229 sess: &Session,
1230 untracked: &Untracked,
1231 ) -> CommonConsts<'tcx> {
1232 let mk_const = |c| {
1233 interners.intern_const(
1234 c, sess, untracked,
1236 )
1237 };
1238
1239 let mk_valtree = |v| {
1240 ty::ValTree(Interned::new_unchecked(
1241 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1242 ))
1243 };
1244
1245 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1246 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1247 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1248
1249 CommonConsts {
1250 unit: mk_const(ty::ConstKind::Value(ty::Value {
1251 ty: types.unit,
1252 valtree: valtree_zst,
1253 })),
1254 true_: mk_const(ty::ConstKind::Value(ty::Value {
1255 ty: types.bool,
1256 valtree: valtree_true,
1257 })),
1258 false_: mk_const(ty::ConstKind::Value(ty::Value {
1259 ty: types.bool,
1260 valtree: valtree_false,
1261 })),
1262 valtree_zst,
1263 }
1264 }
1265}
1266
1267#[derive(Debug)]
1270pub struct FreeRegionInfo {
1271 pub scope: LocalDefId,
1273 pub region_def_id: DefId,
1275 pub is_impl_item: bool,
1277}
1278
1279#[derive(Copy, Clone)]
1281pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1282 pub tcx: TyCtxt<'tcx>,
1283 key: KEY,
1285}
1286
1287impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1290
1291#[derive(Copy, Clone)]
1296pub struct Feed<'tcx, KEY: Copy> {
1297 _tcx: PhantomData<TyCtxt<'tcx>>,
1298 key: KEY,
1300}
1301
1302impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1305
1306impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1307 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1308 self.key.fmt(f)
1309 }
1310}
1311
1312impl<'tcx> TyCtxt<'tcx> {
1317 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1320 self.dep_graph.assert_ignored();
1321 TyCtxtFeed { tcx: self, key: () }
1322 }
1323
1324 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1327 let key = self.untracked().source_span.push(span);
1328 assert_eq!(key, CRATE_DEF_ID);
1329 TyCtxtFeed { tcx: self, key }
1330 }
1331
1332 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1336 debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1337 TyCtxtFeed { tcx: self, key }.type_of(value)
1338 }
1339}
1340
1341impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1342 #[inline(always)]
1343 pub fn key(&self) -> KEY {
1344 self.key
1345 }
1346
1347 #[inline(always)]
1348 pub fn downgrade(self) -> Feed<'tcx, KEY> {
1349 Feed { _tcx: PhantomData, key: self.key }
1350 }
1351}
1352
1353impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1354 #[inline(always)]
1355 pub fn key(&self) -> KEY {
1356 self.key
1357 }
1358
1359 #[inline(always)]
1360 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1361 TyCtxtFeed { tcx, key: self.key }
1362 }
1363}
1364
1365impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1366 #[inline(always)]
1367 pub fn def_id(&self) -> LocalDefId {
1368 self.key
1369 }
1370
1371 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1373 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1374 }
1375
1376 pub fn feed_hir(&self) {
1378 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1379
1380 let node = hir::OwnerNode::Synthetic;
1381 let bodies = Default::default();
1382 let attrs = hir::AttributeMap::EMPTY;
1383
1384 let (opt_hash_including_bodies, _, _) =
1385 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
1386 let node = node.into();
1387 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1388 opt_hash_including_bodies,
1389 nodes: IndexVec::from_elem_n(
1390 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1391 1,
1392 ),
1393 bodies,
1394 })));
1395 self.feed_owner_id().hir_attr_map(attrs);
1396 }
1397}
1398
1399#[derive(Copy, Clone)]
1417#[rustc_diagnostic_item = "TyCtxt"]
1418#[rustc_pass_by_value]
1419pub struct TyCtxt<'tcx> {
1420 gcx: &'tcx GlobalCtxt<'tcx>,
1421}
1422
1423impl<'tcx> LintEmitter for TyCtxt<'tcx> {
1424 fn emit_node_span_lint(
1425 self,
1426 lint: &'static Lint,
1427 hir_id: HirId,
1428 span: impl Into<MultiSpan>,
1429 decorator: impl for<'a> LintDiagnostic<'a, ()>,
1430 ) {
1431 self.emit_node_span_lint(lint, hir_id, span, decorator);
1432 }
1433}
1434
1435unsafe impl DynSend for TyCtxt<'_> {}
1439unsafe impl DynSync for TyCtxt<'_> {}
1440fn _assert_tcx_fields() {
1441 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1442 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1443}
1444
1445impl<'tcx> Deref for TyCtxt<'tcx> {
1446 type Target = &'tcx GlobalCtxt<'tcx>;
1447 #[inline(always)]
1448 fn deref(&self) -> &Self::Target {
1449 &self.gcx
1450 }
1451}
1452
1453pub struct GlobalCtxt<'tcx> {
1455 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1456 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1457
1458 interners: CtxtInterners<'tcx>,
1459
1460 pub sess: &'tcx Session,
1461 crate_types: Vec<CrateType>,
1462 stable_crate_id: StableCrateId,
1468
1469 pub dep_graph: DepGraph,
1470
1471 pub prof: SelfProfilerRef,
1472
1473 pub types: CommonTypes<'tcx>,
1475
1476 pub lifetimes: CommonLifetimes<'tcx>,
1478
1479 pub consts: CommonConsts<'tcx>,
1481
1482 pub(crate) hooks: crate::hooks::Providers,
1485
1486 untracked: Untracked,
1487
1488 pub query_system: QuerySystem<'tcx>,
1489 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1490
1491 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1493
1494 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1497
1498 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1502
1503 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1505 pub new_solver_canonical_param_env_cache:
1506 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
1507
1508 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1509
1510 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
1512 pub clauses_cache:
1514 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
1515
1516 pub data_layout: TargetDataLayout,
1518
1519 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1521
1522 current_gcx: CurrentGcx,
1523
1524 pub jobserver_proxy: Arc<Proxy>,
1526}
1527
1528impl<'tcx> GlobalCtxt<'tcx> {
1529 pub fn enter<F, R>(&'tcx self, f: F) -> R
1532 where
1533 F: FnOnce(TyCtxt<'tcx>) -> R,
1534 {
1535 let icx = tls::ImplicitCtxt::new(self);
1536
1537 let _on_drop = defer(move || {
1539 *self.current_gcx.value.write() = None;
1540 });
1541
1542 {
1544 let mut guard = self.current_gcx.value.write();
1545 assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1546 *guard = Some(self as *const _ as *const ());
1547 }
1548
1549 tls::enter_context(&icx, || f(icx.tcx))
1550 }
1551}
1552
1553#[derive(Clone)]
1560pub struct CurrentGcx {
1561 value: Arc<RwLock<Option<*const ()>>>,
1564}
1565
1566unsafe impl DynSend for CurrentGcx {}
1567unsafe impl DynSync for CurrentGcx {}
1568
1569impl CurrentGcx {
1570 pub fn new() -> Self {
1571 Self { value: Arc::new(RwLock::new(None)) }
1572 }
1573
1574 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1575 let read_guard = self.value.read();
1576 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1577 f(unsafe { &*gcx })
1581 }
1582}
1583
1584impl<'tcx> TyCtxt<'tcx> {
1585 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1586 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1589 if typeck_root_def_id != def_id.to_def_id() {
1590 return self.has_typeck_results(typeck_root_def_id.expect_local());
1591 }
1592
1593 self.hir_node_by_def_id(def_id).body_id().is_some()
1594 }
1595
1596 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1601 let def_kind = self.def_kind(def_id);
1602 if def_kind.has_codegen_attrs() {
1603 self.codegen_fn_attrs(def_id)
1604 } else if matches!(
1605 def_kind,
1606 DefKind::AnonConst
1607 | DefKind::AssocConst
1608 | DefKind::Const
1609 | DefKind::InlineConst
1610 | DefKind::GlobalAsm
1611 ) {
1612 CodegenFnAttrs::EMPTY
1613 } else {
1614 bug!(
1615 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1616 def_id,
1617 def_kind
1618 )
1619 }
1620 }
1621
1622 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1623 self.arena.alloc(Steal::new(thir))
1624 }
1625
1626 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1627 self.arena.alloc(Steal::new(mir))
1628 }
1629
1630 pub fn alloc_steal_promoted(
1631 self,
1632 promoted: IndexVec<Promoted, Body<'tcx>>,
1633 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1634 self.arena.alloc(Steal::new(promoted))
1635 }
1636
1637 pub fn mk_adt_def(
1638 self,
1639 did: DefId,
1640 kind: AdtKind,
1641 variants: IndexVec<VariantIdx, ty::VariantDef>,
1642 repr: ReprOptions,
1643 ) -> ty::AdtDef<'tcx> {
1644 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1645 }
1646
1647 pub fn allocate_bytes_dedup<'a>(
1650 self,
1651 bytes: impl Into<Cow<'a, [u8]>>,
1652 salt: usize,
1653 ) -> interpret::AllocId {
1654 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
1656 let alloc = self.mk_const_alloc(alloc);
1657 self.reserve_and_set_memory_dedup(alloc, salt)
1658 }
1659
1660 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1662 if self.sess.opts.unstable_opts.experimental_default_bounds {
1663 &[
1664 LangItem::DefaultTrait1,
1665 LangItem::DefaultTrait2,
1666 LangItem::DefaultTrait3,
1667 LangItem::DefaultTrait4,
1668 ]
1669 } else {
1670 &[]
1671 }
1672 }
1673
1674 pub fn is_default_trait(self, def_id: DefId) -> bool {
1675 self.default_traits()
1676 .iter()
1677 .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
1678 }
1679
1680 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1684 let start = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1685 let end = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1686 (start, end)
1687 }
1688
1689 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1690 value.lift_to_interner(self)
1691 }
1692
1693 pub fn create_global_ctxt<T>(
1700 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1701 s: &'tcx Session,
1702 crate_types: Vec<CrateType>,
1703 stable_crate_id: StableCrateId,
1704 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1705 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1706 untracked: Untracked,
1707 dep_graph: DepGraph,
1708 query_kinds: &'tcx [DepKindStruct<'tcx>],
1709 query_system: QuerySystem<'tcx>,
1710 hooks: crate::hooks::Providers,
1711 current_gcx: CurrentGcx,
1712 jobserver_proxy: Arc<Proxy>,
1713 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1714 ) -> T {
1715 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1716 s.dcx().emit_fatal(err);
1717 });
1718 let interners = CtxtInterners::new(arena);
1719 let common_types = CommonTypes::new(&interners, s, &untracked);
1720 let common_lifetimes = CommonLifetimes::new(&interners);
1721 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1722
1723 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1724 sess: s,
1725 crate_types,
1726 stable_crate_id,
1727 arena,
1728 hir_arena,
1729 interners,
1730 dep_graph,
1731 hooks,
1732 prof: s.prof.clone(),
1733 types: common_types,
1734 lifetimes: common_lifetimes,
1735 consts: common_consts,
1736 untracked,
1737 query_system,
1738 query_kinds,
1739 ty_rcache: Default::default(),
1740 selection_cache: Default::default(),
1741 evaluation_cache: Default::default(),
1742 new_solver_evaluation_cache: Default::default(),
1743 new_solver_canonical_param_env_cache: Default::default(),
1744 canonical_param_env_cache: Default::default(),
1745 highest_var_in_clauses_cache: Default::default(),
1746 clauses_cache: Default::default(),
1747 data_layout,
1748 alloc_map: interpret::AllocMap::new(),
1749 current_gcx,
1750 jobserver_proxy,
1751 });
1752
1753 gcx.enter(f)
1755 }
1756
1757 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1759 self.get_lang_items(())
1760 }
1761
1762 #[track_caller]
1764 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1765 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1766 self.type_of(ordering_enum).no_bound_vars().unwrap()
1767 }
1768
1769 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1772 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1773 }
1774
1775 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1777 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1778 }
1779
1780 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1782 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1783 }
1784
1785 pub fn is_coroutine(self, def_id: DefId) -> bool {
1786 self.coroutine_kind(def_id).is_some()
1787 }
1788
1789 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1790 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1791 }
1792
1793 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1796 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1797 }
1798
1799 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1801 matches!(
1802 self.coroutine_kind(def_id),
1803 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1804 )
1805 }
1806
1807 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1810 matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1811 }
1812
1813 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1816 matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1817 }
1818
1819 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1821 matches!(
1822 self.coroutine_kind(def_id),
1823 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1824 )
1825 }
1826
1827 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1829 matches!(
1830 self.coroutine_kind(def_id),
1831 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1832 )
1833 }
1834
1835 pub fn features(self) -> &'tcx rustc_feature::Features {
1836 self.features_query(())
1837 }
1838
1839 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1840 let id = id.into_query_param();
1841 if let Some(id) = id.as_local() {
1843 self.definitions_untracked().def_key(id)
1844 } else {
1845 self.cstore_untracked().def_key(id)
1846 }
1847 }
1848
1849 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1855 if let Some(id) = id.as_local() {
1857 self.definitions_untracked().def_path(id)
1858 } else {
1859 self.cstore_untracked().def_path(id)
1860 }
1861 }
1862
1863 #[inline]
1864 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1865 if let Some(def_id) = def_id.as_local() {
1867 self.definitions_untracked().def_path_hash(def_id)
1868 } else {
1869 self.cstore_untracked().def_path_hash(def_id)
1870 }
1871 }
1872
1873 #[inline]
1874 pub fn crate_types(self) -> &'tcx [CrateType] {
1875 &self.crate_types
1876 }
1877
1878 pub fn needs_metadata(self) -> bool {
1879 self.crate_types().iter().any(|ty| match *ty {
1880 CrateType::Executable
1881 | CrateType::Staticlib
1882 | CrateType::Cdylib
1883 | CrateType::Sdylib => false,
1884 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1885 })
1886 }
1887
1888 pub fn needs_crate_hash(self) -> bool {
1889 cfg!(debug_assertions)
1901 || self.sess.opts.incremental.is_some()
1902 || self.needs_metadata()
1903 || self.sess.instrument_coverage()
1904 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1905 }
1906
1907 #[inline]
1908 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1909 if crate_num == LOCAL_CRATE {
1910 self.stable_crate_id
1911 } else {
1912 self.cstore_untracked().stable_crate_id(crate_num)
1913 }
1914 }
1915
1916 #[inline]
1919 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1920 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1921 LOCAL_CRATE
1922 } else {
1923 *self
1924 .untracked()
1925 .stable_crate_ids
1926 .read()
1927 .get(&stable_crate_id)
1928 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1929 }
1930 }
1931
1932 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1936 debug!("def_path_hash_to_def_id({:?})", hash);
1937
1938 let stable_crate_id = hash.stable_crate_id();
1939
1940 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1943 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1944 } else {
1945 Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
1946 }
1947 }
1948
1949 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1950 let (crate_name, stable_crate_id) = if def_id.is_local() {
1955 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1956 } else {
1957 let cstore = &*self.cstore_untracked();
1958 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1959 };
1960
1961 format!(
1962 "{}[{:04x}]{}",
1963 crate_name,
1964 stable_crate_id.as_u64() >> (8 * 6),
1967 self.def_path(def_id).to_string_no_crate_verbose()
1968 )
1969 }
1970
1971 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1972 self.sess.dcx()
1973 }
1974
1975 pub fn is_target_feature_call_safe(
1976 self,
1977 callee_features: &[TargetFeature],
1978 body_features: &[TargetFeature],
1979 ) -> bool {
1980 self.sess.target.options.is_like_wasm
1985 || callee_features
1986 .iter()
1987 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1988 }
1989
1990 pub fn adjust_target_feature_sig(
1993 self,
1994 fun_def: DefId,
1995 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1996 caller: DefId,
1997 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1998 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1999 let callee_features = &self.codegen_fn_attrs(caller).target_features;
2000 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
2001 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
2002 }
2003 None
2004 }
2005
2006 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
2009 match self.env_var_os(key.as_ref()) {
2010 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
2011 None => Err(VarError::NotPresent),
2012 }
2013 }
2014}
2015
2016impl<'tcx> TyCtxtAt<'tcx> {
2017 pub fn create_def(
2019 self,
2020 parent: LocalDefId,
2021 name: Option<Symbol>,
2022 def_kind: DefKind,
2023 override_def_path_data: Option<DefPathData>,
2024 disambiguator: &mut DisambiguatorState,
2025 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2026 let feed =
2027 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
2028
2029 feed.def_span(self.span);
2030 feed
2031 }
2032}
2033
2034impl<'tcx> TyCtxt<'tcx> {
2035 pub fn create_def(
2037 self,
2038 parent: LocalDefId,
2039 name: Option<Symbol>,
2040 def_kind: DefKind,
2041 override_def_path_data: Option<DefPathData>,
2042 disambiguator: &mut DisambiguatorState,
2043 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2044 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2045 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2055
2056 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2061
2062 let feed = TyCtxtFeed { tcx: self, key: def_id };
2063 feed.def_kind(def_kind);
2064 if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2069 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2070 feed.visibility(ty::Visibility::Restricted(parent_mod));
2071 }
2072
2073 feed
2074 }
2075
2076 pub fn create_crate_num(
2077 self,
2078 stable_crate_id: StableCrateId,
2079 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2080 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2081 return Err(existing);
2082 }
2083
2084 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2085 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2086 Ok(TyCtxtFeed { key: num, tcx: self })
2087 }
2088
2089 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2090 self.ensure_ok().analysis(());
2092
2093 let definitions = &self.untracked.definitions;
2094 gen {
2095 let mut i = 0;
2096
2097 while i < { definitions.read().num_definitions() } {
2100 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2101 yield LocalDefId { local_def_index };
2102 i += 1;
2103 }
2104
2105 definitions.freeze();
2107 }
2108 }
2109
2110 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2111 self.ensure_ok().analysis(());
2113
2114 self.untracked.definitions.freeze().def_path_table()
2117 }
2118
2119 pub fn def_path_hash_to_def_index_map(
2120 self,
2121 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2122 self.ensure_ok().hir_crate_items(());
2125 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2128 }
2129
2130 #[inline]
2133 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2134 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2135 }
2136
2137 pub fn untracked(self) -> &'tcx Untracked {
2139 &self.untracked
2140 }
2141 #[inline]
2144 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2145 self.untracked.definitions.read()
2146 }
2147
2148 #[inline]
2151 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2152 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2153 }
2154
2155 #[inline(always)]
2156 pub fn with_stable_hashing_context<R>(
2157 self,
2158 f: impl FnOnce(StableHashingContext<'_>) -> R,
2159 ) -> R {
2160 f(StableHashingContext::new(self.sess, &self.untracked))
2161 }
2162
2163 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2164 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2165 }
2166
2167 #[inline]
2168 pub fn local_crate_exports_generics(self) -> bool {
2169 self.crate_types().iter().any(|crate_type| {
2170 match crate_type {
2171 CrateType::Executable
2172 | CrateType::Staticlib
2173 | CrateType::ProcMacro
2174 | CrateType::Cdylib
2175 | CrateType::Sdylib => false,
2176
2177 CrateType::Dylib => true,
2182
2183 CrateType::Rlib => true,
2184 }
2185 })
2186 }
2187
2188 pub fn is_suitable_region(
2190 self,
2191 generic_param_scope: LocalDefId,
2192 mut region: Region<'tcx>,
2193 ) -> Option<FreeRegionInfo> {
2194 let (suitable_region_binding_scope, region_def_id) = loop {
2195 let def_id =
2196 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2197 let scope = self.local_parent(def_id);
2198 if self.def_kind(scope) == DefKind::OpaqueTy {
2199 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2202 continue;
2203 }
2204 break (scope, def_id.into());
2205 };
2206
2207 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2208 Node::Item(..) | Node::TraitItem(..) => false,
2209 Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2210 _ => false,
2211 };
2212
2213 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2214 }
2215
2216 pub fn return_type_impl_or_dyn_traits(
2218 self,
2219 scope_def_id: LocalDefId,
2220 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2221 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2222 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2223 self.hir_fn_decl_by_hir_id(hir_id)
2224 else {
2225 return vec![];
2226 };
2227
2228 let mut v = TraitObjectVisitor(vec![]);
2229 v.visit_ty_unambig(hir_output);
2230 v.0
2231 }
2232
2233 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2237 self,
2238 scope_def_id: LocalDefId,
2239 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2240 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2241 let mut v = TraitObjectVisitor(vec![]);
2242 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2244 && let hir::TyKind::Path(hir::QPath::Resolved(
2245 None,
2246 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2247 && let Some(local_id) = def_id.as_local()
2248 && 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()
2250 {
2251 v.visit_ty_unambig(alias_ty);
2252 if !v.0.is_empty() {
2253 return Some((
2254 v.0,
2255 alias_generics.span,
2256 alias_generics.span_for_lifetime_suggestion(),
2257 ));
2258 }
2259 }
2260 None
2261 }
2262
2263 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2265 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2266 if self.impl_trait_ref(container_id).is_some() {
2267 return true;
2274 }
2275 false
2276 }
2277
2278 pub fn has_strict_asm_symbol_naming(self) -> bool {
2281 self.sess.target.arch.contains("nvptx")
2282 }
2283
2284 pub fn caller_location_ty(self) -> Ty<'tcx> {
2286 Ty::new_imm_ref(
2287 self,
2288 self.lifetimes.re_static,
2289 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2290 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2291 )
2292 }
2293
2294 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2296 let kind = self.def_kind(def_id);
2297 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2298 }
2299
2300 pub fn type_length_limit(self) -> Limit {
2301 self.limits(()).type_length_limit
2302 }
2303
2304 pub fn recursion_limit(self) -> Limit {
2305 self.limits(()).recursion_limit
2306 }
2307
2308 pub fn move_size_limit(self) -> Limit {
2309 self.limits(()).move_size_limit
2310 }
2311
2312 pub fn pattern_complexity_limit(self) -> Limit {
2313 self.limits(()).pattern_complexity_limit
2314 }
2315
2316 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
2318 iter::once(LOCAL_CRATE)
2319 .chain(self.crates(()).iter().copied())
2320 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2321 }
2322
2323 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2325 let visible_crates =
2326 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2327
2328 iter::once(LOCAL_CRATE)
2329 .chain(visible_crates)
2330 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2331 }
2332
2333 #[inline]
2334 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2335 self.visibility(def_id).expect_local()
2336 }
2337
2338 #[instrument(skip(self), level = "trace", ret)]
2340 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2341 self.hir_expect_opaque_ty(def_id).origin
2342 }
2343
2344 pub fn finish(self) {
2345 self.alloc_self_profile_query_strings();
2348
2349 self.save_dep_graph();
2350 self.query_key_hash_verify_all();
2351
2352 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2353 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2354 }
2355 }
2356}
2357
2358macro_rules! nop_lift {
2359 ($set:ident; $ty:ty => $lifted:ty) => {
2360 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2361 type Lifted = $lifted;
2362 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2363 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2368 _x: Interned<'tcx, Inner>,
2369 ) -> InternedSet<'tcx, Inner> {
2370 unreachable!()
2371 }
2372 fn _type_eq<T>(_x: &T, _y: &T) {}
2373 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2374 let interner = _intern_set_ty_from_interned_ty(x.0);
2378 _type_eq(&interner, &tcx.interners.$set);
2380 }
2381
2382 tcx.interners
2383 .$set
2384 .contains_pointer_to(&InternedInSet(&*self.0.0))
2385 .then(|| unsafe { mem::transmute(self) })
2388 }
2389 }
2390 };
2391}
2392
2393macro_rules! nop_list_lift {
2394 ($set:ident; $ty:ty => $lifted:ty) => {
2395 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2396 type Lifted = &'tcx List<$lifted>;
2397 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2398 if false {
2400 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2401 }
2402
2403 if self.is_empty() {
2404 return Some(List::empty());
2405 }
2406 tcx.interners
2407 .$set
2408 .contains_pointer_to(&InternedInSet(self))
2409 .then(|| unsafe { mem::transmute(self) })
2410 }
2411 }
2412 };
2413}
2414
2415nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2416nop_lift! { region; Region<'a> => Region<'tcx> }
2417nop_lift! { const_; Const<'a> => Const<'tcx> }
2418nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2419nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2420nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2421nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2422nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2423nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2424
2425nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2426nop_list_lift! {
2427 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2428}
2429nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2430
2431nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2433
2434macro_rules! sty_debug_print {
2435 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2436 #[allow(non_snake_case)]
2439 mod inner {
2440 use crate::ty::{self, TyCtxt};
2441 use crate::ty::context::InternedInSet;
2442
2443 #[derive(Copy, Clone)]
2444 struct DebugStat {
2445 total: usize,
2446 lt_infer: usize,
2447 ty_infer: usize,
2448 ct_infer: usize,
2449 all_infer: usize,
2450 }
2451
2452 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2453 let mut total = DebugStat {
2454 total: 0,
2455 lt_infer: 0,
2456 ty_infer: 0,
2457 ct_infer: 0,
2458 all_infer: 0,
2459 };
2460 $(let mut $variant = total;)*
2461
2462 for shard in tcx.interners.type_.lock_shards() {
2463 #[allow(rustc::potential_query_instability)]
2465 let types = shard.iter();
2466 for &(InternedInSet(t), ()) in types {
2467 let variant = match t.internee {
2468 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2469 ty::Float(..) | ty::Str | ty::Never => continue,
2470 ty::Error(_) => continue,
2471 $(ty::$variant(..) => &mut $variant,)*
2472 };
2473 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2474 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2475 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2476
2477 variant.total += 1;
2478 total.total += 1;
2479 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2480 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2481 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2482 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2483 }
2484 }
2485 writeln!(fmt, "Ty interner total ty lt ct all")?;
2486 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2487 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2488 stringify!($variant),
2489 uses = $variant.total,
2490 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2491 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2492 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2493 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2494 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2495 )*
2496 writeln!(fmt, " total {uses:6} \
2497 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2498 uses = total.total,
2499 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2500 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2501 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2502 all = total.all_infer as f64 * 100.0 / total.total as f64)
2503 }
2504 }
2505
2506 inner::go($fmt, $ctxt)
2507 }}
2508}
2509
2510impl<'tcx> TyCtxt<'tcx> {
2511 pub fn debug_stats(self) -> impl fmt::Debug {
2512 fmt::from_fn(move |fmt| {
2513 sty_debug_print!(
2514 fmt,
2515 self,
2516 Adt,
2517 Array,
2518 Slice,
2519 RawPtr,
2520 Ref,
2521 FnDef,
2522 FnPtr,
2523 UnsafeBinder,
2524 Placeholder,
2525 Coroutine,
2526 CoroutineWitness,
2527 Dynamic,
2528 Closure,
2529 CoroutineClosure,
2530 Tuple,
2531 Bound,
2532 Param,
2533 Infer,
2534 Alias,
2535 Pat,
2536 Foreign
2537 )?;
2538
2539 writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2540 writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2541 writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2542 writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2543
2544 Ok(())
2545 })
2546 }
2547}
2548
2549struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2554
2555impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2556 fn clone(&self) -> Self {
2557 InternedInSet(self.0)
2558 }
2559}
2560
2561impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2562
2563impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2564 fn into_pointer(&self) -> *const () {
2565 self.0 as *const _ as *const ()
2566 }
2567}
2568
2569#[allow(rustc::usage_of_ty_tykind)]
2570impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2571 fn borrow(&self) -> &T {
2572 &self.0.internee
2573 }
2574}
2575
2576impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2577 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2578 self.0.internee == other.0.internee
2581 }
2582}
2583
2584impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2585
2586impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2587 fn hash<H: Hasher>(&self, s: &mut H) {
2588 self.0.internee.hash(s)
2590 }
2591}
2592
2593impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2594 fn borrow(&self) -> &[T] {
2595 &self.0[..]
2596 }
2597}
2598
2599impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2600 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2601 self.0[..] == other.0[..]
2604 }
2605}
2606
2607impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2608
2609impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2610 fn hash<H: Hasher>(&self, s: &mut H) {
2611 self.0[..].hash(s)
2613 }
2614}
2615
2616impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2617 fn borrow(&self) -> &[T] {
2618 &self.0[..]
2619 }
2620}
2621
2622impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2623 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2624 self.0[..] == other.0[..]
2627 }
2628}
2629
2630impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2631
2632impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2633 fn hash<H: Hasher>(&self, s: &mut H) {
2634 self.0[..].hash(s)
2636 }
2637}
2638
2639macro_rules! direct_interners {
2640 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2641 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2642 fn borrow<'a>(&'a self) -> &'a $ty {
2643 &self.0
2644 }
2645 }
2646
2647 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2648 fn eq(&self, other: &Self) -> bool {
2649 self.0 == other.0
2652 }
2653 }
2654
2655 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2656
2657 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2658 fn hash<H: Hasher>(&self, s: &mut H) {
2659 self.0.hash(s)
2662 }
2663 }
2664
2665 impl<'tcx> TyCtxt<'tcx> {
2666 $vis fn $method(self, v: $ty) -> $ret_ty {
2667 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2668 InternedInSet(self.interners.arena.alloc(v))
2669 }).0))
2670 }
2671 })+
2672 }
2673}
2674
2675direct_interners! {
2679 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2680 valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2681 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2682 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2683 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2684 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2685 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2686 ExternalConstraints -> ExternalConstraints<'tcx>,
2687 predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2688 PredefinedOpaques -> PredefinedOpaques<'tcx>,
2689}
2690
2691macro_rules! slice_interners {
2692 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2693 impl<'tcx> TyCtxt<'tcx> {
2694 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2695 if v.is_empty() {
2696 List::empty()
2697 } else {
2698 self.interners.$field.intern_ref(v, || {
2699 InternedInSet(List::from_arena(&*self.arena, (), v))
2700 }).0
2701 }
2702 })+
2703 }
2704 );
2705}
2706
2707slice_interners!(
2711 const_lists: pub mk_const_list(Const<'tcx>),
2712 args: pub mk_args(GenericArg<'tcx>),
2713 type_lists: pub mk_type_list(Ty<'tcx>),
2714 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2715 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2716 projs: pub mk_projs(ProjectionKind),
2717 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2718 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2719 fields: pub mk_fields(FieldIdx),
2720 local_def_ids: intern_local_def_ids(LocalDefId),
2721 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2722 offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2723 patterns: pub mk_patterns(Pattern<'tcx>),
2724 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2725);
2726
2727impl<'tcx> TyCtxt<'tcx> {
2728 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2732 assert!(sig.safety().is_safe());
2733 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2734 }
2735
2736 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2739 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2740 self.associated_items(trait_did)
2741 .filter_by_name_unhygienic(assoc_name.name)
2742 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2743 })
2744 }
2745
2746 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2748 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2749 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2750
2751 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2752 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2753 return false;
2754 };
2755 trait_predicate.trait_ref.def_id == future_trait
2756 && trait_predicate.polarity == PredicatePolarity::Positive
2757 })
2758 }
2759
2760 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2768 sig.map_bound(|s| {
2769 let params = match s.inputs()[0].kind() {
2770 ty::Tuple(params) => *params,
2771 _ => bug!(),
2772 };
2773 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2774 })
2775 }
2776
2777 #[inline]
2778 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2779 self.interners.intern_predicate(
2780 binder,
2781 self.sess,
2782 &self.untracked,
2784 )
2785 }
2786
2787 #[inline]
2788 pub fn reuse_or_mk_predicate(
2789 self,
2790 pred: Predicate<'tcx>,
2791 binder: Binder<'tcx, PredicateKind<'tcx>>,
2792 ) -> Predicate<'tcx> {
2793 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2794 }
2795
2796 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2797 self.check_args_compatible_inner(def_id, args, false)
2798 }
2799
2800 fn check_args_compatible_inner(
2801 self,
2802 def_id: DefId,
2803 args: &'tcx [ty::GenericArg<'tcx>],
2804 nested: bool,
2805 ) -> bool {
2806 let generics = self.generics_of(def_id);
2807
2808 let own_args = if !nested
2811 && let DefKind::AssocTy = self.def_kind(def_id)
2812 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2813 {
2814 if generics.own_params.len() + 1 != args.len() {
2815 return false;
2816 }
2817
2818 if !matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2819 return false;
2820 }
2821
2822 &args[1..]
2823 } else {
2824 if generics.count() != args.len() {
2825 return false;
2826 }
2827
2828 let (parent_args, own_args) = args.split_at(generics.parent_count);
2829
2830 if let Some(parent) = generics.parent
2831 && !self.check_args_compatible_inner(parent, parent_args, true)
2832 {
2833 return false;
2834 }
2835
2836 own_args
2837 };
2838
2839 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2840 match (¶m.kind, arg.kind()) {
2841 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2842 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2843 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2844 _ => return false,
2845 }
2846 }
2847
2848 true
2849 }
2850
2851 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2854 if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2855 if let DefKind::AssocTy = self.def_kind(def_id)
2856 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2857 {
2858 bug!(
2859 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2860 self.def_path_str(def_id),
2861 args,
2862 self.mk_args_from_iter(
2864 [self.types.self_param.into()].into_iter().chain(
2865 self.generics_of(def_id)
2866 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2867 .iter()
2868 .copied()
2869 )
2870 )
2871 );
2872 } else {
2873 bug!(
2874 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2875 self.def_path_str(def_id),
2876 args,
2877 ty::GenericArgs::identity_for_item(self, def_id)
2878 );
2879 }
2880 }
2881 }
2882
2883 #[inline(always)]
2884 pub(crate) fn check_and_mk_args(
2885 self,
2886 def_id: DefId,
2887 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2888 ) -> GenericArgsRef<'tcx> {
2889 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2890 self.debug_assert_args_compatible(def_id, args);
2891 args
2892 }
2893
2894 #[inline]
2895 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2896 self.interners.intern_const(
2897 kind,
2898 self.sess,
2899 &self.untracked,
2901 )
2902 }
2903
2904 #[allow(rustc::usage_of_ty_tykind)]
2906 #[inline]
2907 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2908 self.interners.intern_ty(
2909 st,
2910 self.sess,
2911 &self.untracked,
2913 )
2914 }
2915
2916 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2917 match param.kind {
2918 GenericParamDefKind::Lifetime => {
2919 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2920 }
2921 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2922 GenericParamDefKind::Const { .. } => {
2923 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2924 .into()
2925 }
2926 }
2927 }
2928
2929 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2930 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2931 }
2932
2933 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2934 self.mk_place_elem(place, PlaceElem::Deref)
2935 }
2936
2937 pub fn mk_place_downcast(
2938 self,
2939 place: Place<'tcx>,
2940 adt_def: AdtDef<'tcx>,
2941 variant_index: VariantIdx,
2942 ) -> Place<'tcx> {
2943 self.mk_place_elem(
2944 place,
2945 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2946 )
2947 }
2948
2949 pub fn mk_place_downcast_unnamed(
2950 self,
2951 place: Place<'tcx>,
2952 variant_index: VariantIdx,
2953 ) -> Place<'tcx> {
2954 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2955 }
2956
2957 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2958 self.mk_place_elem(place, PlaceElem::Index(index))
2959 }
2960
2961 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2965 let mut projection = place.projection.to_vec();
2966 projection.push(elem);
2967
2968 Place { local: place.local, projection: self.mk_place_elems(&projection) }
2969 }
2970
2971 pub fn mk_poly_existential_predicates(
2972 self,
2973 eps: &[PolyExistentialPredicate<'tcx>],
2974 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2975 assert!(!eps.is_empty());
2976 assert!(
2977 eps.array_windows()
2978 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2979 != Ordering::Greater)
2980 );
2981 self.intern_poly_existential_predicates(eps)
2982 }
2983
2984 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2985 self.interners.intern_clauses(clauses)
2989 }
2990
2991 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2992 self.intern_local_def_ids(def_ids)
2996 }
2997
2998 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2999 where
3000 I: Iterator<Item = T>,
3001 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
3002 {
3003 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
3004 }
3005
3006 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
3007 where
3008 I: Iterator<Item = T>,
3009 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
3010 {
3011 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
3012 }
3013
3014 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
3015 where
3016 I: Iterator<Item = T>,
3017 T: CollectAndApply<
3018 &'tcx ty::CapturedPlace<'tcx>,
3019 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
3020 >,
3021 {
3022 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
3023 }
3024
3025 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
3026 where
3027 I: Iterator<Item = T>,
3028 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
3029 {
3030 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3031 }
3032
3033 pub fn mk_fn_sig<I, T>(
3038 self,
3039 inputs: I,
3040 output: I::Item,
3041 c_variadic: bool,
3042 safety: hir::Safety,
3043 abi: ExternAbi,
3044 ) -> T::Output
3045 where
3046 I: IntoIterator<Item = T>,
3047 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3048 {
3049 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3050 inputs_and_output: self.mk_type_list(xs),
3051 c_variadic,
3052 safety,
3053 abi,
3054 })
3055 }
3056
3057 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3058 where
3059 I: Iterator<Item = T>,
3060 T: CollectAndApply<
3061 PolyExistentialPredicate<'tcx>,
3062 &'tcx List<PolyExistentialPredicate<'tcx>>,
3063 >,
3064 {
3065 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3066 }
3067
3068 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3069 where
3070 I: Iterator<Item = T>,
3071 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3072 {
3073 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3074 }
3075
3076 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3077 where
3078 I: Iterator<Item = T>,
3079 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3080 {
3081 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3082 }
3083
3084 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3085 where
3086 I: Iterator<Item = T>,
3087 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3088 {
3089 T::collect_and_apply(iter, |xs| self.mk_args(xs))
3090 }
3091
3092 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3093 where
3094 I: Iterator<Item = T>,
3095 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3096 {
3097 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3098 }
3099
3100 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3101 where
3102 I: Iterator<Item = T>,
3103 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3104 {
3105 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3106 }
3107
3108 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3109 where
3110 I: Iterator<Item = T>,
3111 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3112 {
3113 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3114 }
3115
3116 pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
3117 where
3118 I: Iterator<Item = T>,
3119 T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
3120 {
3121 T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
3122 }
3123
3124 pub fn mk_args_trait(
3125 self,
3126 self_ty: Ty<'tcx>,
3127 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3128 ) -> GenericArgsRef<'tcx> {
3129 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3130 }
3131
3132 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3133 where
3134 I: Iterator<Item = T>,
3135 T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3136 {
3137 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3138 }
3139
3140 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
3141 where
3142 I: Iterator<Item = T>,
3143 T: CollectAndApply<
3144 ty::ArgOutlivesPredicate<'tcx>,
3145 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
3146 >,
3147 {
3148 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
3149 }
3150
3151 #[track_caller]
3154 pub fn emit_node_span_lint(
3155 self,
3156 lint: &'static Lint,
3157 hir_id: HirId,
3158 span: impl Into<MultiSpan>,
3159 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3160 ) {
3161 let level = self.lint_level_at_node(lint, hir_id);
3162 lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3163 decorator.decorate_lint(lint);
3164 })
3165 }
3166
3167 #[rustc_lint_diagnostics]
3171 #[track_caller]
3172 pub fn node_span_lint(
3173 self,
3174 lint: &'static Lint,
3175 hir_id: HirId,
3176 span: impl Into<MultiSpan>,
3177 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3178 ) {
3179 let level = self.lint_level_at_node(lint, hir_id);
3180 lint_level(self.sess, lint, level, Some(span.into()), decorate);
3181 }
3182
3183 pub fn crate_level_attribute_injection_span(self) -> Span {
3185 let node = self.hir_node(hir::CRATE_HIR_ID);
3186 let hir::Node::Crate(m) = node else { bug!() };
3187 m.spans.inject_use_span.shrink_to_lo()
3188 }
3189
3190 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3191 self,
3192 diag: &mut Diag<'_, E>,
3193 features: impl IntoIterator<Item = (String, Symbol)>,
3194 ) {
3195 if !self.sess.is_nightly_build() {
3196 return;
3197 }
3198
3199 let span = self.crate_level_attribute_injection_span();
3200 for (desc, feature) in features {
3201 let msg =
3203 format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3204 diag.span_suggestion_verbose(
3205 span,
3206 msg,
3207 format!("#![feature({feature})]\n"),
3208 Applicability::MaybeIncorrect,
3209 );
3210 }
3211 }
3212
3213 #[track_caller]
3216 pub fn emit_node_lint(
3217 self,
3218 lint: &'static Lint,
3219 id: HirId,
3220 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3221 ) {
3222 self.node_lint(lint, id, |lint| {
3223 decorator.decorate_lint(lint);
3224 })
3225 }
3226
3227 #[rustc_lint_diagnostics]
3231 #[track_caller]
3232 pub fn node_lint(
3233 self,
3234 lint: &'static Lint,
3235 id: HirId,
3236 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3237 ) {
3238 let level = self.lint_level_at_node(lint, id);
3239 lint_level(self.sess, lint, level, None, decorate);
3240 }
3241
3242 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3243 let map = self.in_scope_traits_map(id.owner)?;
3244 let candidates = map.get(&id.local_id)?;
3245 Some(candidates)
3246 }
3247
3248 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3249 debug!(?id, "named_region");
3250 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3251 }
3252
3253 pub fn is_late_bound(self, id: HirId) -> bool {
3254 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3255 }
3256
3257 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3258 self.mk_bound_variable_kinds(
3259 &self
3260 .late_bound_vars_map(id.owner)
3261 .get(&id.local_id)
3262 .cloned()
3263 .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3264 )
3265 }
3266
3267 pub fn map_opaque_lifetime_to_parent_lifetime(
3275 self,
3276 mut opaque_lifetime_param_def_id: LocalDefId,
3277 ) -> ty::Region<'tcx> {
3278 debug_assert!(
3279 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3280 "{opaque_lifetime_param_def_id:?} is a {}",
3281 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3282 );
3283
3284 loop {
3285 let parent = self.local_parent(opaque_lifetime_param_def_id);
3286 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3287
3288 let Some((lifetime, _)) = lifetime_mapping
3289 .iter()
3290 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3291 else {
3292 bug!("duplicated lifetime param should be present");
3293 };
3294
3295 match *lifetime {
3296 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3297 let new_parent = self.local_parent(ebv);
3298
3299 if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3302 debug_assert_eq!(self.local_parent(parent), new_parent);
3303 opaque_lifetime_param_def_id = ebv;
3304 continue;
3305 }
3306
3307 let generics = self.generics_of(new_parent);
3308 return ty::Region::new_early_param(
3309 self,
3310 ty::EarlyParamRegion {
3311 index: generics
3312 .param_def_id_to_index(self, ebv.to_def_id())
3313 .expect("early-bound var should be present in fn generics"),
3314 name: self.item_name(ebv.to_def_id()),
3315 },
3316 );
3317 }
3318 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3319 let new_parent = self.local_parent(lbv);
3320 return ty::Region::new_late_param(
3321 self,
3322 new_parent.to_def_id(),
3323 ty::LateParamRegionKind::Named(lbv.to_def_id()),
3324 );
3325 }
3326 resolve_bound_vars::ResolvedArg::Error(guar) => {
3327 return ty::Region::new_error(self, guar);
3328 }
3329 _ => {
3330 return ty::Region::new_error_with_message(
3331 self,
3332 self.def_span(opaque_lifetime_param_def_id),
3333 "cannot resolve lifetime",
3334 );
3335 }
3336 }
3337 }
3338 }
3339
3340 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3345 self.is_const_fn(def_id)
3346 && match self.lookup_const_stability(def_id) {
3347 None => true, Some(stability) if stability.is_const_stable() => true,
3349 _ => false,
3350 }
3351 }
3352
3353 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3355 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3356 && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3357 }
3358
3359 pub fn is_sdylib_interface_build(self) -> bool {
3360 self.sess.opts.unstable_opts.build_sdylib_interface
3361 }
3362
3363 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3364 match self.def_kind(def_id) {
3365 DefKind::Fn | DefKind::AssocFn => {}
3366 _ => return None,
3367 }
3368 self.intrinsic_raw(def_id)
3369 }
3370
3371 pub fn next_trait_solver_globally(self) -> bool {
3372 self.sess.opts.unstable_opts.next_solver.globally
3373 }
3374
3375 pub fn next_trait_solver_in_coherence(self) -> bool {
3376 self.sess.opts.unstable_opts.next_solver.coherence
3377 }
3378
3379 #[allow(rustc::bad_opt_access)]
3380 pub fn use_typing_mode_borrowck(self) -> bool {
3381 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3382 }
3383
3384 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3385 self.opt_rpitit_info(def_id).is_some()
3386 }
3387
3388 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3398 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3399 }
3400
3401 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
3403 self.resolutions(()).extern_crate_map.get(&def_id).copied()
3404 }
3405
3406 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3407 self.resolver_for_lowering_raw(()).0
3408 }
3409
3410 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
3411 crate::dep_graph::make_metadata(self)
3412 }
3413
3414 pub fn impl_trait_ref(
3417 self,
3418 def_id: impl IntoQueryParam<DefId>,
3419 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3420 Some(self.impl_trait_header(def_id)?.trait_ref)
3421 }
3422
3423 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3424 self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3425 }
3426
3427 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3428 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3429 self.coroutine_kind(def_id)
3430 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3431 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3432 {
3433 true
3434 } else {
3435 false
3436 }
3437 }
3438
3439 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3441 self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3442 }
3443
3444 pub fn is_entrypoint(self, def_id: DefId) -> bool {
3447 if self.is_lang_item(def_id, LangItem::Start) {
3448 return true;
3449 }
3450 if let Some((entry_def_id, _)) = self.entry_fn(())
3451 && entry_def_id == def_id
3452 {
3453 return true;
3454 }
3455 false
3456 }
3457}
3458
3459#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3468pub struct DeducedParamAttrs {
3469 pub read_only: bool,
3472}
3473
3474pub fn provide(providers: &mut Providers) {
3475 providers.is_panic_runtime =
3476 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3477 providers.is_compiler_builtins =
3478 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3479 providers.has_panic_handler = |tcx, LocalCrate| {
3480 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3482 };
3483 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3484}
3485
3486pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3487 attrs.iter().any(|x| x.has_name(name))
3488}