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 is_type_const(self, def_id: DefId) -> bool {
1891 #[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)
1892 && {
{
'done:
{
for i in self.get_all_attrs(def_id) {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::TypeConst(_)) =>
{
break 'done Some(());
}
_ => {}
}
}
None
}
}.is_some()
}find_attr!(self.get_all_attrs(def_id), AttributeKind::TypeConst(_))
1893 }
1894
1895 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1898 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1899 }
1900
1901 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1903 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1904 self.coroutine_kind(def_id),
1905 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1906 )
1907 }
1908
1909 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1912 #[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)
1913 }
1914
1915 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1918 #[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(_)))
1919 }
1920
1921 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1923 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1924 self.coroutine_kind(def_id),
1925 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1926 )
1927 }
1928
1929 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1931 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1932 self.coroutine_kind(def_id),
1933 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1934 )
1935 }
1936
1937 pub fn features(self) -> &'tcx rustc_feature::Features {
1938 self.features_query(())
1939 }
1940
1941 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1942 let id = id.into_query_param();
1943 if let Some(id) = id.as_local() {
1945 self.definitions_untracked().def_key(id)
1946 } else {
1947 self.cstore_untracked().def_key(id)
1948 }
1949 }
1950
1951 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1957 if let Some(id) = id.as_local() {
1959 self.definitions_untracked().def_path(id)
1960 } else {
1961 self.cstore_untracked().def_path(id)
1962 }
1963 }
1964
1965 #[inline]
1966 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1967 if let Some(def_id) = def_id.as_local() {
1969 self.definitions_untracked().def_path_hash(def_id)
1970 } else {
1971 self.cstore_untracked().def_path_hash(def_id)
1972 }
1973 }
1974
1975 #[inline]
1976 pub fn crate_types(self) -> &'tcx [CrateType] {
1977 &self.crate_types
1978 }
1979
1980 pub fn needs_metadata(self) -> bool {
1981 self.crate_types().iter().any(|ty| match *ty {
1982 CrateType::Executable
1983 | CrateType::StaticLib
1984 | CrateType::Cdylib
1985 | CrateType::Sdylib => false,
1986 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1987 })
1988 }
1989
1990 pub fn needs_crate_hash(self) -> bool {
1991 truecfg!(debug_assertions)
2003 || self.sess.opts.incremental.is_some()
2004 || self.needs_metadata()
2005 || self.sess.instrument_coverage()
2006 || self.sess.opts.unstable_opts.metrics_dir.is_some()
2007 }
2008
2009 #[inline]
2010 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
2011 if crate_num == LOCAL_CRATE {
2012 self.stable_crate_id
2013 } else {
2014 self.cstore_untracked().stable_crate_id(crate_num)
2015 }
2016 }
2017
2018 #[inline]
2021 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
2022 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
2023 LOCAL_CRATE
2024 } else {
2025 *self
2026 .untracked()
2027 .stable_crate_ids
2028 .read()
2029 .get(&stable_crate_id)
2030 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
2031 }
2032 }
2033
2034 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
2038 {
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:2038",
"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(2038u32),
::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);
2039
2040 let stable_crate_id = hash.stable_crate_id();
2041
2042 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
2045 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
2046 } else {
2047 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
2048 }
2049 }
2050
2051 pub fn def_path_debug_str(self, def_id: DefId) -> String {
2052 let (crate_name, stable_crate_id) = if def_id.is_local() {
2057 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
2058 } else {
2059 let cstore = &*self.cstore_untracked();
2060 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
2061 };
2062
2063 ::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!(
2064 "{}[{:04x}]{}",
2065 crate_name,
2066 stable_crate_id.as_u64() >> (8 * 6),
2069 self.def_path(def_id).to_string_no_crate_verbose()
2070 )
2071 }
2072
2073 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
2074 self.sess.dcx()
2075 }
2076
2077 pub fn is_target_feature_call_safe(
2080 self,
2081 callee_features: &[TargetFeature],
2082 body_features: &[TargetFeature],
2083 ) -> bool {
2084 self.sess.target.options.is_like_wasm
2089 || callee_features
2090 .iter()
2091 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
2092 }
2093
2094 pub fn adjust_target_feature_sig(
2097 self,
2098 fun_def: DefId,
2099 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
2100 caller: DefId,
2101 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
2102 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
2103 let callee_features = &self.codegen_fn_attrs(caller).target_features;
2104 if self.is_target_feature_call_safe(&fun_features, &callee_features) {
2105 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
2106 }
2107 None
2108 }
2109
2110 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
2113 match self.env_var_os(key.as_ref()) {
2114 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
2115 None => Err(VarError::NotPresent),
2116 }
2117 }
2118}
2119
2120impl<'tcx> TyCtxtAt<'tcx> {
2121 pub fn create_def(
2123 self,
2124 parent: LocalDefId,
2125 name: Option<Symbol>,
2126 def_kind: DefKind,
2127 override_def_path_data: Option<DefPathData>,
2128 disambiguator: &mut DisambiguatorState,
2129 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2130 let feed =
2131 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
2132
2133 feed.def_span(self.span);
2134 feed
2135 }
2136}
2137
2138impl<'tcx> TyCtxt<'tcx> {
2139 pub fn create_def(
2141 self,
2142 parent: LocalDefId,
2143 name: Option<Symbol>,
2144 def_kind: DefKind,
2145 override_def_path_data: Option<DefPathData>,
2146 disambiguator: &mut DisambiguatorState,
2147 ) -> TyCtxtFeed<'tcx, LocalDefId> {
2148 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
2149 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
2159
2160 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
2165
2166 let feed = TyCtxtFeed { tcx: self, key: def_id };
2167 feed.def_kind(def_kind);
2168 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
2173 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
2174 feed.visibility(ty::Visibility::Restricted(parent_mod));
2175 }
2176
2177 feed
2178 }
2179
2180 pub fn create_crate_num(
2181 self,
2182 stable_crate_id: StableCrateId,
2183 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
2184 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
2185 return Err(existing);
2186 }
2187
2188 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
2189 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
2190 Ok(TyCtxtFeed { key: num, tcx: self })
2191 }
2192
2193 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
2194 self.ensure_ok().analysis(());
2196
2197 let definitions = &self.untracked.definitions;
2198 gen {
2199 let mut i = 0;
2200
2201 while i < { definitions.read().num_definitions() } {
2204 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
2205 yield LocalDefId { local_def_index };
2206 i += 1;
2207 }
2208
2209 definitions.freeze();
2211 }
2212 }
2213
2214 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
2215 self.ensure_ok().analysis(());
2217
2218 self.untracked.definitions.freeze().def_path_table()
2221 }
2222
2223 pub fn def_path_hash_to_def_index_map(
2224 self,
2225 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
2226 self.ensure_ok().hir_crate_items(());
2229 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
2232 }
2233
2234 #[inline]
2237 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
2238 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
2239 }
2240
2241 pub fn untracked(self) -> &'tcx Untracked {
2243 &self.untracked
2244 }
2245 #[inline]
2248 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
2249 self.untracked.definitions.read()
2250 }
2251
2252 #[inline]
2255 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
2256 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
2257 }
2258
2259 #[inline(always)]
2260 pub fn with_stable_hashing_context<R>(
2261 self,
2262 f: impl FnOnce(StableHashingContext<'_>) -> R,
2263 ) -> R {
2264 f(StableHashingContext::new(self.sess, &self.untracked))
2265 }
2266
2267 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
2268 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
2269 }
2270
2271 #[inline]
2272 pub fn local_crate_exports_generics(self) -> bool {
2273 if self.is_compiler_builtins(LOCAL_CRATE) {
2277 return false;
2278 }
2279 self.crate_types().iter().any(|crate_type| {
2280 match crate_type {
2281 CrateType::Executable
2282 | CrateType::StaticLib
2283 | CrateType::ProcMacro
2284 | CrateType::Cdylib
2285 | CrateType::Sdylib => false,
2286
2287 CrateType::Dylib => true,
2292
2293 CrateType::Rlib => true,
2294 }
2295 })
2296 }
2297
2298 pub fn is_suitable_region(
2300 self,
2301 generic_param_scope: LocalDefId,
2302 mut region: Region<'tcx>,
2303 ) -> Option<FreeRegionInfo> {
2304 let (suitable_region_binding_scope, region_def_id) = loop {
2305 let def_id =
2306 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
2307 let scope = self.local_parent(def_id);
2308 if self.def_kind(scope) == DefKind::OpaqueTy {
2309 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
2312 continue;
2313 }
2314 break (scope, def_id.into());
2315 };
2316
2317 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
2318 Node::Item(..) | Node::TraitItem(..) => false,
2319 Node::ImplItem(impl_item) => match impl_item.impl_kind {
2320 hir::ImplItemImplKind::Trait { .. } => true,
2327 _ => false,
2328 },
2329 _ => false,
2330 };
2331
2332 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
2333 }
2334
2335 pub fn return_type_impl_or_dyn_traits(
2337 self,
2338 scope_def_id: LocalDefId,
2339 ) -> Vec<&'tcx hir::Ty<'tcx>> {
2340 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2341 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
2342 self.hir_fn_decl_by_hir_id(hir_id)
2343 else {
2344 return ::alloc::vec::Vec::new()vec![];
2345 };
2346
2347 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
2348 v.visit_ty_unambig(hir_output);
2349 v.0
2350 }
2351
2352 pub fn return_type_impl_or_dyn_traits_with_type_alias(
2356 self,
2357 scope_def_id: LocalDefId,
2358 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
2359 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
2360 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
2361 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
2363 && let hir::TyKind::Path(hir::QPath::Resolved(
2364 None,
2365 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
2366 && let Some(local_id) = def_id.as_local()
2367 && 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()
2369 {
2370 v.visit_ty_unambig(alias_ty);
2371 if !v.0.is_empty() {
2372 return Some((
2373 v.0,
2374 alias_generics.span,
2375 alias_generics.span_for_lifetime_suggestion(),
2376 ));
2377 }
2378 }
2379 None
2380 }
2381
2382 pub fn has_strict_asm_symbol_naming(self) -> bool {
2385 self.sess.target.llvm_target.starts_with("nvptx")
2386 }
2387
2388 pub fn caller_location_ty(self) -> Ty<'tcx> {
2390 Ty::new_imm_ref(
2391 self,
2392 self.lifetimes.re_static,
2393 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
2394 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
2395 )
2396 }
2397
2398 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
2400 let kind = self.def_kind(def_id);
2401 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
2402 }
2403
2404 pub fn type_length_limit(self) -> Limit {
2405 self.limits(()).type_length_limit
2406 }
2407
2408 pub fn recursion_limit(self) -> Limit {
2409 self.limits(()).recursion_limit
2410 }
2411
2412 pub fn move_size_limit(self) -> Limit {
2413 self.limits(()).move_size_limit
2414 }
2415
2416 pub fn pattern_complexity_limit(self) -> Limit {
2417 self.limits(()).pattern_complexity_limit
2418 }
2419
2420 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
2422 iter::once(LOCAL_CRATE)
2423 .chain(self.crates(()).iter().copied())
2424 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2425 }
2426
2427 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
2429 let visible_crates =
2430 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2431
2432 iter::once(LOCAL_CRATE)
2433 .chain(visible_crates)
2434 .flat_map(move |cnum| self.traits(cnum).iter().copied())
2435 }
2436
2437 #[inline]
2438 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
2439 self.visibility(def_id).expect_local()
2440 }
2441
2442 x;#[instrument(skip(self), level = "trace", ret)]
2444 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
2445 self.hir_expect_opaque_ty(def_id).origin
2446 }
2447
2448 pub fn finish(self) {
2449 self.alloc_self_profile_query_strings();
2452
2453 self.save_dep_graph();
2454 self.query_key_hash_verify_all();
2455
2456 if let Err((path, error)) = self.dep_graph.finish_encoding() {
2457 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
2458 }
2459 }
2460}
2461
2462macro_rules! nop_lift {
2463 ($set:ident; $ty:ty => $lifted:ty) => {
2464 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
2465 type Lifted = $lifted;
2466 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2467 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
2472 _x: Interned<'tcx, Inner>,
2473 ) -> InternedSet<'tcx, Inner> {
2474 unreachable!()
2475 }
2476 fn _type_eq<T>(_x: &T, _y: &T) {}
2477 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
2478 let interner = _intern_set_ty_from_interned_ty(x.0);
2482 _type_eq(&interner, &tcx.interners.$set);
2484 }
2485
2486 tcx.interners
2487 .$set
2488 .contains_pointer_to(&InternedInSet(&*self.0.0))
2489 .then(|| unsafe { mem::transmute(self) })
2492 }
2493 }
2494 };
2495}
2496
2497macro_rules! nop_list_lift {
2498 ($set:ident; $ty:ty => $lifted:ty) => {
2499 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
2500 type Lifted = &'tcx List<$lifted>;
2501 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
2502 if false {
2504 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
2505 }
2506
2507 if self.is_empty() {
2508 return Some(List::empty());
2509 }
2510 tcx.interners
2511 .$set
2512 .contains_pointer_to(&InternedInSet(self))
2513 .then(|| unsafe { mem::transmute(self) })
2514 }
2515 }
2516 };
2517}
2518
2519impl<'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> }
2520impl<'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> }
2521impl<'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> }
2522impl<'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> }
2523impl<'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> }
2524impl<'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> }
2525impl<'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> }
2526impl<'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> }
2527impl<'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> }
2528
2529impl<'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> }
2530impl<'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! {
2531 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
2532}
2533impl<'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> }
2534
2535impl<'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> }
2537
2538macro_rules! sty_debug_print {
2539 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
2540 #[allow(non_snake_case)]
2543 mod inner {
2544 use crate::ty::{self, TyCtxt};
2545 use crate::ty::context::InternedInSet;
2546
2547 #[derive(Copy, Clone)]
2548 struct DebugStat {
2549 total: usize,
2550 lt_infer: usize,
2551 ty_infer: usize,
2552 ct_infer: usize,
2553 all_infer: usize,
2554 }
2555
2556 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
2557 let mut total = DebugStat {
2558 total: 0,
2559 lt_infer: 0,
2560 ty_infer: 0,
2561 ct_infer: 0,
2562 all_infer: 0,
2563 };
2564 $(let mut $variant = total;)*
2565
2566 for shard in tcx.interners.type_.lock_shards() {
2567 #[allow(rustc::potential_query_instability)]
2569 let types = shard.iter();
2570 for &(InternedInSet(t), ()) in types {
2571 let variant = match t.internee {
2572 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
2573 ty::Float(..) | ty::Str | ty::Never => continue,
2574 ty::Error(_) => continue,
2575 $(ty::$variant(..) => &mut $variant,)*
2576 };
2577 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
2578 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
2579 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
2580
2581 variant.total += 1;
2582 total.total += 1;
2583 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
2584 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
2585 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
2586 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
2587 }
2588 }
2589 writeln!(fmt, "Ty interner total ty lt ct all")?;
2590 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
2591 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2592 stringify!($variant),
2593 uses = $variant.total,
2594 usespc = $variant.total as f64 * 100.0 / total.total as f64,
2595 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
2596 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
2597 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
2598 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
2599 )*
2600 writeln!(fmt, " total {uses:6} \
2601 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
2602 uses = total.total,
2603 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
2604 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
2605 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
2606 all = total.all_infer as f64 * 100.0 / total.total as f64)
2607 }
2608 }
2609
2610 inner::go($fmt, $ctxt)
2611 }}
2612}
2613
2614impl<'tcx> TyCtxt<'tcx> {
2615 pub fn debug_stats(self) -> impl fmt::Debug {
2616 fmt::from_fn(move |fmt| {
2617 {
#[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!(
2618 fmt,
2619 self,
2620 Adt,
2621 Array,
2622 Slice,
2623 RawPtr,
2624 Ref,
2625 FnDef,
2626 FnPtr,
2627 UnsafeBinder,
2628 Placeholder,
2629 Coroutine,
2630 CoroutineWitness,
2631 Dynamic,
2632 Closure,
2633 CoroutineClosure,
2634 Tuple,
2635 Bound,
2636 Param,
2637 Infer,
2638 Alias,
2639 Pat,
2640 Foreign
2641 )?;
2642
2643 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2644 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2645 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())?;
2646 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2647
2648 Ok(())
2649 })
2650 }
2651}
2652
2653struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
2658
2659impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
2660 fn clone(&self) -> Self {
2661 *self
2662 }
2663}
2664
2665impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
2666
2667impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
2668 fn into_pointer(&self) -> *const () {
2669 self.0 as *const _ as *const ()
2670 }
2671}
2672
2673#[allow(rustc::usage_of_ty_tykind)]
2674impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2675 fn borrow(&self) -> &T {
2676 &self.0.internee
2677 }
2678}
2679
2680impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2681 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2682 self.0.internee == other.0.internee
2685 }
2686}
2687
2688impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2689
2690impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2691 fn hash<H: Hasher>(&self, s: &mut H) {
2692 self.0.internee.hash(s)
2694 }
2695}
2696
2697impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2698 fn borrow(&self) -> &[T] {
2699 &self.0[..]
2700 }
2701}
2702
2703impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2704 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2705 self.0[..] == other.0[..]
2708 }
2709}
2710
2711impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2712
2713impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2714 fn hash<H: Hasher>(&self, s: &mut H) {
2715 self.0[..].hash(s)
2717 }
2718}
2719
2720impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2721 fn borrow(&self) -> &[T] {
2722 &self.0[..]
2723 }
2724}
2725
2726impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2727 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2728 self.0[..] == other.0[..]
2731 }
2732}
2733
2734impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2735
2736impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2737 fn hash<H: Hasher>(&self, s: &mut H) {
2738 self.0[..].hash(s)
2740 }
2741}
2742
2743macro_rules! direct_interners {
2744 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2745 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2746 fn borrow<'a>(&'a self) -> &'a $ty {
2747 &self.0
2748 }
2749 }
2750
2751 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2752 fn eq(&self, other: &Self) -> bool {
2753 self.0 == other.0
2756 }
2757 }
2758
2759 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2760
2761 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2762 fn hash<H: Hasher>(&self, s: &mut H) {
2763 self.0.hash(s)
2766 }
2767 }
2768
2769 impl<'tcx> TyCtxt<'tcx> {
2770 $vis fn $method(self, v: $ty) -> $ret_ty {
2771 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2772 InternedInSet(self.interners.arena.alloc(v))
2773 }).0))
2774 }
2775 })+
2776 }
2777}
2778
2779impl<'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! {
2783 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2784 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2785 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2786 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2787 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2788 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2789 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2790 ExternalConstraints -> ExternalConstraints<'tcx>,
2791}
2792
2793macro_rules! slice_interners {
2794 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2795 impl<'tcx> TyCtxt<'tcx> {
2796 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2797 if v.is_empty() {
2798 List::empty()
2799 } else {
2800 self.interners.$field.intern_ref(v, || {
2801 InternedInSet(List::from_arena(&*self.arena, (), v))
2802 }).0
2803 }
2804 })+
2805 }
2806 );
2807}
2808
2809impl<'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!(
2813 const_lists: pub mk_const_list(Const<'tcx>),
2814 args: pub mk_args(GenericArg<'tcx>),
2815 type_lists: pub mk_type_list(Ty<'tcx>),
2816 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2817 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2818 projs: pub mk_projs(ProjectionKind),
2819 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2820 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2821 fields: pub mk_fields(FieldIdx),
2822 local_def_ids: intern_local_def_ids(LocalDefId),
2823 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2824 patterns: pub mk_patterns(Pattern<'tcx>),
2825 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2826 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2827);
2828
2829impl<'tcx> TyCtxt<'tcx> {
2830 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2834 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2835 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2836 }
2837
2838 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2842 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2843 sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig })
2844 }
2845
2846 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2849 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2850 self.associated_items(trait_did)
2851 .filter_by_name_unhygienic(assoc_name.name)
2852 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2853 })
2854 }
2855
2856 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2858 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
2859 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2860
2861 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2862 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2863 return false;
2864 };
2865 trait_predicate.trait_ref.def_id == future_trait
2866 && trait_predicate.polarity == PredicatePolarity::Positive
2867 })
2868 }
2869
2870 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2878 sig.map_bound(|s| {
2879 let params = match s.inputs()[0].kind() {
2880 ty::Tuple(params) => *params,
2881 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2882 };
2883 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2884 })
2885 }
2886
2887 #[inline]
2888 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2889 self.interners.intern_predicate(
2890 binder,
2891 self.sess,
2892 &self.untracked,
2894 )
2895 }
2896
2897 #[inline]
2898 pub fn reuse_or_mk_predicate(
2899 self,
2900 pred: Predicate<'tcx>,
2901 binder: Binder<'tcx, PredicateKind<'tcx>>,
2902 ) -> Predicate<'tcx> {
2903 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2904 }
2905
2906 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2907 self.check_args_compatible_inner(def_id, args, false)
2908 }
2909
2910 fn check_args_compatible_inner(
2911 self,
2912 def_id: DefId,
2913 args: &'tcx [ty::GenericArg<'tcx>],
2914 nested: bool,
2915 ) -> bool {
2916 let generics = self.generics_of(def_id);
2917
2918 let own_args = if !nested
2921 && let DefKind::AssocTy = self.def_kind(def_id)
2922 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2923 {
2924 if generics.own_params.len() + 1 != args.len() {
2925 return false;
2926 }
2927
2928 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2929 return false;
2930 }
2931
2932 &args[1..]
2933 } else {
2934 if generics.count() != args.len() {
2935 return false;
2936 }
2937
2938 let (parent_args, own_args) = args.split_at(generics.parent_count);
2939
2940 if let Some(parent) = generics.parent
2941 && !self.check_args_compatible_inner(parent, parent_args, true)
2942 {
2943 return false;
2944 }
2945
2946 own_args
2947 };
2948
2949 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2950 match (¶m.kind, arg.kind()) {
2951 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2952 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2953 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2954 _ => return false,
2955 }
2956 }
2957
2958 true
2959 }
2960
2961 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2964 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2965 if let DefKind::AssocTy = self.def_kind(def_id)
2966 && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
2967 {
2968 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!(
2969 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2970 self.def_path_str(def_id),
2971 args,
2972 self.mk_args_from_iter(
2974 [self.types.self_param.into()].into_iter().chain(
2975 self.generics_of(def_id)
2976 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2977 .iter()
2978 .copied()
2979 )
2980 )
2981 );
2982 } else {
2983 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!(
2984 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2985 self.def_path_str(def_id),
2986 args,
2987 ty::GenericArgs::identity_for_item(self, def_id)
2988 );
2989 }
2990 }
2991 }
2992
2993 #[inline(always)]
2994 pub(crate) fn check_and_mk_args(
2995 self,
2996 def_id: DefId,
2997 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2998 ) -> GenericArgsRef<'tcx> {
2999 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
3000 self.debug_assert_args_compatible(def_id, args);
3001 args
3002 }
3003
3004 #[inline]
3005 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
3006 self.interners.intern_const(
3007 kind,
3008 self.sess,
3009 &self.untracked,
3011 )
3012 }
3013
3014 #[allow(rustc::usage_of_ty_tykind)]
3016 #[inline]
3017 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
3018 self.interners.intern_ty(
3019 st,
3020 self.sess,
3021 &self.untracked,
3023 )
3024 }
3025
3026 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
3027 match param.kind {
3028 GenericParamDefKind::Lifetime => {
3029 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
3030 }
3031 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
3032 GenericParamDefKind::Const { .. } => {
3033 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
3034 .into()
3035 }
3036 }
3037 }
3038
3039 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
3040 self.mk_place_elem(place, PlaceElem::Field(f, ty))
3041 }
3042
3043 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
3044 self.mk_place_elem(place, PlaceElem::Deref)
3045 }
3046
3047 pub fn mk_place_downcast(
3048 self,
3049 place: Place<'tcx>,
3050 adt_def: AdtDef<'tcx>,
3051 variant_index: VariantIdx,
3052 ) -> Place<'tcx> {
3053 self.mk_place_elem(
3054 place,
3055 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
3056 )
3057 }
3058
3059 pub fn mk_place_downcast_unnamed(
3060 self,
3061 place: Place<'tcx>,
3062 variant_index: VariantIdx,
3063 ) -> Place<'tcx> {
3064 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
3065 }
3066
3067 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
3068 self.mk_place_elem(place, PlaceElem::Index(index))
3069 }
3070
3071 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
3075 let mut projection = place.projection.to_vec();
3076 projection.push(elem);
3077
3078 Place { local: place.local, projection: self.mk_place_elems(&projection) }
3079 }
3080
3081 pub fn mk_poly_existential_predicates(
3082 self,
3083 eps: &[PolyExistentialPredicate<'tcx>],
3084 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
3085 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
3086 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!(
3087 eps.array_windows()
3088 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
3089 != Ordering::Greater)
3090 );
3091 self.intern_poly_existential_predicates(eps)
3092 }
3093
3094 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
3095 self.interners.intern_clauses(clauses)
3099 }
3100
3101 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
3102 self.intern_local_def_ids(def_ids)
3106 }
3107
3108 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
3109 where
3110 I: Iterator<Item = T>,
3111 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
3112 {
3113 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
3114 }
3115
3116 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
3117 where
3118 I: Iterator<Item = T>,
3119 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
3120 {
3121 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
3122 }
3123
3124 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
3125 where
3126 I: Iterator<Item = T>,
3127 T: CollectAndApply<
3128 &'tcx ty::CapturedPlace<'tcx>,
3129 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
3130 >,
3131 {
3132 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
3133 }
3134
3135 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
3136 where
3137 I: Iterator<Item = T>,
3138 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
3139 {
3140 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
3141 }
3142
3143 pub fn mk_fn_sig<I, T>(
3148 self,
3149 inputs: I,
3150 output: I::Item,
3151 c_variadic: bool,
3152 safety: hir::Safety,
3153 abi: ExternAbi,
3154 ) -> T::Output
3155 where
3156 I: IntoIterator<Item = T>,
3157 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
3158 {
3159 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
3160 inputs_and_output: self.mk_type_list(xs),
3161 c_variadic,
3162 safety,
3163 abi,
3164 })
3165 }
3166
3167 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
3168 where
3169 I: Iterator<Item = T>,
3170 T: CollectAndApply<
3171 PolyExistentialPredicate<'tcx>,
3172 &'tcx List<PolyExistentialPredicate<'tcx>>,
3173 >,
3174 {
3175 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
3176 }
3177
3178 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
3179 where
3180 I: Iterator<Item = T>,
3181 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
3182 {
3183 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
3184 }
3185
3186 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
3187 where
3188 I: Iterator<Item = T>,
3189 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
3190 {
3191 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
3192 }
3193
3194 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
3195 where
3196 I: Iterator<Item = T>,
3197 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
3198 {
3199 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
3200 }
3201
3202 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
3203 where
3204 I: Iterator<Item = T>,
3205 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
3206 {
3207 T::collect_and_apply(iter, |xs| self.mk_args(xs))
3208 }
3209
3210 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
3211 where
3212 I: Iterator<Item = T>,
3213 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3214 {
3215 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
3216 }
3217
3218 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
3219 where
3220 I: Iterator<Item = T>,
3221 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
3222 {
3223 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
3224 }
3225
3226 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
3227 where
3228 I: Iterator<Item = T>,
3229 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
3230 {
3231 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
3232 }
3233
3234 pub fn mk_args_trait(
3235 self,
3236 self_ty: Ty<'tcx>,
3237 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
3238 ) -> GenericArgsRef<'tcx> {
3239 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
3240 }
3241
3242 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
3243 where
3244 I: Iterator<Item = T>,
3245 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
3246 {
3247 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
3248 }
3249
3250 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
3251 where
3252 I: Iterator<Item = T>,
3253 T: CollectAndApply<
3254 ty::ArgOutlivesPredicate<'tcx>,
3255 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
3256 >,
3257 {
3258 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
3259 }
3260
3261 #[track_caller]
3264 pub fn emit_node_span_lint(
3265 self,
3266 lint: &'static Lint,
3267 hir_id: HirId,
3268 span: impl Into<MultiSpan>,
3269 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3270 ) {
3271 let level = self.lint_level_at_node(lint, hir_id);
3272 lint_level(self.sess, lint, level, Some(span.into()), |lint| {
3273 decorator.decorate_lint(lint);
3274 })
3275 }
3276
3277 #[track_caller]
3281 pub fn node_span_lint(
3282 self,
3283 lint: &'static Lint,
3284 hir_id: HirId,
3285 span: impl Into<MultiSpan>,
3286 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3287 ) {
3288 let level = self.lint_level_at_node(lint, hir_id);
3289 lint_level(self.sess, lint, level, Some(span.into()), decorate);
3290 }
3291
3292 pub fn crate_level_attribute_injection_span(self) -> Span {
3294 let node = self.hir_node(hir::CRATE_HIR_ID);
3295 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
3296 m.spans.inject_use_span.shrink_to_lo()
3297 }
3298
3299 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
3300 self,
3301 diag: &mut Diag<'_, E>,
3302 features: impl IntoIterator<Item = (String, Symbol)>,
3303 ) {
3304 if !self.sess.is_nightly_build() {
3305 return;
3306 }
3307
3308 let span = self.crate_level_attribute_injection_span();
3309 for (desc, feature) in features {
3310 let msg =
3312 ::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}");
3313 diag.span_suggestion_verbose(
3314 span,
3315 msg,
3316 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
3317 Applicability::MaybeIncorrect,
3318 );
3319 }
3320 }
3321
3322 #[track_caller]
3325 pub fn emit_node_lint(
3326 self,
3327 lint: &'static Lint,
3328 id: HirId,
3329 decorator: impl for<'a> LintDiagnostic<'a, ()>,
3330 ) {
3331 self.node_lint(lint, id, |lint| {
3332 decorator.decorate_lint(lint);
3333 })
3334 }
3335
3336 #[track_caller]
3340 pub fn node_lint(
3341 self,
3342 lint: &'static Lint,
3343 id: HirId,
3344 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
3345 ) {
3346 let level = self.lint_level_at_node(lint, id);
3347 lint_level(self.sess, lint, level, None, decorate);
3348 }
3349
3350 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
3351 let map = self.in_scope_traits_map(id.owner)?;
3352 let candidates = map.get(&id.local_id)?;
3353 Some(candidates)
3354 }
3355
3356 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
3357 {
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:3357",
"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(3357u32),
::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");
3358 self.named_variable_map(id.owner).get(&id.local_id).cloned()
3359 }
3360
3361 pub fn is_late_bound(self, id: HirId) -> bool {
3362 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
3363 }
3364
3365 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
3366 self.mk_bound_variable_kinds(
3367 &self
3368 .late_bound_vars_map(id.owner)
3369 .get(&id.local_id)
3370 .cloned()
3371 .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))),
3372 )
3373 }
3374
3375 pub fn map_opaque_lifetime_to_parent_lifetime(
3383 self,
3384 mut opaque_lifetime_param_def_id: LocalDefId,
3385 ) -> ty::Region<'tcx> {
3386 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!(
3387 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
3388 "{opaque_lifetime_param_def_id:?} is a {}",
3389 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
3390 );
3391
3392 loop {
3393 let parent = self.local_parent(opaque_lifetime_param_def_id);
3394 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
3395
3396 let Some((lifetime, _)) = lifetime_mapping
3397 .iter()
3398 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
3399 else {
3400 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
3401 };
3402
3403 match *lifetime {
3404 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
3405 let new_parent = self.local_parent(ebv);
3406
3407 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
3410 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);
3411 opaque_lifetime_param_def_id = ebv;
3412 continue;
3413 }
3414
3415 let generics = self.generics_of(new_parent);
3416 return ty::Region::new_early_param(
3417 self,
3418 ty::EarlyParamRegion {
3419 index: generics
3420 .param_def_id_to_index(self, ebv.to_def_id())
3421 .expect("early-bound var should be present in fn generics"),
3422 name: self.item_name(ebv.to_def_id()),
3423 },
3424 );
3425 }
3426 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
3427 let new_parent = self.local_parent(lbv);
3428 return ty::Region::new_late_param(
3429 self,
3430 new_parent.to_def_id(),
3431 ty::LateParamRegionKind::Named(lbv.to_def_id()),
3432 );
3433 }
3434 resolve_bound_vars::ResolvedArg::Error(guar) => {
3435 return ty::Region::new_error(self, guar);
3436 }
3437 _ => {
3438 return ty::Region::new_error_with_message(
3439 self,
3440 self.def_span(opaque_lifetime_param_def_id),
3441 "cannot resolve lifetime",
3442 );
3443 }
3444 }
3445 }
3446 }
3447
3448 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3453 self.is_const_fn(def_id)
3454 && match self.lookup_const_stability(def_id) {
3455 None => true, Some(stability) if stability.is_const_stable() => true,
3457 _ => false,
3458 }
3459 }
3460
3461 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3463 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3464 && self.impl_trait_header(def_id).constness == hir::Constness::Const
3465 }
3466
3467 pub fn is_sdylib_interface_build(self) -> bool {
3468 self.sess.opts.unstable_opts.build_sdylib_interface
3469 }
3470
3471 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
3472 match self.def_kind(def_id) {
3473 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
3474 _ => None,
3475 }
3476 }
3477
3478 pub fn next_trait_solver_globally(self) -> bool {
3479 self.sess.opts.unstable_opts.next_solver.globally
3480 }
3481
3482 pub fn next_trait_solver_in_coherence(self) -> bool {
3483 self.sess.opts.unstable_opts.next_solver.coherence
3484 }
3485
3486 #[allow(rustc::bad_opt_access)]
3487 pub fn use_typing_mode_borrowck(self) -> bool {
3488 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
3489 }
3490
3491 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
3492 self.opt_rpitit_info(def_id).is_some()
3493 }
3494
3495 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
3505 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
3506 }
3507
3508 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
3510 self.resolutions(()).extern_crate_map.get(&def_id).copied()
3511 }
3512
3513 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
3514 self.resolver_for_lowering_raw(()).0
3515 }
3516
3517 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
3518 crate::dep_graph::make_metadata(self)
3519 }
3520
3521 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
3522 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
3523 self.coroutine_kind(def_id)
3524 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
3525 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
3526 {
3527 true
3528 } else {
3529 false
3530 }
3531 }
3532
3533 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3535 {
{
'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 { .. })
3536 }
3537
3538 pub fn is_trivial_const<P>(self, def_id: P) -> bool
3539 where
3540 P: IntoQueryParam<DefId>,
3541 {
3542 self.trivial_const(def_id).is_some()
3543 }
3544
3545 pub fn is_entrypoint(self, def_id: DefId) -> bool {
3548 if self.is_lang_item(def_id, LangItem::Start) {
3549 return true;
3550 }
3551 if let Some((entry_def_id, _)) = self.entry_fn(())
3552 && entry_def_id == def_id
3553 {
3554 return true;
3555 }
3556 false
3557 }
3558}
3559
3560pub fn provide(providers: &mut Providers) {
3561 providers.is_panic_runtime =
3562 |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);
3563 providers.is_compiler_builtins =
3564 |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);
3565 providers.has_panic_handler = |tcx, LocalCrate| {
3566 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3568 };
3569 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3570}