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