1#![allow(rustc::usage_of_ty_tykind)]
4
5pub mod tls;
6
7use std::assert_matches::debug_assert_matches;
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::{PhantomData, PointeeSized};
14use std::ops::{Bound, Deref};
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::fingerprint::Fingerprint;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::jobserver::Proxy;
25use rustc_data_structures::profiling::SelfProfilerRef;
26use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
27use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
28use rustc_data_structures::steal::Steal;
29use rustc_data_structures::sync::{
30 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
31};
32use rustc_errors::{
33 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, LintEmitter, MultiSpan,
34};
35use rustc_hir::attrs::AttributeKind;
36use rustc_hir::def::{CtorKind, DefKind};
37use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
38use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
39use rustc_hir::intravisit::VisitorExt;
40use rustc_hir::lang_items::LangItem;
41use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate, find_attr};
42use rustc_index::IndexVec;
43use rustc_macros::{HashStable, TyDecodable, TyEncodable};
44use rustc_query_system::cache::WithDepNode;
45use rustc_query_system::dep_graph::DepNodeIndex;
46use rustc_query_system::ich::StableHashingContext;
47use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
48use rustc_session::config::CrateType;
49use rustc_session::cstore::{CrateStoreDyn, Untracked};
50use rustc_session::lint::Lint;
51use rustc_session::{Limit, Session};
52use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
53use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
54use rustc_type_ir::TyKind::*;
55use rustc_type_ir::lang_items::TraitSolverLangItem;
56pub use rustc_type_ir::lift::Lift;
57use rustc_type_ir::{
58 CollectAndApply, Interner, TypeFlags, TypeFoldable, WithCachedTypeInfo, elaborate, search_graph,
59};
60use tracing::{debug, instrument};
61
62use crate::arena::Arena;
63use crate::dep_graph::{DepGraph, DepKindStruct};
64use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind, CanonicalVarKinds};
65use crate::lint::lint_level;
66use crate::metadata::ModChild;
67use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
68use crate::middle::resolve_bound_vars;
69use crate::mir::interpret::{self, Allocation, ConstAllocation};
70use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
71use crate::query::plumbing::QuerySystem;
72use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
73use crate::thir::Thir;
74use crate::traits;
75use crate::traits::solve;
76use crate::traits::solve::{
77 ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData,
78};
79use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
80use crate::ty::{
81 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
82 GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, ParamTy,
83 Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
84 PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
85 ValTree, ValTreeKind, Visibility,
86};
87
88#[allow(rustc::usage_of_ty_tykind)]
89impl<'tcx> Interner for TyCtxt<'tcx> {
90 fn next_trait_solver_globally(self) -> bool {
91 self.next_trait_solver_globally()
92 }
93
94 type DefId = DefId;
95 type LocalDefId = LocalDefId;
96 type Span = Span;
97
98 type GenericArgs = ty::GenericArgsRef<'tcx>;
99
100 type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
101 type GenericArg = ty::GenericArg<'tcx>;
102 type Term = ty::Term<'tcx>;
103 type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
104
105 type BoundVarKind = ty::BoundVariableKind;
106 type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
107
108 fn mk_predefined_opaques_in_body(
109 self,
110 data: PredefinedOpaquesData<Self>,
111 ) -> Self::PredefinedOpaques {
112 self.mk_predefined_opaques_in_body(data)
113 }
114 type LocalDefIds = &'tcx ty::List<LocalDefId>;
115 type CanonicalVarKinds = CanonicalVarKinds<'tcx>;
116 fn mk_canonical_var_kinds(
117 self,
118 kinds: &[ty::CanonicalVarKind<Self>],
119 ) -> Self::CanonicalVarKinds {
120 self.mk_canonical_var_kinds(kinds)
121 }
122
123 type ExternalConstraints = ExternalConstraints<'tcx>;
124 fn mk_external_constraints(
125 self,
126 data: ExternalConstraintsData<Self>,
127 ) -> ExternalConstraints<'tcx> {
128 self.mk_external_constraints(data)
129 }
130 type DepNodeIndex = DepNodeIndex;
131 fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
132 self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
133 }
134 type Ty = Ty<'tcx>;
135 type Tys = &'tcx List<Ty<'tcx>>;
136
137 type FnInputTys = &'tcx [Ty<'tcx>];
138 type ParamTy = ParamTy;
139 type BoundTy = ty::BoundTy;
140 type Symbol = Symbol;
141
142 type PlaceholderTy = ty::PlaceholderType;
143 type ErrorGuaranteed = ErrorGuaranteed;
144 type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
145
146 type AllocId = crate::mir::interpret::AllocId;
147 type Pat = Pattern<'tcx>;
148 type PatList = &'tcx List<Pattern<'tcx>>;
149 type Safety = hir::Safety;
150 type Abi = ExternAbi;
151 type Const = ty::Const<'tcx>;
152 type PlaceholderConst = ty::PlaceholderConst;
153
154 type ParamConst = ty::ParamConst;
155 type BoundConst = ty::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!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
449 self.is_conditionally_const(def_id)
450 }
451
452 fn alias_has_const_conditions(self, def_id: DefId) -> bool {
453 debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
454 self.is_conditionally_const(def_id)
455 }
456
457 fn const_conditions(
458 self,
459 def_id: DefId,
460 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
461 ty::EarlyBinder::bind(
462 self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
463 )
464 }
465
466 fn explicit_implied_const_bounds(
467 self,
468 def_id: DefId,
469 ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
470 ty::EarlyBinder::bind(
471 self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
472 )
473 }
474
475 fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
476 self.impl_self_is_guaranteed_unsized(impl_def_id)
477 }
478
479 fn has_target_features(self, def_id: DefId) -> bool {
480 !self.codegen_fn_attrs(def_id).target_features.is_empty()
481 }
482
483 fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
484 self.require_lang_item(trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
485 }
486
487 fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
488 self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
489 }
490
491 fn is_default_trait(self, def_id: DefId) -> bool {
492 self.is_default_trait(def_id)
493 }
494
495 fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
496 lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
497 }
498
499 fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
500 self.associated_items(def_id)
501 .in_definition_order()
502 .filter(|assoc_item| assoc_item.is_type())
503 .map(|assoc_item| assoc_item.def_id)
504 }
505
506 fn for_each_relevant_impl(
510 self,
511 trait_def_id: DefId,
512 self_ty: Ty<'tcx>,
513 mut f: impl FnMut(DefId),
514 ) {
515 let tcx = self;
516 let trait_impls = tcx.trait_impls_of(trait_def_id);
517 let mut consider_impls_for_simplified_type = |simp| {
518 if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
519 for &impl_def_id in impls_for_type {
520 f(impl_def_id);
521 }
522 }
523 };
524
525 match self_ty.kind() {
526 ty::Bool
527 | ty::Char
528 | ty::Int(_)
529 | ty::Uint(_)
530 | ty::Float(_)
531 | ty::Adt(_, _)
532 | ty::Foreign(_)
533 | ty::Str
534 | ty::Array(_, _)
535 | ty::Pat(_, _)
536 | ty::Slice(_)
537 | ty::RawPtr(_, _)
538 | ty::Ref(_, _, _)
539 | ty::FnDef(_, _)
540 | ty::FnPtr(..)
541 | ty::Dynamic(_, _, _)
542 | ty::Closure(..)
543 | ty::CoroutineClosure(..)
544 | ty::Coroutine(_, _)
545 | ty::Never
546 | ty::Tuple(_)
547 | ty::UnsafeBinder(_) => {
548 let simp = ty::fast_reject::simplify_type(
549 tcx,
550 self_ty,
551 ty::fast_reject::TreatParams::AsRigid,
552 )
553 .unwrap();
554 consider_impls_for_simplified_type(simp);
555 }
556
557 ty::Infer(ty::IntVar(_)) => {
560 use ty::IntTy::*;
561 use ty::UintTy::*;
562 let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
564 let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
565 let possible_integers = [
566 ty::SimplifiedType::Int(I8),
568 ty::SimplifiedType::Int(I16),
569 ty::SimplifiedType::Int(I32),
570 ty::SimplifiedType::Int(I64),
571 ty::SimplifiedType::Int(I128),
572 ty::SimplifiedType::Int(Isize),
573 ty::SimplifiedType::Uint(U8),
575 ty::SimplifiedType::Uint(U16),
576 ty::SimplifiedType::Uint(U32),
577 ty::SimplifiedType::Uint(U64),
578 ty::SimplifiedType::Uint(U128),
579 ty::SimplifiedType::Uint(Usize),
580 ];
581 for simp in possible_integers {
582 consider_impls_for_simplified_type(simp);
583 }
584 }
585
586 ty::Infer(ty::FloatVar(_)) => {
587 let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
589 let possible_floats = [
590 ty::SimplifiedType::Float(ty::FloatTy::F16),
591 ty::SimplifiedType::Float(ty::FloatTy::F32),
592 ty::SimplifiedType::Float(ty::FloatTy::F64),
593 ty::SimplifiedType::Float(ty::FloatTy::F128),
594 ];
595
596 for simp in possible_floats {
597 consider_impls_for_simplified_type(simp);
598 }
599 }
600
601 ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
606
607 ty::CoroutineWitness(..) => (),
611
612 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
614 | ty::Param(_)
615 | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
616 }
617
618 let trait_impls = tcx.trait_impls_of(trait_def_id);
619 for &impl_def_id in trait_impls.blanket_impls() {
620 f(impl_def_id);
621 }
622 }
623
624 fn has_item_definition(self, def_id: DefId) -> bool {
625 self.defaultness(def_id).has_value()
626 }
627
628 fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
629 self.specializes((impl_def_id, victim_def_id))
630 }
631
632 fn impl_is_default(self, impl_def_id: DefId) -> bool {
633 self.defaultness(impl_def_id).is_default()
634 }
635
636 fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
637 self.impl_trait_ref(impl_def_id).unwrap()
638 }
639
640 fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
641 self.impl_polarity(impl_def_id)
642 }
643
644 fn trait_is_auto(self, trait_def_id: DefId) -> bool {
645 self.trait_is_auto(trait_def_id)
646 }
647
648 fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
649 self.trait_is_coinductive(trait_def_id)
650 }
651
652 fn trait_is_alias(self, trait_def_id: DefId) -> bool {
653 self.trait_is_alias(trait_def_id)
654 }
655
656 fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
657 self.is_dyn_compatible(trait_def_id)
658 }
659
660 fn trait_is_fundamental(self, def_id: DefId) -> bool {
661 self.trait_def(def_id).is_fundamental
662 }
663
664 fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
665 self.trait_def(trait_def_id).implement_via_object
666 }
667
668 fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
669 self.trait_def(trait_def_id).safety.is_unsafe()
670 }
671
672 fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
673 self.is_impl_trait_in_trait(def_id)
674 }
675
676 fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
677 self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
678 }
679
680 fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
681 self.is_general_coroutine(coroutine_def_id)
682 }
683
684 fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
685 self.coroutine_is_async(coroutine_def_id)
686 }
687
688 fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
689 self.coroutine_is_gen(coroutine_def_id)
690 }
691
692 fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
693 self.coroutine_is_async_gen(coroutine_def_id)
694 }
695
696 type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
697 fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
698 self.unsizing_params_for_adt(adt_def_id)
699 }
700
701 fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
702 self,
703 binder: ty::Binder<'tcx, T>,
704 ) -> ty::Binder<'tcx, T> {
705 self.anonymize_bound_vars(binder)
706 }
707
708 fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
709 self.opaque_types_defined_by(defining_anchor)
710 }
711
712 fn opaque_types_and_coroutines_defined_by(
713 self,
714 defining_anchor: Self::LocalDefId,
715 ) -> Self::LocalDefIds {
716 let coroutines_defined_by = self
717 .nested_bodies_within(defining_anchor)
718 .iter()
719 .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
720 self.mk_local_def_ids_from_iter(
721 self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
722 )
723 }
724}
725
726macro_rules! bidirectional_lang_item_map {
727 ($($name:ident),+ $(,)?) => {
728 fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
729 match lang_item {
730 $(TraitSolverLangItem::$name => LangItem::$name,)+
731 }
732 }
733
734 fn lang_item_to_trait_lang_item(lang_item: LangItem) -> Option<TraitSolverLangItem> {
735 Some(match lang_item {
736 $(LangItem::$name => TraitSolverLangItem::$name,)+
737 _ => return None,
738 })
739 }
740 }
741}
742
743bidirectional_lang_item_map! {
744AsyncFn,
746 AsyncFnKindHelper,
747 AsyncFnKindUpvars,
748 AsyncFnMut,
749 AsyncFnOnce,
750 AsyncFnOnceOutput,
751 AsyncIterator,
752 BikeshedGuaranteedNoDrop,
753 CallOnceFuture,
754 CallRefFuture,
755 Clone,
756 Copy,
757 Coroutine,
758 CoroutineReturn,
759 CoroutineYield,
760 Destruct,
761 DiscriminantKind,
762 Drop,
763 DynMetadata,
764 Fn,
765 FnMut,
766 FnOnce,
767 FnPtrTrait,
768 FusedIterator,
769 Future,
770 FutureOutput,
771 Iterator,
772 MetaSized,
773 Metadata,
774 Option,
775 PointeeSized,
776 PointeeTrait,
777 Poll,
778 Sized,
779 TransmuteTrait,
780 Tuple,
781 Unpin,
782 Unsize,
783}
785
786impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
787 fn is_local(self) -> bool {
788 self.is_local()
789 }
790
791 fn as_local(self) -> Option<LocalDefId> {
792 self.as_local()
793 }
794}
795
796impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
797 fn rust() -> Self {
798 ExternAbi::Rust
799 }
800
801 fn is_rust(self) -> bool {
802 matches!(self, ExternAbi::Rust)
803 }
804}
805
806impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
807 fn safe() -> Self {
808 hir::Safety::Safe
809 }
810
811 fn is_safe(self) -> bool {
812 self.is_safe()
813 }
814
815 fn prefix_str(self) -> &'static str {
816 self.prefix_str()
817 }
818}
819
820impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
821 fn generic_const_exprs(self) -> bool {
822 self.generic_const_exprs()
823 }
824
825 fn coroutine_clone(self) -> bool {
826 self.coroutine_clone()
827 }
828
829 fn associated_const_equality(self) -> bool {
830 self.associated_const_equality()
831 }
832
833 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
834 !self.staged_api() && self.enabled(symbol)
838 }
839}
840
841impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
842 fn dummy() -> Self {
843 DUMMY_SP
844 }
845}
846
847type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
848
849pub struct CtxtInterners<'tcx> {
850 arena: &'tcx WorkerLocal<Arena<'tcx>>,
852
853 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
856 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
857 args: InternedSet<'tcx, GenericArgs<'tcx>>,
858 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
859 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
860 region: InternedSet<'tcx, RegionKind<'tcx>>,
861 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
862 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
863 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
864 projs: InternedSet<'tcx, List<ProjectionKind>>,
865 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
866 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
867 pat: InternedSet<'tcx, PatternKind<'tcx>>,
868 const_allocation: InternedSet<'tcx, Allocation>,
869 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
870 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
871 adt_def: InternedSet<'tcx, AdtDefData>,
872 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
873 predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
874 fields: InternedSet<'tcx, List<FieldIdx>>,
875 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
876 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
877 offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
878 valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
879 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
880 outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
881}
882
883impl<'tcx> CtxtInterners<'tcx> {
884 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
885 const N: usize = 2048;
888 CtxtInterners {
889 arena,
890 type_: InternedSet::with_capacity(N * 16),
894 const_lists: InternedSet::with_capacity(N * 4),
895 args: InternedSet::with_capacity(N * 4),
896 type_lists: InternedSet::with_capacity(N * 4),
897 region: InternedSet::with_capacity(N * 4),
898 poly_existential_predicates: InternedSet::with_capacity(N / 4),
899 canonical_var_kinds: InternedSet::with_capacity(N / 2),
900 predicate: InternedSet::with_capacity(N),
901 clauses: InternedSet::with_capacity(N),
902 projs: InternedSet::with_capacity(N * 4),
903 place_elems: InternedSet::with_capacity(N * 2),
904 const_: InternedSet::with_capacity(N * 2),
905 pat: InternedSet::with_capacity(N),
906 const_allocation: InternedSet::with_capacity(N),
907 bound_variable_kinds: InternedSet::with_capacity(N * 2),
908 layout: InternedSet::with_capacity(N),
909 adt_def: InternedSet::with_capacity(N),
910 external_constraints: InternedSet::with_capacity(N),
911 predefined_opaques_in_body: InternedSet::with_capacity(N),
912 fields: InternedSet::with_capacity(N * 4),
913 local_def_ids: InternedSet::with_capacity(N),
914 captures: InternedSet::with_capacity(N),
915 offset_of: InternedSet::with_capacity(N),
916 valtree: InternedSet::with_capacity(N),
917 patterns: InternedSet::with_capacity(N),
918 outlives: InternedSet::with_capacity(N),
919 }
920 }
921
922 #[allow(rustc::usage_of_ty_tykind)]
924 #[inline(never)]
925 fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
926 Ty(Interned::new_unchecked(
927 self.type_
928 .intern(kind, |kind| {
929 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
930 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
931
932 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
933 internee: kind,
934 stable_hash,
935 flags: flags.flags,
936 outer_exclusive_binder: flags.outer_exclusive_binder,
937 }))
938 })
939 .0,
940 ))
941 }
942
943 #[allow(rustc::usage_of_ty_tykind)]
945 #[inline(never)]
946 fn intern_const(
947 &self,
948 kind: ty::ConstKind<'tcx>,
949 sess: &Session,
950 untracked: &Untracked,
951 ) -> Const<'tcx> {
952 Const(Interned::new_unchecked(
953 self.const_
954 .intern(kind, |kind: ty::ConstKind<'_>| {
955 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
956 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
957
958 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
959 internee: kind,
960 stable_hash,
961 flags: flags.flags,
962 outer_exclusive_binder: flags.outer_exclusive_binder,
963 }))
964 })
965 .0,
966 ))
967 }
968
969 fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
970 &self,
971 flags: &ty::FlagComputation<TyCtxt<'tcx>>,
972 sess: &'a Session,
973 untracked: &'a Untracked,
974 val: &T,
975 ) -> Fingerprint {
976 if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
979 Fingerprint::ZERO
980 } else {
981 let mut hasher = StableHasher::new();
982 let mut hcx = StableHashingContext::new(sess, untracked);
983 val.hash_stable(&mut hcx, &mut hasher);
984 hasher.finish()
985 }
986 }
987
988 #[inline(never)]
990 fn intern_predicate(
991 &self,
992 kind: Binder<'tcx, PredicateKind<'tcx>>,
993 sess: &Session,
994 untracked: &Untracked,
995 ) -> Predicate<'tcx> {
996 Predicate(Interned::new_unchecked(
997 self.predicate
998 .intern(kind, |kind| {
999 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
1000
1001 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
1002
1003 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
1004 internee: kind,
1005 stable_hash,
1006 flags: flags.flags,
1007 outer_exclusive_binder: flags.outer_exclusive_binder,
1008 }))
1009 })
1010 .0,
1011 ))
1012 }
1013
1014 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
1015 if clauses.is_empty() {
1016 ListWithCachedTypeInfo::empty()
1017 } else {
1018 self.clauses
1019 .intern_ref(clauses, || {
1020 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
1021
1022 InternedInSet(ListWithCachedTypeInfo::from_arena(
1023 &*self.arena,
1024 flags.into(),
1025 clauses,
1026 ))
1027 })
1028 .0
1029 }
1030 }
1031}
1032
1033const NUM_PREINTERNED_TY_VARS: u32 = 100;
1038const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
1039const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
1040const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
1041const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
1042const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
1043
1044const NUM_PREINTERNED_RE_VARS: u32 = 500;
1046const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
1047const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
1048
1049pub struct CommonTypes<'tcx> {
1050 pub unit: Ty<'tcx>,
1051 pub bool: Ty<'tcx>,
1052 pub char: Ty<'tcx>,
1053 pub isize: Ty<'tcx>,
1054 pub i8: Ty<'tcx>,
1055 pub i16: Ty<'tcx>,
1056 pub i32: Ty<'tcx>,
1057 pub i64: Ty<'tcx>,
1058 pub i128: Ty<'tcx>,
1059 pub usize: Ty<'tcx>,
1060 pub u8: Ty<'tcx>,
1061 pub u16: Ty<'tcx>,
1062 pub u32: Ty<'tcx>,
1063 pub u64: Ty<'tcx>,
1064 pub u128: Ty<'tcx>,
1065 pub f16: Ty<'tcx>,
1066 pub f32: Ty<'tcx>,
1067 pub f64: Ty<'tcx>,
1068 pub f128: Ty<'tcx>,
1069 pub str_: Ty<'tcx>,
1070 pub never: Ty<'tcx>,
1071 pub self_param: Ty<'tcx>,
1072
1073 pub trait_object_dummy_self: Ty<'tcx>,
1078
1079 pub ty_vars: Vec<Ty<'tcx>>,
1081
1082 pub fresh_tys: Vec<Ty<'tcx>>,
1084
1085 pub fresh_int_tys: Vec<Ty<'tcx>>,
1087
1088 pub fresh_float_tys: Vec<Ty<'tcx>>,
1090
1091 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
1095}
1096
1097pub struct CommonLifetimes<'tcx> {
1098 pub re_static: Region<'tcx>,
1100
1101 pub re_erased: Region<'tcx>,
1103
1104 pub re_vars: Vec<Region<'tcx>>,
1106
1107 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
1111}
1112
1113pub struct CommonConsts<'tcx> {
1114 pub unit: Const<'tcx>,
1115 pub true_: Const<'tcx>,
1116 pub false_: Const<'tcx>,
1117 pub(crate) valtree_zst: ValTree<'tcx>,
1119}
1120
1121impl<'tcx> CommonTypes<'tcx> {
1122 fn new(
1123 interners: &CtxtInterners<'tcx>,
1124 sess: &Session,
1125 untracked: &Untracked,
1126 ) -> CommonTypes<'tcx> {
1127 let mk = |ty| interners.intern_ty(ty, sess, untracked);
1128
1129 let ty_vars =
1130 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
1131 let fresh_tys: Vec<_> =
1132 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
1133 let fresh_int_tys: Vec<_> =
1134 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
1135 let fresh_float_tys: Vec<_> =
1136 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
1137
1138 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
1139 .map(|i| {
1140 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
1141 .map(|v| {
1142 mk(ty::Bound(
1143 ty::DebruijnIndex::from(i),
1144 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
1145 ))
1146 })
1147 .collect()
1148 })
1149 .collect();
1150
1151 CommonTypes {
1152 unit: mk(Tuple(List::empty())),
1153 bool: mk(Bool),
1154 char: mk(Char),
1155 never: mk(Never),
1156 isize: mk(Int(ty::IntTy::Isize)),
1157 i8: mk(Int(ty::IntTy::I8)),
1158 i16: mk(Int(ty::IntTy::I16)),
1159 i32: mk(Int(ty::IntTy::I32)),
1160 i64: mk(Int(ty::IntTy::I64)),
1161 i128: mk(Int(ty::IntTy::I128)),
1162 usize: mk(Uint(ty::UintTy::Usize)),
1163 u8: mk(Uint(ty::UintTy::U8)),
1164 u16: mk(Uint(ty::UintTy::U16)),
1165 u32: mk(Uint(ty::UintTy::U32)),
1166 u64: mk(Uint(ty::UintTy::U64)),
1167 u128: mk(Uint(ty::UintTy::U128)),
1168 f16: mk(Float(ty::FloatTy::F16)),
1169 f32: mk(Float(ty::FloatTy::F32)),
1170 f64: mk(Float(ty::FloatTy::F64)),
1171 f128: mk(Float(ty::FloatTy::F128)),
1172 str_: mk(Str),
1173 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
1174
1175 trait_object_dummy_self: fresh_tys[0],
1176
1177 ty_vars,
1178 fresh_tys,
1179 fresh_int_tys,
1180 fresh_float_tys,
1181 anon_bound_tys,
1182 }
1183 }
1184}
1185
1186impl<'tcx> CommonLifetimes<'tcx> {
1187 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
1188 let mk = |r| {
1189 Region(Interned::new_unchecked(
1190 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
1191 ))
1192 };
1193
1194 let re_vars =
1195 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
1196
1197 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
1198 .map(|i| {
1199 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
1200 .map(|v| {
1201 mk(ty::ReBound(
1202 ty::DebruijnIndex::from(i),
1203 ty::BoundRegion {
1204 var: ty::BoundVar::from(v),
1205 kind: ty::BoundRegionKind::Anon,
1206 },
1207 ))
1208 })
1209 .collect()
1210 })
1211 .collect();
1212
1213 CommonLifetimes {
1214 re_static: mk(ty::ReStatic),
1215 re_erased: mk(ty::ReErased),
1216 re_vars,
1217 anon_re_bounds,
1218 }
1219 }
1220}
1221
1222impl<'tcx> CommonConsts<'tcx> {
1223 fn new(
1224 interners: &CtxtInterners<'tcx>,
1225 types: &CommonTypes<'tcx>,
1226 sess: &Session,
1227 untracked: &Untracked,
1228 ) -> CommonConsts<'tcx> {
1229 let mk_const = |c| {
1230 interners.intern_const(
1231 c, sess, untracked,
1233 )
1234 };
1235
1236 let mk_valtree = |v| {
1237 ty::ValTree(Interned::new_unchecked(
1238 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
1239 ))
1240 };
1241
1242 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
1243 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
1244 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
1245
1246 CommonConsts {
1247 unit: mk_const(ty::ConstKind::Value(ty::Value {
1248 ty: types.unit,
1249 valtree: valtree_zst,
1250 })),
1251 true_: mk_const(ty::ConstKind::Value(ty::Value {
1252 ty: types.bool,
1253 valtree: valtree_true,
1254 })),
1255 false_: mk_const(ty::ConstKind::Value(ty::Value {
1256 ty: types.bool,
1257 valtree: valtree_false,
1258 })),
1259 valtree_zst,
1260 }
1261 }
1262}
1263
1264#[derive(Debug)]
1267pub struct FreeRegionInfo {
1268 pub scope: LocalDefId,
1270 pub region_def_id: DefId,
1272 pub is_impl_item: bool,
1274}
1275
1276#[derive(Copy, Clone)]
1278pub struct TyCtxtFeed<'tcx, KEY: Copy> {
1279 pub tcx: TyCtxt<'tcx>,
1280 key: KEY,
1282}
1283
1284impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
1287
1288#[derive(Copy, Clone)]
1293pub struct Feed<'tcx, KEY: Copy> {
1294 _tcx: PhantomData<TyCtxt<'tcx>>,
1295 key: KEY,
1297}
1298
1299impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
1302
1303impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
1304 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1305 self.key.fmt(f)
1306 }
1307}
1308
1309impl<'tcx> TyCtxt<'tcx> {
1314 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
1317 self.dep_graph.assert_ignored();
1318 TyCtxtFeed { tcx: self, key: () }
1319 }
1320
1321 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
1324 let key = self.untracked().source_span.push(span);
1325 assert_eq!(key, CRATE_DEF_ID);
1326 TyCtxtFeed { tcx: self, key }
1327 }
1328
1329 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
1333 debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
1334 TyCtxtFeed { tcx: self, key }.type_of(value)
1335 }
1336}
1337
1338impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
1339 #[inline(always)]
1340 pub fn key(&self) -> KEY {
1341 self.key
1342 }
1343
1344 #[inline(always)]
1345 pub fn downgrade(self) -> Feed<'tcx, KEY> {
1346 Feed { _tcx: PhantomData, key: self.key }
1347 }
1348}
1349
1350impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
1351 #[inline(always)]
1352 pub fn key(&self) -> KEY {
1353 self.key
1354 }
1355
1356 #[inline(always)]
1357 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
1358 TyCtxtFeed { tcx, key: self.key }
1359 }
1360}
1361
1362impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1363 #[inline(always)]
1364 pub fn def_id(&self) -> LocalDefId {
1365 self.key
1366 }
1367
1368 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
1370 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
1371 }
1372
1373 pub fn feed_hir(&self) {
1375 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
1376
1377 let node = hir::OwnerNode::Synthetic;
1378 let bodies = Default::default();
1379 let attrs = hir::AttributeMap::EMPTY;
1380
1381 let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
1382 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
1383 let node = node.into();
1384 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
1385 opt_hash_including_bodies,
1386 nodes: IndexVec::from_elem_n(
1387 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
1388 1,
1389 ),
1390 bodies,
1391 })));
1392 self.feed_owner_id().hir_attr_map(attrs);
1393 }
1394}
1395
1396#[derive(Copy, Clone)]
1414#[rustc_diagnostic_item = "TyCtxt"]
1415#[rustc_pass_by_value]
1416pub struct TyCtxt<'tcx> {
1417 gcx: &'tcx GlobalCtxt<'tcx>,
1418}
1419
1420impl<'tcx> LintEmitter for TyCtxt<'tcx> {
1421 fn emit_node_span_lint(
1422 self,
1423 lint: &'static Lint,
1424 hir_id: HirId,
1425 span: impl Into<MultiSpan>,
1426 decorator: impl for<'a> LintDiagnostic<'a, ()>,
1427 ) {
1428 self.emit_node_span_lint(lint, hir_id, span, decorator);
1429 }
1430}
1431
1432unsafe impl DynSend for TyCtxt<'_> {}
1436unsafe impl DynSync for TyCtxt<'_> {}
1437fn _assert_tcx_fields() {
1438 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
1439 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
1440}
1441
1442impl<'tcx> Deref for TyCtxt<'tcx> {
1443 type Target = &'tcx GlobalCtxt<'tcx>;
1444 #[inline(always)]
1445 fn deref(&self) -> &Self::Target {
1446 &self.gcx
1447 }
1448}
1449
1450pub struct GlobalCtxt<'tcx> {
1452 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
1453 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1454
1455 interners: CtxtInterners<'tcx>,
1456
1457 pub sess: &'tcx Session,
1458 crate_types: Vec<CrateType>,
1459 stable_crate_id: StableCrateId,
1465
1466 pub dep_graph: DepGraph,
1467
1468 pub prof: SelfProfilerRef,
1469
1470 pub types: CommonTypes<'tcx>,
1472
1473 pub lifetimes: CommonLifetimes<'tcx>,
1475
1476 pub consts: CommonConsts<'tcx>,
1478
1479 pub(crate) hooks: crate::hooks::Providers,
1482
1483 untracked: Untracked,
1484
1485 pub query_system: QuerySystem<'tcx>,
1486 pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>],
1487
1488 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
1490
1491 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
1494
1495 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
1499
1500 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
1502 pub new_solver_canonical_param_env_cache:
1503 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
1504
1505 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
1506
1507 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
1509 pub clauses_cache:
1511 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
1512
1513 pub data_layout: TargetDataLayout,
1515
1516 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
1518
1519 current_gcx: CurrentGcx,
1520
1521 pub jobserver_proxy: Arc<Proxy>,
1523}
1524
1525impl<'tcx> GlobalCtxt<'tcx> {
1526 pub fn enter<F, R>(&'tcx self, f: F) -> R
1529 where
1530 F: FnOnce(TyCtxt<'tcx>) -> R,
1531 {
1532 let icx = tls::ImplicitCtxt::new(self);
1533
1534 let _on_drop = defer(move || {
1536 *self.current_gcx.value.write() = None;
1537 });
1538
1539 {
1541 let mut guard = self.current_gcx.value.write();
1542 assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
1543 *guard = Some(self as *const _ as *const ());
1544 }
1545
1546 tls::enter_context(&icx, || f(icx.tcx))
1547 }
1548}
1549
1550#[derive(Clone)]
1557pub struct CurrentGcx {
1558 value: Arc<RwLock<Option<*const ()>>>,
1561}
1562
1563unsafe impl DynSend for CurrentGcx {}
1564unsafe impl DynSync for CurrentGcx {}
1565
1566impl CurrentGcx {
1567 pub fn new() -> Self {
1568 Self { value: Arc::new(RwLock::new(None)) }
1569 }
1570
1571 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
1572 let read_guard = self.value.read();
1573 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
1574 f(unsafe { &*gcx })
1578 }
1579}
1580
1581impl<'tcx> TyCtxt<'tcx> {
1582 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
1583 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
1586 if typeck_root_def_id != def_id.to_def_id() {
1587 return self.has_typeck_results(typeck_root_def_id.expect_local());
1588 }
1589
1590 self.hir_node_by_def_id(def_id).body_id().is_some()
1591 }
1592
1593 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
1598 let def_kind = self.def_kind(def_id);
1599 if def_kind.has_codegen_attrs() {
1600 self.codegen_fn_attrs(def_id)
1601 } else if matches!(
1602 def_kind,
1603 DefKind::AnonConst
1604 | DefKind::AssocConst
1605 | DefKind::Const
1606 | DefKind::InlineConst
1607 | DefKind::GlobalAsm
1608 ) {
1609 CodegenFnAttrs::EMPTY
1610 } else {
1611 bug!(
1612 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
1613 def_id,
1614 def_kind
1615 )
1616 }
1617 }
1618
1619 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
1620 self.arena.alloc(Steal::new(thir))
1621 }
1622
1623 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
1624 self.arena.alloc(Steal::new(mir))
1625 }
1626
1627 pub fn alloc_steal_promoted(
1628 self,
1629 promoted: IndexVec<Promoted, Body<'tcx>>,
1630 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1631 self.arena.alloc(Steal::new(promoted))
1632 }
1633
1634 pub fn mk_adt_def(
1635 self,
1636 did: DefId,
1637 kind: AdtKind,
1638 variants: IndexVec<VariantIdx, ty::VariantDef>,
1639 repr: ReprOptions,
1640 ) -> ty::AdtDef<'tcx> {
1641 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1642 }
1643
1644 pub fn allocate_bytes_dedup<'a>(
1647 self,
1648 bytes: impl Into<Cow<'a, [u8]>>,
1649 salt: usize,
1650 ) -> interpret::AllocId {
1651 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
1653 let alloc = self.mk_const_alloc(alloc);
1654 self.reserve_and_set_memory_dedup(alloc, salt)
1655 }
1656
1657 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1659 if self.sess.opts.unstable_opts.experimental_default_bounds {
1660 &[
1661 LangItem::DefaultTrait1,
1662 LangItem::DefaultTrait2,
1663 LangItem::DefaultTrait3,
1664 LangItem::DefaultTrait4,
1665 ]
1666 } else {
1667 &[]
1668 }
1669 }
1670
1671 pub fn is_default_trait(self, def_id: DefId) -> bool {
1672 self.default_traits()
1673 .iter()
1674 .any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
1675 }
1676
1677 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1681 let start = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1682 let end = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
1683 (start, end)
1684 }
1685
1686 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1687 value.lift_to_interner(self)
1688 }
1689
1690 pub fn create_global_ctxt<T>(
1697 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1698 s: &'tcx Session,
1699 crate_types: Vec<CrateType>,
1700 stable_crate_id: StableCrateId,
1701 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1702 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1703 untracked: Untracked,
1704 dep_graph: DepGraph,
1705 query_kinds: &'tcx [DepKindStruct<'tcx>],
1706 query_system: QuerySystem<'tcx>,
1707 hooks: crate::hooks::Providers,
1708 current_gcx: CurrentGcx,
1709 jobserver_proxy: Arc<Proxy>,
1710 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1711 ) -> T {
1712 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1713 s.dcx().emit_fatal(err);
1714 });
1715 let interners = CtxtInterners::new(arena);
1716 let common_types = CommonTypes::new(&interners, s, &untracked);
1717 let common_lifetimes = CommonLifetimes::new(&interners);
1718 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1719
1720 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1721 sess: s,
1722 crate_types,
1723 stable_crate_id,
1724 arena,
1725 hir_arena,
1726 interners,
1727 dep_graph,
1728 hooks,
1729 prof: s.prof.clone(),
1730 types: common_types,
1731 lifetimes: common_lifetimes,
1732 consts: common_consts,
1733 untracked,
1734 query_system,
1735 query_kinds,
1736 ty_rcache: Default::default(),
1737 selection_cache: Default::default(),
1738 evaluation_cache: Default::default(),
1739 new_solver_evaluation_cache: Default::default(),
1740 new_solver_canonical_param_env_cache: Default::default(),
1741 canonical_param_env_cache: Default::default(),
1742 highest_var_in_clauses_cache: Default::default(),
1743 clauses_cache: Default::default(),
1744 data_layout,
1745 alloc_map: interpret::AllocMap::new(),
1746 current_gcx,
1747 jobserver_proxy,
1748 });
1749
1750 gcx.enter(f)
1752 }
1753
1754 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1756 self.get_lang_items(())
1757 }
1758
1759 #[track_caller]
1761 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1762 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1763 self.type_of(ordering_enum).no_bound_vars().unwrap()
1764 }
1765
1766 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1769 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1770 }
1771
1772 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1774 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1775 }
1776
1777 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1779 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1780 }
1781
1782 pub fn is_coroutine(self, def_id: DefId) -> bool {
1783 self.coroutine_kind(def_id).is_some()
1784 }
1785
1786 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1787 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1788 }
1789
1790 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1793 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1794 }
1795
1796 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1798 matches!(
1799 self.coroutine_kind(def_id),
1800 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1801 )
1802 }
1803
1804 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1807 matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1808 }
1809
1810 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1813 matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
1814 }
1815
1816 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1818 matches!(
1819 self.coroutine_kind(def_id),
1820 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1821 )
1822 }
1823
1824 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1826 matches!(
1827 self.coroutine_kind(def_id),
1828 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1829 )
1830 }
1831
1832 pub fn features(self) -> &'tcx rustc_feature::Features {
1833 self.features_query(())
1834 }
1835
1836 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1837 let id = id.into_query_param();
1838 if let Some(id) = id.as_local() {
1840 self.definitions_untracked().def_key(id)
1841 } else {
1842 self.cstore_untracked().def_key(id)
1843 }
1844 }
1845
1846 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1852 if let Some(id) = id.as_local() {
1854 self.definitions_untracked().def_path(id)
1855 } else {
1856 self.cstore_untracked().def_path(id)
1857 }
1858 }
1859
1860 #[inline]
1861 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1862 if let Some(def_id) = def_id.as_local() {
1864 self.definitions_untracked().def_path_hash(def_id)
1865 } else {
1866 self.cstore_untracked().def_path_hash(def_id)
1867 }
1868 }
1869
1870 #[inline]
1871 pub fn crate_types(self) -> &'tcx [CrateType] {
1872 &self.crate_types
1873 }
1874
1875 pub fn needs_metadata(self) -> bool {
1876 self.crate_types().iter().any(|ty| match *ty {
1877 CrateType::Executable
1878 | CrateType::Staticlib
1879 | CrateType::Cdylib
1880 | CrateType::Sdylib => false,
1881 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1882 })
1883 }
1884
1885 pub fn needs_crate_hash(self) -> bool {
1886 cfg!(debug_assertions)
1898 || self.sess.opts.incremental.is_some()
1899 || self.needs_metadata()
1900 || self.sess.instrument_coverage()
1901 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1902 }
1903
1904 #[inline]
1905 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1906 if crate_num == LOCAL_CRATE {
1907 self.stable_crate_id
1908 } else {
1909 self.cstore_untracked().stable_crate_id(crate_num)
1910 }
1911 }
1912
1913 #[inline]
1916 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1917 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1918 LOCAL_CRATE
1919 } else {
1920 *self
1921 .untracked()
1922 .stable_crate_ids
1923 .read()
1924 .get(&stable_crate_id)
1925 .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1926 }
1927 }
1928
1929 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1933 debug!("def_path_hash_to_def_id({:?})", hash);
1934
1935 let stable_crate_id = hash.stable_crate_id();
1936
1937 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1940 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1941 } else {
1942 Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
1943 }
1944 }
1945
1946 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1947 let (crate_name, stable_crate_id) = if def_id.is_local() {
1952 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1953 } else {
1954 let cstore = &*self.cstore_untracked();
1955 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1956 };
1957
1958 format!(
1959 "{}[{:04x}]{}",
1960 crate_name,
1961 stable_crate_id.as_u64() >> (8 * 6),
1964 self.def_path(def_id).to_string_no_crate_verbose()
1965 )
1966 }
1967
1968 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1969 self.sess.dcx()
1970 }
1971
1972 pub fn is_target_feature_call_safe(
1973 self,
1974 callee_features: &[TargetFeature],
1975 body_features: &[TargetFeature],
1976 ) -> bool {
1977 self.sess.target.options.is_like_wasm
1982 || callee_features
1983 .iter()
1984 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1985 }
1986
1987 pub fn adjust_target_feature_sig(
1990 self,
1991 fun_def: DefId,
1992 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1993 caller: DefId,
1994 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1995 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1996 let callee_features = &self.codegen_fn_attrs(caller).target_features;
1997 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
1998 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
1999 }
2000 None
2001 }
2002
2003 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
2006 match self.env_var_os(key.as_ref()) {
2007 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
2008 None => Err(VarError::NotPresent),
2009 }
2010 }
2011}
2012
2013impl<'tcx> TyCtxtAt<'tcx> {
2014 pub fn create_def(
2016 self,
2017 parent: LocalDefId,
2018 name: Option<Symbol>,
2019 def_kind: DefKind,
2020 override_def_path_data: Option<DefPathData>,
2021 disambiguator: &mut DisambiguatorState,
2022 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2023 let feed =
2024 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
2025
2026 feed.def_span(self.span);
2027 feed
2028 }
2029}
2030
2031impl<'tcx> TyCtxt<'tcx> {
2032 pub fn create_def(
2034 self,
2035 parent: LocalDefId,
2036 name: Option<Symbol>,
2037 def_kind: DefKind,
2038 override_def_path_data: Option<DefPathData>,
2039 disambiguator: &mut DisambiguatorState,
2040 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2041 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2042 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2052
2053 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2058
2059 let feed = TyCtxtFeed { tcx: self, key: def_id };
2060 feed.def_kind(def_kind);
2061 if matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2066 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2067 feed.visibility(ty::Visibility::Restricted(parent_mod));
2068 }
2069
2070 feed
2071 }
2072
2073 pub fn create_crate_num(
2074 self,
2075 stable_crate_id: StableCrateId,
2076 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2077 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2078 return Err(existing);
2079 }
2080
2081 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2082 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2083 Ok(TyCtxtFeed { key: num, tcx: self })
2084 }
2085
2086 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2087 self.ensure_ok().analysis(());
2089
2090 let definitions = &self.untracked.definitions;
2091 gen {
2092 let mut i = 0;
2093
2094 while i < { definitions.read().num_definitions() } {
2097 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2098 yield LocalDefId { local_def_index };
2099 i += 1;
2100 }
2101
2102 definitions.freeze();
2104 }
2105 }
2106
2107 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2108 self.ensure_ok().analysis(());
2110
2111 self.untracked.definitions.freeze().def_path_table()
2114 }
2115
2116 pub fn def_path_hash_to_def_index_map(
2117 self,
2118 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2119 self.ensure_ok().hir_crate_items(());
2122 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2125 }
2126
2127 #[inline]
2130 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2131 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2132 }
2133
2134 pub fn untracked(self) -> &'tcx Untracked {
2136 &self.untracked
2137 }
2138 #[inline]
2141 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2142 self.untracked.definitions.read()
2143 }
2144
2145 #[inline]
2148 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2149 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2150 }
2151
2152 #[inline(always)]
2153 pub fn with_stable_hashing_context<R>(
2154 self,
2155 f: impl FnOnce(StableHashingContext<'_>) -> R,
2156 ) -> R {
2157 f(StableHashingContext::new(self.sess, &self.untracked))
2158 }
2159
2160 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2161 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2162 }
2163
2164 #[inline]
2165 pub fn local_crate_exports_generics(self) -> bool {
2166 self.crate_types().iter().any(|crate_type| {
2167 match crate_type {
2168 CrateType::Executable
2169 | CrateType::Staticlib
2170 | CrateType::ProcMacro
2171 | CrateType::Cdylib
2172 | CrateType::Sdylib => false,
2173
2174 CrateType::Dylib => true,
2179
2180 CrateType::Rlib => true,
2181 }
2182 })
2183 }
2184
2185 pub fn is_suitable_region(
2187 self,
2188 generic_param_scope: LocalDefId,
2189 mut region: Region<'tcx>,
2190 ) -> Option<FreeRegionInfo> {
2191 let (suitable_region_binding_scope, region_def_id) = loop {
2192 let def_id =
2193 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2194 let scope = self.local_parent(def_id);
2195 if self.def_kind(scope) == DefKind::OpaqueTy {
2196 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2199 continue;
2200 }
2201 break (scope, def_id.into());
2202 };
2203
2204 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2205 Node::Item(..) | Node::TraitItem(..) => false,
2206 Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2207 _ => false,
2208 };
2209
2210 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2211 }
2212
2213 pub fn return_type_impl_or_dyn_traits(
2215 self,
2216 scope_def_id: LocalDefId,
2217 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2218 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2219 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2220 self.hir_fn_decl_by_hir_id(hir_id)
2221 else {
2222 return vec![];
2223 };
2224
2225 let mut v = TraitObjectVisitor(vec![]);
2226 v.visit_ty_unambig(hir_output);
2227 v.0
2228 }
2229
2230 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2234 self,
2235 scope_def_id: LocalDefId,
2236 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2237 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2238 let mut v = TraitObjectVisitor(vec![]);
2239 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2241 && let hir::TyKind::Path(hir::QPath::Resolved(
2242 None,
2243 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2244 && let Some(local_id) = def_id.as_local()
2245 && 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()
2247 {
2248 v.visit_ty_unambig(alias_ty);
2249 if !v.0.is_empty() {
2250 return Some((
2251 v.0,
2252 alias_generics.span,
2253 alias_generics.span_for_lifetime_suggestion(),
2254 ));
2255 }
2256 }
2257 None
2258 }
2259
2260 pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2262 let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2263 if self.impl_trait_ref(container_id).is_some() {
2264 return true;
2271 }
2272 false
2273 }
2274
2275 pub fn has_strict_asm_symbol_naming(self) -> bool {
2278 self.sess.target.arch.contains("nvptx")
2279 }
2280
2281 pub fn caller_location_ty(self) -> Ty<'tcx> {
2283 Ty::new_imm_ref(
2284 self,
2285 self.lifetimes.re_static,
2286 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2287 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2288 )
2289 }
2290
2291 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2293 let kind = self.def_kind(def_id);
2294 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2295 }
2296
2297 pub fn type_length_limit(self) -> Limit {
2298 self.limits(()).type_length_limit
2299 }
2300
2301 pub fn recursion_limit(self) -> Limit {
2302 self.limits(()).recursion_limit
2303 }
2304
2305 pub fn move_size_limit(self) -> Limit {
2306 self.limits(()).move_size_limit
2307 }
2308
2309 pub fn pattern_complexity_limit(self) -> Limit {
2310 self.limits(()).pattern_complexity_limit
2311 }
2312
2313 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
2315 iter::once(LOCAL_CRATE)
2316 .chain(self.crates(()).iter().copied())
2317 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2318 }
2319
2320 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2322 let visible_crates =
2323 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2324
2325 iter::once(LOCAL_CRATE)
2326 .chain(visible_crates)
2327 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2328 }
2329
2330 #[inline]
2331 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2332 self.visibility(def_id).expect_local()
2333 }
2334
2335 #[instrument(skip(self), level = "trace", ret)]
2337 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2338 self.hir_expect_opaque_ty(def_id).origin
2339 }
2340
2341 pub fn finish(self) {
2342 self.alloc_self_profile_query_strings();
2345
2346 self.save_dep_graph();
2347 self.query_key_hash_verify_all();
2348
2349 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2350 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2351 }
2352 }
2353}
2354
2355macro_rules! nop_lift {
2356 ($set:ident; $ty:ty => $lifted:ty) => {
2357 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2358 type Lifted = $lifted;
2359 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2360 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2365 _x: Interned<'tcx, Inner>,
2366 ) -> InternedSet<'tcx, Inner> {
2367 unreachable!()
2368 }
2369 fn _type_eq<T>(_x: &T, _y: &T) {}
2370 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2371 let interner = _intern_set_ty_from_interned_ty(x.0);
2375 _type_eq(&interner, &tcx.interners.$set);
2377 }
2378
2379 tcx.interners
2380 .$set
2381 .contains_pointer_to(&InternedInSet(&*self.0.0))
2382 .then(|| unsafe { mem::transmute(self) })
2385 }
2386 }
2387 };
2388}
2389
2390macro_rules! nop_list_lift {
2391 ($set:ident; $ty:ty => $lifted:ty) => {
2392 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2393 type Lifted = &'tcx List<$lifted>;
2394 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2395 if false {
2397 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2398 }
2399
2400 if self.is_empty() {
2401 return Some(List::empty());
2402 }
2403 tcx.interners
2404 .$set
2405 .contains_pointer_to(&InternedInSet(self))
2406 .then(|| unsafe { mem::transmute(self) })
2407 }
2408 }
2409 };
2410}
2411
2412nop_lift! { type_; Ty<'a> => Ty<'tcx> }
2413nop_lift! { region; Region<'a> => Region<'tcx> }
2414nop_lift! { const_; Const<'a> => Const<'tcx> }
2415nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
2416nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
2417nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
2418nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
2419nop_lift! { layout; Layout<'a> => Layout<'tcx> }
2420nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
2421
2422nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
2423nop_list_lift! {
2424 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2425}
2426nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind }
2427
2428nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
2430
2431macro_rules! sty_debug_print {
2432 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2433 #[allow(non_snake_case)]
2436 mod inner {
2437 use crate::ty::{self, TyCtxt};
2438 use crate::ty::context::InternedInSet;
2439
2440 #[derive(Copy, Clone)]
2441 struct DebugStat {
2442 total: usize,
2443 lt_infer: usize,
2444 ty_infer: usize,
2445 ct_infer: usize,
2446 all_infer: usize,
2447 }
2448
2449 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2450 let mut total = DebugStat {
2451 total: 0,
2452 lt_infer: 0,
2453 ty_infer: 0,
2454 ct_infer: 0,
2455 all_infer: 0,
2456 };
2457 $(let mut $variant = total;)*
2458
2459 for shard in tcx.interners.type_.lock_shards() {
2460 #[allow(rustc::potential_query_instability)]
2462 let types = shard.iter();
2463 for &(InternedInSet(t), ()) in types {
2464 let variant = match t.internee {
2465 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2466 ty::Float(..) | ty::Str | ty::Never => continue,
2467 ty::Error(_) => continue,
2468 $(ty::$variant(..) => &mut $variant,)*
2469 };
2470 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2471 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2472 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2473
2474 variant.total += 1;
2475 total.total += 1;
2476 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2477 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2478 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2479 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2480 }
2481 }
2482 writeln!(fmt, "Ty interner total ty lt ct all")?;
2483 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2484 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2485 stringify!($variant),
2486 uses = $variant.total,
2487 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2488 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2489 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2490 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2491 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2492 )*
2493 writeln!(fmt, " total {uses:6} \
2494 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2495 uses = total.total,
2496 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2497 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2498 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2499 all = total.all_infer as f64 * 100.0 / total.total as f64)
2500 }
2501 }
2502
2503 inner::go($fmt, $ctxt)
2504 }}
2505}
2506
2507impl<'tcx> TyCtxt<'tcx> {
2508 pub fn debug_stats(self) -> impl fmt::Debug {
2509 fmt::from_fn(move |fmt| {
2510 sty_debug_print!(
2511 fmt,
2512 self,
2513 Adt,
2514 Array,
2515 Slice,
2516 RawPtr,
2517 Ref,
2518 FnDef,
2519 FnPtr,
2520 UnsafeBinder,
2521 Placeholder,
2522 Coroutine,
2523 CoroutineWitness,
2524 Dynamic,
2525 Closure,
2526 CoroutineClosure,
2527 Tuple,
2528 Bound,
2529 Param,
2530 Infer,
2531 Alias,
2532 Pat,
2533 Foreign
2534 )?;
2535
2536 writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2537 writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2538 writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2539 writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2540
2541 Ok(())
2542 })
2543 }
2544}
2545
2546struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2551
2552impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2553 fn clone(&self) -> Self {
2554 InternedInSet(self.0)
2555 }
2556}
2557
2558impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2559
2560impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2561 fn into_pointer(&self) -> *const () {
2562 self.0 as *const _ as *const ()
2563 }
2564}
2565
2566#[allow(rustc::usage_of_ty_tykind)]
2567impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2568 fn borrow(&self) -> &T {
2569 &self.0.internee
2570 }
2571}
2572
2573impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2574 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2575 self.0.internee == other.0.internee
2578 }
2579}
2580
2581impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2582
2583impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2584 fn hash<H: Hasher>(&self, s: &mut H) {
2585 self.0.internee.hash(s)
2587 }
2588}
2589
2590impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2591 fn borrow(&self) -> &[T] {
2592 &self.0[..]
2593 }
2594}
2595
2596impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2597 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2598 self.0[..] == other.0[..]
2601 }
2602}
2603
2604impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2605
2606impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2607 fn hash<H: Hasher>(&self, s: &mut H) {
2608 self.0[..].hash(s)
2610 }
2611}
2612
2613impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2614 fn borrow(&self) -> &[T] {
2615 &self.0[..]
2616 }
2617}
2618
2619impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2620 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2621 self.0[..] == other.0[..]
2624 }
2625}
2626
2627impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2628
2629impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2630 fn hash<H: Hasher>(&self, s: &mut H) {
2631 self.0[..].hash(s)
2633 }
2634}
2635
2636macro_rules! direct_interners {
2637 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2638 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2639 fn borrow<'a>(&'a self) -> &'a $ty {
2640 &self.0
2641 }
2642 }
2643
2644 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2645 fn eq(&self, other: &Self) -> bool {
2646 self.0 == other.0
2649 }
2650 }
2651
2652 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2653
2654 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2655 fn hash<H: Hasher>(&self, s: &mut H) {
2656 self.0.hash(s)
2659 }
2660 }
2661
2662 impl<'tcx> TyCtxt<'tcx> {
2663 $vis fn $method(self, v: $ty) -> $ret_ty {
2664 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2665 InternedInSet(self.interners.arena.alloc(v))
2666 }).0))
2667 }
2668 })+
2669 }
2670}
2671
2672direct_interners! {
2676 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2677 valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2678 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2679 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2680 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2681 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2682 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2683 ExternalConstraints -> ExternalConstraints<'tcx>,
2684 predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
2685 PredefinedOpaques -> PredefinedOpaques<'tcx>,
2686}
2687
2688macro_rules! slice_interners {
2689 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2690 impl<'tcx> TyCtxt<'tcx> {
2691 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2692 if v.is_empty() {
2693 List::empty()
2694 } else {
2695 self.interners.$field.intern_ref(v, || {
2696 InternedInSet(List::from_arena(&*self.arena, (), v))
2697 }).0
2698 }
2699 })+
2700 }
2701 );
2702}
2703
2704slice_interners!(
2708 const_lists: pub mk_const_list(Const<'tcx>),
2709 args: pub mk_args(GenericArg<'tcx>),
2710 type_lists: pub mk_type_list(Ty<'tcx>),
2711 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2712 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2713 projs: pub mk_projs(ProjectionKind),
2714 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2715 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
2716 fields: pub mk_fields(FieldIdx),
2717 local_def_ids: intern_local_def_ids(LocalDefId),
2718 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2719 offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
2720 patterns: pub mk_patterns(Pattern<'tcx>),
2721 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2722);
2723
2724impl<'tcx> TyCtxt<'tcx> {
2725 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2729 assert!(sig.safety().is_safe());
2730 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2731 }
2732
2733 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2736 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2737 self.associated_items(trait_did)
2738 .filter_by_name_unhygienic(assoc_name.name)
2739 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2740 })
2741 }
2742
2743 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2745 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2746 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2747
2748 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2749 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2750 return false;
2751 };
2752 trait_predicate.trait_ref.def_id == future_trait
2753 && trait_predicate.polarity == PredicatePolarity::Positive
2754 })
2755 }
2756
2757 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2765 sig.map_bound(|s| {
2766 let params = match s.inputs()[0].kind() {
2767 ty::Tuple(params) => *params,
2768 _ => bug!(),
2769 };
2770 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2771 })
2772 }
2773
2774 #[inline]
2775 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2776 self.interners.intern_predicate(
2777 binder,
2778 self.sess,
2779 &self.untracked,
2781 )
2782 }
2783
2784 #[inline]
2785 pub fn reuse_or_mk_predicate(
2786 self,
2787 pred: Predicate<'tcx>,
2788 binder: Binder<'tcx, PredicateKind<'tcx>>,
2789 ) -> Predicate<'tcx> {
2790 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2791 }
2792
2793 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2794 self.check_args_compatible_inner(def_id, args, false)
2795 }
2796
2797 fn check_args_compatible_inner(
2798 self,
2799 def_id: DefId,
2800 args: &'tcx [ty::GenericArg<'tcx>],
2801 nested: bool,
2802 ) -> bool {
2803 let generics = self.generics_of(def_id);
2804
2805 let own_args = if !nested
2808 && let DefKind::AssocTy = self.def_kind(def_id)
2809 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2810 {
2811 if generics.own_params.len() + 1 != args.len() {
2812 return false;
2813 }
2814
2815 if !matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2816 return false;
2817 }
2818
2819 &args[1..]
2820 } else {
2821 if generics.count() != args.len() {
2822 return false;
2823 }
2824
2825 let (parent_args, own_args) = args.split_at(generics.parent_count);
2826
2827 if let Some(parent) = generics.parent
2828 && !self.check_args_compatible_inner(parent, parent_args, true)
2829 {
2830 return false;
2831 }
2832
2833 own_args
2834 };
2835
2836 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2837 match (¶m.kind, arg.kind()) {
2838 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2839 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2840 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2841 _ => return false,
2842 }
2843 }
2844
2845 true
2846 }
2847
2848 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2851 if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2852 if let DefKind::AssocTy = self.def_kind(def_id)
2853 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2854 {
2855 bug!(
2856 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2857 self.def_path_str(def_id),
2858 args,
2859 self.mk_args_from_iter(
2861 [self.types.self_param.into()].into_iter().chain(
2862 self.generics_of(def_id)
2863 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2864 .iter()
2865 .copied()
2866 )
2867 )
2868 );
2869 } else {
2870 bug!(
2871 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2872 self.def_path_str(def_id),
2873 args,
2874 ty::GenericArgs::identity_for_item(self, def_id)
2875 );
2876 }
2877 }
2878 }
2879
2880 #[inline(always)]
2881 pub(crate) fn check_and_mk_args(
2882 self,
2883 def_id: DefId,
2884 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2885 ) -> GenericArgsRef<'tcx> {
2886 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2887 self.debug_assert_args_compatible(def_id, args);
2888 args
2889 }
2890
2891 #[inline]
2892 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2893 self.interners.intern_const(
2894 kind,
2895 self.sess,
2896 &self.untracked,
2898 )
2899 }
2900
2901 #[allow(rustc::usage_of_ty_tykind)]
2903 #[inline]
2904 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2905 self.interners.intern_ty(
2906 st,
2907 self.sess,
2908 &self.untracked,
2910 )
2911 }
2912
2913 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2914 match param.kind {
2915 GenericParamDefKind::Lifetime => {
2916 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2917 }
2918 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2919 GenericParamDefKind::Const { .. } => {
2920 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2921 .into()
2922 }
2923 }
2924 }
2925
2926 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2927 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2928 }
2929
2930 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2931 self.mk_place_elem(place, PlaceElem::Deref)
2932 }
2933
2934 pub fn mk_place_downcast(
2935 self,
2936 place: Place<'tcx>,
2937 adt_def: AdtDef<'tcx>,
2938 variant_index: VariantIdx,
2939 ) -> Place<'tcx> {
2940 self.mk_place_elem(
2941 place,
2942 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2943 )
2944 }
2945
2946 pub fn mk_place_downcast_unnamed(
2947 self,
2948 place: Place<'tcx>,
2949 variant_index: VariantIdx,
2950 ) -> Place<'tcx> {
2951 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2952 }
2953
2954 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2955 self.mk_place_elem(place, PlaceElem::Index(index))
2956 }
2957
2958 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2962 let mut projection = place.projection.to_vec();
2963 projection.push(elem);
2964
2965 Place { local: place.local, projection: self.mk_place_elems(&projection) }
2966 }
2967
2968 pub fn mk_poly_existential_predicates(
2969 self,
2970 eps: &[PolyExistentialPredicate<'tcx>],
2971 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2972 assert!(!eps.is_empty());
2973 assert!(
2974 eps.array_windows()
2975 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2976 != Ordering::Greater)
2977 );
2978 self.intern_poly_existential_predicates(eps)
2979 }
2980
2981 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2982 self.interners.intern_clauses(clauses)
2986 }
2987
2988 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2989 self.intern_local_def_ids(def_ids)
2993 }
2994
2995 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2996 where
2997 I: Iterator<Item = T>,
2998 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2999 {
3000 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
3001 }
3002
3003 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
3004 where
3005 I: Iterator<Item = T>,
3006 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
3007 {
3008 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
3009 }
3010
3011 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
3012 where
3013 I: Iterator<Item = T>,
3014 T: CollectAndApply<
3015 &'tcx ty::CapturedPlace<'tcx>,
3016 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
3017 >,
3018 {
3019 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
3020 }
3021
3022 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
3023 where
3024 I: Iterator<Item = T>,
3025 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
3026 {
3027 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3028 }
3029
3030 pub fn mk_fn_sig<I, T>(
3035 self,
3036 inputs: I,
3037 output: I::Item,
3038 c_variadic: bool,
3039 safety: hir::Safety,
3040 abi: ExternAbi,
3041 ) -> T::Output
3042 where
3043 I: IntoIterator<Item = T>,
3044 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3045 {
3046 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3047 inputs_and_output: self.mk_type_list(xs),
3048 c_variadic,
3049 safety,
3050 abi,
3051 })
3052 }
3053
3054 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3055 where
3056 I: Iterator<Item = T>,
3057 T: CollectAndApply<
3058 PolyExistentialPredicate<'tcx>,
3059 &'tcx List<PolyExistentialPredicate<'tcx>>,
3060 >,
3061 {
3062 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3063 }
3064
3065 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3066 where
3067 I: Iterator<Item = T>,
3068 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3069 {
3070 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3071 }
3072
3073 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3074 where
3075 I: Iterator<Item = T>,
3076 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3077 {
3078 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3079 }
3080
3081 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3082 where
3083 I: Iterator<Item = T>,
3084 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3085 {
3086 T::collect_and_apply(iter, |xs| self.mk_args(xs))
3087 }
3088
3089 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3090 where
3091 I: Iterator<Item = T>,
3092 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3093 {
3094 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3095 }
3096
3097 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3098 where
3099 I: Iterator<Item = T>,
3100 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3101 {
3102 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3103 }
3104
3105 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3106 where
3107 I: Iterator<Item = T>,
3108 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3109 {
3110 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3111 }
3112
3113 pub fn mk_offset_of_from_iter<I, T>(self, iter: I) -> T::Output
3114 where
3115 I: Iterator<Item = T>,
3116 T: CollectAndApply<(VariantIdx, FieldIdx), &'tcx List<(VariantIdx, FieldIdx)>>,
3117 {
3118 T::collect_and_apply(iter, |xs| self.mk_offset_of(xs))
3119 }
3120
3121 pub fn mk_args_trait(
3122 self,
3123 self_ty: Ty<'tcx>,
3124 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3125 ) -> GenericArgsRef<'tcx> {
3126 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3127 }
3128
3129 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3130 where
3131 I: Iterator<Item = T>,
3132 T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
3133 {
3134 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3135 }
3136
3137 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
3138 where
3139 I: Iterator<Item = T>,
3140 T: CollectAndApply<
3141 ty::ArgOutlivesPredicate<'tcx>,
3142 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
3143 >,
3144 {
3145 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
3146 }
3147
3148 #[track_caller]
3151 pub fn emit_node_span_lint(
3152 self,
3153 lint: &'static Lint,
3154 hir_id: HirId,
3155 span: impl Into<MultiSpan>,
3156 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3157 ) {
3158 let level = self.lint_level_at_node(lint, hir_id);
3159 lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3160 decorator.decorate_lint(lint);
3161 })
3162 }
3163
3164 #[rustc_lint_diagnostics]
3168 #[track_caller]
3169 pub fn node_span_lint(
3170 self,
3171 lint: &'static Lint,
3172 hir_id: HirId,
3173 span: impl Into<MultiSpan>,
3174 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3175 ) {
3176 let level = self.lint_level_at_node(lint, hir_id);
3177 lint_level(self.sess, lint, level, Some(span.into()), decorate);
3178 }
3179
3180 pub fn crate_level_attribute_injection_span(self) -> Span {
3182 let node = self.hir_node(hir::CRATE_HIR_ID);
3183 let hir::Node::Crate(m) = node else { bug!() };
3184 m.spans.inject_use_span.shrink_to_lo()
3185 }
3186
3187 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3188 self,
3189 diag: &mut Diag<'_, E>,
3190 features: impl IntoIterator<Item = (String, Symbol)>,
3191 ) {
3192 if !self.sess.is_nightly_build() {
3193 return;
3194 }
3195
3196 let span = self.crate_level_attribute_injection_span();
3197 for (desc, feature) in features {
3198 let msg =
3200 format!("add `#![feature({feature})]` to the crate attributes to enable{desc}");
3201 diag.span_suggestion_verbose(
3202 span,
3203 msg,
3204 format!("#![feature({feature})]\n"),
3205 Applicability::MaybeIncorrect,
3206 );
3207 }
3208 }
3209
3210 #[track_caller]
3213 pub fn emit_node_lint(
3214 self,
3215 lint: &'static Lint,
3216 id: HirId,
3217 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3218 ) {
3219 self.node_lint(lint, id, |lint| {
3220 decorator.decorate_lint(lint);
3221 })
3222 }
3223
3224 #[rustc_lint_diagnostics]
3228 #[track_caller]
3229 pub fn node_lint(
3230 self,
3231 lint: &'static Lint,
3232 id: HirId,
3233 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3234 ) {
3235 let level = self.lint_level_at_node(lint, id);
3236 lint_level(self.sess, lint, level, None, decorate);
3237 }
3238
3239 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3240 let map = self.in_scope_traits_map(id.owner)?;
3241 let candidates = map.get(&id.local_id)?;
3242 Some(candidates)
3243 }
3244
3245 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3246 debug!(?id, "named_region");
3247 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3248 }
3249
3250 pub fn is_late_bound(self, id: HirId) -> bool {
3251 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3252 }
3253
3254 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
3255 self.mk_bound_variable_kinds(
3256 &self
3257 .late_bound_vars_map(id.owner)
3258 .get(&id.local_id)
3259 .cloned()
3260 .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
3261 )
3262 }
3263
3264 pub fn map_opaque_lifetime_to_parent_lifetime(
3272 self,
3273 mut opaque_lifetime_param_def_id: LocalDefId,
3274 ) -> ty::Region<'tcx> {
3275 debug_assert!(
3276 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3277 "{opaque_lifetime_param_def_id:?} is a {}",
3278 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3279 );
3280
3281 loop {
3282 let parent = self.local_parent(opaque_lifetime_param_def_id);
3283 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3284
3285 let Some((lifetime, _)) = lifetime_mapping
3286 .iter()
3287 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3288 else {
3289 bug!("duplicated lifetime param should be present");
3290 };
3291
3292 match *lifetime {
3293 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3294 let new_parent = self.local_parent(ebv);
3295
3296 if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3299 debug_assert_eq!(self.local_parent(parent), new_parent);
3300 opaque_lifetime_param_def_id = ebv;
3301 continue;
3302 }
3303
3304 let generics = self.generics_of(new_parent);
3305 return ty::Region::new_early_param(
3306 self,
3307 ty::EarlyParamRegion {
3308 index: generics
3309 .param_def_id_to_index(self, ebv.to_def_id())
3310 .expect("early-bound var should be present in fn generics"),
3311 name: self.item_name(ebv.to_def_id()),
3312 },
3313 );
3314 }
3315 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3316 let new_parent = self.local_parent(lbv);
3317 return ty::Region::new_late_param(
3318 self,
3319 new_parent.to_def_id(),
3320 ty::LateParamRegionKind::Named(lbv.to_def_id()),
3321 );
3322 }
3323 resolve_bound_vars::ResolvedArg::Error(guar) => {
3324 return ty::Region::new_error(self, guar);
3325 }
3326 _ => {
3327 return ty::Region::new_error_with_message(
3328 self,
3329 self.def_span(opaque_lifetime_param_def_id),
3330 "cannot resolve lifetime",
3331 );
3332 }
3333 }
3334 }
3335 }
3336
3337 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3342 self.is_const_fn(def_id)
3343 && match self.lookup_const_stability(def_id) {
3344 None => true, Some(stability) if stability.is_const_stable() => true,
3346 _ => false,
3347 }
3348 }
3349
3350 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3352 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3353 && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const
3354 }
3355
3356 pub fn is_sdylib_interface_build(self) -> bool {
3357 self.sess.opts.unstable_opts.build_sdylib_interface
3358 }
3359
3360 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3361 match self.def_kind(def_id) {
3362 DefKind::Fn | DefKind::AssocFn => {}
3363 _ => return None,
3364 }
3365 self.intrinsic_raw(def_id)
3366 }
3367
3368 pub fn next_trait_solver_globally(self) -> bool {
3369 self.sess.opts.unstable_opts.next_solver.globally
3370 }
3371
3372 pub fn next_trait_solver_in_coherence(self) -> bool {
3373 self.sess.opts.unstable_opts.next_solver.coherence
3374 }
3375
3376 #[allow(rustc::bad_opt_access)]
3377 pub fn use_typing_mode_borrowck(self) -> bool {
3378 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3379 }
3380
3381 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3382 self.opt_rpitit_info(def_id).is_some()
3383 }
3384
3385 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3395 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3396 }
3397
3398 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
3400 self.resolutions(()).extern_crate_map.get(&def_id).copied()
3401 }
3402
3403 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3404 self.resolver_for_lowering_raw(()).0
3405 }
3406
3407 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
3408 crate::dep_graph::make_metadata(self)
3409 }
3410
3411 pub fn impl_trait_ref(
3414 self,
3415 def_id: impl IntoQueryParam<DefId>,
3416 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
3417 Some(self.impl_trait_header(def_id)?.trait_ref)
3418 }
3419
3420 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
3421 self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
3422 }
3423
3424 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3425 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3426 self.coroutine_kind(def_id)
3427 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3428 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3429 {
3430 true
3431 } else {
3432 false
3433 }
3434 }
3435
3436 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3438 self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
3439 }
3440
3441 pub fn is_entrypoint(self, def_id: DefId) -> bool {
3444 if self.is_lang_item(def_id, LangItem::Start) {
3445 return true;
3446 }
3447 if let Some((entry_def_id, _)) = self.entry_fn(())
3448 && entry_def_id == def_id
3449 {
3450 return true;
3451 }
3452 false
3453 }
3454}
3455
3456#[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)]
3465pub struct DeducedParamAttrs {
3466 pub read_only: bool,
3469}
3470
3471pub fn provide(providers: &mut Providers) {
3472 providers.is_panic_runtime =
3473 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
3474 providers.is_compiler_builtins =
3475 |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins);
3476 providers.has_panic_handler = |tcx, LocalCrate| {
3477 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3479 };
3480 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3481}
3482
3483pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
3484 attrs.iter().any(|x| x.has_name(name))
3485}