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, CtorOf, 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::BoundConst;
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_ref = ty::TraitRef::from_assoc(self, trait_def_id, args);
294 (trait_ref, &args[trait_ref.args.len()..])
295 }
296
297 fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
298 self.mk_args(args)
299 }
300
301 fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
302 where
303 I: Iterator<Item = T>,
304 T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
305 {
306 self.mk_args_from_iter(args)
307 }
308
309 fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
310 self.check_args_compatible(def_id, args)
311 }
312
313 fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
314 self.debug_assert_args_compatible(def_id, args);
315 }
316
317 fn debug_assert_existential_args_compatible(
321 self,
322 def_id: Self::DefId,
323 args: Self::GenericArgs,
324 ) {
325 if cfg!(debug_assertions) {
328 self.debug_assert_args_compatible(
329 def_id,
330 self.mk_args_from_iter(
331 [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
332 ),
333 );
334 }
335 }
336
337 fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
338 where
339 I: Iterator<Item = T>,
340 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
341 {
342 self.mk_type_list_from_iter(args)
343 }
344
345 fn parent(self, def_id: DefId) -> DefId {
346 self.parent(def_id)
347 }
348
349 fn recursion_limit(self) -> usize {
350 self.recursion_limit().0
351 }
352
353 type Features = &'tcx rustc_feature::Features;
354
355 fn features(self) -> Self::Features {
356 self.features()
357 }
358
359 fn coroutine_hidden_types(
360 self,
361 def_id: DefId,
362 ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> {
363 self.coroutine_hidden_types(def_id)
364 }
365
366 fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
367 self.fn_sig(def_id)
368 }
369
370 fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
371 self.coroutine_movability(def_id)
372 }
373
374 fn coroutine_for_closure(self, def_id: DefId) -> DefId {
375 self.coroutine_for_closure(def_id)
376 }
377
378 fn generics_require_sized_self(self, def_id: DefId) -> bool {
379 self.generics_require_sized_self(def_id)
380 }
381
382 fn item_bounds(
383 self,
384 def_id: DefId,
385 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
386 self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
387 }
388
389 fn item_self_bounds(
390 self,
391 def_id: DefId,
392 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
393 self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
394 }
395
396 fn item_non_self_bounds(
397 self,
398 def_id: DefId,
399 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
400 self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
401 }
402
403 fn predicates_of(
404 self,
405 def_id: DefId,
406 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
407 ty::EarlyBinder::bind(
408 self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
409 )
410 }
411
412 fn own_predicates_of(
413 self,
414 def_id: DefId,
415 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
416 ty::EarlyBinder::bind(
417 self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
418 )
419 }
420
421 fn explicit_super_predicates_of(
422 self,
423 def_id: DefId,
424 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
425 self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
426 }
427
428 fn explicit_implied_predicates_of(
429 self,
430 def_id: DefId,
431 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
432 self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
433 }
434
435 fn impl_super_outlives(
436 self,
437 impl_def_id: DefId,
438 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
439 self.impl_super_outlives(impl_def_id)
440 }
441
442 fn impl_is_const(self, def_id: DefId) -> bool {
443 debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
444 self.is_conditionally_const(def_id)
445 }
446
447 fn fn_is_const(self, def_id: DefId) -> bool {
448 debug_assert_matches!(
449 self.def_kind(def_id),
450 DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
451 );
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 rustc_middle::hir::Hashes { 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 type Id = HirId;
1425
1426 fn emit_node_span_lint(
1427 self,
1428 lint: &'static Lint,
1429 hir_id: HirId,
1430 span: impl Into<MultiSpan>,
1431 decorator: impl for<'a> LintDiagnostic<'a, ()>,
1432 ) {
1433 self.emit_node_span_lint(lint, hir_id, span, decorator);
1434 }
1435}
1436
1437unsafe impl DynSend for TyCtxt<'_> {}
1441unsafe impl DynSync for TyCtxt<'_> {}
1442fn _assert_tcx_fields() {
1443 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1444 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1445}
1446
1447impl<'tcx> Deref for TyCtxt<'tcx> {
1448 type Target = &'tcx GlobalCtxt<'tcx>;
1449 #[inline(always)]
1450 fn deref(&self) -> &Self::Target {
1451 &self.gcx
1452 }
1453}
1454
1455pub struct GlobalCtxt<'tcx> {
1457 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1458 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1459
1460 interners: CtxtInterners<'tcx>,
1461
1462 pub sess: &'tcx Session,
1463 crate_types: Vec<CrateType>,
1464 stable_crate_id: StableCrateId,
1470
1471 pub dep_graph: DepGraph,
1472
1473 pub prof: SelfProfilerRef,
1474
1475 pub types: CommonTypes<'tcx>,
1477
1478 pub lifetimes: CommonLifetimes<'tcx>,
1480
1481 pub consts: CommonConsts<'tcx>,
1483
1484 pub(crate) hooks: crate::hooks::Providers,
1487
1488 untracked: Untracked,
1489
1490 pub query_system: QuerySystem<'tcx>,
1491 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1492
1493 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1495
1496 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1499
1500 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1504
1505 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1507 pub new_solver_canonical_param_env_cache:
1508 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
1509
1510 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1511
1512 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
1514 pub clauses_cache:
1516 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
1517
1518 pub data_layout: TargetDataLayout,
1520
1521 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1523
1524 current_gcx: CurrentGcx,
1525
1526 pub jobserver_proxy: Arc<Proxy>,
1528}
1529
1530impl<'tcx> GlobalCtxt<'tcx> {
1531 pub fn enter<F, R>(&'tcx self, f: F) -> R
1534 where
1535 F: FnOnce(TyCtxt<'tcx>) -> R,
1536 {
1537 let icx = tls::ImplicitCtxt::new(self);
1538
1539 let _on_drop = defer(move || {
1541 *self.current_gcx.value.write() = None;
1542 });
1543
1544 {
1546 let mut guard = self.current_gcx.value.write();
1547 assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1548 *guard = Some(self as *const _ as *const ());
1549 }
1550
1551 tls::enter_context(&icx, || f(icx.tcx))
1552 }
1553}
1554
1555#[derive(Clone)]
1562pub struct CurrentGcx {
1563 value: Arc<RwLock<Option<*const ()>>>,
1566}
1567
1568unsafe impl DynSend for CurrentGcx {}
1569unsafe impl DynSync for CurrentGcx {}
1570
1571impl CurrentGcx {
1572 pub fn new() -> Self {
1573 Self { value: Arc::new(RwLock::new(None)) }
1574 }
1575
1576 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1577 let read_guard = self.value.read();
1578 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1579 f(unsafe { &*gcx })
1583 }
1584}
1585
1586impl<'tcx> TyCtxt<'tcx> {
1587 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1588 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1591 if typeck_root_def_id != def_id.to_def_id() {
1592 return self.has_typeck_results(typeck_root_def_id.expect_local());
1593 }
1594
1595 self.hir_node_by_def_id(def_id).body_id().is_some()
1596 }
1597
1598 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1603 let def_kind = self.def_kind(def_id);
1604 if def_kind.has_codegen_attrs() {
1605 self.codegen_fn_attrs(def_id)
1606 } else if matches!(
1607 def_kind,
1608 DefKind::AnonConst
1609 | DefKind::AssocConst
1610 | DefKind::Const
1611 | DefKind::InlineConst
1612 | DefKind::GlobalAsm
1613 ) {
1614 CodegenFnAttrs::EMPTY
1615 } else {
1616 bug!(
1617 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1618 def_id,
1619 def_kind
1620 )
1621 }
1622 }
1623
1624 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1625 self.arena.alloc(Steal::new(thir))
1626 }
1627
1628 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1629 self.arena.alloc(Steal::new(mir))
1630 }
1631
1632 pub fn alloc_steal_promoted(
1633 self,
1634 promoted: IndexVec<Promoted, Body<'tcx>>,
1635 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1636 self.arena.alloc(Steal::new(promoted))
1637 }
1638
1639 pub fn mk_adt_def(
1640 self,
1641 did: DefId,
1642 kind: AdtKind,
1643 variants: IndexVec<VariantIdx, ty::VariantDef>,
1644 repr: ReprOptions,
1645 ) -> ty::AdtDef<'tcx> {
1646 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1647 }
1648
1649 pub fn allocate_bytes_dedup<'a>(
1652 self,
1653 bytes: impl Into<Cow<'a, [u8]>>,
1654 salt: usize,
1655 ) -> interpret::AllocId {
1656 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
1658 let alloc = self.mk_const_alloc(alloc);
1659 self.reserve_and_set_memory_dedup(alloc, salt)
1660 }
1661
1662 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1664 if self.sess.opts.unstable_opts.experimental_default_bounds {
1665 &[
1666 LangItem::DefaultTrait1,
1667 LangItem::DefaultTrait2,
1668 LangItem::DefaultTrait3,
1669 LangItem::DefaultTrait4,
1670 ]
1671 } else {
1672 &[]
1673 }
1674 }
1675
1676 pub fn is_default_trait(self, def_id: DefId) -> bool {
1677 self.default_traits()
1678 .iter()
1679 .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
1680 }
1681
1682 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1686 let start = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1687 let end = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1688 (start, end)
1689 }
1690
1691 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1692 value.lift_to_interner(self)
1693 }
1694
1695 pub fn create_global_ctxt<T>(
1702 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1703 s: &'tcx Session,
1704 crate_types: Vec<CrateType>,
1705 stable_crate_id: StableCrateId,
1706 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1707 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1708 untracked: Untracked,
1709 dep_graph: DepGraph,
1710 query_kinds: &'tcx [DepKindStruct<'tcx>],
1711 query_system: QuerySystem<'tcx>,
1712 hooks: crate::hooks::Providers,
1713 current_gcx: CurrentGcx,
1714 jobserver_proxy: Arc<Proxy>,
1715 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1716 ) -> T {
1717 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1718 s.dcx().emit_fatal(err);
1719 });
1720 let interners = CtxtInterners::new(arena);
1721 let common_types = CommonTypes::new(&interners, s, &untracked);
1722 let common_lifetimes = CommonLifetimes::new(&interners);
1723 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1724
1725 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1726 sess: s,
1727 crate_types,
1728 stable_crate_id,
1729 arena,
1730 hir_arena,
1731 interners,
1732 dep_graph,
1733 hooks,
1734 prof: s.prof.clone(),
1735 types: common_types,
1736 lifetimes: common_lifetimes,
1737 consts: common_consts,
1738 untracked,
1739 query_system,
1740 query_kinds,
1741 ty_rcache: Default::default(),
1742 selection_cache: Default::default(),
1743 evaluation_cache: Default::default(),
1744 new_solver_evaluation_cache: Default::default(),
1745 new_solver_canonical_param_env_cache: Default::default(),
1746 canonical_param_env_cache: Default::default(),
1747 highest_var_in_clauses_cache: Default::default(),
1748 clauses_cache: Default::default(),
1749 data_layout,
1750 alloc_map: interpret::AllocMap::new(),
1751 current_gcx,
1752 jobserver_proxy,
1753 });
1754
1755 gcx.enter(f)
1757 }
1758
1759 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1761 self.get_lang_items(())
1762 }
1763
1764 #[track_caller]
1766 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1767 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1768 self.type_of(ordering_enum).no_bound_vars().unwrap()
1769 }
1770
1771 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1774 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1775 }
1776
1777 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1779 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1780 }
1781
1782 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1784 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1785 }
1786
1787 pub fn is_coroutine(self, def_id: DefId) -> bool {
1788 self.coroutine_kind(def_id).is_some()
1789 }
1790
1791 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1792 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1793 }
1794
1795 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1798 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1799 }
1800
1801 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1803 matches!(
1804 self.coroutine_kind(def_id),
1805 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1806 )
1807 }
1808
1809 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1812 matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1813 }
1814
1815 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1818 matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1819 }
1820
1821 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1823 matches!(
1824 self.coroutine_kind(def_id),
1825 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1826 )
1827 }
1828
1829 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1831 matches!(
1832 self.coroutine_kind(def_id),
1833 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1834 )
1835 }
1836
1837 pub fn features(self) -> &'tcx rustc_feature::Features {
1838 self.features_query(())
1839 }
1840
1841 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1842 let id = id.into_query_param();
1843 if let Some(id) = id.as_local() {
1845 self.definitions_untracked().def_key(id)
1846 } else {
1847 self.cstore_untracked().def_key(id)
1848 }
1849 }
1850
1851 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1857 if let Some(id) = id.as_local() {
1859 self.definitions_untracked().def_path(id)
1860 } else {
1861 self.cstore_untracked().def_path(id)
1862 }
1863 }
1864
1865 #[inline]
1866 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1867 if let Some(def_id) = def_id.as_local() {
1869 self.definitions_untracked().def_path_hash(def_id)
1870 } else {
1871 self.cstore_untracked().def_path_hash(def_id)
1872 }
1873 }
1874
1875 #[inline]
1876 pub fn crate_types(self) -> &'tcx [CrateType] {
1877 &self.crate_types
1878 }
1879
1880 pub fn needs_metadata(self) -> bool {
1881 self.crate_types().iter().any(|ty| match *ty {
1882 CrateType::Executable
1883 | CrateType::Staticlib
1884 | CrateType::Cdylib
1885 | CrateType::Sdylib => false,
1886 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1887 })
1888 }
1889
1890 pub fn needs_crate_hash(self) -> bool {
1891 cfg!(debug_assertions)
1903 || self.sess.opts.incremental.is_some()
1904 || self.needs_metadata()
1905 || self.sess.instrument_coverage()
1906 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1907 }
1908
1909 #[inline]
1910 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1911 if crate_num == LOCAL_CRATE {
1912 self.stable_crate_id
1913 } else {
1914 self.cstore_untracked().stable_crate_id(crate_num)
1915 }
1916 }
1917
1918 #[inline]
1921 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1922 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1923 LOCAL_CRATE
1924 } else {
1925 *self
1926 .untracked()
1927 .stable_crate_ids
1928 .read()
1929 .get(&stable_crate_id)
1930 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1931 }
1932 }
1933
1934 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1938 debug!("def_path_hash_to_def_id({:?})", hash);
1939
1940 let stable_crate_id = hash.stable_crate_id();
1941
1942 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1945 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1946 } else {
1947 Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
1948 }
1949 }
1950
1951 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1952 let (crate_name, stable_crate_id) = if def_id.is_local() {
1957 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1958 } else {
1959 let cstore = &*self.cstore_untracked();
1960 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1961 };
1962
1963 format!(
1964 "{}[{:04x}]{}",
1965 crate_name,
1966 stable_crate_id.as_u64() >> (8 * 6),
1969 self.def_path(def_id).to_string_no_crate_verbose()
1970 )
1971 }
1972
1973 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1974 self.sess.dcx()
1975 }
1976
1977 pub fn is_target_feature_call_safe(
1978 self,
1979 callee_features: &[TargetFeature],
1980 body_features: &[TargetFeature],
1981 ) -> bool {
1982 self.sess.target.options.is_like_wasm
1987 || callee_features
1988 .iter()
1989 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1990 }
1991
1992 pub fn adjust_target_feature_sig(
1995 self,
1996 fun_def: DefId,
1997 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1998 caller: DefId,
1999 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
2000 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
2001 let callee_features = &self.codegen_fn_attrs(caller).target_features;
2002 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
2003 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
2004 }
2005 None
2006 }
2007
2008 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
2011 match self.env_var_os(key.as_ref()) {
2012 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
2013 None => Err(VarError::NotPresent),
2014 }
2015 }
2016}
2017
2018impl<'tcx> TyCtxtAt<'tcx> {
2019 pub fn create_def(
2021 self,
2022 parent: LocalDefId,
2023 name: Option<Symbol>,
2024 def_kind: DefKind,
2025 override_def_path_data: Option<DefPathData>,
2026 disambiguator: &mut DisambiguatorState,
2027 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2028 let feed =
2029 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
2030
2031 feed.def_span(self.span);
2032 feed
2033 }
2034}
2035
2036impl<'tcx> TyCtxt<'tcx> {
2037 pub fn create_def(
2039 self,
2040 parent: LocalDefId,
2041 name: Option<Symbol>,
2042 def_kind: DefKind,
2043 override_def_path_data: Option<DefPathData>,
2044 disambiguator: &mut DisambiguatorState,
2045 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2046 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2047 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2057
2058 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2063
2064 let feed = TyCtxtFeed { tcx: self, key: def_id };
2065 feed.def_kind(def_kind);
2066 if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2071 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2072 feed.visibility(ty::Visibility::Restricted(parent_mod));
2073 }
2074
2075 feed
2076 }
2077
2078 pub fn create_crate_num(
2079 self,
2080 stable_crate_id: StableCrateId,
2081 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2082 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2083 return Err(existing);
2084 }
2085
2086 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2087 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2088 Ok(TyCtxtFeed { key: num, tcx: self })
2089 }
2090
2091 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2092 self.ensure_ok().analysis(());
2094
2095 let definitions = &self.untracked.definitions;
2096 gen {
2097 let mut i = 0;
2098
2099 while i < { definitions.read().num_definitions() } {
2102 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2103 yield LocalDefId { local_def_index };
2104 i += 1;
2105 }
2106
2107 definitions.freeze();
2109 }
2110 }
2111
2112 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2113 self.ensure_ok().analysis(());
2115
2116 self.untracked.definitions.freeze().def_path_table()
2119 }
2120
2121 pub fn def_path_hash_to_def_index_map(
2122 self,
2123 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2124 self.ensure_ok().hir_crate_items(());
2127 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2130 }
2131
2132 #[inline]
2135 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2136 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2137 }
2138
2139 pub fn untracked(self) -> &'tcx Untracked {
2141 &self.untracked
2142 }
2143 #[inline]
2146 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2147 self.untracked.definitions.read()
2148 }
2149
2150 #[inline]
2153 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2154 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2155 }
2156
2157 #[inline(always)]
2158 pub fn with_stable_hashing_context<R>(
2159 self,
2160 f: impl FnOnce(StableHashingContext<'_>) -> R,
2161 ) -> R {
2162 f(StableHashingContext::new(self.sess, &self.untracked))
2163 }
2164
2165 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2166 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2167 }
2168
2169 #[inline]
2170 pub fn local_crate_exports_generics(self) -> bool {
2171 self.crate_types().iter().any(|crate_type| {
2172 match crate_type {
2173 CrateType::Executable
2174 | CrateType::Staticlib
2175 | CrateType::ProcMacro
2176 | CrateType::Cdylib
2177 | CrateType::Sdylib => false,
2178
2179 CrateType::Dylib => true,
2184
2185 CrateType::Rlib => true,
2186 }
2187 })
2188 }
2189
2190 pub fn is_suitable_region(
2192 self,
2193 generic_param_scope: LocalDefId,
2194 mut region: Region<'tcx>,
2195 ) -> Option<FreeRegionInfo> {
2196 let (suitable_region_binding_scope, region_def_id) = loop {
2197 let def_id =
2198 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2199 let scope = self.local_parent(def_id);
2200 if self.def_kind(scope) == DefKind::OpaqueTy {
2201 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2204 continue;
2205 }
2206 break (scope, def_id.into());
2207 };
2208
2209 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2210 Node::Item(..) | Node::TraitItem(..) => false,
2211 Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2212 _ => false,
2213 };
2214
2215 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2216 }
2217
2218 pub fn return_type_impl_or_dyn_traits(
2220 self,
2221 scope_def_id: LocalDefId,
2222 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2223 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2224 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2225 self.hir_fn_decl_by_hir_id(hir_id)
2226 else {
2227 return vec![];
2228 };
2229
2230 let mut v = TraitObjectVisitor(vec![]);
2231 v.visit_ty_unambig(hir_output);
2232 v.0
2233 }
2234
2235 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2239 self,
2240 scope_def_id: LocalDefId,
2241 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2242 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2243 let mut v = TraitObjectVisitor(vec![]);
2244 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2246 && let hir::TyKind::Path(hir::QPath::Resolved(
2247 None,
2248 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2249 && let Some(local_id) = def_id.as_local()
2250 && 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()
2252 {
2253 v.visit_ty_unambig(alias_ty);
2254 if !v.0.is_empty() {
2255 return Some((
2256 v.0,
2257 alias_generics.span,
2258 alias_generics.span_for_lifetime_suggestion(),
2259 ));
2260 }
2261 }
2262 None
2263 }
2264
2265 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2267 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2268 if self.impl_trait_ref(container_id).is_some() {
2269 return true;
2276 }
2277 false
2278 }
2279
2280 pub fn has_strict_asm_symbol_naming(self) -> bool {
2283 self.sess.target.arch.contains("nvptx")
2284 }
2285
2286 pub fn caller_location_ty(self) -> Ty<'tcx> {
2288 Ty::new_imm_ref(
2289 self,
2290 self.lifetimes.re_static,
2291 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2292 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2293 )
2294 }
2295
2296 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2298 let kind = self.def_kind(def_id);
2299 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2300 }
2301
2302 pub fn type_length_limit(self) -> Limit {
2303 self.limits(()).type_length_limit
2304 }
2305
2306 pub fn recursion_limit(self) -> Limit {
2307 self.limits(()).recursion_limit
2308 }
2309
2310 pub fn move_size_limit(self) -> Limit {
2311 self.limits(()).move_size_limit
2312 }
2313
2314 pub fn pattern_complexity_limit(self) -> Limit {
2315 self.limits(()).pattern_complexity_limit
2316 }
2317
2318 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
2320 iter::once(LOCAL_CRATE)
2321 .chain(self.crates(()).iter().copied())
2322 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2323 }
2324
2325 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2327 let visible_crates =
2328 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2329
2330 iter::once(LOCAL_CRATE)
2331 .chain(visible_crates)
2332 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2333 }
2334
2335 #[inline]
2336 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2337 self.visibility(def_id).expect_local()
2338 }
2339
2340 #[instrument(skip(self), level = "trace", ret)]
2342 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2343 self.hir_expect_opaque_ty(def_id).origin
2344 }
2345
2346 pub fn finish(self) {
2347 self.alloc_self_profile_query_strings();
2350
2351 self.save_dep_graph();
2352 self.query_key_hash_verify_all();
2353
2354 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2355 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2356 }
2357 }
2358}
2359
2360macro_rules! nop_lift {
2361 ($set:ident; $ty:ty => $lifted:ty) => {
2362 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2363 type Lifted = $lifted;
2364 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2365 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2370 _x: Interned<'tcx, Inner>,
2371 ) -> InternedSet<'tcx, Inner> {
2372 unreachable!()
2373 }
2374 fn _type_eq<T>(_x: &T, _y: &T) {}
2375 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2376 let interner = _intern_set_ty_from_interned_ty(x.0);
2380 _type_eq(&interner, &tcx.interners.$set);
2382 }
2383
2384 tcx.interners
2385 .$set
2386 .contains_pointer_to(&InternedInSet(&*self.0.0))
2387 .then(|| unsafe { mem::transmute(self) })
2390 }
2391 }
2392 };
2393}
2394
2395macro_rules! nop_list_lift {
2396 ($set:ident; $ty:ty => $lifted:ty) => {
2397 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2398 type Lifted = &'tcx List<$lifted>;
2399 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2400 if false {
2402 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2403 }
2404
2405 if self.is_empty() {
2406 return Some(List::empty());
2407 }
2408 tcx.interners
2409 .$set
2410 .contains_pointer_to(&InternedInSet(self))
2411 .then(|| unsafe { mem::transmute(self) })
2412 }
2413 }
2414 };
2415}
2416
2417nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2418nop_lift! { region; Region<'a> => Region<'tcx> }
2419nop_lift! { const_; Const<'a> => Const<'tcx> }
2420nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2421nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2422nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2423nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2424nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2425nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2426
2427nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2428nop_list_lift! {
2429 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2430}
2431nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2432
2433nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2435
2436macro_rules! sty_debug_print {
2437 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2438 #[allow(non_snake_case)]
2441 mod inner {
2442 use crate::ty::{self, TyCtxt};
2443 use crate::ty::context::InternedInSet;
2444
2445 #[derive(Copy, Clone)]
2446 struct DebugStat {
2447 total: usize,
2448 lt_infer: usize,
2449 ty_infer: usize,
2450 ct_infer: usize,
2451 all_infer: usize,
2452 }
2453
2454 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2455 let mut total = DebugStat {
2456 total: 0,
2457 lt_infer: 0,
2458 ty_infer: 0,
2459 ct_infer: 0,
2460 all_infer: 0,
2461 };
2462 $(let mut $variant = total;)*
2463
2464 for shard in tcx.interners.type_.lock_shards() {
2465 #[allow(rustc::potential_query_instability)]
2467 let types = shard.iter();
2468 for &(InternedInSet(t), ()) in types {
2469 let variant = match t.internee {
2470 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2471 ty::Float(..) | ty::Str | ty::Never => continue,
2472 ty::Error(_) => continue,
2473 $(ty::$variant(..) => &mut $variant,)*
2474 };
2475 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2476 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2477 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2478
2479 variant.total += 1;
2480 total.total += 1;
2481 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2482 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2483 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2484 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2485 }
2486 }
2487 writeln!(fmt, "Ty interner total ty lt ct all")?;
2488 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2489 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2490 stringify!($variant),
2491 uses = $variant.total,
2492 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2493 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2494 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2495 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2496 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2497 )*
2498 writeln!(fmt, " total {uses:6} \
2499 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2500 uses = total.total,
2501 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2502 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2503 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2504 all = total.all_infer as f64 * 100.0 / total.total as f64)
2505 }
2506 }
2507
2508 inner::go($fmt, $ctxt)
2509 }}
2510}
2511
2512impl<'tcx> TyCtxt<'tcx> {
2513 pub fn debug_stats(self) -> impl fmt::Debug {
2514 fmt::from_fn(move |fmt| {
2515 sty_debug_print!(
2516 fmt,
2517 self,
2518 Adt,
2519 Array,
2520 Slice,
2521 RawPtr,
2522 Ref,
2523 FnDef,
2524 FnPtr,
2525 UnsafeBinder,
2526 Placeholder,
2527 Coroutine,
2528 CoroutineWitness,
2529 Dynamic,
2530 Closure,
2531 CoroutineClosure,
2532 Tuple,
2533 Bound,
2534 Param,
2535 Infer,
2536 Alias,
2537 Pat,
2538 Foreign
2539 )?;
2540
2541 writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2542 writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2543 writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2544 writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2545
2546 Ok(())
2547 })
2548 }
2549}
2550
2551struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2556
2557impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2558 fn clone(&self) -> Self {
2559 InternedInSet(self.0)
2560 }
2561}
2562
2563impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2564
2565impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2566 fn into_pointer(&self) -> *const () {
2567 self.0 as *const _ as *const ()
2568 }
2569}
2570
2571#[allow(rustc::usage_of_ty_tykind)]
2572impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2573 fn borrow(&self) -> &T {
2574 &self.0.internee
2575 }
2576}
2577
2578impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2579 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2580 self.0.internee == other.0.internee
2583 }
2584}
2585
2586impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2587
2588impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2589 fn hash<H: Hasher>(&self, s: &mut H) {
2590 self.0.internee.hash(s)
2592 }
2593}
2594
2595impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2596 fn borrow(&self) -> &[T] {
2597 &self.0[..]
2598 }
2599}
2600
2601impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2602 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2603 self.0[..] == other.0[..]
2606 }
2607}
2608
2609impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2610
2611impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2612 fn hash<H: Hasher>(&self, s: &mut H) {
2613 self.0[..].hash(s)
2615 }
2616}
2617
2618impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2619 fn borrow(&self) -> &[T] {
2620 &self.0[..]
2621 }
2622}
2623
2624impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2625 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2626 self.0[..] == other.0[..]
2629 }
2630}
2631
2632impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2633
2634impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2635 fn hash<H: Hasher>(&self, s: &mut H) {
2636 self.0[..].hash(s)
2638 }
2639}
2640
2641macro_rules! direct_interners {
2642 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2643 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2644 fn borrow<'a>(&'a self) -> &'a $ty {
2645 &self.0
2646 }
2647 }
2648
2649 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2650 fn eq(&self, other: &Self) -> bool {
2651 self.0 == other.0
2654 }
2655 }
2656
2657 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2658
2659 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2660 fn hash<H: Hasher>(&self, s: &mut H) {
2661 self.0.hash(s)
2664 }
2665 }
2666
2667 impl<'tcx> TyCtxt<'tcx> {
2668 $vis fn $method(self, v: $ty) -> $ret_ty {
2669 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2670 InternedInSet(self.interners.arena.alloc(v))
2671 }).0))
2672 }
2673 })+
2674 }
2675}
2676
2677direct_interners! {
2681 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2682 valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2683 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2684 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2685 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2686 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2687 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2688 ExternalConstraints -> ExternalConstraints<'tcx>,
2689 predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2690 PredefinedOpaques -> PredefinedOpaques<'tcx>,
2691}
2692
2693macro_rules! slice_interners {
2694 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2695 impl<'tcx> TyCtxt<'tcx> {
2696 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2697 if v.is_empty() {
2698 List::empty()
2699 } else {
2700 self.interners.$field.intern_ref(v, || {
2701 InternedInSet(List::from_arena(&*self.arena, (), v))
2702 }).0
2703 }
2704 })+
2705 }
2706 );
2707}
2708
2709slice_interners!(
2713 const_lists: pub mk_const_list(Const<'tcx>),
2714 args: pub mk_args(GenericArg<'tcx>),
2715 type_lists: pub mk_type_list(Ty<'tcx>),
2716 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2717 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2718 projs: pub mk_projs(ProjectionKind),
2719 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2720 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2721 fields: pub mk_fields(FieldIdx),
2722 local_def_ids: intern_local_def_ids(LocalDefId),
2723 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2724 offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2725 patterns: pub mk_patterns(Pattern<'tcx>),
2726 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2727);
2728
2729impl<'tcx> TyCtxt<'tcx> {
2730 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2734 assert!(sig.safety().is_safe());
2735 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2736 }
2737
2738 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2741 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2742 self.associated_items(trait_did)
2743 .filter_by_name_unhygienic(assoc_name.name)
2744 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2745 })
2746 }
2747
2748 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2750 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2751 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2752
2753 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2754 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2755 return false;
2756 };
2757 trait_predicate.trait_ref.def_id == future_trait
2758 && trait_predicate.polarity == PredicatePolarity::Positive
2759 })
2760 }
2761
2762 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2770 sig.map_bound(|s| {
2771 let params = match s.inputs()[0].kind() {
2772 ty::Tuple(params) => *params,
2773 _ => bug!(),
2774 };
2775 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2776 })
2777 }
2778
2779 #[inline]
2780 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2781 self.interners.intern_predicate(
2782 binder,
2783 self.sess,
2784 &self.untracked,
2786 )
2787 }
2788
2789 #[inline]
2790 pub fn reuse_or_mk_predicate(
2791 self,
2792 pred: Predicate<'tcx>,
2793 binder: Binder<'tcx, PredicateKind<'tcx>>,
2794 ) -> Predicate<'tcx> {
2795 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2796 }
2797
2798 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2799 self.check_args_compatible_inner(def_id, args, false)
2800 }
2801
2802 fn check_args_compatible_inner(
2803 self,
2804 def_id: DefId,
2805 args: &'tcx [ty::GenericArg<'tcx>],
2806 nested: bool,
2807 ) -> bool {
2808 let generics = self.generics_of(def_id);
2809
2810 let own_args = if !nested
2813 && let DefKind::AssocTy = self.def_kind(def_id)
2814 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2815 {
2816 if generics.own_params.len() + 1 != args.len() {
2817 return false;
2818 }
2819
2820 if !matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2821 return false;
2822 }
2823
2824 &args[1..]
2825 } else {
2826 if generics.count() != args.len() {
2827 return false;
2828 }
2829
2830 let (parent_args, own_args) = args.split_at(generics.parent_count);
2831
2832 if let Some(parent) = generics.parent
2833 && !self.check_args_compatible_inner(parent, parent_args, true)
2834 {
2835 return false;
2836 }
2837
2838 own_args
2839 };
2840
2841 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2842 match (¶m.kind, arg.kind()) {
2843 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2844 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2845 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2846 _ => return false,
2847 }
2848 }
2849
2850 true
2851 }
2852
2853 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2856 if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2857 if let DefKind::AssocTy = self.def_kind(def_id)
2858 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2859 {
2860 bug!(
2861 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2862 self.def_path_str(def_id),
2863 args,
2864 self.mk_args_from_iter(
2866 [self.types.self_param.into()].into_iter().chain(
2867 self.generics_of(def_id)
2868 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2869 .iter()
2870 .copied()
2871 )
2872 )
2873 );
2874 } else {
2875 bug!(
2876 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2877 self.def_path_str(def_id),
2878 args,
2879 ty::GenericArgs::identity_for_item(self, def_id)
2880 );
2881 }
2882 }
2883 }
2884
2885 #[inline(always)]
2886 pub(crate) fn check_and_mk_args(
2887 self,
2888 def_id: DefId,
2889 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2890 ) -> GenericArgsRef<'tcx> {
2891 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2892 self.debug_assert_args_compatible(def_id, args);
2893 args
2894 }
2895
2896 #[inline]
2897 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2898 self.interners.intern_const(
2899 kind,
2900 self.sess,
2901 &self.untracked,
2903 )
2904 }
2905
2906 #[allow(rustc::usage_of_ty_tykind)]
2908 #[inline]
2909 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2910 self.interners.intern_ty(
2911 st,
2912 self.sess,
2913 &self.untracked,
2915 )
2916 }
2917
2918 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2919 match param.kind {
2920 GenericParamDefKind::Lifetime => {
2921 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2922 }
2923 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2924 GenericParamDefKind::Const { .. } => {
2925 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2926 .into()
2927 }
2928 }
2929 }
2930
2931 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2932 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2933 }
2934
2935 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2936 self.mk_place_elem(place, PlaceElem::Deref)
2937 }
2938
2939 pub fn mk_place_downcast(
2940 self,
2941 place: Place<'tcx>,
2942 adt_def: AdtDef<'tcx>,
2943 variant_index: VariantIdx,
2944 ) -> Place<'tcx> {
2945 self.mk_place_elem(
2946 place,
2947 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2948 )
2949 }
2950
2951 pub fn mk_place_downcast_unnamed(
2952 self,
2953 place: Place<'tcx>,
2954 variant_index: VariantIdx,
2955 ) -> Place<'tcx> {
2956 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2957 }
2958
2959 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2960 self.mk_place_elem(place, PlaceElem::Index(index))
2961 }
2962
2963 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2967 let mut projection = place.projection.to_vec();
2968 projection.push(elem);
2969
2970 Place { local: place.local, projection: self.mk_place_elems(&projection) }
2971 }
2972
2973 pub fn mk_poly_existential_predicates(
2974 self,
2975 eps: &[PolyExistentialPredicate<'tcx>],
2976 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2977 assert!(!eps.is_empty());
2978 assert!(
2979 eps.array_windows()
2980 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2981 != Ordering::Greater)
2982 );
2983 self.intern_poly_existential_predicates(eps)
2984 }
2985
2986 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2987 self.interners.intern_clauses(clauses)
2991 }
2992
2993 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2994 self.intern_local_def_ids(def_ids)
2998 }
2999
3000 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
3001 where
3002 I: Iterator<Item = T>,
3003 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
3004 {
3005 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
3006 }
3007
3008 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
3009 where
3010 I: Iterator<Item = T>,
3011 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
3012 {
3013 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
3014 }
3015
3016 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
3017 where
3018 I: Iterator<Item = T>,
3019 T: CollectAndApply<
3020 &'tcx ty::CapturedPlace<'tcx>,
3021 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
3022 >,
3023 {
3024 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
3025 }
3026
3027 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
3028 where
3029 I: Iterator<Item = T>,
3030 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
3031 {
3032 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3033 }
3034
3035 pub fn mk_fn_sig<I, T>(
3040 self,
3041 inputs: I,
3042 output: I::Item,
3043 c_variadic: bool,
3044 safety: hir::Safety,
3045 abi: ExternAbi,
3046 ) -> T::Output
3047 where
3048 I: IntoIterator<Item = T>,
3049 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3050 {
3051 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3052 inputs_and_output: self.mk_type_list(xs),
3053 c_variadic,
3054 safety,
3055 abi,
3056 })
3057 }
3058
3059 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3060 where
3061 I: Iterator<Item = T>,
3062 T: CollectAndApply<
3063 PolyExistentialPredicate<'tcx>,
3064 &'tcx List<PolyExistentialPredicate<'tcx>>,
3065 >,
3066 {
3067 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3068 }
3069
3070 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3071 where
3072 I: Iterator<Item = T>,
3073 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3074 {
3075 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3076 }
3077
3078 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3079 where
3080 I: Iterator<Item = T>,
3081 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3082 {
3083 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3084 }
3085
3086 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3087 where
3088 I: Iterator<Item = T>,
3089 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3090 {
3091 T::collect_and_apply(iter, |xs| self.mk_args(xs))
3092 }
3093
3094 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3095 where
3096 I: Iterator<Item = T>,
3097 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3098 {
3099 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3100 }
3101
3102 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3103 where
3104 I: Iterator<Item = T>,
3105 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3106 {
3107 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3108 }
3109
3110 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3111 where
3112 I: Iterator<Item = T>,
3113 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3114 {
3115 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3116 }
3117
3118 pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
3119 where
3120 I: Iterator<Item = T>,
3121 T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
3122 {
3123 T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
3124 }
3125
3126 pub fn mk_args_trait(
3127 self,
3128 self_ty: Ty<'tcx>,
3129 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3130 ) -> GenericArgsRef<'tcx> {
3131 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3132 }
3133
3134 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3135 where
3136 I: Iterator<Item = T>,
3137 T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3138 {
3139 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3140 }
3141
3142 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
3143 where
3144 I: Iterator<Item = T>,
3145 T: CollectAndApply<
3146 ty::ArgOutlivesPredicate<'tcx>,
3147 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
3148 >,
3149 {
3150 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
3151 }
3152
3153 #[track_caller]
3156 pub fn emit_node_span_lint(
3157 self,
3158 lint: &'static Lint,
3159 hir_id: HirId,
3160 span: impl Into<MultiSpan>,
3161 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3162 ) {
3163 let level = self.lint_level_at_node(lint, hir_id);
3164 lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3165 decorator.decorate_lint(lint);
3166 })
3167 }
3168
3169 #[rustc_lint_diagnostics]
3173 #[track_caller]
3174 pub fn node_span_lint(
3175 self,
3176 lint: &'static Lint,
3177 hir_id: HirId,
3178 span: impl Into<MultiSpan>,
3179 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3180 ) {
3181 let level = self.lint_level_at_node(lint, hir_id);
3182 lint_level(self.sess, lint, level, Some(span.into()), decorate);
3183 }
3184
3185 pub fn crate_level_attribute_injection_span(self) -> Span {
3187 let node = self.hir_node(hir::CRATE_HIR_ID);
3188 let hir::Node::Crate(m) = node else { bug!() };
3189 m.spans.inject_use_span.shrink_to_lo()
3190 }
3191
3192 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3193 self,
3194 diag: &mut Diag<'_, E>,
3195 features: impl IntoIterator<Item = (String, Symbol)>,
3196 ) {
3197 if !self.sess.is_nightly_build() {
3198 return;
3199 }
3200
3201 let span = self.crate_level_attribute_injection_span();
3202 for (desc, feature) in features {
3203 let msg =
3205 format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3206 diag.span_suggestion_verbose(
3207 span,
3208 msg,
3209 format!("#![feature({feature})]\n"),
3210 Applicability::MaybeIncorrect,
3211 );
3212 }
3213 }
3214
3215 #[track_caller]
3218 pub fn emit_node_lint(
3219 self,
3220 lint: &'static Lint,
3221 id: HirId,
3222 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3223 ) {
3224 self.node_lint(lint, id, |lint| {
3225 decorator.decorate_lint(lint);
3226 })
3227 }
3228
3229 #[rustc_lint_diagnostics]
3233 #[track_caller]
3234 pub fn node_lint(
3235 self,
3236 lint: &'static Lint,
3237 id: HirId,
3238 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3239 ) {
3240 let level = self.lint_level_at_node(lint, id);
3241 lint_level(self.sess, lint, level, None, decorate);
3242 }
3243
3244 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3245 let map = self.in_scope_traits_map(id.owner)?;
3246 let candidates = map.get(&id.local_id)?;
3247 Some(candidates)
3248 }
3249
3250 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3251 debug!(?id, "named_region");
3252 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3253 }
3254
3255 pub fn is_late_bound(self, id: HirId) -> bool {
3256 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3257 }
3258
3259 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3260 self.mk_bound_variable_kinds(
3261 &self
3262 .late_bound_vars_map(id.owner)
3263 .get(&id.local_id)
3264 .cloned()
3265 .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3266 )
3267 }
3268
3269 pub fn map_opaque_lifetime_to_parent_lifetime(
3277 self,
3278 mut opaque_lifetime_param_def_id: LocalDefId,
3279 ) -> ty::Region<'tcx> {
3280 debug_assert!(
3281 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3282 "{opaque_lifetime_param_def_id:?} is a {}",
3283 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3284 );
3285
3286 loop {
3287 let parent = self.local_parent(opaque_lifetime_param_def_id);
3288 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3289
3290 let Some((lifetime, _)) = lifetime_mapping
3291 .iter()
3292 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3293 else {
3294 bug!("duplicated lifetime param should be present");
3295 };
3296
3297 match *lifetime {
3298 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3299 let new_parent = self.local_parent(ebv);
3300
3301 if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3304 debug_assert_eq!(self.local_parent(parent), new_parent);
3305 opaque_lifetime_param_def_id = ebv;
3306 continue;
3307 }
3308
3309 let generics = self.generics_of(new_parent);
3310 return ty::Region::new_early_param(
3311 self,
3312 ty::EarlyParamRegion {
3313 index: generics
3314 .param_def_id_to_index(self, ebv.to_def_id())
3315 .expect("early-bound var should be present in fn generics"),
3316 name: self.item_name(ebv.to_def_id()),
3317 },
3318 );
3319 }
3320 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3321 let new_parent = self.local_parent(lbv);
3322 return ty::Region::new_late_param(
3323 self,
3324 new_parent.to_def_id(),
3325 ty::LateParamRegionKind::Named(lbv.to_def_id()),
3326 );
3327 }
3328 resolve_bound_vars::ResolvedArg::Error(guar) => {
3329 return ty::Region::new_error(self, guar);
3330 }
3331 _ => {
3332 return ty::Region::new_error_with_message(
3333 self,
3334 self.def_span(opaque_lifetime_param_def_id),
3335 "cannot resolve lifetime",
3336 );
3337 }
3338 }
3339 }
3340 }
3341
3342 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3347 self.is_const_fn(def_id)
3348 && match self.lookup_const_stability(def_id) {
3349 None => true, Some(stability) if stability.is_const_stable() => true,
3351 _ => false,
3352 }
3353 }
3354
3355 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3357 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3358 && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3359 }
3360
3361 pub fn is_sdylib_interface_build(self) -> bool {
3362 self.sess.opts.unstable_opts.build_sdylib_interface
3363 }
3364
3365 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3366 match self.def_kind(def_id) {
3367 DefKind::Fn | DefKind::AssocFn => {}
3368 _ => return None,
3369 }
3370 self.intrinsic_raw(def_id)
3371 }
3372
3373 pub fn next_trait_solver_globally(self) -> bool {
3374 self.sess.opts.unstable_opts.next_solver.globally
3375 }
3376
3377 pub fn next_trait_solver_in_coherence(self) -> bool {
3378 self.sess.opts.unstable_opts.next_solver.coherence
3379 }
3380
3381 #[allow(rustc::bad_opt_access)]
3382 pub fn use_typing_mode_borrowck(self) -> bool {
3383 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3384 }
3385
3386 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3387 self.opt_rpitit_info(def_id).is_some()
3388 }
3389
3390 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3400 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3401 }
3402
3403 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
3405 self.resolutions(()).extern_crate_map.get(&def_id).copied()
3406 }
3407
3408 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3409 self.resolver_for_lowering_raw(()).0
3410 }
3411
3412 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
3413 crate::dep_graph::make_metadata(self)
3414 }
3415
3416 pub fn impl_trait_ref(
3419 self,
3420 def_id: impl IntoQueryParam<DefId>,
3421 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3422 Some(self.impl_trait_header(def_id)?.trait_ref)
3423 }
3424
3425 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3426 self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3427 }
3428
3429 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3430 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3431 self.coroutine_kind(def_id)
3432 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3433 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3434 {
3435 true
3436 } else {
3437 false
3438 }
3439 }
3440
3441 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3443 self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3444 }
3445
3446 pub fn is_entrypoint(self, def_id: DefId) -> bool {
3449 if self.is_lang_item(def_id, LangItem::Start) {
3450 return true;
3451 }
3452 if let Some((entry_def_id, _)) = self.entry_fn(())
3453 && entry_def_id == def_id
3454 {
3455 return true;
3456 }
3457 false
3458 }
3459}
3460
3461#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3470pub struct DeducedParamAttrs {
3471 pub read_only: bool,
3474}
3475
3476pub fn provide(providers: &mut Providers) {
3477 providers.is_panic_runtime =
3478 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3479 providers.is_compiler_builtins =
3480 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3481 providers.has_panic_handler = |tcx, LocalCrate| {
3482 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3484 };
3485 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3486}
3487
3488pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3489 attrs.iter().any(|x| x.has_name(name))
3490}