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::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::fx::FxHashMap;
22use rustc_data_structures::intern::Interned;
23use rustc_data_structures::jobserver::Proxy;
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::def::DefKind;
33use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
34use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState};
35use rustc_hir::intravisit::VisitorExt;
36use rustc_hir::lang_items::LangItem;
37use rustc_hir::limit::Limit;
38use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, MaybeOwner, Node, TraitCandidate, find_attr};
39use rustc_index::IndexVec;
40use rustc_macros::Diagnostic;
41use rustc_session::Session;
42use rustc_session::config::CrateType;
43use rustc_session::cstore::{CrateStoreDyn, Untracked};
44use rustc_session::lint::Lint;
45use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
46use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
47use rustc_type_ir::TyKind::*;
48pub use rustc_type_ir::lift::Lift;
49use rustc_type_ir::{CollectAndApply, WithCachedTypeInfo, elaborate, search_graph};
50use tracing::{debug, instrument};
51
52use crate::arena::Arena;
53use crate::dep_graph::dep_node::make_metadata;
54use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
55use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo};
56use crate::ich::StableHashState;
57use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
58use crate::lint::emit_lint_base;
59use crate::metadata::ModChild;
60use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
61use crate::middle::resolve_bound_vars;
62use crate::mir::interpret::{self, Allocation, ConstAllocation};
63use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
64use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
65use crate::thir::Thir;
66use crate::traits;
67use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
68use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
69use crate::ty::{
70 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, FnSigKind, GenericArg,
71 GenericArgs, GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst,
72 Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
73 PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
74 ValTree, ValTreeKind, Visibility,
75};
76
77impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
78 fn is_local(self) -> bool {
79 self.is_local()
80 }
81
82 fn as_local(self) -> Option<LocalDefId> {
83 self.as_local()
84 }
85}
86
87impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
88 fn safe() -> Self {
89 hir::Safety::Safe
90 }
91
92 fn unsafe_mode() -> Self {
93 hir::Safety::Unsafe
94 }
95
96 fn is_safe(self) -> bool {
97 self.is_safe()
98 }
99
100 fn prefix_str(self) -> &'static str {
101 self.prefix_str()
102 }
103}
104
105impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
106 fn generic_const_exprs(self) -> bool {
107 self.generic_const_exprs()
108 }
109
110 fn generic_const_args(self) -> bool {
111 self.generic_const_args()
112 }
113
114 fn coroutine_clone(self) -> bool {
115 self.coroutine_clone()
116 }
117
118 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
119 !self.staged_api() && self.enabled(symbol)
123 }
124}
125
126impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
127 fn dummy() -> Self {
128 DUMMY_SP
129 }
130}
131
132type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
133
134pub struct CtxtInterners<'tcx> {
135 arena: &'tcx WorkerLocal<Arena<'tcx>>,
137
138 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
141 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
142 args: InternedSet<'tcx, GenericArgs<'tcx>>,
143 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
144 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
145 region: InternedSet<'tcx, RegionKind<'tcx>>,
146 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
147 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
148 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
149 projs: InternedSet<'tcx, List<ProjectionKind>>,
150 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
151 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
152 pat: InternedSet<'tcx, PatternKind<'tcx>>,
153 const_allocation: InternedSet<'tcx, Allocation>,
154 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
155 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
156 adt_def: InternedSet<'tcx, AdtDefData>,
157 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
158 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
159 fields: InternedSet<'tcx, List<FieldIdx>>,
160 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
161 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
162 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
163 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
164 outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
165}
166
167impl<'tcx> CtxtInterners<'tcx> {
168 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
169 const N: usize = 2048;
172 CtxtInterners {
173 arena,
174 type_: InternedSet::with_capacity(N * 16),
179 const_lists: InternedSet::with_capacity(N * 4),
180 args: InternedSet::with_capacity(N * 4),
181 type_lists: InternedSet::with_capacity(N * 4),
182 region: InternedSet::with_capacity(N * 4),
183 poly_existential_predicates: InternedSet::with_capacity(N / 4),
184 canonical_var_kinds: InternedSet::with_capacity(N / 2),
185 predicate: InternedSet::with_capacity(N),
186 clauses: InternedSet::with_capacity(N),
187 projs: InternedSet::with_capacity(N * 4),
188 place_elems: InternedSet::with_capacity(N * 2),
189 const_: InternedSet::with_capacity(N * 2),
190 pat: InternedSet::with_capacity(N),
191 const_allocation: InternedSet::with_capacity(N),
192 bound_variable_kinds: InternedSet::with_capacity(N * 2),
193 layout: InternedSet::with_capacity(N),
194 adt_def: InternedSet::with_capacity(N),
195 external_constraints: InternedSet::with_capacity(N),
196 predefined_opaques_in_body: InternedSet::with_capacity(N),
197 fields: InternedSet::with_capacity(N * 4),
198 local_def_ids: InternedSet::with_capacity(N),
199 captures: InternedSet::with_capacity(N),
200 valtree: InternedSet::with_capacity(N),
201 patterns: InternedSet::with_capacity(N),
202 outlives: InternedSet::with_capacity(N),
203 }
204 }
205
206 #[allow(rustc::usage_of_ty_tykind)]
208 #[inline(never)]
209 fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
210 Ty(Interned::new_unchecked(
211 self.type_
212 .intern(kind, |kind| {
213 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
214 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
215 internee: kind,
216 flags: flags.flags,
217 outer_exclusive_binder: flags.outer_exclusive_binder,
218 }))
219 })
220 .0,
221 ))
222 }
223
224 #[allow(rustc::usage_of_ty_tykind)]
226 #[inline(never)]
227 fn intern_const(&self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
228 Const(Interned::new_unchecked(
229 self.const_
230 .intern(kind, |kind: ty::ConstKind<'_>| {
231 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
232 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
233 internee: kind,
234 flags: flags.flags,
235 outer_exclusive_binder: flags.outer_exclusive_binder,
236 }))
237 })
238 .0,
239 ))
240 }
241
242 #[inline(never)]
244 fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
245 Predicate(Interned::new_unchecked(
246 self.predicate
247 .intern(kind, |kind| {
248 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
249 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
250 internee: kind,
251 flags: flags.flags,
252 outer_exclusive_binder: flags.outer_exclusive_binder,
253 }))
254 })
255 .0,
256 ))
257 }
258
259 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
260 if clauses.is_empty() {
261 ListWithCachedTypeInfo::empty()
262 } else {
263 self.clauses
264 .intern_ref(clauses, || {
265 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
266
267 InternedInSet(ListWithCachedTypeInfo::from_arena(
268 &*self.arena,
269 flags.into(),
270 clauses,
271 ))
272 })
273 .0
274 }
275 }
276}
277
278const NUM_PREINTERNED_TY_VARS: u32 = 100;
283const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
284const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
285const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
286const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
287
288const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
298
299const NUM_PREINTERNED_RE_VARS: u32 = 500;
301const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
302const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
303
304pub struct CommonTypes<'tcx> {
305 pub unit: Ty<'tcx>,
306 pub bool: Ty<'tcx>,
307 pub char: Ty<'tcx>,
308 pub isize: Ty<'tcx>,
309 pub i8: Ty<'tcx>,
310 pub i16: Ty<'tcx>,
311 pub i32: Ty<'tcx>,
312 pub i64: Ty<'tcx>,
313 pub i128: Ty<'tcx>,
314 pub usize: Ty<'tcx>,
315 pub u8: Ty<'tcx>,
316 pub u16: Ty<'tcx>,
317 pub u32: Ty<'tcx>,
318 pub u64: Ty<'tcx>,
319 pub u128: Ty<'tcx>,
320 pub f16: Ty<'tcx>,
321 pub f32: Ty<'tcx>,
322 pub f64: Ty<'tcx>,
323 pub f128: Ty<'tcx>,
324 pub str_: Ty<'tcx>,
325 pub never: Ty<'tcx>,
326 pub self_param: Ty<'tcx>,
327
328 pub trait_object_dummy_self: Ty<'tcx>,
355
356 pub ty_vars: Vec<Ty<'tcx>>,
358
359 pub fresh_tys: Vec<Ty<'tcx>>,
361
362 pub fresh_int_tys: Vec<Ty<'tcx>>,
364
365 pub fresh_float_tys: Vec<Ty<'tcx>>,
367
368 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
372
373 pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
377}
378
379pub struct CommonLifetimes<'tcx> {
380 pub re_static: Region<'tcx>,
382
383 pub re_erased: Region<'tcx>,
385
386 pub re_vars: Vec<Region<'tcx>>,
388
389 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
393
394 pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
398}
399
400pub struct CommonConsts<'tcx> {
401 pub unit: Const<'tcx>,
402 pub true_: Const<'tcx>,
403 pub false_: Const<'tcx>,
404 pub(crate) valtree_zst: ValTree<'tcx>,
406}
407
408impl<'tcx> CommonTypes<'tcx> {
409 fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
410 let mk = |ty| interners.intern_ty(ty);
411
412 let ty_vars =
413 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
414 let fresh_tys: Vec<_> =
415 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
416 let fresh_int_tys: Vec<_> =
417 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
418 let fresh_float_tys: Vec<_> =
419 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
420
421 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
422 .map(|i| {
423 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
424 .map(|v| {
425 mk(ty::Bound(
426 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
427 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
428 ))
429 })
430 .collect()
431 })
432 .collect();
433
434 let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
435 .map(|v| {
436 mk(ty::Bound(
437 ty::BoundVarIndexKind::Canonical,
438 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
439 ))
440 })
441 .collect();
442
443 CommonTypes {
444 unit: mk(Tuple(List::empty())),
445 bool: mk(Bool),
446 char: mk(Char),
447 never: mk(Never),
448 isize: mk(Int(ty::IntTy::Isize)),
449 i8: mk(Int(ty::IntTy::I8)),
450 i16: mk(Int(ty::IntTy::I16)),
451 i32: mk(Int(ty::IntTy::I32)),
452 i64: mk(Int(ty::IntTy::I64)),
453 i128: mk(Int(ty::IntTy::I128)),
454 usize: mk(Uint(ty::UintTy::Usize)),
455 u8: mk(Uint(ty::UintTy::U8)),
456 u16: mk(Uint(ty::UintTy::U16)),
457 u32: mk(Uint(ty::UintTy::U32)),
458 u64: mk(Uint(ty::UintTy::U64)),
459 u128: mk(Uint(ty::UintTy::U128)),
460 f16: mk(Float(ty::FloatTy::F16)),
461 f32: mk(Float(ty::FloatTy::F32)),
462 f64: mk(Float(ty::FloatTy::F64)),
463 f128: mk(Float(ty::FloatTy::F128)),
464 str_: mk(Str),
465 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
466
467 trait_object_dummy_self: fresh_tys[0],
468
469 ty_vars,
470 fresh_tys,
471 fresh_int_tys,
472 fresh_float_tys,
473 anon_bound_tys,
474 anon_canonical_bound_tys,
475 }
476 }
477}
478
479impl<'tcx> CommonLifetimes<'tcx> {
480 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
481 let mk = |r| {
482 Region(Interned::new_unchecked(
483 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
484 ))
485 };
486
487 let re_vars =
488 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
489
490 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
491 .map(|i| {
492 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
493 .map(|v| {
494 mk(ty::ReBound(
495 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
496 ty::BoundRegion {
497 var: ty::BoundVar::from(v),
498 kind: ty::BoundRegionKind::Anon,
499 },
500 ))
501 })
502 .collect()
503 })
504 .collect();
505
506 let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
507 .map(|v| {
508 mk(ty::ReBound(
509 ty::BoundVarIndexKind::Canonical,
510 ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
511 ))
512 })
513 .collect();
514
515 CommonLifetimes {
516 re_static: mk(ty::ReStatic),
517 re_erased: mk(ty::ReErased),
518 re_vars,
519 anon_re_bounds,
520 anon_re_canonical_bounds,
521 }
522 }
523}
524
525impl<'tcx> CommonConsts<'tcx> {
526 fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
527 let mk_const = |c| interners.intern_const(c);
528
529 let mk_valtree = |v| {
530 ty::ValTree(Interned::new_unchecked(
531 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
532 ))
533 };
534
535 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
536 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
537 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
538
539 CommonConsts {
540 unit: mk_const(ty::ConstKind::Value(ty::Value {
541 ty: types.unit,
542 valtree: valtree_zst,
543 })),
544 true_: mk_const(ty::ConstKind::Value(ty::Value {
545 ty: types.bool,
546 valtree: valtree_true,
547 })),
548 false_: mk_const(ty::ConstKind::Value(ty::Value {
549 ty: types.bool,
550 valtree: valtree_false,
551 })),
552 valtree_zst,
553 }
554 }
555}
556
557#[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)]
560pub struct FreeRegionInfo {
561 pub scope: LocalDefId,
563 pub region_def_id: DefId,
565 pub is_impl_item: bool,
567}
568
569#[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)]
571pub struct TyCtxtFeed<'tcx, K: Copy> {
572 pub tcx: TyCtxt<'tcx>,
573 key: K,
575}
576
577impl<K: Copy> !StableHash for TyCtxtFeed<'_, K> {}
579
580impl<'tcx> TyCtxt<'tcx> {
585 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
588 self.dep_graph.assert_ignored();
589 TyCtxtFeed { tcx: self, key: () }
590 }
591
592 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
595 let key = self.untracked().source_span.push(span);
596 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);
597 TyCtxtFeed { tcx: self, key }
598 }
599
600 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
604 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);
605 TyCtxtFeed { tcx: self, key }.type_of(value)
606 }
607
608 pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) {
610 self.dep_graph.assert_ignored();
611 TyCtxtFeed { tcx: self, key }.hir_delayed_owner(owner);
612 }
613
614 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
622 if truecfg!(debug_assertions) {
623 match self.def_kind(self.local_parent(key)) {
624 DefKind::Impl { of_trait: true } => {}
625 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:?}"),
626 }
627 }
628 TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id())
629 }
630}
631
632impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> {
633 #[inline(always)]
634 pub fn key(&self) -> K {
635 self.key
636 }
637}
638
639impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
640 #[inline(always)]
641 pub fn def_id(&self) -> LocalDefId {
642 self.key
643 }
644
645 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
647 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
648 }
649
650 pub fn feed_hir(&self) {
652 self.hir_owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo::new(
653 self.tcx.arena.alloc(hir::OwnerNodes::synthetic()),
654 self.tcx.arena.alloc(Default::default()),
655 self.tcx.arena.alloc(Default::default()),
656 self.tcx.arena.alloc(Steal::new(Default::default())),
657 )));
658
659 self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
660 }
661}
662
663#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for TyCtxt<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for TyCtxt<'tcx> {
#[inline]
fn clone(&self) -> TyCtxt<'tcx> {
let _: ::core::clone::AssertParamIsClone<&'tcx GlobalCtxt<'tcx>>;
*self
}
}Clone)]
681#[rustc_diagnostic_item = "TyCtxt"]
682#[rustc_pass_by_value]
683pub struct TyCtxt<'tcx> {
684 gcx: &'tcx GlobalCtxt<'tcx>,
685}
686
687unsafe impl DynSend for TyCtxt<'_> {}
691unsafe impl DynSync for TyCtxt<'_> {}
692fn _assert_tcx_fields() {
693 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
694 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
695}
696
697impl<'tcx> Deref for TyCtxt<'tcx> {
698 type Target = &'tcx GlobalCtxt<'tcx>;
699 #[inline(always)]
700 fn deref(&self) -> &Self::Target {
701 &self.gcx
702 }
703}
704
705pub struct GlobalCtxt<'tcx> {
707 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
708 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
709
710 interners: CtxtInterners<'tcx>,
711
712 pub sess: &'tcx Session,
713 crate_types: Vec<CrateType>,
714 stable_crate_id: StableCrateId,
720
721 pub dep_graph: DepGraph,
722
723 pub prof: SelfProfilerRef,
724
725 pub types: CommonTypes<'tcx>,
727
728 pub lifetimes: CommonLifetimes<'tcx>,
730
731 pub consts: CommonConsts<'tcx>,
733
734 pub(crate) hooks: crate::hooks::Providers,
737
738 untracked: Untracked,
739
740 pub query_system: QuerySystem<'tcx>,
741 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
742
743 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
745
746 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
749
750 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
754
755 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
757 pub new_solver_canonical_param_env_cache:
758 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
759
760 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
761
762 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
764 pub clauses_cache:
766 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
767
768 pub data_layout: TargetDataLayout,
770
771 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
773
774 current_gcx: CurrentGcx,
775
776 pub jobserver_proxy: Arc<Proxy>,
778}
779
780impl<'tcx> GlobalCtxt<'tcx> {
781 pub fn enter<F, R>(&'tcx self, f: F) -> R
784 where
785 F: FnOnce(TyCtxt<'tcx>) -> R,
786 {
787 let icx = tls::ImplicitCtxt::new(self);
788
789 let _on_drop = defer(move || {
791 *self.current_gcx.value.write() = None;
792 });
793
794 {
796 let mut guard = self.current_gcx.value.write();
797 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
798 *guard = Some(self as *const _ as *const ());
799 }
800
801 tls::enter_context(&icx, || f(icx.tcx))
802 }
803}
804
805#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
812pub struct CurrentGcx {
813 value: Arc<RwLock<Option<*const ()>>>,
816}
817
818unsafe impl DynSend for CurrentGcx {}
819unsafe impl DynSync for CurrentGcx {}
820
821impl CurrentGcx {
822 pub fn new() -> Self {
823 Self { value: Arc::new(RwLock::new(None)) }
824 }
825
826 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
827 let read_guard = self.value.read();
828 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
829 f(unsafe { &*gcx })
833 }
834}
835
836impl<'tcx> TyCtxt<'tcx> {
837 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
838 let root = self.typeck_root_def_id_local(def_id);
841 self.hir_node_by_def_id(root).body_id().is_some()
842 }
843
844 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
849 let def_kind = self.def_kind(def_id);
850 if def_kind.has_codegen_attrs() {
851 self.codegen_fn_attrs(def_id)
852 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
DefKind::InlineConst | DefKind::GlobalAsm => true,
_ => false,
}matches!(
853 def_kind,
854 DefKind::AnonConst
855 | DefKind::AssocConst { .. }
856 | DefKind::Const { .. }
857 | DefKind::InlineConst
858 | DefKind::GlobalAsm
859 ) {
860 CodegenFnAttrs::EMPTY
861 } else {
862 crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind))bug!(
863 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
864 def_id,
865 def_kind
866 )
867 }
868 }
869
870 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
871 self.arena.alloc(Steal::new(thir))
872 }
873
874 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
875 self.arena.alloc(Steal::new(mir))
876 }
877
878 pub fn alloc_steal_promoted(
879 self,
880 promoted: IndexVec<Promoted, Body<'tcx>>,
881 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
882 self.arena.alloc(Steal::new(promoted))
883 }
884
885 pub fn mk_adt_def(
886 self,
887 did: DefId,
888 kind: AdtKind,
889 variants: IndexVec<VariantIdx, ty::VariantDef>,
890 repr: ReprOptions,
891 ) -> ty::AdtDef<'tcx> {
892 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
893 }
894
895 pub fn allocate_bytes_dedup<'a>(
898 self,
899 bytes: impl Into<Cow<'a, [u8]>>,
900 salt: usize,
901 ) -> interpret::AllocId {
902 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
904 let alloc = self.mk_const_alloc(alloc);
905 self.reserve_and_set_memory_dedup(alloc, salt)
906 }
907
908 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
910 if self.sess.opts.unstable_opts.experimental_default_bounds {
911 &[
912 LangItem::DefaultTrait1,
913 LangItem::DefaultTrait2,
914 LangItem::DefaultTrait3,
915 LangItem::DefaultTrait4,
916 ]
917 } else {
918 &[]
919 }
920 }
921
922 pub fn is_default_trait(self, def_id: DefId) -> bool {
923 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
924 }
925
926 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
927 #[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))
928 }
929
930 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> T::Lifted {
931 value.lift_to_interner(self)
932 }
933
934 pub fn create_global_ctxt<T>(
941 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
942 sess: &'tcx Session,
943 crate_types: Vec<CrateType>,
944 stable_crate_id: StableCrateId,
945 arena: &'tcx WorkerLocal<Arena<'tcx>>,
946 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
947 untracked: Untracked,
948 dep_graph: DepGraph,
949 dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
950 query_system: QuerySystem<'tcx>,
951 hooks: crate::hooks::Providers,
952 current_gcx: CurrentGcx,
953 jobserver_proxy: Arc<Proxy>,
954 f: impl FnOnce(TyCtxt<'tcx>) -> T,
955 ) -> T {
956 let data_layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
957 sess.dcx().emit_fatal(err);
958 });
959 let interners = CtxtInterners::new(arena);
960 let common_types = CommonTypes::new(&interners);
961 let common_lifetimes = CommonLifetimes::new(&interners);
962 let common_consts = CommonConsts::new(&interners, &common_types);
963
964 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
965 sess,
966 crate_types,
967 stable_crate_id,
968 arena,
969 hir_arena,
970 interners,
971 dep_graph,
972 hooks,
973 prof: sess.prof.clone(),
974 types: common_types,
975 lifetimes: common_lifetimes,
976 consts: common_consts,
977 untracked,
978 query_system,
979 dep_kind_vtables,
980 ty_rcache: Default::default(),
981 selection_cache: Default::default(),
982 evaluation_cache: Default::default(),
983 new_solver_evaluation_cache: Default::default(),
984 new_solver_canonical_param_env_cache: Default::default(),
985 canonical_param_env_cache: Default::default(),
986 highest_var_in_clauses_cache: Default::default(),
987 clauses_cache: Default::default(),
988 data_layout,
989 alloc_map: interpret::AllocMap::new(),
990 current_gcx,
991 jobserver_proxy,
992 });
993
994 gcx.enter(f)
996 }
997
998 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1000 self.get_lang_items(())
1001 }
1002
1003 #[track_caller]
1005 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1006 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1007 self.type_of(ordering_enum).no_bound_vars().unwrap()
1008 }
1009
1010 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1013 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1014 }
1015
1016 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1018 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1019 }
1020
1021 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1023 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1024 }
1025
1026 pub fn is_coroutine(self, def_id: DefId) -> bool {
1027 self.coroutine_kind(def_id).is_some()
1028 }
1029
1030 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1031 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1032 }
1033
1034 pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1035 if !self.is_type_const(def_id) {
1036 return None;
1037 }
1038 Some(self.def_span(def_id))
1039 }
1040
1041 pub fn is_type_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1043 let def_id = def_id.into_query_key();
1044 match self.def_kind(def_id) {
1045 DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1046 is_type_const
1047 }
1048 _ => false,
1049 }
1050 }
1051
1052 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1055 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1056 }
1057
1058 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1060 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1061 self.coroutine_kind(def_id),
1062 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1063 )
1064 }
1065
1066 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1069 #[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)
1070 }
1071
1072 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1075 #[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(_)))
1076 }
1077
1078 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1080 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1081 self.coroutine_kind(def_id),
1082 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1083 )
1084 }
1085
1086 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1088 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1089 self.coroutine_kind(def_id),
1090 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1091 )
1092 }
1093
1094 pub fn features(self) -> &'tcx rustc_feature::Features {
1095 self.features_query(())
1096 }
1097
1098 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1099 let id = id.into_query_key();
1100 if let Some(id) = id.as_local() {
1102 self.definitions_untracked().def_key(id)
1103 } else {
1104 self.cstore_untracked().def_key(id)
1105 }
1106 }
1107
1108 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1114 if let Some(id) = id.as_local() {
1116 self.definitions_untracked().def_path(id)
1117 } else {
1118 self.cstore_untracked().def_path(id)
1119 }
1120 }
1121
1122 #[inline]
1123 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1124 if let Some(def_id) = def_id.as_local() {
1126 self.definitions_untracked().def_path_hash(def_id)
1127 } else {
1128 self.cstore_untracked().def_path_hash(def_id)
1129 }
1130 }
1131
1132 #[inline]
1133 pub fn crate_types(self) -> &'tcx [CrateType] {
1134 &self.crate_types
1135 }
1136
1137 pub fn needs_metadata(self) -> bool {
1138 self.crate_types().iter().any(|ty| match *ty {
1139 CrateType::Executable
1140 | CrateType::StaticLib
1141 | CrateType::Cdylib
1142 | CrateType::Sdylib => false,
1143 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1144 })
1145 }
1146
1147 pub fn needs_hir_hash(self) -> bool {
1148 truecfg!(debug_assertions)
1160 || self.sess.opts.incremental.is_some()
1161 || self.needs_metadata()
1162 || self.sess.instrument_coverage()
1163 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1164 }
1165
1166 #[inline]
1167 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1168 if crate_num == LOCAL_CRATE {
1169 self.stable_crate_id
1170 } else {
1171 self.cstore_untracked().stable_crate_id(crate_num)
1172 }
1173 }
1174
1175 #[inline]
1178 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1179 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1180 LOCAL_CRATE
1181 } else {
1182 *self
1183 .untracked()
1184 .stable_crate_ids
1185 .read()
1186 .get(&stable_crate_id)
1187 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1188 }
1189 }
1190
1191 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1195 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/context.rs:1195",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1195u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("def_path_hash_to_def_id({0:?})",
hash) as &dyn Value))])
});
} else { ; }
};debug!("def_path_hash_to_def_id({:?})", hash);
1196
1197 let stable_crate_id = hash.stable_crate_id();
1198
1199 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1202 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1203 } else {
1204 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1205 }
1206 }
1207
1208 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1209 let (crate_name, stable_crate_id) = if def_id.is_local() {
1214 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1215 } else {
1216 let cstore = &*self.cstore_untracked();
1217 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1218 };
1219
1220 ::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!(
1221 "{}[{:04x}]{}",
1222 crate_name,
1223 stable_crate_id.as_u64() >> (8 * 6),
1226 self.def_path(def_id).to_string_no_crate_verbose()
1227 )
1228 }
1229
1230 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1231 self.sess.dcx()
1232 }
1233
1234 pub fn is_target_feature_call_safe(
1237 self,
1238 callee_features: &[TargetFeature],
1239 body_features: &[TargetFeature],
1240 ) -> bool {
1241 self.sess.target.options.is_like_wasm
1246 || callee_features
1247 .iter()
1248 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1249 }
1250
1251 pub fn adjust_target_feature_sig(
1254 self,
1255 fun_def: DefId,
1256 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1257 caller: DefId,
1258 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1259 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1260 let caller_features = &self.body_codegen_attrs(caller).target_features;
1261 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1262 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1263 fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1264 ..sig
1265 }));
1266 }
1267 None
1268 }
1269
1270 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1273 match self.env_var_os(key.as_ref()) {
1274 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1275 None => Err(VarError::NotPresent),
1276 }
1277 }
1278}
1279
1280impl<'tcx> TyCtxtAt<'tcx> {
1281 pub fn create_def(
1283 self,
1284 parent: LocalDefId,
1285 name: Option<Symbol>,
1286 def_kind: DefKind,
1287 override_def_path_data: Option<DefPathData>,
1288 disambiguator: &mut PerParentDisambiguatorState,
1289 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1290 let feed =
1291 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1292
1293 feed.def_span(self.span);
1294 feed
1295 }
1296}
1297
1298impl<'tcx> TyCtxt<'tcx> {
1299 pub fn create_def(
1301 self,
1302 parent: LocalDefId,
1303 name: Option<Symbol>,
1304 def_kind: DefKind,
1305 override_def_path_data: Option<DefPathData>,
1306 disambiguator: &mut PerParentDisambiguatorState,
1307 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1308 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1309 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1319
1320 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1325
1326 let feed = TyCtxtFeed { tcx: self, key: def_id };
1327 feed.def_kind(def_kind);
1328 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1333 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1334 feed.visibility(ty::Visibility::Restricted(parent_mod));
1335 }
1336
1337 feed
1338 }
1339
1340 pub fn create_crate_num(
1341 self,
1342 stable_crate_id: StableCrateId,
1343 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1344 let mut lock = self.untracked().stable_crate_ids.write();
1345 if let Some(&existing) = lock.get(&stable_crate_id) {
1346 return Err(existing);
1347 }
1348 let num = CrateNum::new(lock.len());
1349 lock.insert(stable_crate_id, num);
1350 Ok(TyCtxtFeed { key: num, tcx: self })
1351 }
1352
1353 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1354 self.ensure_ok().analysis(());
1356
1357 let definitions = &self.untracked.definitions;
1358 gen {
1359 let mut i = 0;
1360
1361 while i < { definitions.read().num_definitions() } {
1364 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1365 yield LocalDefId { local_def_index };
1366 i += 1;
1367 }
1368
1369 definitions.freeze();
1371 }
1372 }
1373
1374 pub fn definitions(self) -> &'tcx rustc_hir::definitions::Definitions {
1375 self.ensure_ok().analysis(());
1377
1378 self.untracked.definitions.freeze()
1381 }
1382
1383 pub fn def_path_hash_to_def_index_map(
1384 self,
1385 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1386 self.ensure_ok().hir_crate_items(());
1389 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1392 }
1393
1394 #[inline]
1397 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1398 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1399 }
1400
1401 pub fn untracked(self) -> &'tcx Untracked {
1403 &self.untracked
1404 }
1405 #[inline]
1408 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1409 self.untracked.definitions.read()
1410 }
1411
1412 #[inline]
1415 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1416 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1417 }
1418
1419 #[inline(always)]
1420 pub fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashState<'_>) -> R) -> R {
1421 f(StableHashState::new(self.sess, &self.untracked))
1422 }
1423
1424 #[inline]
1425 pub fn local_crate_exports_generics(self) -> bool {
1426 if self.is_compiler_builtins(LOCAL_CRATE) {
1430 return false;
1431 }
1432 self.crate_types().iter().any(|crate_type| {
1433 match crate_type {
1434 CrateType::Executable
1435 | CrateType::StaticLib
1436 | CrateType::ProcMacro
1437 | CrateType::Cdylib
1438 | CrateType::Sdylib => false,
1439
1440 CrateType::Dylib => true,
1445
1446 CrateType::Rlib => true,
1447 }
1448 })
1449 }
1450
1451 pub fn is_suitable_region(
1453 self,
1454 generic_param_scope: LocalDefId,
1455 mut region: Region<'tcx>,
1456 ) -> Option<FreeRegionInfo> {
1457 let (suitable_region_binding_scope, region_def_id) = loop {
1458 let def_id =
1459 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1460 let scope = self.local_parent(def_id);
1461 if self.def_kind(scope) == DefKind::OpaqueTy {
1462 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1465 continue;
1466 }
1467 break (scope, def_id.into());
1468 };
1469
1470 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1471 Node::Item(..) | Node::TraitItem(..) => false,
1472 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1473 hir::ImplItemImplKind::Trait { .. } => true,
1480 _ => false,
1481 },
1482 _ => false,
1483 };
1484
1485 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1486 }
1487
1488 pub fn return_type_impl_or_dyn_traits(
1490 self,
1491 scope_def_id: LocalDefId,
1492 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1493 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1494 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1495 self.hir_fn_decl_by_hir_id(hir_id)
1496 else {
1497 return ::alloc::vec::Vec::new()vec![];
1498 };
1499
1500 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1501 v.visit_ty_unambig(hir_output);
1502 v.0
1503 }
1504
1505 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1509 self,
1510 scope_def_id: LocalDefId,
1511 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1512 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1513 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1514 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1516 && let hir::TyKind::Path(hir::QPath::Resolved(
1517 None,
1518 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1519 && let Some(local_id) = def_id.as_local()
1520 && 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()
1522 {
1523 v.visit_ty_unambig(alias_ty);
1524 if !v.0.is_empty() {
1525 return Some((
1526 v.0,
1527 alias_generics.span,
1528 alias_generics.span_for_lifetime_suggestion(),
1529 ));
1530 }
1531 }
1532 None
1533 }
1534
1535 pub fn has_strict_asm_symbol_naming(self) -> bool {
1538 self.sess.target.llvm_target.starts_with("nvptx")
1539 }
1540
1541 pub fn caller_location_ty(self) -> Ty<'tcx> {
1543 Ty::new_imm_ref(
1544 self,
1545 self.lifetimes.re_static,
1546 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1547 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1548 .skip_norm_wip(),
1549 )
1550 }
1551
1552 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1554 let kind = self.def_kind(def_id);
1555 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1556 }
1557
1558 pub fn type_length_limit(self) -> Limit {
1559 self.limits(()).type_length_limit
1560 }
1561
1562 pub fn recursion_limit(self) -> Limit {
1563 self.limits(()).recursion_limit
1564 }
1565
1566 pub fn move_size_limit(self) -> Limit {
1567 self.limits(()).move_size_limit
1568 }
1569
1570 pub fn pattern_complexity_limit(self) -> Limit {
1571 self.limits(()).pattern_complexity_limit
1572 }
1573
1574 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1576 iter::once(LOCAL_CRATE)
1577 .chain(self.crates(()).iter().copied())
1578 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1579 }
1580
1581 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1583 let visible_crates =
1584 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1585
1586 iter::once(LOCAL_CRATE)
1587 .chain(visible_crates)
1588 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1589 }
1590
1591 #[inline]
1592 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1593 self.visibility(def_id).expect_local()
1594 }
1595
1596 x;#[instrument(skip(self), level = "trace", ret)]
1598 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1599 self.hir_expect_opaque_ty(def_id).origin
1600 }
1601
1602 pub fn finish(self) {
1603 self.alloc_self_profile_query_strings();
1606
1607 self.save_dep_graph();
1608 self.verify_query_key_hashes();
1609
1610 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1611 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
1612 }
1613 }
1614
1615 pub fn report_unused_features(self) {
1616 #[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)]
1617 #[diag("feature `{$feature}` is declared but not used")]
1618 struct UnusedFeature {
1619 feature: Symbol,
1620 }
1621
1622 let used_features = self.sess.used_features.lock();
1624 let unused_features = self
1625 .features()
1626 .enabled_features_iter_stable_order()
1627 .filter(|(f, _)| {
1628 !used_features.contains_key(f)
1629 && f.as_str() != "restricted_std"
1636 && *f != sym::doc_cfg
1640 })
1641 .collect::<Vec<_>>();
1642
1643 for (feature, span) in unused_features {
1644 self.emit_node_span_lint(
1645 rustc_session::lint::builtin::UNUSED_FEATURES,
1646 CRATE_HIR_ID,
1647 span,
1648 UnusedFeature { feature },
1649 );
1650 }
1651 }
1652}
1653
1654macro_rules! nop_lift {
1655 ($set:ident; $ty:ty => $lifted:ty) => {
1656 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1657 type Lifted = $lifted;
1658 #[track_caller]
1659 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1660 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1665 _x: Interned<'tcx, Inner>,
1666 ) -> InternedSet<'tcx, Inner> {
1667 unreachable!()
1668 }
1669 fn _type_eq<T>(_x: &T, _y: &T) {}
1670 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1671 let interner = _intern_set_ty_from_interned_ty(x.0);
1675 _type_eq(&interner, &tcx.interners.$set);
1677 }
1678
1679 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1680 unsafe { mem::transmute(self) }
1683 }
1684 }
1685 };
1686}
1687
1688macro_rules! nop_list_lift {
1689 ($set:ident; $ty:ty => $lifted:ty) => {
1690 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
1691 type Lifted = &'tcx List<$lifted>;
1692 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1693 if false {
1695 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
1696 }
1697
1698 if self.is_empty() {
1699 return List::empty();
1700 }
1701 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1702 unsafe { mem::transmute(self) }
1705 }
1706 }
1707 };
1708}
1709
1710impl<'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> }
1711impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Region<'a> {
type Lifted = Region<'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: Region<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.region);
}
if !tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { region; Region<'a> => Region<'tcx> }
1712impl<'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> }
1713impl<'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> }
1714impl<'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> }
1715impl<'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> }
1716impl<'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> }
1717impl<'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> }
1718impl<'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> }
1719
1720impl<'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> }
1721impl<'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! {
1722 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1723}
1724impl<'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> }
1725
1726impl<'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> }
1728
1729macro_rules! sty_debug_print {
1730 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1731 #[allow(non_snake_case)]
1734 mod inner {
1735 use crate::ty::{self, TyCtxt};
1736 use crate::ty::context::InternedInSet;
1737
1738 #[derive(Copy, Clone)]
1739 struct DebugStat {
1740 total: usize,
1741 lt_infer: usize,
1742 ty_infer: usize,
1743 ct_infer: usize,
1744 all_infer: usize,
1745 }
1746
1747 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1748 let mut total = DebugStat {
1749 total: 0,
1750 lt_infer: 0,
1751 ty_infer: 0,
1752 ct_infer: 0,
1753 all_infer: 0,
1754 };
1755 $(let mut $variant = total;)*
1756
1757 for shard in tcx.interners.type_.lock_shards() {
1758 #[allow(rustc::potential_query_instability)]
1760 let types = shard.iter();
1761 for &(InternedInSet(t), ()) in types {
1762 let variant = match t.internee {
1763 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1764 ty::Float(..) | ty::Str | ty::Never => continue,
1765 ty::Error(_) => continue,
1766 $(ty::$variant(..) => &mut $variant,)*
1767 };
1768 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1769 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1770 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1771
1772 variant.total += 1;
1773 total.total += 1;
1774 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1775 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1776 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1777 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1778 }
1779 }
1780 writeln!(fmt, "Ty interner total ty lt ct all")?;
1781 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1782 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1783 stringify!($variant),
1784 uses = $variant.total,
1785 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1786 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1787 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1788 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1789 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1790 )*
1791 writeln!(fmt, " total {uses:6} \
1792 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1793 uses = total.total,
1794 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1795 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1796 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1797 all = total.all_infer as f64 * 100.0 / total.total as f64)
1798 }
1799 }
1800
1801 inner::go($fmt, $ctxt)
1802 }}
1803}
1804
1805impl<'tcx> TyCtxt<'tcx> {
1806 pub fn debug_stats(self) -> impl fmt::Debug {
1807 fmt::from_fn(move |fmt| {
1808 {
#[allow(non_snake_case)]
mod inner {
use crate::ty::{self, TyCtxt};
use crate::ty::context::InternedInSet;
struct DebugStat {
total: usize,
lt_infer: usize,
ty_infer: usize,
ct_infer: usize,
all_infer: usize,
}
#[automatically_derived]
impl ::core::marker::Copy for DebugStat { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DebugStat { }
#[automatically_derived]
impl ::core::clone::Clone for DebugStat {
#[inline]
fn clone(&self) -> DebugStat {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}
pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>)
-> std::fmt::Result {
let mut total =
DebugStat {
total: 0,
lt_infer: 0,
ty_infer: 0,
ct_infer: 0,
all_infer: 0,
};
let mut Adt = total;
let mut Array = total;
let mut Slice = total;
let mut RawPtr = total;
let mut Ref = total;
let mut FnDef = total;
let mut FnPtr = total;
let mut UnsafeBinder = total;
let mut Placeholder = total;
let mut Coroutine = total;
let mut CoroutineWitness = total;
let mut Dynamic = total;
let mut Closure = total;
let mut CoroutineClosure = total;
let mut Tuple = total;
let mut Bound = total;
let mut Param = total;
let mut Infer = total;
let mut Alias = total;
let mut Pat = total;
let mut Foreign = total;
for shard in tcx.interners.type_.lock_shards() {
#[allow(rustc :: potential_query_instability)]
let types = shard.iter();
for &(InternedInSet(t), ()) in types {
let variant =
match t.internee {
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
ty::Float(..) | ty::Str | ty::Never => continue,
ty::Error(_) => continue,
ty::Adt(..) => &mut Adt,
ty::Array(..) => &mut Array,
ty::Slice(..) => &mut Slice,
ty::RawPtr(..) => &mut RawPtr,
ty::Ref(..) => &mut Ref,
ty::FnDef(..) => &mut FnDef,
ty::FnPtr(..) => &mut FnPtr,
ty::UnsafeBinder(..) => &mut UnsafeBinder,
ty::Placeholder(..) => &mut Placeholder,
ty::Coroutine(..) => &mut Coroutine,
ty::CoroutineWitness(..) => &mut CoroutineWitness,
ty::Dynamic(..) => &mut Dynamic,
ty::Closure(..) => &mut Closure,
ty::CoroutineClosure(..) => &mut CoroutineClosure,
ty::Tuple(..) => &mut Tuple,
ty::Bound(..) => &mut Bound,
ty::Param(..) => &mut Param,
ty::Infer(..) => &mut Infer,
ty::Alias(..) => &mut Alias,
ty::Pat(..) => &mut Pat,
ty::Foreign(..) => &mut Foreign,
};
let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
variant.total += 1;
total.total += 1;
if lt { total.lt_infer += 1; variant.lt_infer += 1 }
if ty { total.ty_infer += 1; variant.ty_infer += 1 }
if ct { total.ct_infer += 1; variant.ct_infer += 1 }
if lt && ty && ct {
total.all_infer += 1;
variant.all_infer += 1
}
}
}
fmt.write_fmt(format_args!("Ty interner total ty lt ct all\n"))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Adt", Adt.total,
Adt.total as f64 * 100.0 / total.total as f64,
Adt.ty_infer as f64 * 100.0 / total.total as f64,
Adt.lt_infer as f64 * 100.0 / total.total as f64,
Adt.ct_infer as f64 * 100.0 / total.total as f64,
Adt.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Array", Array.total,
Array.total as f64 * 100.0 / total.total as f64,
Array.ty_infer as f64 * 100.0 / total.total as f64,
Array.lt_infer as f64 * 100.0 / total.total as f64,
Array.ct_infer as f64 * 100.0 / total.total as f64,
Array.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Slice", Slice.total,
Slice.total as f64 * 100.0 / total.total as f64,
Slice.ty_infer as f64 * 100.0 / total.total as f64,
Slice.lt_infer as f64 * 100.0 / total.total as f64,
Slice.ct_infer as f64 * 100.0 / total.total as f64,
Slice.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"RawPtr", RawPtr.total,
RawPtr.total as f64 * 100.0 / total.total as f64,
RawPtr.ty_infer as f64 * 100.0 / total.total as f64,
RawPtr.lt_infer as f64 * 100.0 / total.total as f64,
RawPtr.ct_infer as f64 * 100.0 / total.total as f64,
RawPtr.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Ref", Ref.total,
Ref.total as f64 * 100.0 / total.total as f64,
Ref.ty_infer as f64 * 100.0 / total.total as f64,
Ref.lt_infer as f64 * 100.0 / total.total as f64,
Ref.ct_infer as f64 * 100.0 / total.total as f64,
Ref.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"FnDef", FnDef.total,
FnDef.total as f64 * 100.0 / total.total as f64,
FnDef.ty_infer as f64 * 100.0 / total.total as f64,
FnDef.lt_infer as f64 * 100.0 / total.total as f64,
FnDef.ct_infer as f64 * 100.0 / total.total as f64,
FnDef.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"FnPtr", FnPtr.total,
FnPtr.total as f64 * 100.0 / total.total as f64,
FnPtr.ty_infer as f64 * 100.0 / total.total as f64,
FnPtr.lt_infer as f64 * 100.0 / total.total as f64,
FnPtr.ct_infer as f64 * 100.0 / total.total as f64,
FnPtr.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"UnsafeBinder", UnsafeBinder.total,
UnsafeBinder.total as f64 * 100.0 / total.total as f64,
UnsafeBinder.ty_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.lt_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.ct_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Placeholder", Placeholder.total,
Placeholder.total as f64 * 100.0 / total.total as f64,
Placeholder.ty_infer as f64 * 100.0 / total.total as f64,
Placeholder.lt_infer as f64 * 100.0 / total.total as f64,
Placeholder.ct_infer as f64 * 100.0 / total.total as f64,
Placeholder.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Coroutine", Coroutine.total,
Coroutine.total as f64 * 100.0 / total.total as f64,
Coroutine.ty_infer as f64 * 100.0 / total.total as f64,
Coroutine.lt_infer as f64 * 100.0 / total.total as f64,
Coroutine.ct_infer as f64 * 100.0 / total.total as f64,
Coroutine.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"CoroutineWitness", CoroutineWitness.total,
CoroutineWitness.total as f64 * 100.0 / total.total as f64,
CoroutineWitness.ty_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.lt_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.ct_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Dynamic", Dynamic.total,
Dynamic.total as f64 * 100.0 / total.total as f64,
Dynamic.ty_infer as f64 * 100.0 / total.total as f64,
Dynamic.lt_infer as f64 * 100.0 / total.total as f64,
Dynamic.ct_infer as f64 * 100.0 / total.total as f64,
Dynamic.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Closure", Closure.total,
Closure.total as f64 * 100.0 / total.total as f64,
Closure.ty_infer as f64 * 100.0 / total.total as f64,
Closure.lt_infer as f64 * 100.0 / total.total as f64,
Closure.ct_infer as f64 * 100.0 / total.total as f64,
Closure.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"CoroutineClosure", CoroutineClosure.total,
CoroutineClosure.total as f64 * 100.0 / total.total as f64,
CoroutineClosure.ty_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.lt_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.ct_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Tuple", Tuple.total,
Tuple.total as f64 * 100.0 / total.total as f64,
Tuple.ty_infer as f64 * 100.0 / total.total as f64,
Tuple.lt_infer as f64 * 100.0 / total.total as f64,
Tuple.ct_infer as f64 * 100.0 / total.total as f64,
Tuple.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Bound", Bound.total,
Bound.total as f64 * 100.0 / total.total as f64,
Bound.ty_infer as f64 * 100.0 / total.total as f64,
Bound.lt_infer as f64 * 100.0 / total.total as f64,
Bound.ct_infer as f64 * 100.0 / total.total as f64,
Bound.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Param", Param.total,
Param.total as f64 * 100.0 / total.total as f64,
Param.ty_infer as f64 * 100.0 / total.total as f64,
Param.lt_infer as f64 * 100.0 / total.total as f64,
Param.ct_infer as f64 * 100.0 / total.total as f64,
Param.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Infer", Infer.total,
Infer.total as f64 * 100.0 / total.total as f64,
Infer.ty_infer as f64 * 100.0 / total.total as f64,
Infer.lt_infer as f64 * 100.0 / total.total as f64,
Infer.ct_infer as f64 * 100.0 / total.total as f64,
Infer.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Alias", Alias.total,
Alias.total as f64 * 100.0 / total.total as f64,
Alias.ty_infer as f64 * 100.0 / total.total as f64,
Alias.lt_infer as f64 * 100.0 / total.total as f64,
Alias.ct_infer as f64 * 100.0 / total.total as f64,
Alias.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Pat", Pat.total,
Pat.total as f64 * 100.0 / total.total as f64,
Pat.ty_infer as f64 * 100.0 / total.total as f64,
Pat.lt_infer as f64 * 100.0 / total.total as f64,
Pat.ct_infer as f64 * 100.0 / total.total as f64,
Pat.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Foreign", Foreign.total,
Foreign.total as f64 * 100.0 / total.total as f64,
Foreign.ty_infer as f64 * 100.0 / total.total as f64,
Foreign.lt_infer as f64 * 100.0 / total.total as f64,
Foreign.ct_infer as f64 * 100.0 / total.total as f64,
Foreign.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" total {0:6} {1:4.1}% {2:5.1}% {3:4.1}% {4:4.1}%\n",
total.total,
total.ty_infer as f64 * 100.0 / total.total as f64,
total.lt_infer as f64 * 100.0 / total.total as f64,
total.ct_infer as f64 * 100.0 / total.total as f64,
total.all_infer as f64 * 100.0 / total.total as f64))
}
}
inner::go(fmt, self)
}sty_debug_print!(
1809 fmt,
1810 self,
1811 Adt,
1812 Array,
1813 Slice,
1814 RawPtr,
1815 Ref,
1816 FnDef,
1817 FnPtr,
1818 UnsafeBinder,
1819 Placeholder,
1820 Coroutine,
1821 CoroutineWitness,
1822 Dynamic,
1823 Closure,
1824 CoroutineClosure,
1825 Tuple,
1826 Bound,
1827 Param,
1828 Infer,
1829 Alias,
1830 Pat,
1831 Foreign
1832 )?;
1833
1834 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1835 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1836 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())?;
1837 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1838
1839 Ok(())
1840 })
1841 }
1842}
1843
1844struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1849
1850impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1851 fn clone(&self) -> Self {
1852 *self
1853 }
1854}
1855
1856impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1857
1858impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1859 fn into_pointer(&self) -> *const () {
1860 self.0 as *const _ as *const ()
1861 }
1862}
1863
1864#[allow(rustc::usage_of_ty_tykind)]
1865impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1866 fn borrow(&self) -> &T {
1867 &self.0.internee
1868 }
1869}
1870
1871impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1872 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1873 self.0.internee == other.0.internee
1876 }
1877}
1878
1879impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1880
1881impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1882 fn hash<H: Hasher>(&self, s: &mut H) {
1883 self.0.internee.hash(s)
1885 }
1886}
1887
1888impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1889 fn borrow(&self) -> &[T] {
1890 &self.0[..]
1891 }
1892}
1893
1894impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1895 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1896 self.0[..] == other.0[..]
1899 }
1900}
1901
1902impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1903
1904impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1905 fn hash<H: Hasher>(&self, s: &mut H) {
1906 self.0[..].hash(s)
1908 }
1909}
1910
1911impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1912 fn borrow(&self) -> &[T] {
1913 &self.0[..]
1914 }
1915}
1916
1917impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1918 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1919 self.0[..] == other.0[..]
1922 }
1923}
1924
1925impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1926
1927impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1928 fn hash<H: Hasher>(&self, s: &mut H) {
1929 self.0[..].hash(s)
1931 }
1932}
1933
1934macro_rules! direct_interners {
1935 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1936 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1937 fn borrow<'a>(&'a self) -> &'a $ty {
1938 &self.0
1939 }
1940 }
1941
1942 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1943 fn eq(&self, other: &Self) -> bool {
1944 self.0 == other.0
1947 }
1948 }
1949
1950 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1951
1952 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1953 fn hash<H: Hasher>(&self, s: &mut H) {
1954 self.0.hash(s)
1957 }
1958 }
1959
1960 impl<'tcx> TyCtxt<'tcx> {
1961 $vis fn $method(self, v: $ty) -> $ret_ty {
1962 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1963 InternedInSet(self.interners.arena.alloc(v))
1964 }).0))
1965 }
1966 })+
1967 }
1968}
1969
1970impl<'tcx> Borrow<ExternalConstraintsData<TyCtxt<'tcx>>> for
InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a ExternalConstraintsData<TyCtxt<'tcx>> {
&self.0
}
}
impl<'tcx> PartialEq for
InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>
{}
impl<'tcx> Hash for InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>
{
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_external_constraints(self,
v: ExternalConstraintsData<TyCtxt<'tcx>>)
-> ExternalConstraints<'tcx> {
ExternalConstraints(Interned::new_unchecked(self.interners.external_constraints.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}direct_interners! {
1974 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
1975 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
1976 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
1977 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
1978 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
1979 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
1980 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
1981 ExternalConstraints -> ExternalConstraints<'tcx>,
1982}
1983
1984macro_rules! slice_interners {
1985 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
1986 impl<'tcx> TyCtxt<'tcx> {
1987 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
1988 if v.is_empty() {
1989 List::empty()
1990 } else {
1991 self.interners.$field.intern_ref(v, || {
1992 InternedInSet(List::from_arena(&*self.arena, (), v))
1993 }).0
1994 }
1995 })+
1996 }
1997 );
1998}
1999
2000impl<'tcx> TyCtxt<'tcx> {
pub fn mk_const_list(self, v: &[Const<'tcx>]) -> &'tcx List<Const<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.const_lists.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_args(self, v: &[GenericArg<'tcx>])
-> &'tcx List<GenericArg<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.args.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.type_lists.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_canonical_var_kinds(self, v: &[CanonicalVarKind<'tcx>])
-> &'tcx List<CanonicalVarKind<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.canonical_var_kinds.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_poly_existential_predicates(self,
v: &[PolyExistentialPredicate<'tcx>])
-> &'tcx List<PolyExistentialPredicate<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.poly_existential_predicates.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_projs(self, v: &[ProjectionKind])
-> &'tcx List<ProjectionKind> {
if v.is_empty() {
List::empty()
} else {
self.interners.projs.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_place_elems(self, v: &[PlaceElem<'tcx>])
-> &'tcx List<PlaceElem<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.place_elems.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_bound_variable_kinds(self, v: &[ty::BoundVariableKind<'tcx>])
-> &'tcx List<ty::BoundVariableKind<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.bound_variable_kinds.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_fields(self, v: &[FieldIdx]) -> &'tcx List<FieldIdx> {
if v.is_empty() {
List::empty()
} else {
self.interners.fields.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_local_def_ids(self, v: &[LocalDefId])
-> &'tcx List<LocalDefId> {
if v.is_empty() {
List::empty()
} else {
self.interners.local_def_ids.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_captures(self, v: &[&'tcx ty::CapturedPlace<'tcx>])
-> &'tcx List<&'tcx ty::CapturedPlace<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.captures.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_patterns(self, v: &[Pattern<'tcx>])
-> &'tcx List<Pattern<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.patterns.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_outlives(self, v: &[ty::ArgOutlivesPredicate<'tcx>])
-> &'tcx List<ty::ArgOutlivesPredicate<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.outlives.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_predefined_opaques_in_body(self,
v: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)])
-> &'tcx List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
if v.is_empty() {
List::empty()
} else {
self.interners.predefined_opaques_in_body.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
}slice_interners!(
2004 const_lists: pub mk_const_list(Const<'tcx>),
2005 args: pub mk_args(GenericArg<'tcx>),
2006 type_lists: pub mk_type_list(Ty<'tcx>),
2007 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2008 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2009 projs: pub mk_projs(ProjectionKind),
2010 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2011 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2012 fields: pub mk_fields(FieldIdx),
2013 local_def_ids: intern_local_def_ids(LocalDefId),
2014 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2015 patterns: pub mk_patterns(Pattern<'tcx>),
2016 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2017 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2018);
2019
2020impl<'tcx> TyCtxt<'tcx> {
2021 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2025 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2026 Ty::new_fn_ptr(
2027 self,
2028 sig.map_bound(|sig| ty::FnSig {
2029 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2030 ..sig
2031 }),
2032 )
2033 }
2034
2035 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2039 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2040 sig.map_bound(|sig| ty::FnSig {
2041 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2042 ..sig
2043 })
2044 }
2045
2046 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2049 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2050 self.associated_items(trait_did)
2051 .filter_by_name_unhygienic(assoc_name.name)
2052 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2053 })
2054 }
2055
2056 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2058 let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2059 return false;
2060 };
2061 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2062
2063 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2064 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2065 return false;
2066 };
2067 trait_predicate.trait_ref.def_id == future_trait
2068 && trait_predicate.polarity == PredicatePolarity::Positive
2069 })
2070 }
2071
2072 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2080 sig.map_bound(|s| {
2081 let params = match s.inputs()[0].kind() {
2082 ty::Tuple(params) => *params,
2083 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2084 };
2085 self.mk_fn_sig(
2086 params,
2087 s.output(),
2088 s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2089 )
2090 })
2091 }
2092
2093 #[inline]
2094 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2095 self.interners.intern_predicate(binder)
2096 }
2097
2098 #[inline]
2099 pub fn reuse_or_mk_predicate(
2100 self,
2101 pred: Predicate<'tcx>,
2102 binder: Binder<'tcx, PredicateKind<'tcx>>,
2103 ) -> Predicate<'tcx> {
2104 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2105 }
2106
2107 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2108 self.check_args_compatible_inner(def_id, args, false)
2109 }
2110
2111 fn check_args_compatible_inner(
2112 self,
2113 def_id: DefId,
2114 args: &'tcx [ty::GenericArg<'tcx>],
2115 nested: bool,
2116 ) -> bool {
2117 let generics = self.generics_of(def_id);
2118
2119 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)
2123 && #[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 });
2124 let is_inherent_assoc_type_const =
2125 #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocConst { is_type_const: true } => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocConst { is_type_const: true })
2126 && #[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 });
2127 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2128 if generics.own_params.len() + 1 != args.len() {
2129 return false;
2130 }
2131
2132 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2133 return false;
2134 }
2135
2136 &args[1..]
2137 } else {
2138 if generics.count() != args.len() {
2139 return false;
2140 }
2141
2142 let (parent_args, own_args) = args.split_at(generics.parent_count);
2143
2144 if let Some(parent) = generics.parent
2145 && !self.check_args_compatible_inner(parent, parent_args, true)
2146 {
2147 return false;
2148 }
2149
2150 own_args
2151 };
2152
2153 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2154 match (¶m.kind, arg.kind()) {
2155 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2156 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2157 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2158 _ => return false,
2159 }
2160 }
2161
2162 true
2163 }
2164
2165 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2168 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2169 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)
2170 && #[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 });
2171 let is_inherent_assoc_type_const =
2172 #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocConst { is_type_const: true } => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocConst { is_type_const: true })
2173 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(
2174 self.def_kind(self.parent(def_id)),
2175 DefKind::Impl { of_trait: false }
2176 );
2177 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2178 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!(
2179 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2180 self.def_path_str(def_id),
2181 args,
2182 self.mk_args_from_iter(
2184 [self.types.self_param.into()].into_iter().chain(
2185 self.generics_of(def_id)
2186 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2187 .iter()
2188 .copied()
2189 )
2190 )
2191 );
2192 } else {
2193 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!(
2194 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2195 self.def_path_str(def_id),
2196 args,
2197 ty::GenericArgs::identity_for_item(self, def_id)
2198 );
2199 }
2200 }
2201 }
2202
2203 #[inline(always)]
2204 pub(crate) fn check_and_mk_args(
2205 self,
2206 def_id: DefId,
2207 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2208 ) -> GenericArgsRef<'tcx> {
2209 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2210 self.debug_assert_args_compatible(def_id, args);
2211 args
2212 }
2213
2214 #[inline]
2215 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2216 self.interners.intern_const(kind)
2217 }
2218
2219 #[allow(rustc::usage_of_ty_tykind)]
2221 #[inline]
2222 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2223 self.interners.intern_ty(st)
2224 }
2225
2226 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2227 match param.kind {
2228 GenericParamDefKind::Lifetime => {
2229 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2230 }
2231 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2232 GenericParamDefKind::Const { .. } => {
2233 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2234 .into()
2235 }
2236 }
2237 }
2238
2239 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2240 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2241 }
2242
2243 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2244 self.mk_place_elem(place, PlaceElem::Deref)
2245 }
2246
2247 pub fn mk_place_downcast(
2248 self,
2249 place: Place<'tcx>,
2250 adt_def: AdtDef<'tcx>,
2251 variant_index: VariantIdx,
2252 ) -> Place<'tcx> {
2253 self.mk_place_elem(
2254 place,
2255 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2256 )
2257 }
2258
2259 pub fn mk_place_downcast_unnamed(
2260 self,
2261 place: Place<'tcx>,
2262 variant_index: VariantIdx,
2263 ) -> Place<'tcx> {
2264 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2265 }
2266
2267 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2268 self.mk_place_elem(place, PlaceElem::Index(index))
2269 }
2270
2271 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2275 Place {
2276 local: place.local,
2277 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2278 }
2279 }
2280
2281 pub fn mk_poly_existential_predicates(
2282 self,
2283 eps: &[PolyExistentialPredicate<'tcx>],
2284 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2285 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2286 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!(
2287 eps.array_windows()
2288 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2289 != Ordering::Greater)
2290 );
2291 self.intern_poly_existential_predicates(eps)
2292 }
2293
2294 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2295 self.interners.intern_clauses(clauses)
2299 }
2300
2301 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2302 self.intern_local_def_ids(def_ids)
2306 }
2307
2308 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2309 where
2310 I: Iterator<Item = T>,
2311 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2312 {
2313 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2314 }
2315
2316 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2317 where
2318 I: Iterator<Item = T>,
2319 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2320 {
2321 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2322 }
2323
2324 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2325 where
2326 I: Iterator<Item = T>,
2327 T: CollectAndApply<
2328 &'tcx ty::CapturedPlace<'tcx>,
2329 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2330 >,
2331 {
2332 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2333 }
2334
2335 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2336 where
2337 I: Iterator<Item = T>,
2338 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2339 {
2340 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2341 }
2342
2343 pub fn mk_fn_sig<I, T>(
2348 self,
2349 inputs: I,
2350 output: I::Item,
2351 fn_sig_kind: FnSigKind<'tcx>,
2352 ) -> T::Output
2353 where
2354 I: IntoIterator<Item = T>,
2355 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2356 {
2357 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2358 inputs_and_output: self.mk_type_list(xs),
2359 fn_sig_kind,
2360 })
2361 }
2362
2363 pub fn mk_fn_sig_rust_abi<I, T>(
2365 self,
2366 inputs: I,
2367 output: I::Item,
2368 safety: hir::Safety,
2369 ) -> T::Output
2370 where
2371 I: IntoIterator<Item = T>,
2372 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2373 {
2374 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2375 }
2376
2377 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2379 where
2380 I: IntoIterator<Item = T>,
2381 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2382 {
2383 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2384 }
2385
2386 pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2388 where
2389 I: IntoIterator<Item = T>,
2390 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2391 {
2392 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2393 }
2394
2395 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2396 where
2397 I: Iterator<Item = T>,
2398 T: CollectAndApply<
2399 PolyExistentialPredicate<'tcx>,
2400 &'tcx List<PolyExistentialPredicate<'tcx>>,
2401 >,
2402 {
2403 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2404 }
2405
2406 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2407 where
2408 I: Iterator<Item = T>,
2409 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2410 {
2411 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2412 }
2413
2414 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2415 where
2416 I: Iterator<Item = T>,
2417 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2418 {
2419 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2420 }
2421
2422 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2423 where
2424 I: Iterator<Item = T>,
2425 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2426 {
2427 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2428 }
2429
2430 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2431 where
2432 I: Iterator<Item = T>,
2433 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2434 {
2435 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2436 }
2437
2438 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2439 where
2440 I: Iterator<Item = T>,
2441 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2442 {
2443 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2444 }
2445
2446 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2447 where
2448 I: Iterator<Item = T>,
2449 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2450 {
2451 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2452 }
2453
2454 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2455 where
2456 I: Iterator<Item = T>,
2457 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2458 {
2459 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2460 }
2461
2462 pub fn mk_args_trait(
2463 self,
2464 self_ty: Ty<'tcx>,
2465 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2466 ) -> GenericArgsRef<'tcx> {
2467 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2468 }
2469
2470 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2471 where
2472 I: Iterator<Item = T>,
2473 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2474 {
2475 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2476 }
2477
2478 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2479 where
2480 I: Iterator<Item = T>,
2481 T: CollectAndApply<
2482 ty::ArgOutlivesPredicate<'tcx>,
2483 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2484 >,
2485 {
2486 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2487 }
2488
2489 #[track_caller]
2492 pub fn emit_node_span_lint(
2493 self,
2494 lint: &'static Lint,
2495 hir_id: HirId,
2496 span: impl Into<MultiSpan>,
2497 decorator: impl for<'a> Diagnostic<'a, ()>,
2498 ) {
2499 let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2500 emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2501 }
2502
2503 pub fn crate_level_attribute_injection_span(self) -> Span {
2505 let node = self.hir_node(hir::CRATE_HIR_ID);
2506 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2507 m.spans.inject_use_span.shrink_to_lo()
2508 }
2509
2510 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2511 self,
2512 diag: &mut Diag<'_, E>,
2513 features: impl IntoIterator<Item = (String, Symbol)>,
2514 ) {
2515 if !self.sess.is_nightly_build() {
2516 return;
2517 }
2518
2519 let span = self.crate_level_attribute_injection_span();
2520 for (desc, feature) in features {
2521 let msg =
2523 ::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}");
2524 diag.span_suggestion_verbose(
2525 span,
2526 msg,
2527 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2528 Applicability::MaybeIncorrect,
2529 );
2530 }
2531 }
2532
2533 #[track_caller]
2536 pub fn emit_node_lint(
2537 self,
2538 lint: &'static Lint,
2539 id: HirId,
2540 decorator: impl for<'a> Diagnostic<'a, ()>,
2541 ) {
2542 let level_spec = self.lint_level_spec_at_node(lint, id);
2543 emit_lint_base(self.sess, lint, level_spec, None, decorator);
2544 }
2545
2546 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2547 let map = self.in_scope_traits_map(id.owner)?;
2548 let candidates = map.get(&id.local_id)?;
2549 Some(candidates)
2550 }
2551
2552 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2553 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/context.rs:2553",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(2553u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&["message", "id"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("named_region")
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&id) as
&dyn Value))])
});
} else { ; }
};debug!(?id, "named_region");
2554 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2555 }
2556
2557 pub fn is_late_bound(self, id: HirId) -> bool {
2558 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2559 }
2560
2561 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2562 self.mk_bound_variable_kinds(
2563 &self
2564 .late_bound_vars_map(id.owner)
2565 .get(&id.local_id)
2566 .cloned()
2567 .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))),
2568 )
2569 }
2570
2571 pub fn map_opaque_lifetime_to_parent_lifetime(
2579 self,
2580 mut opaque_lifetime_param_def_id: LocalDefId,
2581 ) -> ty::Region<'tcx> {
2582 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!(
2583 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2584 "{opaque_lifetime_param_def_id:?} is a {}",
2585 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2586 );
2587
2588 loop {
2589 let parent = self.local_parent(opaque_lifetime_param_def_id);
2590 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2591
2592 let Some((lifetime, _)) = lifetime_mapping
2593 .iter()
2594 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2595 else {
2596 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2597 };
2598
2599 match *lifetime {
2600 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2601 let new_parent = self.local_parent(ebv);
2602
2603 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2606 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);
2607 opaque_lifetime_param_def_id = ebv;
2608 continue;
2609 }
2610
2611 let generics = self.generics_of(new_parent);
2612 return ty::Region::new_early_param(
2613 self,
2614 ty::EarlyParamRegion {
2615 index: generics
2616 .param_def_id_to_index(self, ebv.to_def_id())
2617 .expect("early-bound var should be present in fn generics"),
2618 name: self.item_name(ebv.to_def_id()),
2619 },
2620 );
2621 }
2622 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2623 let new_parent = self.local_parent(lbv);
2624 return ty::Region::new_late_param(
2625 self,
2626 new_parent.to_def_id(),
2627 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2628 );
2629 }
2630 resolve_bound_vars::ResolvedArg::Error(guar) => {
2631 return ty::Region::new_error(self, guar);
2632 }
2633 _ => {
2634 return ty::Region::new_error_with_message(
2635 self,
2636 self.def_span(opaque_lifetime_param_def_id),
2637 "cannot resolve lifetime",
2638 );
2639 }
2640 }
2641 }
2642 }
2643
2644 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2649 self.is_const_fn(def_id)
2650 && match self.lookup_const_stability(def_id) {
2651 None => true, Some(stability) if stability.is_const_stable() => true,
2653 _ => false,
2654 }
2655 }
2656
2657 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2659 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2660 && self.impl_trait_header(def_id).constness == hir::Constness::Const
2661 }
2662
2663 pub fn is_sdylib_interface_build(self) -> bool {
2664 self.sess.opts.unstable_opts.build_sdylib_interface
2665 }
2666
2667 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2668 let def_id = def_id.into_query_key();
2669 match self.def_kind(def_id) {
2670 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2671 _ => None,
2672 }
2673 }
2674
2675 pub fn next_trait_solver_globally(self) -> bool {
2676 self.sess.opts.unstable_opts.next_solver.globally
2677 }
2678
2679 pub fn next_trait_solver_in_coherence(self) -> bool {
2680 self.sess.opts.unstable_opts.next_solver.coherence
2681 }
2682
2683 pub fn disable_trait_solver_fast_paths(self) -> bool {
2684 self.sess.opts.unstable_opts.disable_fast_paths
2685 }
2686
2687 #[allow(rustc::bad_opt_access)]
2688 pub fn use_typing_mode_borrowck(self) -> bool {
2689 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
2690 }
2691
2692 pub fn assumptions_on_binders(self) -> bool {
2693 self.sess.opts.unstable_opts.assumptions_on_binders
2694 }
2695
2696 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2697 self.opt_rpitit_info(def_id).is_some()
2698 }
2699
2700 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2710 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2711 }
2712
2713 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2715 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2716 }
2717
2718 pub fn resolver_for_lowering(
2719 self,
2720 ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc<ast::Crate>)> {
2721 self.resolver_for_lowering_raw(()).0
2722 }
2723
2724 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2725 make_metadata(self)
2726 }
2727
2728 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2729 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2730 self.coroutine_kind(def_id)
2731 && let ty::Coroutine(_, args) =
2732 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2733 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2734 {
2735 true
2736 } else {
2737 false
2738 }
2739 }
2740
2741 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2743 {
{
'done:
{
for i in
::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(DoNotRecommend) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(self, def_id, DoNotRecommend)
2744 }
2745
2746 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2747 let def_id = def_id.into_query_key();
2748 self.trivial_const(def_id).is_some()
2749 }
2750
2751 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2754 if self.is_lang_item(def_id, LangItem::Start) {
2755 return true;
2756 }
2757 if let Some((entry_def_id, _)) = self.entry_fn(())
2758 && entry_def_id == def_id
2759 {
2760 return true;
2761 }
2762 false
2763 }
2764}
2765
2766pub fn provide(providers: &mut Providers) {
2767 providers.is_panic_runtime = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(PanicRuntime) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, PanicRuntime);
2768 providers.is_compiler_builtins = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(CompilerBuiltins) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, CompilerBuiltins);
2769 providers.has_panic_handler = |tcx, LocalCrate| {
2770 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2772 };
2773 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2774}