1#![allow(rustc::usage_of_ty_tykind)]
4
5mod impl_interner;
6pub mod tls;
7
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::PointeeSized;
14use std::ops::Deref;
15use std::sync::{Arc, OnceLock};
16use std::{debug_assert_matches, fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_crate_store::{CrateStoreDyn, Untracked};
21use rustc_data_structures::defer;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::profiling::SelfProfilerRef;
25use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
26use rustc_data_structures::stable_hash::StableHash;
27use rustc_data_structures::steal::Steal;
28use rustc_data_structures::sync::{
29 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
30};
31use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
32use rustc_hir::attrs::lang_items::LangItem;
33use rustc_hir::def::DefKind;
34use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
35use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState};
36use rustc_hir::intravisit::VisitorExt;
37use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr};
38use rustc_index::IndexVec;
39use rustc_lint_defs::Lint;
40use rustc_lint_defs::builtin::UNUSED_FEATURES;
41use rustc_macros::Diagnostic;
42use rustc_session::{IncrCompSession, Session};
43use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
44use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
45use rustc_structures::{CrateType, Limit};
46use rustc_type_ir::TyKind::*;
47pub use rustc_type_ir::lift::Lift;
48use rustc_type_ir::{CollectAndApply, WithCachedTypeInfo, elaborate, search_graph};
49use tracing::{debug, instrument};
50
51use crate::arena::Arena;
52use crate::dep_graph::dep_node::make_metadata;
53use crate::dep_graph::{DepGraph, DepNodeIndex};
54use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo};
55use crate::ich::StableHashState;
56use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
57use crate::lint::emit_lint_base;
58use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
59use crate::middle::resolve::{ModChild, ResolverAstLowering};
60use crate::middle::resolve_bound_vars;
61use crate::mir::interpret::{self, Allocation, ConstAllocation};
62use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
63use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
64use crate::thir::Thir;
65use crate::traits;
66use crate::traits::solve::{
67 CanonicalInput, CanonicalInputData, ExternalConstraints, ExternalConstraintsData,
68 PredefinedOpaques,
69};
70use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
71use crate::ty::{
72 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, ClausePolarity, Clauses, Const, FnSigKind,
73 GenericArg, GenericArgs, GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo,
74 ParamConst, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate,
75 PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, ValTree,
76 ValTreeKind, Visibility,
77};
78
79impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
80 fn is_local(self) -> bool {
81 self.is_local()
82 }
83
84 fn as_local(self) -> Option<LocalDefId> {
85 self.as_local()
86 }
87}
88
89impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
90 fn safe() -> Self {
91 hir::Safety::Safe
92 }
93
94 fn unsafe_mode() -> Self {
95 hir::Safety::Unsafe
96 }
97
98 fn is_safe(self) -> bool {
99 self.is_safe()
100 }
101
102 fn prefix_str(self) -> &'static str {
103 self.prefix_str()
104 }
105}
106
107impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
108 fn generic_const_exprs(self) -> bool {
109 self.generic_const_exprs()
110 }
111
112 fn generic_const_args(self) -> bool {
113 self.generic_const_args()
114 }
115
116 fn coroutine_clone(self) -> bool {
117 self.coroutine_clone()
118 }
119
120 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
121 !self.staged_api() && self.enabled(symbol)
125 }
126}
127
128impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
129 fn dummy() -> Self {
130 DUMMY_SP
131 }
132}
133
134type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
135
136pub struct CtxtInterners<'tcx> {
137 arena: &'tcx WorkerLocal<Arena<'tcx>>,
139
140 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
143 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
144 args: InternedSet<'tcx, GenericArgs<'tcx>>,
145 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
146 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
147 region: InternedSet<'tcx, RegionKind<'tcx>>,
148 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
149 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
150 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
151 projs: InternedSet<'tcx, List<ProjectionKind>>,
152 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
153 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
154 pat: InternedSet<'tcx, PatternKind<'tcx>>,
155 const_allocation: InternedSet<'tcx, Allocation>,
156 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
157 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
158 adt_def: InternedSet<'tcx, AdtDefData>,
159 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
160 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
161 fields: InternedSet<'tcx, List<FieldIdx>>,
162 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
163 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
164 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
165 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
166 outlives: InternedSet<'tcx, List<ty::ArgOutlivesClause<'tcx>>>,
167 canonical_inputs: InternedSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>>,
168}
169
170impl<'tcx> CtxtInterners<'tcx> {
171 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
172 const N: usize = 2048;
175 CtxtInterners {
176 arena,
177 type_: InternedSet::with_capacity(N * 16),
182 const_lists: InternedSet::with_capacity(N * 4),
183 args: InternedSet::with_capacity(N * 4),
184 type_lists: InternedSet::with_capacity(N * 4),
185 region: InternedSet::with_capacity(N * 4),
186 poly_existential_predicates: InternedSet::with_capacity(N / 4),
187 canonical_var_kinds: InternedSet::with_capacity(N / 2),
188 predicate: InternedSet::with_capacity(N),
189 clauses: InternedSet::with_capacity(N),
190 projs: InternedSet::with_capacity(N * 4),
191 place_elems: InternedSet::with_capacity(N * 2),
192 const_: InternedSet::with_capacity(N * 2),
193 pat: InternedSet::with_capacity(N),
194 const_allocation: InternedSet::with_capacity(N),
195 bound_variable_kinds: InternedSet::with_capacity(N * 2),
196 layout: InternedSet::with_capacity(N),
197 adt_def: InternedSet::with_capacity(N),
198 external_constraints: InternedSet::with_capacity(N),
199 predefined_opaques_in_body: InternedSet::with_capacity(N),
200 fields: InternedSet::with_capacity(N * 4),
201 local_def_ids: InternedSet::with_capacity(N),
202 captures: InternedSet::with_capacity(N),
203 valtree: InternedSet::with_capacity(N),
204 patterns: InternedSet::with_capacity(N),
205 outlives: InternedSet::with_capacity(N),
206 canonical_inputs: InternedSet::with_capacity(N),
207 }
208 }
209
210 #[allow(rustc::usage_of_ty_tykind)]
212 #[inline(never)]
213 fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
214 Ty(Interned::new_unchecked(
215 self.type_
216 .intern(kind, |kind| {
217 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
218 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
219 internee: kind,
220 flags: flags.flags,
221 outer_exclusive_binder: flags.outer_exclusive_binder,
222 }))
223 })
224 .0,
225 ))
226 }
227
228 #[allow(rustc::usage_of_ty_tykind)]
230 #[inline(never)]
231 fn intern_const(&self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
232 Const(Interned::new_unchecked(
233 self.const_
234 .intern(kind, |kind: ty::ConstKind<'_>| {
235 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
236 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
237 internee: kind,
238 flags: flags.flags,
239 outer_exclusive_binder: flags.outer_exclusive_binder,
240 }))
241 })
242 .0,
243 ))
244 }
245
246 #[inline(never)]
248 fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
249 Predicate(Interned::new_unchecked(
250 self.predicate
251 .intern(kind, |kind| {
252 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
253 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
254 internee: kind,
255 flags: flags.flags,
256 outer_exclusive_binder: flags.outer_exclusive_binder,
257 }))
258 })
259 .0,
260 ))
261 }
262
263 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
264 if clauses.is_empty() {
265 ListWithCachedTypeInfo::empty()
266 } else {
267 self.clauses
268 .intern_ref(clauses, || {
269 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
270
271 InternedInSet(ListWithCachedTypeInfo::from_arena(
272 &*self.arena,
273 flags.into(),
274 clauses,
275 ))
276 })
277 .0
278 }
279 }
280}
281
282const NUM_PREINTERNED_TY_VARS: u32 = 100;
287const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
288const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
289const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
290const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
291
292const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
302
303const NUM_PREINTERNED_RE_VARS: u32 = 500;
305const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
306const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
307
308pub struct CommonTypes<'tcx> {
309 pub unit: Ty<'tcx>,
310 pub bool: Ty<'tcx>,
311 pub char: Ty<'tcx>,
312 pub isize: Ty<'tcx>,
313 pub i8: Ty<'tcx>,
314 pub i16: Ty<'tcx>,
315 pub i32: Ty<'tcx>,
316 pub i64: Ty<'tcx>,
317 pub i128: Ty<'tcx>,
318 pub usize: Ty<'tcx>,
319 pub u8: Ty<'tcx>,
320 pub u16: Ty<'tcx>,
321 pub u32: Ty<'tcx>,
322 pub u64: Ty<'tcx>,
323 pub u128: Ty<'tcx>,
324 pub f16: Ty<'tcx>,
325 pub f32: Ty<'tcx>,
326 pub f64: Ty<'tcx>,
327 pub f128: Ty<'tcx>,
328 pub str_: Ty<'tcx>,
329 pub never: Ty<'tcx>,
330 pub self_param: Ty<'tcx>,
331
332 pub trait_object_dummy_self: Ty<'tcx>,
359
360 pub ty_vars: Vec<Ty<'tcx>>,
362
363 pub fresh_tys: Vec<Ty<'tcx>>,
365
366 pub fresh_int_tys: Vec<Ty<'tcx>>,
368
369 pub fresh_float_tys: Vec<Ty<'tcx>>,
371
372 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
376
377 pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
381}
382
383pub struct CommonLifetimes<'tcx> {
384 pub re_static: Region<'tcx>,
386
387 pub re_erased: Region<'tcx>,
389
390 pub re_vars: Vec<Region<'tcx>>,
392
393 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
397
398 pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
402}
403
404pub struct CommonConsts<'tcx> {
405 pub unit: Const<'tcx>,
406 pub true_: Const<'tcx>,
407 pub false_: Const<'tcx>,
408 pub(crate) valtree_zst: ValTree<'tcx>,
410}
411
412impl<'tcx> CommonTypes<'tcx> {
413 fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
414 let mk = |ty| interners.intern_ty(ty);
415
416 let ty_vars =
417 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
418 let fresh_tys: Vec<_> =
419 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
420 let fresh_int_tys: Vec<_> =
421 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
422 let fresh_float_tys: Vec<_> =
423 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
424
425 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
426 .map(|i| {
427 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
428 .map(|v| {
429 mk(ty::Bound(
430 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
431 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
432 ))
433 })
434 .collect()
435 })
436 .collect();
437
438 let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
439 .map(|v| {
440 mk(ty::Bound(
441 ty::BoundVarIndexKind::Canonical,
442 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
443 ))
444 })
445 .collect();
446
447 CommonTypes {
448 unit: mk(Tuple(List::empty())),
449 bool: mk(Bool),
450 char: mk(Char),
451 never: mk(Never),
452 isize: mk(Int(ty::IntTy::Isize)),
453 i8: mk(Int(ty::IntTy::I8)),
454 i16: mk(Int(ty::IntTy::I16)),
455 i32: mk(Int(ty::IntTy::I32)),
456 i64: mk(Int(ty::IntTy::I64)),
457 i128: mk(Int(ty::IntTy::I128)),
458 usize: mk(Uint(ty::UintTy::Usize)),
459 u8: mk(Uint(ty::UintTy::U8)),
460 u16: mk(Uint(ty::UintTy::U16)),
461 u32: mk(Uint(ty::UintTy::U32)),
462 u64: mk(Uint(ty::UintTy::U64)),
463 u128: mk(Uint(ty::UintTy::U128)),
464 f16: mk(Float(ty::FloatTy::F16)),
465 f32: mk(Float(ty::FloatTy::F32)),
466 f64: mk(Float(ty::FloatTy::F64)),
467 f128: mk(Float(ty::FloatTy::F128)),
468 str_: mk(Str),
469 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
470
471 trait_object_dummy_self: fresh_tys[0],
472
473 ty_vars,
474 fresh_tys,
475 fresh_int_tys,
476 fresh_float_tys,
477 anon_bound_tys,
478 anon_canonical_bound_tys,
479 }
480 }
481}
482
483impl<'tcx> CommonLifetimes<'tcx> {
484 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
485 let mk = |r| {
486 Region(Interned::new_unchecked(
487 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
488 ))
489 };
490
491 let re_vars =
492 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
493
494 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
495 .map(|i| {
496 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
497 .map(|v| {
498 mk(ty::ReBound(
499 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
500 ty::BoundRegion {
501 var: ty::BoundVar::from(v),
502 kind: ty::BoundRegionKind::Anon,
503 },
504 ))
505 })
506 .collect()
507 })
508 .collect();
509
510 let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
511 .map(|v| {
512 mk(ty::ReBound(
513 ty::BoundVarIndexKind::Canonical,
514 ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
515 ))
516 })
517 .collect();
518
519 CommonLifetimes {
520 re_static: mk(ty::ReStatic),
521 re_erased: mk(ty::ReErased),
522 re_vars,
523 anon_re_bounds,
524 anon_re_canonical_bounds,
525 }
526 }
527}
528
529impl<'tcx> CommonConsts<'tcx> {
530 fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
531 let mk_const = |c| interners.intern_const(c);
532
533 let mk_valtree = |v| {
534 ty::ValTree(Interned::new_unchecked(
535 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
536 ))
537 };
538
539 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
540 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
541 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
542
543 CommonConsts {
544 unit: mk_const(ty::ConstKind::Value(ty::Value {
545 ty: types.unit,
546 valtree: valtree_zst,
547 })),
548 true_: mk_const(ty::ConstKind::Value(ty::Value {
549 ty: types.bool,
550 valtree: valtree_true,
551 })),
552 false_: mk_const(ty::ConstKind::Value(ty::Value {
553 ty: types.bool,
554 valtree: valtree_false,
555 })),
556 valtree_zst,
557 }
558 }
559}
560
561#[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)]
564pub struct FreeRegionInfo {
565 pub scope: LocalDefId,
567 pub region_def_id: DefId,
569 pub is_impl_item: bool,
571}
572
573#[derive(#[automatically_derived]
impl<'tcx, K: ::core::marker::Copy + Copy> ::core::marker::Copy for
TyCtxtFeed<'tcx, K> {
}Copy, #[automatically_derived]
impl<'tcx, K: ::core::clone::Clone + Copy> ::core::clone::Clone for
TyCtxtFeed<'tcx, K> {
#[inline]
fn clone(&self) -> TyCtxtFeed<'tcx, K> {
TyCtxtFeed {
tcx: ::core::clone::Clone::clone(&self.tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
575pub struct TyCtxtFeed<'tcx, K: Copy> {
576 pub tcx: TyCtxt<'tcx>,
577 key: K,
579}
580
581impl<K: Copy> !StableHash for TyCtxtFeed<'_, K> {}
583
584impl<'tcx> TyCtxt<'tcx> {
589 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
592 self.dep_graph.assert_ignored();
593 TyCtxtFeed { tcx: self, key: () }
594 }
595
596 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
599 let key = self.untracked().source_span.push(span);
600 {
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);
601 TyCtxtFeed { tcx: self, key }
602 }
603
604 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
608 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);
609 if true {
if !(self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline)
{
::core::panicking::panic("assertion failed: self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline")
};
};debug_assert!(self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline);
610 TyCtxtFeed { tcx: self, key }.type_of(value)
611 }
612
613 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
621 if truecfg!(debug_assertions) {
622 match self.def_kind(self.local_parent(key)) {
623 DefKind::Impl { of_trait: true } => {}
624 other => crate::util::bug::bug_fmt(format_args!("{0:?} is not an assoc item of a trait impl: {1:?}",
key, other))bug!("{key:?} is not an assoc item of a trait impl: {other:?}"),
625 }
626 }
627 TyCtxtFeed { tcx: self, key }.visibility(vis.to_mod_id())
628 }
629}
630
631impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> {
632 #[inline(always)]
633 pub fn key(&self) -> K {
634 self.key
635 }
636}
637
638impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
639 #[inline(always)]
640 pub fn def_id(&self) -> LocalDefId {
641 self.key
642 }
643
644 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
646 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
647 }
648
649 pub fn feed_hir(&self) {
651 self.hir_owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo::new(
652 self.tcx.arena.alloc(hir::OwnerNodes::synthetic()),
653 self.tcx.arena.alloc(Default::default()),
654 self.tcx.arena.alloc(Default::default()),
655 self.tcx.arena.alloc(Steal::new(Default::default())),
656 )));
657
658 self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
659 }
660}
661
662#[derive(#[automatically_derived]
impl<'tcx> ::core::default::Default for GlobalCaches<'tcx> {
#[inline]
fn default() -> GlobalCaches<'tcx> {
GlobalCaches {
ty_rcache: ::core::default::Default::default(),
selection_cache: ::core::default::Default::default(),
evaluation_cache: ::core::default::Default::default(),
new_solver_evaluation_cache: ::core::default::Default::default(),
new_solver_canonical_param_env_cache: ::core::default::Default::default(),
canonical_param_env_cache: ::core::default::Default::default(),
highest_var_in_clauses_cache: ::core::default::Default::default(),
clauses_cache: ::core::default::Default::default(),
}
}
}Default)]
667pub struct GlobalCaches<'tcx> {
668 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
670
671 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
674
675 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
679
680 new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
682 new_solver_canonical_param_env_cache: Lock<ty::CanonicalParamEnvCache<TyCtxt<'tcx>>>,
683
684 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
685
686 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
688
689 pub clauses_cache:
691 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
692}
693
694#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for TyCtxt<'tcx> { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for TyCtxt<'tcx> { }
#[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)]
712#[rustc_diagnostic_item = "TyCtxt"]
713#[rustc_pass_by_value]
714pub struct TyCtxt<'tcx> {
715 gcx: &'tcx GlobalCtxt<'tcx>,
716}
717
718unsafe impl DynSend for TyCtxt<'_> {}
722unsafe impl DynSync for TyCtxt<'_> {}
723fn _assert_tcx_fields() {
724 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
725 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
726}
727
728impl<'tcx> Deref for TyCtxt<'tcx> {
729 type Target = &'tcx GlobalCtxt<'tcx>;
730 #[inline(always)]
731 fn deref(&self) -> &Self::Target {
732 &self.gcx
733 }
734}
735
736pub struct GlobalCtxt<'tcx> {
738 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
739 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
740
741 interners: CtxtInterners<'tcx>,
742
743 pub sess: &'tcx Session,
744 crate_types: Vec<CrateType>,
745 stable_crate_id: StableCrateId,
751
752 pub incr_comp_session: Option<&'tcx IncrCompSession>,
753 pub dep_graph: DepGraph,
754
755 pub prof: SelfProfilerRef,
758
759 pub types: CommonTypes<'tcx>,
761
762 pub lifetimes: CommonLifetimes<'tcx>,
764
765 pub consts: CommonConsts<'tcx>,
767
768 pub(crate) hooks: crate::hooks::Providers,
771
772 untracked: Untracked,
773
774 pub query_system: QuerySystem<'tcx>,
775
776 pub caches: GlobalCaches<'tcx>,
777
778 pub data_layout: TargetDataLayout,
780
781 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
783
784 current_gcx: CurrentGcx,
785}
786
787impl<'tcx> GlobalCtxt<'tcx> {
788 pub fn enter<F, R>(&'tcx self, f: F) -> R
791 where
792 F: FnOnce(TyCtxt<'tcx>) -> R,
793 {
794 let icx = tls::ImplicitCtxt::new(self);
795
796 let _on_drop = defer(move || {
798 *self.current_gcx.value.write() = None;
799 });
800
801 {
803 let mut guard = self.current_gcx.value.write();
804 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
805 *guard = Some(self as *const _ as *const ());
806 }
807
808 tls::enter_context(&icx, || f(icx.tcx))
809 }
810}
811
812#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
819pub struct CurrentGcx {
820 value: Arc<RwLock<Option<*const ()>>>,
823}
824
825unsafe impl DynSend for CurrentGcx {}
826unsafe impl DynSync for CurrentGcx {}
827
828impl CurrentGcx {
829 pub fn new() -> Self {
830 Self { value: Arc::new(RwLock::new(None)) }
831 }
832
833 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
834 let read_guard = self.value.read();
835 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
836 f(unsafe { &*gcx })
840 }
841}
842
843impl<'tcx> TyCtxt<'tcx> {
844 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
845 let root = self.typeck_root_def_id_local(def_id);
848 self.hir_node_by_def_id(root).body_id().is_some()
849 }
850
851 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
856 let def_kind = self.def_kind(def_id);
857 if def_kind.has_codegen_attrs() {
858 self.codegen_fn_attrs(def_id)
859 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
DefKind::GlobalAsm => true,
_ => false,
}matches!(
860 def_kind,
861 DefKind::AnonConst
862 | DefKind::AssocConst { .. }
863 | DefKind::Const { .. }
864 | DefKind::GlobalAsm
865 ) {
866 CodegenFnAttrs::EMPTY
867 } else {
868 crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind))bug!(
869 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
870 def_id,
871 def_kind
872 )
873 }
874 }
875
876 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
877 self.arena.alloc(Steal::new(thir))
878 }
879
880 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
881 self.arena.alloc(Steal::new(mir))
882 }
883
884 pub fn alloc_steal_promoted(
885 self,
886 promoted: IndexVec<Promoted, Body<'tcx>>,
887 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
888 self.arena.alloc(Steal::new(promoted))
889 }
890
891 pub fn mk_adt_def(
892 self,
893 did: DefId,
894 kind: AdtKind,
895 variants: IndexVec<VariantIdx, ty::VariantDef>,
896 repr: ReprOptions,
897 ) -> ty::AdtDef<'tcx> {
898 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
899 }
900
901 pub fn allocate_bytes_dedup<'a>(
904 self,
905 bytes: impl Into<Cow<'a, [u8]>>,
906 salt: usize,
907 ) -> interpret::AllocId {
908 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
910 let alloc = self.mk_const_alloc(alloc);
911 self.reserve_and_set_memory_dedup(alloc, salt)
912 }
913
914 pub fn default_traits(self) -> &'static [LangItem] {
916 if self.sess.opts.unstable_opts.experimental_default_bounds {
917 &[
918 LangItem::DefaultTrait1,
919 LangItem::DefaultTrait2,
920 LangItem::DefaultTrait3,
921 LangItem::DefaultTrait4,
922 ]
923 } else {
924 &[]
925 }
926 }
927
928 pub fn is_default_trait(self, def_id: DefId) -> bool {
929 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
930 }
931
932 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
933 #[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))
934 }
935
936 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> T::Lifted {
937 value.lift_to_interner(self)
938 }
939
940 pub fn create_global_ctxt<T>(
947 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
948 sess: &'tcx Session,
949 crate_types: Vec<CrateType>,
950 stable_crate_id: StableCrateId,
951 arena: &'tcx WorkerLocal<Arena<'tcx>>,
952 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
953 untracked: Untracked,
954 incr_comp_session: Option<&'tcx IncrCompSession>,
955 dep_graph: DepGraph,
956 query_system: QuerySystem<'tcx>,
957 hooks: crate::hooks::Providers,
958 current_gcx: CurrentGcx,
959 f: impl FnOnce(TyCtxt<'tcx>) -> T,
960 ) -> T {
961 let data_layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
962 sess.dcx().emit_fatal(err);
963 });
964 let interners = CtxtInterners::new(arena);
965 let common_types = CommonTypes::new(&interners);
966 let common_lifetimes = CommonLifetimes::new(&interners);
967 let common_consts = CommonConsts::new(&interners, &common_types);
968
969 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
970 sess,
971 crate_types,
972 stable_crate_id,
973 arena,
974 hir_arena,
975 interners,
976 incr_comp_session,
977 dep_graph,
978 hooks,
979 prof: sess.prof.clone(),
980 types: common_types,
981 lifetimes: common_lifetimes,
982 consts: common_consts,
983 untracked,
984 query_system,
985 caches: Default::default(),
986 data_layout,
987 alloc_map: interpret::AllocMap::new(),
988 current_gcx,
989 });
990
991 gcx.enter(f)
993 }
994
995 pub fn lang_items(self) -> &'tcx rustc_hir::attrs::lang_items::LanguageItems {
997 self.get_lang_items(())
998 }
999
1000 #[track_caller]
1002 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1003 let ordering_enum = self.require_lang_item(LangItem::OrderingEnum, span);
1004 self.type_of(ordering_enum).no_bound_vars().unwrap()
1005 }
1006
1007 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1010 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1011 }
1012
1013 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1015 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1016 }
1017
1018 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1020 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1021 }
1022
1023 pub fn is_coroutine(self, def_id: DefId) -> bool {
1024 self.coroutine_kind(def_id).is_some()
1025 }
1026
1027 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1028 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1029 }
1030
1031 pub fn is_direct_const(self, def_id: DefId) -> bool {
1039 if true {
{
match self.def_kind(def_id) {
DefKind::Const { .. } | DefKind::AssocConst { .. } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Const { .. } | DefKind::AssocConst { .. }",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(
1040 self.def_kind(def_id),
1041 DefKind::Const { .. } | DefKind::AssocConst { .. }
1042 );
1043 self.is_type_const_syntax(def_id) || self.const_of_item(def_id).is_some()
1044 }
1045
1046 pub fn is_type_const_syntax(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1051 let def_id = def_id.into_query_key();
1052 match self.def_kind(def_id) {
1053 DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1054 is_type_const
1055 }
1056 _ => false,
1057 }
1058 }
1059
1060 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1063 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1064 }
1065
1066 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1068 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1069 self.coroutine_kind(def_id),
1070 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1071 )
1072 }
1073
1074 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1077 #[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)
1078 }
1079
1080 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1083 #[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(_)))
1084 }
1085
1086 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1088 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1089 self.coroutine_kind(def_id),
1090 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1091 )
1092 }
1093
1094 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1096 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1097 self.coroutine_kind(def_id),
1098 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1099 )
1100 }
1101
1102 pub fn features(self) -> &'tcx rustc_feature::Features {
1103 self.features_query(())
1104 }
1105
1106 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1107 let id = id.into_query_key();
1108 if let Some(id) = id.as_local() {
1110 self.definitions_untracked().def_key(id)
1111 } else {
1112 self.cstore_untracked().def_key(id)
1113 }
1114 }
1115
1116 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1122 if let Some(id) = id.as_local() {
1124 self.definitions_untracked().def_path(id)
1125 } else {
1126 self.cstore_untracked().def_path(id)
1127 }
1128 }
1129
1130 #[inline]
1131 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1132 if let Some(def_id) = def_id.as_local() {
1134 self.definitions_untracked().def_path_hash(def_id)
1135 } else {
1136 self.cstore_untracked().def_path_hash(def_id)
1137 }
1138 }
1139
1140 #[inline]
1141 pub fn crate_types(self) -> &'tcx [CrateType] {
1142 &self.crate_types
1143 }
1144
1145 pub fn needs_metadata(self) -> bool {
1146 self.crate_types().iter().any(|ty| match *ty {
1147 CrateType::Executable
1148 | CrateType::StaticLib
1149 | CrateType::Cdylib
1150 | CrateType::Sdylib => false,
1151 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1152 })
1153 }
1154
1155 pub fn needs_hir_hash(self) -> bool {
1156 truecfg!(debug_assertions)
1168 || self.sess.opts.incremental.is_some()
1169 || self.needs_metadata()
1170 || self.sess.instrument_coverage()
1171 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1172 }
1173
1174 #[inline]
1175 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1176 if crate_num == LOCAL_CRATE {
1177 self.stable_crate_id
1178 } else {
1179 self.cstore_untracked().stable_crate_id(crate_num)
1180 }
1181 }
1182
1183 #[inline]
1186 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1187 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1188 LOCAL_CRATE
1189 } else {
1190 *self
1191 .untracked()
1192 .stable_crate_ids
1193 .read()
1194 .get(&stable_crate_id)
1195 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1196 }
1197 }
1198
1199 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1203 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs:1203",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1203u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("def_path_hash_to_def_id({0:?})",
hash) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("def_path_hash_to_def_id({:?})", hash);
1204
1205 let stable_crate_id = hash.stable_crate_id();
1206
1207 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1210 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1211 } else {
1212 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1213 }
1214 }
1215
1216 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1217 let (crate_name, stable_crate_id) = if def_id.is_local() {
1222 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1223 } else {
1224 let cstore = &*self.cstore_untracked();
1225 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1226 };
1227
1228 ::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!(
1229 "{}[{:04x}]{}",
1230 crate_name,
1231 stable_crate_id.as_u64() >> (8 * 6),
1234 self.def_path(def_id).to_string_no_crate_verbose()
1235 )
1236 }
1237
1238 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1239 self.sess.dcx()
1240 }
1241
1242 pub fn is_target_feature_call_safe(
1245 self,
1246 callee_features: &[TargetFeature],
1247 body_features: &[TargetFeature],
1248 ) -> bool {
1249 self.sess.target.options.is_like_wasm
1254 || callee_features
1255 .iter()
1256 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1257 }
1258
1259 pub fn adjust_target_feature_sig(
1262 self,
1263 fun_def: DefId,
1264 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1265 caller: DefId,
1266 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1267 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1268 let caller_features = &self.body_codegen_attrs(caller).target_features;
1269 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1270 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1271 fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1272 ..sig
1273 }));
1274 }
1275 None
1276 }
1277
1278 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1281 match self.env_var_os(key.as_ref()) {
1282 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1283 None => Err(VarError::NotPresent),
1284 }
1285 }
1286}
1287
1288impl<'tcx> TyCtxtAt<'tcx> {
1289 pub fn create_def(
1291 self,
1292 parent: LocalDefId,
1293 name: Option<Symbol>,
1294 def_kind: DefKind,
1295 override_def_path_data: Option<DefPathData>,
1296 disambiguator: &mut PerParentDisambiguatorState,
1297 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1298 let feed =
1299 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1300
1301 feed.def_span(self.span);
1302 feed
1303 }
1304}
1305
1306impl<'tcx> TyCtxt<'tcx> {
1307 pub fn create_def(
1309 self,
1310 parent: LocalDefId,
1311 name: Option<Symbol>,
1312 def_kind: DefKind,
1313 override_def_path_data: Option<DefPathData>,
1314 disambiguator: &mut PerParentDisambiguatorState,
1315 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1316 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1317 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1327
1328 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1333
1334 let feed = TyCtxtFeed { tcx: self, key: def_id };
1335 feed.def_kind(def_kind);
1336 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1341 let parent_mod = self.parent_module_from_def_id(def_id);
1342 feed.visibility(ty::Visibility::Restricted(parent_mod.to_mod_id()));
1343 }
1344
1345 feed
1346 }
1347
1348 pub fn create_crate_num(
1349 self,
1350 stable_crate_id: StableCrateId,
1351 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1352 let mut lock = self.untracked().stable_crate_ids.write();
1353 if let Some(&existing) = lock.get(&stable_crate_id) {
1354 return Err(existing);
1355 }
1356 let num = CrateNum::new(lock.len());
1357 lock.insert(stable_crate_id, num);
1358 Ok(TyCtxtFeed { key: num, tcx: self })
1359 }
1360
1361 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1362 self.ensure_ok().analysis(());
1364
1365 let definitions = &self.untracked.definitions;
1366 gen {
1367 let mut i = 0;
1368
1369 while i < { definitions.read().num_definitions() } {
1372 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1373 yield LocalDefId { local_def_index };
1374 i += 1;
1375 }
1376
1377 definitions.freeze();
1379 }
1380 }
1381
1382 pub fn definitions(self) -> &'tcx rustc_hir::definitions::Definitions {
1383 self.ensure_ok().analysis(());
1385
1386 self.untracked.definitions.freeze()
1389 }
1390
1391 pub fn def_path_hash_to_def_index_map(
1392 self,
1393 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1394 self.ensure_ok().hir_crate_items(());
1397 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1400 }
1401
1402 #[inline]
1405 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1406 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1407 }
1408
1409 pub fn untracked(self) -> &'tcx Untracked {
1411 &self.untracked
1412 }
1413 #[inline]
1416 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1417 self.untracked.definitions.read()
1418 }
1419
1420 #[inline]
1423 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1424 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1425 }
1426
1427 #[inline(always)]
1428 pub fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashState<'_>) -> R) -> R {
1429 f(StableHashState::new(self.sess, &self.untracked))
1430 }
1431
1432 #[inline]
1433 pub fn local_crate_exports_generics(self) -> bool {
1434 if self.is_compiler_builtins(LOCAL_CRATE) {
1438 return false;
1439 }
1440 self.crate_types().iter().any(|crate_type| {
1441 match crate_type {
1442 CrateType::Executable
1443 | CrateType::StaticLib
1444 | CrateType::ProcMacro
1445 | CrateType::Cdylib
1446 | CrateType::Sdylib => false,
1447
1448 CrateType::Dylib => true,
1453
1454 CrateType::Rlib => true,
1455 }
1456 })
1457 }
1458
1459 pub fn is_suitable_region(
1461 self,
1462 generic_param_scope: LocalDefId,
1463 mut region: Region<'tcx>,
1464 ) -> Option<FreeRegionInfo> {
1465 let (suitable_region_binding_scope, region_def_id) = loop {
1466 let def_id =
1467 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1468 let scope = self.local_parent(def_id);
1469 if self.def_kind(scope) == DefKind::OpaqueTy {
1470 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1473 continue;
1474 }
1475 break (scope, def_id.into());
1476 };
1477
1478 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1479 Node::Item(..) | Node::TraitItem(..) => false,
1480 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1481 hir::ImplItemImplKind::Trait { .. } => true,
1488 _ => false,
1489 },
1490 _ => false,
1491 };
1492
1493 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1494 }
1495
1496 pub fn return_type_impl_or_dyn_traits(
1498 self,
1499 scope_def_id: LocalDefId,
1500 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1501 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1502 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1503 self.hir_fn_decl_by_hir_id(hir_id)
1504 else {
1505 return ::alloc::vec::Vec::new()vec![];
1506 };
1507
1508 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1509 v.visit_ty_unambig(hir_output);
1510 v.0
1511 }
1512
1513 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1517 self,
1518 scope_def_id: LocalDefId,
1519 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1520 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1521 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1522 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1524 && let hir::TyKind::Path(hir::QPath::Resolved(
1525 None,
1526 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1527 && let Some(local_id) = def_id.as_local()
1528 && 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()
1530 {
1531 v.visit_ty_unambig(alias_ty);
1532 if !v.0.is_empty() {
1533 return Some((
1534 v.0,
1535 alias_generics.span,
1536 alias_generics.span_for_lifetime_suggestion(),
1537 ));
1538 }
1539 }
1540 None
1541 }
1542
1543 pub fn has_strict_asm_symbol_naming(self) -> bool {
1546 self.sess.target.llvm_target.starts_with("nvptx")
1547 }
1548
1549 pub fn caller_location_ty(self) -> Ty<'tcx> {
1551 Ty::new_imm_ref(
1552 self,
1553 self.lifetimes.re_static,
1554 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1555 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1556 .skip_norm_wip(),
1557 )
1558 }
1559
1560 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1562 let kind = self.def_kind(def_id);
1563 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1564 }
1565
1566 pub fn type_length_limit(self) -> Limit {
1567 self.limits(()).type_length_limit
1568 }
1569
1570 pub fn recursion_limit(self) -> Limit {
1571 self.limits(()).recursion_limit
1572 }
1573
1574 pub fn move_size_limit(self) -> Limit {
1575 self.limits(()).move_size_limit
1576 }
1577
1578 pub fn pattern_complexity_limit(self) -> Limit {
1579 self.limits(()).pattern_complexity_limit
1580 }
1581
1582 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1584 iter::once(LOCAL_CRATE)
1585 .chain(self.crates(()).iter().copied())
1586 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1587 }
1588
1589 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1591 let visible_crates =
1592 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1593
1594 iter::once(LOCAL_CRATE)
1595 .chain(visible_crates)
1596 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1597 }
1598
1599 #[inline]
1600 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1601 self.visibility(def_id).expect_local()
1602 }
1603
1604 {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("local_opaque_ty_origin",
"rustc_middle::ty::context", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1605u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("def_id")
}> =
::tracing::__macro_support::FieldName::new("def_id");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
hir::OpaqueTyOrigin<LocalDefId> = loop {};
return __tracing_attr_fake_return;
}
{ self.hir_expect_opaque_ty(def_id).origin }
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs:1605",
"rustc_middle::ty::context", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1605u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(skip(self), level = "trace", ret)]
1606 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1607 self.hir_expect_opaque_ty(def_id).origin
1608 }
1609
1610 pub fn finish(self) {
1611 self.alloc_self_profile_query_strings();
1614
1615 self.save_dep_graph();
1616 self.verify_query_key_hashes();
1617
1618 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1619 self.sess
1620 .dcx()
1621 .emit_fatal(crate::diagnostics::FailedWritingFile { path: &path, error });
1622 }
1623 }
1624
1625 pub fn report_unused_features(self) {
1626 #[derive(const _: () =
{
impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for UnusedFeature
where G: rustc_errors::EmissionGuarantee {
#[track_caller]
fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
match self {
UnusedFeature { feature: __binding_0 } => {
let mut diag =
rustc_errors::Diag::new(dcx, level,
rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("feature `{$feature}` is declared but not used")));
;
diag.arg("feature", __binding_0);
diag
}
}
}
}
};Diagnostic)]
1627 #[diag("feature `{$feature}` is declared but not used")]
1628 struct UnusedFeature {
1629 feature: Symbol,
1630 }
1631
1632 let used_features = self.query_system.used_features.lock();
1634 let unused_features = self
1635 .features()
1636 .enabled_features_iter_stable_order()
1637 .filter(|(f, _)| {
1638 !used_features.contains_key(f)
1639 && f.as_str() != "restricted_std"
1646 && *f != sym::doc_cfg
1650 })
1651 .collect::<Vec<_>>();
1652
1653 for (feature, span) in unused_features {
1654 self.emit_node_span_lint(
1655 UNUSED_FEATURES,
1656 CRATE_HIR_ID,
1657 span,
1658 UnusedFeature { feature },
1659 );
1660 }
1661 }
1662}
1663
1664macro_rules! nop_lift {
1665 ($set:ident; $ty:ty => $lifted:ty) => {
1666 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1667 type Lifted = $lifted;
1668 #[track_caller]
1669 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1670 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1675 _x: Interned<'tcx, Inner>,
1676 ) -> InternedSet<'tcx, Inner> {
1677 unreachable!()
1678 }
1679 fn _type_eq<T>(_x: &T, _y: &T) {}
1680 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1681 let interner = _intern_set_ty_from_interned_ty(x.0);
1685 _type_eq(&interner, &tcx.interners.$set);
1687 }
1688
1689 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1690 unsafe { mem::transmute(self) }
1693 }
1694 }
1695 };
1696}
1697
1698macro_rules! nop_list_lift {
1699 ($set:ident; $ty:ty => $lifted:ty) => {
1700 nop_list_lift! { $set: List; $ty => $lifted }
1701 };
1702 ($set:ident: $list:ident; $ty:ty => $lifted:ty) => {
1704 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a $list<$ty> {
1705 type Lifted = &'tcx $list<$lifted>;
1706 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1707 if false {
1709 let _x: &InternedSet<'tcx, $list<$lifted>> = &tcx.interners.$set;
1710 }
1711
1712 if self.is_empty() {
1713 return $list::empty();
1714 }
1715 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1716 unsafe { mem::transmute(self) }
1719 }
1720 }
1721 };
1722}
1723
1724impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Ty<'a> {
type Lifted = Ty<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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_);
}
if !tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { type_; Ty<'a> => Ty<'tcx> }
1725impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Const<'a> {
type Lifted = Const<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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_);
}
if !tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { const_; Const<'a> => Const<'tcx> }
1726impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Pattern<'a> {
type Lifted = Pattern<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
}
if !tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
1727impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ConstAllocation<'a> {
type Lifted = ConstAllocation<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
}
if !tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
1728impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Predicate<'a> {
type Lifted = Predicate<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
}
if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
1729impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Clause<'a> {
type Lifted = Clause<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
}
if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
1730impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Layout<'a> {
type Lifted = Layout<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
}
if !tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { layout; Layout<'a> => Layout<'tcx> }
1731impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ValTree<'a> {
type Lifted = ValTree<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> 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);
}
if !tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
1732
1733impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, RegionKind<'a>> {
1734 type Lifted = Interned<'tcx, RegionKind<'tcx>>;
1735
1736 #[track_caller]
1737 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1738 if !tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0)) {
::core::panicking::panic("assertion failed: tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0))")
};assert!(tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0)));
1739 unsafe { mem::transmute(self) }
1742 }
1743}
1744
1745impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Ty<'a>> {
type Lifted = &'tcx List<Ty<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<Ty<'tcx>>> =
&tcx.interners.type_lists;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self))
{
::core::panicking::panic("assertion failed: tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
1746impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a ListWithCachedTypeInfo<Clause<'a>> {
type Lifted = &'tcx ListWithCachedTypeInfo<Clause<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>> =
&tcx.interners.clauses;
}
if self.is_empty() { return ListWithCachedTypeInfo::empty(); }
if !tcx.interners.clauses.contains_pointer_to(&InternedInSet(self)) {
::core::panicking::panic("assertion failed: tcx.interners.clauses.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { clauses: ListWithCachedTypeInfo; Clause<'a> => Clause<'tcx> }
1747impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<PolyExistentialPredicate<'a>> {
type Lifted = &'tcx List<PolyExistentialPredicate<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>> =
&tcx.interners.poly_existential_predicates;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self))
{
::core::panicking::panic("assertion failed: tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! {
1748 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1749}
1750impl<'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>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>> =
&tcx.interners.bound_variable_kinds;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self))
{
::core::panicking::panic("assertion failed: tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind<'a> => ty::BoundVariableKind<'tcx> }
1751impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Pattern<'a>> {
type Lifted = &'tcx List<Pattern<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<Pattern<'tcx>>> =
&tcx.interners.patterns;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.patterns.contains_pointer_to(&InternedInSet(self)) {
::core::panicking::panic("assertion failed: tcx.interners.patterns.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { patterns; Pattern<'a> => Pattern<'tcx> }
1752impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<ty::ArgOutlivesClause<'a>> {
type Lifted = &'tcx List<ty::ArgOutlivesClause<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<ty::ArgOutlivesClause<'tcx>>> =
&tcx.interners.outlives;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.outlives.contains_pointer_to(&InternedInSet(self)) {
::core::panicking::panic("assertion failed: tcx.interners.outlives.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { outlives; ty::ArgOutlivesClause<'a> => ty::ArgOutlivesClause<'tcx> }
1753
1754impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<GenericArg<'a>> {
type Lifted = &'tcx List<GenericArg<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<GenericArg<'tcx>>> =
&tcx.interners.args;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.args.contains_pointer_to(&InternedInSet(self)) {
::core::panicking::panic("assertion failed: tcx.interners.args.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
1756
1757macro_rules! sty_debug_print {
1758 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1759 #[allow(non_snake_case, reason = "we're using variant names as local variables")]
1760 mod inner {
1761 use crate::ty::{self, TyCtxt};
1762 use crate::ty::context::InternedInSet;
1763
1764 #[derive(Copy, Clone)]
1765 struct DebugStat {
1766 total: usize,
1767 lt_infer: usize,
1768 ty_infer: usize,
1769 ct_infer: usize,
1770 all_infer: usize,
1771 }
1772
1773 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1774 let mut total = DebugStat {
1775 total: 0,
1776 lt_infer: 0,
1777 ty_infer: 0,
1778 ct_infer: 0,
1779 all_infer: 0,
1780 };
1781 $(let mut $variant = total;)*
1782
1783 for shard in tcx.interners.type_.lock_shards() {
1784 #[allow(rustc::potential_query_instability)]
1786 let types = shard.iter();
1787 for &(InternedInSet(t), ()) in types {
1788 let variant = match t.internee {
1789 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1790 ty::Float(..) | ty::Str | ty::Never => continue,
1791 ty::Error(_) => continue,
1792 $(ty::$variant(..) => &mut $variant,)*
1793 };
1794 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1795 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1796 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1797
1798 variant.total += 1;
1799 total.total += 1;
1800 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1801 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1802 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1803 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1804 }
1805 }
1806 writeln!(fmt, "Ty interner total ty lt ct all")?;
1807 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1808 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1809 stringify!($variant),
1810 uses = $variant.total,
1811 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1812 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1813 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1814 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1815 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1816 )*
1817 writeln!(fmt, " total {uses:6} \
1818 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1819 uses = total.total,
1820 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1821 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1822 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1823 all = total.all_infer as f64 * 100.0 / total.total as f64)
1824 }
1825 }
1826
1827 inner::go($fmt, $ctxt)
1828 }}
1829}
1830
1831impl<'tcx> TyCtxt<'tcx> {
1832 pub fn debug_stats(self) -> impl fmt::Debug {
1833 fmt::from_fn(move |fmt| {
1834 {
#[allow(non_snake_case, reason =
"we're using variant names as local variables")]
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!(
1835 fmt,
1836 self,
1837 Adt,
1838 Array,
1839 Slice,
1840 RawPtr,
1841 Ref,
1842 FnDef,
1843 FnPtr,
1844 UnsafeBinder,
1845 Placeholder,
1846 Coroutine,
1847 CoroutineWitness,
1848 Dynamic,
1849 Closure,
1850 CoroutineClosure,
1851 Tuple,
1852 Bound,
1853 Param,
1854 Infer,
1855 Alias,
1856 Pat,
1857 Foreign
1858 )?;
1859
1860 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1861 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1862 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())?;
1863 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1864
1865 Ok(())
1866 })
1867 }
1868}
1869
1870struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1875
1876impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1877 fn clone(&self) -> Self {
1878 *self
1879 }
1880}
1881
1882impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1883
1884impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1885 fn into_pointer(&self) -> *const () {
1886 self.0 as *const _ as *const ()
1887 }
1888}
1889
1890#[allow(rustc::usage_of_ty_tykind)]
1891impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1892 fn borrow(&self) -> &T {
1893 &self.0.internee
1894 }
1895}
1896
1897impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1898 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1899 self.0.internee == other.0.internee
1902 }
1903}
1904
1905impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1906
1907impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1908 fn hash<H: Hasher>(&self, s: &mut H) {
1909 self.0.internee.hash(s)
1911 }
1912}
1913
1914impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1915 fn borrow(&self) -> &[T] {
1916 &self.0[..]
1917 }
1918}
1919
1920impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1921 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1922 self.0[..] == other.0[..]
1925 }
1926}
1927
1928impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1929
1930impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1931 fn hash<H: Hasher>(&self, s: &mut H) {
1932 self.0[..].hash(s)
1934 }
1935}
1936
1937impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1938 fn borrow(&self) -> &[T] {
1939 &self.0[..]
1940 }
1941}
1942
1943impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1944 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1945 self.0[..] == other.0[..]
1948 }
1949}
1950
1951impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1952
1953impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1954 fn hash<H: Hasher>(&self, s: &mut H) {
1955 self.0[..].hash(s)
1957 }
1958}
1959
1960macro_rules! direct_interners {
1961 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1962 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1963 fn borrow<'a>(&'a self) -> &'a $ty {
1964 &self.0
1965 }
1966 }
1967
1968 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1969 fn eq(&self, other: &Self) -> bool {
1970 self.0 == other.0
1973 }
1974 }
1975
1976 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1977
1978 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1979 fn hash<H: Hasher>(&self, s: &mut H) {
1980 self.0.hash(s)
1983 }
1984 }
1985
1986 impl<'tcx> TyCtxt<'tcx> {
1987 $vis fn $method(self, v: $ty) -> $ret_ty {
1988 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1989 InternedInSet(self.interners.arena.alloc(v))
1990 }).0))
1991 }
1992 })+
1993 }
1994}
1995
1996impl<'tcx> Borrow<RegionKind<'tcx>> for InternedInSet<'tcx, RegionKind<'tcx>>
{
fn borrow<'a>(&'a self) -> &'a RegionKind<'tcx> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, RegionKind<'tcx>> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, RegionKind<'tcx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, RegionKind<'tcx>> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub(crate) fn intern_region(self, v: RegionKind<'tcx>) -> Region<'tcx> {
Region(Interned::new_unchecked(self.interners.region.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'tcx> Borrow<ValTreeKind<TyCtxt<'tcx>>> for
InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a ValTreeKind<TyCtxt<'tcx>> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {}
impl<'tcx> Hash for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub(crate) fn intern_valtree(self, v: ValTreeKind<TyCtxt<'tcx>>)
-> ValTree<'tcx> {
ValTree(Interned::new_unchecked(self.interners.valtree.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'tcx> Borrow<PatternKind<'tcx>> for
InternedInSet<'tcx, PatternKind<'tcx>> {
fn borrow<'a>(&'a self) -> &'a PatternKind<'tcx> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, PatternKind<'tcx>> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, PatternKind<'tcx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, PatternKind<'tcx>> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_pat(self, v: PatternKind<'tcx>) -> Pattern<'tcx> {
Pattern(Interned::new_unchecked(self.interners.pat.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'tcx> Borrow<Allocation> for InternedInSet<'tcx, Allocation> {
fn borrow<'a>(&'a self) -> &'a Allocation { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, Allocation> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, Allocation> {}
impl<'tcx> Hash for InternedInSet<'tcx, Allocation> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_const_alloc(self, v: Allocation) -> ConstAllocation<'tcx> {
ConstAllocation(Interned::new_unchecked(self.interners.const_allocation.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'tcx> Borrow<LayoutData<FieldIdx, VariantIdx>> for
InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {
fn borrow<'a>(&'a self) -> &'a LayoutData<FieldIdx, VariantIdx> {
&self.0
}
}
impl<'tcx> PartialEq for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>>
{
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_layout(self, v: LayoutData<FieldIdx, VariantIdx>)
-> Layout<'tcx> {
Layout(Interned::new_unchecked(self.interners.layout.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'tcx> Borrow<AdtDefData> for InternedInSet<'tcx, AdtDefData> {
fn borrow<'a>(&'a self) -> &'a AdtDefData { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, AdtDefData> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, AdtDefData> {}
impl<'tcx> Hash for InternedInSet<'tcx, AdtDefData> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_adt_def_from_data(self, v: AdtDefData) -> AdtDef<'tcx> {
AdtDef(Interned::new_unchecked(self.interners.adt_def.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'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))
}
}
impl<'tcx> Borrow<CanonicalInputData<TyCtxt<'tcx>>> for
InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a CanonicalInputData<TyCtxt<'tcx>> {
&self.0
}
}
impl<'tcx> PartialEq for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>>
{
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {}
impl<'tcx> Hash for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
fn intern_canonical_input(self, v: CanonicalInputData<TyCtxt<'tcx>>)
-> CanonicalInput<'tcx> {
CanonicalInput(Interned::new_unchecked(self.interners.canonical_inputs.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}direct_interners! {
2000 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2001 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2002 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2003 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2004 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2005 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2006 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2007 ExternalConstraints -> ExternalConstraints<'tcx>,
2008 canonical_inputs: intern_canonical_input(CanonicalInputData<TyCtxt<'tcx>>): CanonicalInput -> CanonicalInput<'tcx>,
2009}
2010
2011macro_rules! slice_interners {
2012 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2013 impl<'tcx> TyCtxt<'tcx> {
2014 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2015 if v.is_empty() {
2016 List::empty()
2017 } else {
2018 self.interners.$field.intern_ref(v, || {
2019 InternedInSet(List::from_arena(&*self.arena, (), v))
2020 }).0
2021 }
2022 })+
2023 }
2024 );
2025}
2026
2027impl<'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::ArgOutlivesClause<'tcx>])
-> &'tcx List<ty::ArgOutlivesClause<'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!(
2031 const_lists: pub mk_const_list(Const<'tcx>),
2032 args: pub mk_args(GenericArg<'tcx>),
2033 type_lists: pub mk_type_list(Ty<'tcx>),
2034 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2035 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2036 projs: pub mk_projs(ProjectionKind),
2037 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2038 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2039 fields: pub mk_fields(FieldIdx),
2040 local_def_ids: intern_local_def_ids(LocalDefId),
2041 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2042 patterns: pub mk_patterns(Pattern<'tcx>),
2043 outlives: pub mk_outlives(ty::ArgOutlivesClause<'tcx>),
2044 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2045);
2046
2047impl<'tcx> TyCtxt<'tcx> {
2048 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2052 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2053 Ty::new_fn_ptr(
2054 self,
2055 sig.map_bound(|sig| ty::FnSig {
2056 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2057 ..sig
2058 }),
2059 )
2060 }
2061
2062 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2066 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2067 sig.map_bound(|sig| ty::FnSig {
2068 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2069 ..sig
2070 })
2071 }
2072
2073 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2076 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2077 self.associated_items(trait_did)
2078 .filter_by_name_unhygienic(assoc_name.name)
2079 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2080 })
2081 }
2082
2083 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2085 let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2086 return false;
2087 };
2088 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2089
2090 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2091 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2092 return false;
2093 };
2094 trait_predicate.trait_ref.def_id == future_trait
2095 && trait_predicate.polarity == ClausePolarity::Positive
2096 })
2097 }
2098
2099 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2107 sig.map_bound(|s| {
2108 let params = match s.inputs()[0].kind() {
2109 ty::Tuple(params) => *params,
2110 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2111 };
2112 if !s.splatted().is_none() {
::core::panicking::panic("assertion failed: s.splatted().is_none()")
};assert!(s.splatted().is_none());
2114 self.mk_fn_sig(
2115 params,
2116 s.output(),
2117 s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2118 )
2119 })
2120 }
2121
2122 #[inline]
2123 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2124 self.interners.intern_predicate(binder)
2125 }
2126
2127 #[inline]
2128 pub fn reuse_or_mk_predicate(
2129 self,
2130 pred: Predicate<'tcx>,
2131 binder: Binder<'tcx, PredicateKind<'tcx>>,
2132 ) -> Predicate<'tcx> {
2133 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2134 }
2135
2136 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2142 let is_inherent_assoc_ty = #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocTy => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocTy)
2143 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(self.def_kind(self.parent(def_id)), DefKind::Impl { of_trait: false });
2144 self.check_args_compatible_inner(def_id, args, is_inherent_assoc_ty)
2145 }
2146
2147 pub fn check_alias_term_args_compatible(
2148 self,
2149 kind: ty::AliasTermKind<'tcx>,
2150 args: &'tcx [ty::GenericArg<'tcx>],
2151 ) -> bool {
2152 let (def_id, is_self_args) = match kind {
2153 ty::AliasTermKind::ProjectionTy { def_id }
2154 | ty::AliasTermKind::OpaqueTy { def_id }
2155 | ty::AliasTermKind::FreeTy { def_id }
2156 | ty::AliasTermKind::AnonConst { def_id }
2157 | ty::AliasTermKind::ProjectionConst { def_id }
2158 | ty::AliasTermKind::FreeConst { def_id }
2159 | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2160 ty::AliasTermKind::InherentTy { def_id }
2161 | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2162 };
2163 self.check_args_compatible_inner(def_id, args, is_self_args)
2164 }
2165
2166 fn check_args_compatible_inner(
2167 self,
2168 def_id: DefId,
2169 args: &'tcx [ty::GenericArg<'tcx>],
2170 is_self_args: bool,
2171 ) -> bool {
2172 let generics = self.generics_of(def_id);
2173 let own_args = if is_self_args {
2174 if generics.own_params.len() + 1 != args.len() {
2175 return false;
2176 }
2177
2178 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2179 return false;
2180 }
2181
2182 &args[1..]
2183 } else {
2184 if generics.count() != args.len() {
2185 return false;
2186 }
2187
2188 let (parent_args, own_args) = args.split_at(generics.parent_count);
2189
2190 if let Some(parent) = generics.parent
2194 && !self.check_args_compatible_inner(parent, parent_args, false)
2195 {
2196 return false;
2197 }
2198
2199 own_args
2200 };
2201
2202 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2203 match (¶m.kind, arg.kind()) {
2204 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2205 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2206 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2207 _ => return false,
2208 }
2209 }
2210
2211 true
2212 }
2213
2214 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2221 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2222 let is_inherent_assoc_ty = #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocTy => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocTy)
2223 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(self.def_kind(self.parent(def_id)), DefKind::Impl { of_trait: false });
2224 self.emit_bug_args_compatible(def_id, args, is_inherent_assoc_ty);
2225 }
2226 }
2227
2228 pub fn debug_assert_alias_term_args_compatible(
2229 self,
2230 kind: ty::AliasTermKind<'tcx>,
2231 args: ty::GenericArgsRef<'tcx>,
2232 ) {
2233 if truecfg!(debug_assertions) {
2234 self.debug_assert_alias_term_kind_matches_def_kind(kind);
2235 if !self.check_alias_term_args_compatible(kind, args) {
2236 let (def_id, is_self_args) = match kind {
2237 ty::AliasTermKind::ProjectionTy { def_id }
2238 | ty::AliasTermKind::OpaqueTy { def_id }
2239 | ty::AliasTermKind::FreeTy { def_id }
2240 | ty::AliasTermKind::AnonConst { def_id }
2241 | ty::AliasTermKind::ProjectionConst { def_id }
2242 | ty::AliasTermKind::FreeConst { def_id }
2243 | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2244 ty::AliasTermKind::InherentTy { def_id }
2245 | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2246 };
2247 self.emit_bug_args_compatible(def_id, args, is_self_args);
2248 }
2249 }
2250 }
2251
2252 fn debug_assert_alias_term_kind_matches_def_kind(self, kind: ty::AliasTermKind<'tcx>) {
2253 match kind {
2254 ty::AliasTermKind::ProjectionTy { def_id } => {
2255 if true {
{
match self.def_kind(def_id) {
DefKind::AssocTy => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AssocTy", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy);
2256 if true {
{
match self.def_kind(self.parent(def_id)) {
DefKind::Trait | DefKind::Impl { of_trait: true } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Trait | DefKind::Impl { of_trait: true }",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(
2257 self.def_kind(self.parent(def_id)),
2258 DefKind::Trait | DefKind::Impl { of_trait: true }
2259 );
2260 }
2261 ty::AliasTermKind::InherentTy { def_id } => {
2262 if true {
{
match self.def_kind(def_id) {
DefKind::AssocTy => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AssocTy", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy);
2263 if true {
{
match self.def_kind(self.parent(def_id)) {
DefKind::Impl { of_trait: false } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Impl { of_trait: false }",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(
2264 self.def_kind(self.parent(def_id)),
2265 DefKind::Impl { of_trait: false }
2266 );
2267 }
2268 ty::AliasTermKind::OpaqueTy { def_id } => {
2269 if true {
{
match self.def_kind(def_id) {
DefKind::OpaqueTy => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::OpaqueTy", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::OpaqueTy);
2270 }
2271 ty::AliasTermKind::FreeTy { def_id } => {
2272 if true {
{
match self.def_kind(def_id) {
DefKind::TyAlias => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::TyAlias", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::TyAlias);
2273 }
2274 ty::AliasTermKind::AnonConst { def_id } => {
2275 if true {
{
match self.def_kind(def_id) {
DefKind::AnonConst => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AnonConst", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::AnonConst);
2276 }
2277 ty::AliasTermKind::ProjectionConst { def_id } => {
2278 if true {
{
match self.def_kind(def_id) {
DefKind::AssocConst { .. } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AssocConst { .. }", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocConst { .. });
2279 if true {
{
match self.def_kind(self.parent(def_id)) {
DefKind::Trait | DefKind::Impl { of_trait: true } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Trait | DefKind::Impl { of_trait: true }",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(
2280 self.def_kind(self.parent(def_id)),
2281 DefKind::Trait | DefKind::Impl { of_trait: true }
2282 );
2283 }
2284 ty::AliasTermKind::InherentConstSelf { def_id }
2285 | ty::AliasTermKind::InherentConstImpl { def_id } => {
2286 if true {
{
match self.def_kind(def_id) {
DefKind::AssocConst { .. } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AssocConst { .. }", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocConst { .. });
2287 if true {
{
match self.def_kind(self.parent(def_id)) {
DefKind::Impl { of_trait: false } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Impl { of_trait: false }",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(
2288 self.def_kind(self.parent(def_id)),
2289 DefKind::Impl { of_trait: false }
2290 );
2291 }
2292 ty::AliasTermKind::FreeConst { def_id } => {
2293 if true {
{
match self.def_kind(def_id) {
DefKind::Const { .. } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Const { .. }", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::Const { .. });
2294 }
2295 }
2296 }
2297
2298 fn emit_bug_args_compatible(
2299 self,
2300 def_id: DefId,
2301 args: &'tcx [ty::GenericArg<'tcx>],
2302 is_self_args: bool,
2303 ) -> ! {
2304 if is_self_args {
2305 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!(
2306 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2307 self.def_path_str(def_id),
2308 args,
2309 self.mk_args_from_iter(
2311 [self.types.self_param.into()].into_iter().chain(
2312 self.generics_of(def_id)
2313 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2314 .iter()
2315 .copied()
2316 )
2317 )
2318 );
2319 } else {
2320 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!(
2321 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2322 self.def_path_str(def_id),
2323 args,
2324 ty::GenericArgs::identity_for_item(self, def_id)
2325 );
2326 }
2327 }
2328
2329 #[inline(always)]
2330 pub(crate) fn check_and_mk_args(
2331 self,
2332 def_id: DefId,
2333 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2334 ) -> GenericArgsRef<'tcx> {
2335 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2336 self.debug_assert_args_compatible(def_id, args);
2337 args
2338 }
2339
2340 #[inline]
2341 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2342 self.interners.intern_const(kind)
2343 }
2344
2345 #[allow(rustc::usage_of_ty_tykind)]
2347 #[inline]
2348 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2349 self.interners.intern_ty(st)
2350 }
2351
2352 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2353 match param.kind {
2354 GenericParamDefKind::Lifetime => {
2355 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2356 }
2357 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2358 GenericParamDefKind::Const { .. } => {
2359 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2360 .into()
2361 }
2362 }
2363 }
2364
2365 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2366 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2367 }
2368
2369 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2370 self.mk_place_elem(place, PlaceElem::Deref)
2371 }
2372
2373 pub fn mk_place_downcast(
2374 self,
2375 place: Place<'tcx>,
2376 adt_def: AdtDef<'tcx>,
2377 variant_index: VariantIdx,
2378 ) -> Place<'tcx> {
2379 self.mk_place_elem(
2380 place,
2381 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2382 )
2383 }
2384
2385 pub fn mk_place_downcast_unnamed(
2386 self,
2387 place: Place<'tcx>,
2388 variant_index: VariantIdx,
2389 ) -> Place<'tcx> {
2390 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2391 }
2392
2393 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2394 self.mk_place_elem(place, PlaceElem::Index(index))
2395 }
2396
2397 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2401 Place {
2402 local: place.local,
2403 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2404 }
2405 }
2406
2407 pub fn mk_poly_existential_predicates(
2408 self,
2409 eps: &[PolyExistentialPredicate<'tcx>],
2410 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2411 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2412 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!(
2413 eps.array_windows()
2414 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2415 != Ordering::Greater)
2416 );
2417 self.intern_poly_existential_predicates(eps)
2418 }
2419
2420 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2421 self.interners.intern_clauses(clauses)
2425 }
2426
2427 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2428 self.intern_local_def_ids(def_ids)
2432 }
2433
2434 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2435 where
2436 I: Iterator<Item = T>,
2437 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2438 {
2439 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2440 }
2441
2442 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2443 where
2444 I: Iterator<Item = T>,
2445 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2446 {
2447 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2448 }
2449
2450 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2451 where
2452 I: Iterator<Item = T>,
2453 T: CollectAndApply<
2454 &'tcx ty::CapturedPlace<'tcx>,
2455 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2456 >,
2457 {
2458 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2459 }
2460
2461 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2462 where
2463 I: Iterator<Item = T>,
2464 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2465 {
2466 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2467 }
2468
2469 pub fn mk_fn_sig<I, T>(
2474 self,
2475 inputs: I,
2476 output: I::Item,
2477 fn_sig_kind: FnSigKind<'tcx>,
2478 ) -> T::Output
2479 where
2480 I: IntoIterator<Item = T>,
2481 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2482 {
2483 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2484 inputs_and_output: self.mk_type_list(xs),
2485 fn_sig_kind,
2486 })
2487 }
2488
2489 pub fn mk_fn_sig_rust_abi<I, T>(
2491 self,
2492 inputs: I,
2493 output: I::Item,
2494 safety: hir::Safety,
2495 ) -> T::Output
2496 where
2497 I: IntoIterator<Item = T>,
2498 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2499 {
2500 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2501 }
2502
2503 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2505 where
2506 I: IntoIterator<Item = T>,
2507 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2508 {
2509 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2510 }
2511
2512 pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2514 where
2515 I: IntoIterator<Item = T>,
2516 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2517 {
2518 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2519 }
2520
2521 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2522 where
2523 I: Iterator<Item = T>,
2524 T: CollectAndApply<
2525 PolyExistentialPredicate<'tcx>,
2526 &'tcx List<PolyExistentialPredicate<'tcx>>,
2527 >,
2528 {
2529 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2530 }
2531
2532 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2533 where
2534 I: Iterator<Item = T>,
2535 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2536 {
2537 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2538 }
2539
2540 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2541 where
2542 I: Iterator<Item = T>,
2543 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2544 {
2545 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2546 }
2547
2548 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2549 where
2550 I: Iterator<Item = T>,
2551 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2552 {
2553 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2554 }
2555
2556 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2557 where
2558 I: Iterator<Item = T>,
2559 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2560 {
2561 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2562 }
2563
2564 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2565 where
2566 I: Iterator<Item = T>,
2567 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2568 {
2569 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2570 }
2571
2572 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2573 where
2574 I: Iterator<Item = T>,
2575 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2576 {
2577 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2578 }
2579
2580 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2581 where
2582 I: Iterator<Item = T>,
2583 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2584 {
2585 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2586 }
2587
2588 pub fn mk_args_trait(
2589 self,
2590 self_ty: Ty<'tcx>,
2591 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2592 ) -> GenericArgsRef<'tcx> {
2593 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2594 }
2595
2596 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2597 where
2598 I: Iterator<Item = T>,
2599 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2600 {
2601 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2602 }
2603
2604 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2605 where
2606 I: Iterator<Item = T>,
2607 T: CollectAndApply<
2608 ty::ArgOutlivesClause<'tcx>,
2609 &'tcx ty::List<ty::ArgOutlivesClause<'tcx>>,
2610 >,
2611 {
2612 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2613 }
2614
2615 #[track_caller]
2618 pub fn emit_node_span_lint(
2619 self,
2620 lint: &'static Lint,
2621 hir_id: HirId,
2622 span: impl Into<MultiSpan>,
2623 decorator: impl for<'a> Diagnostic<'a, ()>,
2624 ) {
2625 let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2626 emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2627 }
2628
2629 pub fn crate_level_attribute_injection_span(self) -> Span {
2631 let node = self.hir_node(hir::CRATE_HIR_ID);
2632 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2633 m.spans.inject_use_span.shrink_to_lo()
2634 }
2635
2636 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2637 self,
2638 diag: &mut Diag<'_, E>,
2639 features: impl IntoIterator<Item = (String, Symbol)>,
2640 ) {
2641 if !self.sess.is_nightly_build() {
2642 return;
2643 }
2644
2645 let span = self.crate_level_attribute_injection_span();
2646 for (desc, feature) in features {
2647 let msg =
2649 ::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}");
2650 diag.span_suggestion_verbose(
2651 span,
2652 msg,
2653 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2654 Applicability::MaybeIncorrect,
2655 );
2656 }
2657 }
2658
2659 #[track_caller]
2662 pub fn emit_node_lint(
2663 self,
2664 lint: &'static Lint,
2665 id: HirId,
2666 decorator: impl for<'a> Diagnostic<'a, ()>,
2667 ) {
2668 let level_spec = self.lint_level_spec_at_node(lint, id);
2669 emit_lint_base(self.sess, lint, level_spec, None, decorator);
2670 }
2671
2672 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2673 let map = self.in_scope_traits_map(id.owner)?;
2674 let candidates = map.get(&id.local_id)?;
2675 Some(candidates)
2676 }
2677
2678 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2679 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs:2679",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/cea272fa356e94bd2ee2cadf376630aa0683867a/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(2679u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("id")
}> =
::tracing::__macro_support::FieldName::new("id");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("named_region")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&id)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?id, "named_region");
2680 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2681 }
2682
2683 pub fn is_late_bound(self, id: HirId) -> bool {
2684 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2685 }
2686
2687 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2688 self.mk_bound_variable_kinds(
2689 &self
2690 .late_bound_vars_map(id.owner)
2691 .get(&id.local_id)
2692 .cloned()
2693 .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))),
2694 )
2695 }
2696
2697 pub fn map_opaque_lifetime_to_parent_lifetime(
2705 self,
2706 mut opaque_lifetime_param_def_id: LocalDefId,
2707 ) -> ty::Region<'tcx> {
2708 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!(
2709 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2710 "{opaque_lifetime_param_def_id:?} is a {}",
2711 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2712 );
2713
2714 loop {
2715 let parent = self.local_parent(opaque_lifetime_param_def_id);
2716 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2717
2718 let Some((lifetime, _)) = lifetime_mapping
2719 .iter()
2720 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2721 else {
2722 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2723 };
2724
2725 match *lifetime {
2726 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2727 let new_parent = self.local_parent(ebv);
2728
2729 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2732 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);
2733 opaque_lifetime_param_def_id = ebv;
2734 continue;
2735 }
2736
2737 let generics = self.generics_of(new_parent);
2738 return ty::Region::new_early_param(
2739 self,
2740 ty::EarlyParamRegion {
2741 index: generics
2742 .param_def_id_to_index(self, ebv.to_def_id())
2743 .expect("early-bound var should be present in fn generics"),
2744 name: self.item_name(ebv.to_def_id()),
2745 },
2746 );
2747 }
2748 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2749 let new_parent = self.local_parent(lbv);
2750 return ty::Region::new_late_param(
2751 self,
2752 new_parent.to_def_id(),
2753 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2754 );
2755 }
2756 resolve_bound_vars::ResolvedArg::Error(guar) => {
2757 return ty::Region::new_error(self, guar);
2758 }
2759 _ => {
2760 return ty::Region::new_error_with_message(
2761 self,
2762 self.def_span(opaque_lifetime_param_def_id),
2763 "cannot resolve lifetime",
2764 );
2765 }
2766 }
2767 }
2768 }
2769
2770 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2775 self.is_const_fn(def_id)
2776 && match self.lookup_const_stability(def_id) {
2777 None => true, Some(stability) if stability.is_const_stable() => true,
2779 _ => false,
2780 }
2781 }
2782
2783 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2785 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2786 && #[allow(non_exhaustive_omitted_patterns)] match self.impl_trait_header(def_id).constness
{
hir::Constness::Const { always: false } => true,
_ => false,
}matches!(
2787 self.impl_trait_header(def_id).constness,
2788 hir::Constness::Const { always: false }
2789 )
2790 }
2791
2792 pub fn is_sdylib_interface_build(self) -> bool {
2793 self.sess.opts.unstable_opts.build_sdylib_interface
2794 }
2795
2796 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2797 let def_id = def_id.into_query_key();
2798 match self.def_kind(def_id) {
2799 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2800 _ => None,
2801 }
2802 }
2803
2804 pub fn next_trait_solver_globally(self) -> bool {
2805 self.sess.opts.unstable_opts.next_solver.globally && !self.features().generic_const_exprs()
2806 }
2807
2808 pub fn next_trait_solver_in_coherence(self) -> bool {
2809 self.sess.opts.unstable_opts.next_solver.coherence
2810 }
2811
2812 pub fn disable_trait_solver_fast_paths(self) -> bool {
2813 self.sess.opts.unstable_opts.disable_fast_paths
2814 }
2815
2816 pub fn disable_param_env_normalization_hack(self) -> bool {
2817 self.sess.opts.unstable_opts.disable_param_env_normalization_hack
2818 }
2819
2820 pub fn renormalize_rigid_aliases(self) -> bool {
2821 self.sess.opts.unstable_opts.renormalize_rigid_aliases
2822 }
2823
2824 #[allow(rustc::bad_opt_access)]
2825 pub fn use_typing_mode_post_typeck_until_borrowck(self) -> bool {
2826 self.next_trait_solver_globally()
2827 || self.sess.opts.unstable_opts.typing_mode_post_typeck_until_borrowck
2828 }
2829
2830 pub fn assumptions_on_binders(self) -> bool {
2831 self.sess.opts.unstable_opts.assumptions_on_binders
2832 }
2833
2834 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2835 self.opt_rpitit_info(def_id).is_some()
2836 }
2837
2838 pub fn get_impl_future_output_ty(self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
2839 let (def_id, args) = match *ty.kind() {
2840 ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
2841 ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, args, .. })
2842 if self.is_impl_trait_in_trait(def_id) =>
2843 {
2844 (def_id, args)
2845 }
2846 _ => return None,
2847 };
2848
2849 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2850 let item_def_id = self.associated_item_def_ids(future_trait)[0];
2851
2852 self.explicit_item_self_bounds(def_id)
2853 .iter_instantiated_copied(self, args)
2854 .map(ty::Unnormalized::skip_norm_wip)
2855 .find_map(|(predicate, _)| {
2856 predicate
2857 .kind()
2858 .map_bound(|kind| match kind {
2859 ty::ClauseKind::Projection(projection_predicate)
2860 if projection_predicate.def_id() == item_def_id =>
2861 {
2862 projection_predicate.term.as_type()
2863 }
2864 _ => None,
2865 })
2866 .no_bound_vars()
2867 .flatten()
2868 })
2869 }
2870
2871 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2881 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2882 }
2883
2884 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2886 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2887 }
2888
2889 pub fn resolver_for_lowering(
2890 self,
2891 ) -> (&'tcx Steal<ResolverAstLowering<'tcx>>, &'tcx Steal<ast::Crate>) {
2892 let (resolver, krate, _) = self.resolver_for_lowering_raw(());
2893 (resolver, krate)
2894 }
2895
2896 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2897 make_metadata(self)
2898 }
2899
2900 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2901 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2902 self.coroutine_kind(def_id)
2903 && let ty::Coroutine(_, args) =
2904 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2905 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2906 {
2907 true
2908 } else {
2909 false
2910 }
2911 }
2912
2913 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2915 {
{
'done:
{
for i in ::rustc_attr_ir::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(DoNotRecommend) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(self, def_id, DoNotRecommend)
2916 }
2917
2918 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2919 let def_id = def_id.into_query_key();
2920 self.trivial_const(def_id).is_some()
2921 }
2922
2923 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2926 if self.is_lang_item(def_id, LangItem::Start) {
2927 return true;
2928 }
2929 if let Some((entry_def_id, _)) = self.entry_fn(())
2930 && entry_def_id == def_id
2931 {
2932 return true;
2933 }
2934 false
2935 }
2936}
2937
2938pub fn provide(providers: &mut Providers) {
2939 providers.is_panic_runtime = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(PanicRuntime) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, PanicRuntime);
2940 providers.is_compiler_builtins = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(CompilerBuiltins) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, CompilerBuiltins);
2941 providers.has_panic_handler = |tcx, LocalCrate| {
2942 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2944 };
2945 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2946}