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