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