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::config::NextSolverConfig;
44use rustc_session::{IncrCompSession, Session};
45use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
46use rustc_span::{DUMMY_SP, Ident, Span, Symbol, bug, kw, sym};
47use rustc_structures::{CrateType, Limit};
48use rustc_type_ir::TyKind::*;
49pub use rustc_type_ir::lift::Lift;
50use rustc_type_ir::{
51 CollectAndApply, PlaceholderType, WithCachedTypeInfo, elaborate, search_graph,
52};
53use tracing::{debug, instrument};
54
55use crate::arena::Arena;
56use crate::dep_graph::dep_node::make_metadata;
57use crate::dep_graph::{DepGraph, DepNodeIndex};
58use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo};
59use crate::ich::StableHashState;
60use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
61use crate::lint::emit_lint_base;
62use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
63use crate::middle::resolve::{ModChild, ResolverAstLowering};
64use crate::middle::resolve_bound_vars;
65use crate::mir::interpret::{self, Allocation, ConstAllocation};
66use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
67use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
68use crate::thir::Thir;
69use crate::traits;
70use crate::traits::solve::{
71 CanonicalInput, CanonicalInputData, ExternalConstraints, ExternalConstraintsData,
72 PredefinedOpaques,
73};
74use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
75use crate::ty::{
76 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, ClausePolarity, Clauses, Const, ConstKind,
77 FnSigKind, GenericArg, GenericArgs, GenericArgsRef, GenericParamDefKind, List,
78 ListWithCachedTypeInfo, ParamConst, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig,
79 Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind,
80 TyVid, ValTree, ValTreeKind, Visibility,
81};
82
83impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
84 fn is_local(self) -> bool {
85 self.is_local()
86 }
87
88 fn as_local(self) -> Option<LocalDefId> {
89 self.as_local()
90 }
91}
92
93impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
94 fn safe() -> Self {
95 hir::Safety::Safe
96 }
97
98 fn unsafe_mode() -> Self {
99 hir::Safety::Unsafe
100 }
101
102 fn is_safe(self) -> bool {
103 self.is_safe()
104 }
105
106 fn prefix_str(self) -> &'static str {
107 self.prefix_str()
108 }
109}
110
111impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
112 fn generic_const_exprs(self) -> bool {
113 self.generic_const_exprs()
114 }
115
116 fn gca_const_items(self) -> bool {
117 self.gca_const_items()
118 }
119
120 fn coroutine_clone(self) -> bool {
121 self.coroutine_clone()
122 }
123
124 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
125 !self.staged_api() && self.enabled(symbol)
129 }
130}
131
132impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
133 fn dummy() -> Self {
134 DUMMY_SP
135 }
136}
137
138type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
139
140pub struct CtxtInterners<'tcx> {
141 arena: &'tcx WorkerLocal<Arena<'tcx>>,
143
144 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
147 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
148 args: InternedSet<'tcx, GenericArgs<'tcx>>,
149 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
150 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
151 region: InternedSet<'tcx, RegionKind<'tcx>>,
152 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
153 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
154 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
155 projs: InternedSet<'tcx, List<ProjectionKind>>,
156 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
157 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
158 pat: InternedSet<'tcx, PatternKind<'tcx>>,
159 const_allocation: InternedSet<'tcx, Allocation>,
160 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
161 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
162 adt_def: InternedSet<'tcx, AdtDefData>,
163 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
164 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
165 fields: InternedSet<'tcx, List<FieldIdx>>,
166 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
167 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
168 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
169 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
170 outlives: InternedSet<'tcx, List<ty::ArgOutlivesClause<'tcx>>>,
171 canonical_inputs: InternedSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>>,
172}
173
174impl<'tcx> CtxtInterners<'tcx> {
175 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
176 const N: usize = 2048;
179 CtxtInterners {
180 arena,
181 type_: InternedSet::with_capacity(N * 16),
186 const_lists: InternedSet::with_capacity(N * 4),
187 args: InternedSet::with_capacity(N * 4),
188 type_lists: InternedSet::with_capacity(N * 4),
189 region: InternedSet::with_capacity(N * 4),
190 poly_existential_predicates: InternedSet::with_capacity(N / 4),
191 canonical_var_kinds: InternedSet::with_capacity(N / 2),
192 predicate: InternedSet::with_capacity(N),
193 clauses: InternedSet::with_capacity(N),
194 projs: InternedSet::with_capacity(N * 4),
195 place_elems: InternedSet::with_capacity(N * 2),
196 const_: InternedSet::with_capacity(N * 2),
197 pat: InternedSet::with_capacity(N),
198 const_allocation: InternedSet::with_capacity(N),
199 bound_variable_kinds: InternedSet::with_capacity(N * 2),
200 layout: InternedSet::with_capacity(N),
201 adt_def: InternedSet::with_capacity(N),
202 external_constraints: InternedSet::with_capacity(N),
203 predefined_opaques_in_body: InternedSet::with_capacity(N),
204 fields: InternedSet::with_capacity(N * 4),
205 local_def_ids: InternedSet::with_capacity(N),
206 captures: InternedSet::with_capacity(N),
207 valtree: InternedSet::with_capacity(N),
208 patterns: InternedSet::with_capacity(N),
209 outlives: InternedSet::with_capacity(N),
210 canonical_inputs: InternedSet::with_capacity(N),
211 }
212 }
213
214 #[allow(rustc::usage_of_ty_tykind)]
216 #[inline(never)]
217 fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
218 Ty(Interned::new_unchecked(
219 self.type_
220 .intern(kind, |kind| {
221 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
222 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
223 internee: kind,
224 flags: flags.flags,
225 outer_exclusive_binder: flags.outer_exclusive_binder,
226 }))
227 })
228 .0,
229 ))
230 }
231
232 #[allow(rustc::usage_of_ty_tykind)]
234 #[inline(never)]
235 fn intern_const(&self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
236 Const(Interned::new_unchecked(
237 self.const_
238 .intern(kind, |kind: ty::ConstKind<'_>| {
239 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
240 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
241 internee: kind,
242 flags: flags.flags,
243 outer_exclusive_binder: flags.outer_exclusive_binder,
244 }))
245 })
246 .0,
247 ))
248 }
249
250 #[inline(never)]
252 fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
253 Predicate(Interned::new_unchecked(
254 self.predicate
255 .intern(kind, |kind| {
256 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
257 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
258 internee: kind,
259 flags: flags.flags,
260 outer_exclusive_binder: flags.outer_exclusive_binder,
261 }))
262 })
263 .0,
264 ))
265 }
266
267 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
268 if clauses.is_empty() {
269 ListWithCachedTypeInfo::empty()
270 } else {
271 self.clauses
272 .intern_ref(clauses, || {
273 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
274
275 InternedInSet(ListWithCachedTypeInfo::from_arena(
276 &*self.arena,
277 flags.into(),
278 clauses,
279 ))
280 })
281 .0
282 }
283 }
284}
285
286const NUM_PREINTERNED_INFER_TY_VARS: u32 = 512;
293const NUM_PREINTERNED_INFER_FRESH_TYS: u32 = 20;
294const NUM_PREINTERNED_INFER_FRESH_INT_TYS: u32 = 3;
295const NUM_PREINTERNED_INFER_FRESH_FLOAT_TYS: u32 = 3;
296const NUM_PREINTERNED_BOUND_BOUND_ANONS_I: u32 = 3;
297const NUM_PREINTERNED_BOUND_BOUND_ANONS_V: u32 = 20;
298const NUM_PREINTERNED_BOUND_CANONICAL_ANONS: u32 = 128;
299const NUM_PREINTERNED_PLACEHOLDER_ROOT_ANONS: u32 = 128;
300
301const NUM_PREINTERNED_RE_VARS: u32 = 500;
302const NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_I: u32 = 3;
303const NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_V: u32 = 20;
304const NUM_PREINTERNED_RE_BOUND_CANONICAL_ANONS: u32 = 20;
305
306pub struct CommonTypes<'tcx> {
307 pub unit: Ty<'tcx>,
308 pub bool: Ty<'tcx>,
309 pub char: Ty<'tcx>,
310 pub isize: Ty<'tcx>,
311 pub i8: Ty<'tcx>,
312 pub i16: Ty<'tcx>,
313 pub i32: Ty<'tcx>,
314 pub i64: Ty<'tcx>,
315 pub i128: Ty<'tcx>,
316 pub usize: Ty<'tcx>,
317 pub u8: Ty<'tcx>,
318 pub u16: Ty<'tcx>,
319 pub u32: Ty<'tcx>,
320 pub u64: Ty<'tcx>,
321 pub u128: Ty<'tcx>,
322 pub f16: Ty<'tcx>,
323 pub f32: Ty<'tcx>,
324 pub f64: Ty<'tcx>,
325 pub f128: Ty<'tcx>,
326 pub str_: Ty<'tcx>,
327 pub never: Ty<'tcx>,
328 pub self_param: Ty<'tcx>,
329
330 pub trait_object_dummy_self: Ty<'tcx>,
357
358 pub infer_ty_vars: Vec<Ty<'tcx>>,
360
361 pub infer_fresh_tys: Vec<Ty<'tcx>>,
363
364 pub infer_fresh_int_tys: Vec<Ty<'tcx>>,
366
367 pub infer_fresh_float_tys: Vec<Ty<'tcx>>,
369
370 pub bound_bound_anons: Vec<Vec<Ty<'tcx>>>,
377
378 pub bound_canonical_anons: Vec<Ty<'tcx>>,
382
383 pub placeholder_root_anons: Vec<Ty<'tcx>>,
390}
391
392pub struct CommonLifetimes<'tcx> {
393 pub re_static: Region<'tcx>,
395
396 pub re_erased: Region<'tcx>,
398
399 pub re_vars: Vec<Region<'tcx>>,
401
402 pub re_bound_bound_anons: Vec<Vec<Region<'tcx>>>,
406
407 pub re_bound_canonical_anons: Vec<Region<'tcx>>,
411}
412
413pub struct CommonConsts<'tcx> {
414 pub unit: Const<'tcx>,
415 pub true_: Const<'tcx>,
416 pub false_: Const<'tcx>,
417 pub(crate) valtree_zst: ValTree<'tcx>,
419}
420
421impl<'tcx> CommonTypes<'tcx> {
422 fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
423 let mk = |ty| interners.intern_ty(ty);
424
425 let infer_ty_vars = (0..NUM_PREINTERNED_INFER_TY_VARS)
426 .map(|n| mk(Infer(ty::TyVar(TyVid::from(n)))))
427 .collect();
428 let infer_fresh_tys: Vec<_> =
429 (0..NUM_PREINTERNED_INFER_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
430 let infer_fresh_int_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_INT_TYS)
431 .map(|n| mk(Infer(ty::FreshIntTy(n))))
432 .collect();
433 let infer_fresh_float_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_FLOAT_TYS)
434 .map(|n| mk(Infer(ty::FreshFloatTy(n))))
435 .collect();
436
437 let bound_bound_anons = (0..NUM_PREINTERNED_BOUND_BOUND_ANONS_I)
438 .map(|i| {
439 (0..NUM_PREINTERNED_BOUND_BOUND_ANONS_V)
440 .map(|v| {
441 mk(ty::Bound(
442 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
443 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
444 ))
445 })
446 .collect()
447 })
448 .collect();
449
450 let bound_canonical_anons = (0..NUM_PREINTERNED_BOUND_CANONICAL_ANONS)
451 .map(|v| {
452 mk(ty::Bound(
453 ty::BoundVarIndexKind::Canonical,
454 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
455 ))
456 })
457 .collect();
458
459 let placeholder_root_anons = (0..NUM_PREINTERNED_PLACEHOLDER_ROOT_ANONS)
460 .map(|v| {
461 mk(ty::Placeholder(PlaceholderType::new_anon(
462 ty::UniverseIndex::ROOT,
463 ty::BoundVar::from(v),
464 )))
465 })
466 .collect();
467
468 CommonTypes {
469 unit: mk(Tuple(List::empty())),
470 bool: mk(Bool),
471 char: mk(Char),
472 never: mk(Never),
473 isize: mk(Int(ty::IntTy::Isize)),
474 i8: mk(Int(ty::IntTy::I8)),
475 i16: mk(Int(ty::IntTy::I16)),
476 i32: mk(Int(ty::IntTy::I32)),
477 i64: mk(Int(ty::IntTy::I64)),
478 i128: mk(Int(ty::IntTy::I128)),
479 usize: mk(Uint(ty::UintTy::Usize)),
480 u8: mk(Uint(ty::UintTy::U8)),
481 u16: mk(Uint(ty::UintTy::U16)),
482 u32: mk(Uint(ty::UintTy::U32)),
483 u64: mk(Uint(ty::UintTy::U64)),
484 u128: mk(Uint(ty::UintTy::U128)),
485 f16: mk(Float(ty::FloatTy::F16)),
486 f32: mk(Float(ty::FloatTy::F32)),
487 f64: mk(Float(ty::FloatTy::F64)),
488 f128: mk(Float(ty::FloatTy::F128)),
489 str_: mk(Str),
490 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
491
492 trait_object_dummy_self: infer_fresh_tys[0],
493
494 infer_ty_vars,
495 infer_fresh_tys,
496 infer_fresh_int_tys,
497 infer_fresh_float_tys,
498 bound_bound_anons,
499 bound_canonical_anons,
500 placeholder_root_anons,
501 }
502 }
503}
504
505impl<'tcx> CommonLifetimes<'tcx> {
506 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
507 let mk = |r| {
508 Region(Interned::new_unchecked(
509 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
510 ))
511 };
512
513 let re_vars =
514 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
515
516 let re_bound_bound_anons = (0..NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_I)
517 .map(|i| {
518 (0..NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_V)
519 .map(|v| {
520 mk(ty::ReBound(
521 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
522 ty::BoundRegion {
523 var: ty::BoundVar::from(v),
524 kind: ty::BoundRegionKind::Anon,
525 },
526 ))
527 })
528 .collect()
529 })
530 .collect();
531
532 let re_bound_canonical_anons = (0..NUM_PREINTERNED_RE_BOUND_CANONICAL_ANONS)
533 .map(|v| {
534 mk(ty::ReBound(
535 ty::BoundVarIndexKind::Canonical,
536 ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
537 ))
538 })
539 .collect();
540
541 CommonLifetimes {
542 re_static: mk(ty::ReStatic),
543 re_erased: mk(ty::ReErased),
544 re_vars,
545 re_bound_bound_anons,
546 re_bound_canonical_anons,
547 }
548 }
549}
550
551impl<'tcx> CommonConsts<'tcx> {
552 fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
553 let mk_const = |c| interners.intern_const(c);
554
555 let mk_valtree = |v| {
556 ty::ValTree(Interned::new_unchecked(
557 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
558 ))
559 };
560
561 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
562 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
563 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
564
565 CommonConsts {
566 unit: mk_const(ty::ConstKind::Value(ty::Value {
567 ty: types.unit,
568 valtree: valtree_zst,
569 })),
570 true_: mk_const(ty::ConstKind::Value(ty::Value {
571 ty: types.bool,
572 valtree: valtree_true,
573 })),
574 false_: mk_const(ty::ConstKind::Value(ty::Value {
575 ty: types.bool,
576 valtree: valtree_false,
577 })),
578 valtree_zst,
579 }
580 }
581}
582
583#[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)]
586pub struct FreeRegionInfo {
587 pub scope: LocalDefId,
589 pub region_def_id: DefId,
591 pub is_impl_item: bool,
593}
594
595#[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 {
TyCtxtFeed {
tcx: ::core::clone::Clone::clone(&self.tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
597pub struct TyCtxtFeed<'tcx, K: Copy> {
598 pub tcx: TyCtxt<'tcx>,
599 key: K,
601}
602
603impl<K: Copy> !StableHash for TyCtxtFeed<'_, K> {}
605
606impl<'tcx> TyCtxt<'tcx> {
611 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
614 self.dep_graph.assert_ignored();
615 TyCtxtFeed { tcx: self, key: () }
616 }
617
618 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
621 let key = self.untracked().source_span.push(span);
622 {
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);
623 TyCtxtFeed { tcx: self, key }
624 }
625
626 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
630 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);
631 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);
632 TyCtxtFeed { tcx: self, key }.type_of(value)
633 }
634
635 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
643 if truecfg!(debug_assertions) {
644 match self.def_kind(self.local_parent(key)) {
645 DefKind::Impl { of_trait: true } => {}
646 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:?}"),
647 }
648 }
649 TyCtxtFeed { tcx: self, key }.visibility(vis.to_mod_id())
650 }
651}
652
653impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> {
654 #[inline(always)]
655 pub fn key(&self) -> K {
656 self.key
657 }
658}
659
660impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
661 #[inline(always)]
662 pub fn def_id(&self) -> LocalDefId {
663 self.key
664 }
665
666 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
668 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
669 }
670
671 pub fn feed_hir(&self) {
673 self.hir_owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo::new(
674 self.tcx.arena.alloc(hir::OwnerNodes::synthetic()),
675 self.tcx.arena.alloc(Default::default()),
676 self.tcx.arena.alloc(Default::default()),
677 self.tcx.arena.alloc(Steal::new(Default::default())),
678 )));
679
680 self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
681 }
682}
683
684#[derive(#[automatically_derived]
impl<'tcx> ::core::default::Default for GlobalCaches<'tcx> {
#[inline]
fn default() -> Self {
GlobalCaches {
ty_rcache: ::core::default::Default::default(),
selection_cache: ::core::default::Default::default(),
evaluation_cache: ::core::default::Default::default(),
new_solver_evaluation_cache: ::core::default::Default::default(),
new_solver_canonical_param_env_cache: ::core::default::Default::default(),
canonical_param_env_cache: ::core::default::Default::default(),
highest_var_in_clauses_cache: ::core::default::Default::default(),
clauses_cache: ::core::default::Default::default(),
}
}
}Default)]
689pub struct GlobalCaches<'tcx> {
690 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
692
693 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
696
697 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
701
702 new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
704 new_solver_canonical_param_env_cache: Lock<ty::CanonicalParamEnvCache<TyCtxt<'tcx>>>,
705
706 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
707
708 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
710
711 pub clauses_cache:
713 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
714}
715
716#[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)]
734#[rustc_diagnostic_item = "TyCtxt"]
735#[rustc_pass_by_value]
736pub struct TyCtxt<'tcx> {
737 gcx: &'tcx GlobalCtxt<'tcx>,
738}
739
740unsafe impl DynSend for TyCtxt<'_> {}
744unsafe impl DynSync for TyCtxt<'_> {}
745fn _assert_tcx_fields() {
746 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
747 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
748}
749
750impl<'tcx> Deref for TyCtxt<'tcx> {
751 type Target = &'tcx GlobalCtxt<'tcx>;
752 #[inline(always)]
753 fn deref(&self) -> &Self::Target {
754 &self.gcx
755 }
756}
757
758pub struct GlobalCtxt<'tcx> {
760 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
761 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
762
763 interners: CtxtInterners<'tcx>,
764
765 pub sess: &'tcx Session,
766 crate_types: Vec<CrateType>,
767 stable_crate_id: StableCrateId,
773
774 pub incr_comp_session: Option<&'tcx IncrCompSession>,
775 pub dep_graph: DepGraph,
776
777 pub prof: SelfProfilerRef,
780
781 pub types: CommonTypes<'tcx>,
783
784 pub lifetimes: CommonLifetimes<'tcx>,
786
787 pub consts: CommonConsts<'tcx>,
789
790 pub(crate) hooks: crate::hooks::Providers,
793
794 untracked: Untracked,
795
796 pub query_system: QuerySystem<'tcx>,
797
798 pub caches: GlobalCaches<'tcx>,
799
800 pub data_layout: TargetDataLayout,
802
803 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
805
806 current_gcx: CurrentGcx,
807}
808
809impl<'tcx> GlobalCtxt<'tcx> {
810 pub fn enter<F, R>(&'tcx self, f: F) -> R
813 where
814 F: FnOnce(TyCtxt<'tcx>) -> R,
815 {
816 let icx = tls::ImplicitCtxt::new(self);
817
818 let _on_drop = defer(move || {
820 *self.current_gcx.value.write() = None;
821 });
822
823 {
825 let mut guard = self.current_gcx.value.write();
826 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
827 *guard = Some(self as *const _ as *const ());
828 }
829
830 tls::enter_context(&icx, || f(icx.tcx))
831 }
832}
833
834#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> Self {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
841pub struct CurrentGcx {
842 value: Arc<RwLock<Option<*const ()>>>,
845}
846
847unsafe impl DynSend for CurrentGcx {}
848unsafe impl DynSync for CurrentGcx {}
849
850impl CurrentGcx {
851 pub fn new() -> Self {
852 Self { value: Arc::new(RwLock::new(None)) }
853 }
854
855 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
856 let read_guard = self.value.read();
857 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
858 f(unsafe { &*gcx })
862 }
863}
864
865impl<'tcx> TyCtxt<'tcx> {
866 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
867 let root = self.typeck_root_def_id_local(def_id);
870 self.hir_node_by_def_id(root).body_id().is_some()
871 }
872
873 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
878 let def_kind = self.def_kind(def_id);
879 if def_kind.has_codegen_attrs() {
880 self.codegen_fn_attrs(def_id)
881 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst | DefKind::Const |
DefKind::GlobalAsm => true,
_ => false,
}matches!(
882 def_kind,
883 DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::GlobalAsm
884 ) {
885 CodegenFnAttrs::EMPTY
886 } else {
887 ::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!(
888 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
889 def_id,
890 def_kind
891 )
892 }
893 }
894
895 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
896 self.arena.alloc(Steal::new(thir))
897 }
898
899 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
900 self.arena.alloc(Steal::new(mir))
901 }
902
903 pub fn alloc_steal_promoted(
904 self,
905 promoted: IndexVec<Promoted, Body<'tcx>>,
906 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
907 self.arena.alloc(Steal::new(promoted))
908 }
909
910 pub fn mk_adt_def(
911 self,
912 did: DefId,
913 kind: AdtKind,
914 variants: IndexVec<VariantIdx, ty::VariantDef>,
915 repr: ReprOptions,
916 ) -> ty::AdtDef<'tcx> {
917 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
918 }
919
920 pub fn allocate_bytes_dedup<'a>(
923 self,
924 bytes: impl Into<Cow<'a, [u8]>>,
925 salt: usize,
926 ) -> interpret::AllocId {
927 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
929 let alloc = self.mk_const_alloc(alloc);
930 self.reserve_and_set_memory_dedup(alloc, salt)
931 }
932
933 pub fn default_traits(self) -> &'static [LangItem] {
935 if self.sess.opts.unstable_opts.experimental_default_bounds {
936 &[
937 LangItem::DefaultTrait1,
938 LangItem::DefaultTrait2,
939 LangItem::DefaultTrait3,
940 LangItem::DefaultTrait4,
941 ]
942 } else {
943 &[]
944 }
945 }
946
947 pub fn is_default_trait(self, def_id: DefId) -> bool {
948 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
949 }
950
951 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
952 #[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))
953 }
954
955 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> T::Lifted {
956 value.lift_to_interner(self)
957 }
958
959 pub fn create_global_ctxt<T>(
966 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
967 sess: &'tcx Session,
968 crate_types: Vec<CrateType>,
969 stable_crate_id: StableCrateId,
970 arena: &'tcx WorkerLocal<Arena<'tcx>>,
971 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
972 untracked: Untracked,
973 incr_comp_session: Option<&'tcx IncrCompSession>,
974 dep_graph: DepGraph,
975 query_system: QuerySystem<'tcx>,
976 hooks: crate::hooks::Providers,
977 current_gcx: CurrentGcx,
978 f: impl FnOnce(TyCtxt<'tcx>) -> T,
979 ) -> T {
980 let data_layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
981 sess.dcx().emit_fatal(err);
982 });
983 let interners = CtxtInterners::new(arena);
984 let common_types = CommonTypes::new(&interners);
985 let common_lifetimes = CommonLifetimes::new(&interners);
986 let common_consts = CommonConsts::new(&interners, &common_types);
987
988 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
989 sess,
990 crate_types,
991 stable_crate_id,
992 arena,
993 hir_arena,
994 interners,
995 incr_comp_session,
996 dep_graph,
997 hooks,
998 prof: sess.prof.clone(),
999 types: common_types,
1000 lifetimes: common_lifetimes,
1001 consts: common_consts,
1002 untracked,
1003 query_system,
1004 caches: Default::default(),
1005 data_layout,
1006 alloc_map: interpret::AllocMap::new(),
1007 current_gcx,
1008 });
1009
1010 gcx.enter(f)
1012 }
1013
1014 pub fn lang_items(self) -> &'tcx rustc_attr_ir::lang_items::LanguageItems {
1016 self.get_lang_items(())
1017 }
1018
1019 #[track_caller]
1021 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1022 let ordering_enum = self.require_lang_item(LangItem::OrderingEnum, span);
1023 self.type_of(ordering_enum).no_bound_vars().unwrap()
1024 }
1025
1026 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1029 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1030 }
1031
1032 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1034 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1035 }
1036
1037 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1039 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1040 }
1041
1042 pub fn is_coroutine(self, def_id: DefId) -> bool {
1043 self.coroutine_kind(def_id).is_some()
1044 }
1045
1046 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1047 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1048 }
1049
1050 pub fn is_direct_const(self, def_id: DefId) -> bool {
1058 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);
1059 self.is_always_gca(def_id) || self.const_of_item(def_id).is_some()
1060 }
1061
1062 pub fn is_always_gca(self, def_id: DefId) -> bool {
1064 {
{
'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)
1065 }
1066
1067 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1070 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1071 }
1072
1073 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1075 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1076 self.coroutine_kind(def_id),
1077 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1078 )
1079 }
1080
1081 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1084 #[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)
1085 }
1086
1087 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1090 #[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(_)))
1091 }
1092
1093 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1095 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1096 self.coroutine_kind(def_id),
1097 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1098 )
1099 }
1100
1101 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1103 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1104 self.coroutine_kind(def_id),
1105 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1106 )
1107 }
1108
1109 pub fn features(self) -> &'tcx rustc_feature::Features {
1110 self.features_query(())
1111 }
1112
1113 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1114 let id = id.into_query_key();
1115 if let Some(id) = id.as_local() {
1117 self.definitions_untracked().def_key(id)
1118 } else {
1119 self.cstore_untracked().def_key(id)
1120 }
1121 }
1122
1123 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1129 if let Some(id) = id.as_local() {
1131 self.definitions_untracked().def_path(id)
1132 } else {
1133 self.cstore_untracked().def_path(id)
1134 }
1135 }
1136
1137 #[inline]
1138 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1139 if let Some(def_id) = def_id.as_local() {
1141 self.definitions_untracked().def_path_hash(def_id)
1142 } else {
1143 self.cstore_untracked().def_path_hash(def_id)
1144 }
1145 }
1146
1147 #[inline]
1148 pub fn crate_types(self) -> &'tcx [CrateType] {
1149 &self.crate_types
1150 }
1151
1152 pub fn needs_metadata(self) -> bool {
1153 self.crate_types().iter().any(|ty| match *ty {
1154 CrateType::Executable
1155 | CrateType::StaticLib
1156 | CrateType::Cdylib
1157 | CrateType::Sdylib => false,
1158 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1159 }) && !self.sess.opts.actually_rustdoc
1160 }
1161
1162 pub fn needs_hir_hash(self) -> bool {
1163 truecfg!(debug_assertions)
1175 || self.sess.opts.incremental.is_some()
1176 || self.needs_metadata()
1177 || self.sess.instrument_coverage()
1178 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1179 }
1180
1181 pub fn needs_owner_info_hash(self) -> bool {
1196 self.needs_hir_hash()
1197 && (!self.sess.opts.unstable_opts.metadata_crate_hash
1198 || self.sess.opts.incremental.is_some()
1199 || truecfg!(debug_assertions))
1200 }
1201
1202 #[inline]
1203 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1204 if crate_num == LOCAL_CRATE {
1205 self.stable_crate_id
1206 } else {
1207 self.cstore_untracked().stable_crate_id(crate_num)
1208 }
1209 }
1210
1211 #[inline]
1214 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1215 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1216 LOCAL_CRATE
1217 } else {
1218 *self
1219 .untracked()
1220 .stable_crate_ids
1221 .read()
1222 .get(&stable_crate_id)
1223 .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:?}"))
1224 }
1225 }
1226
1227 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1231 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_middle/src/ty/context.rs:1231",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1231u32),
::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);
1232
1233 let stable_crate_id = hash.stable_crate_id();
1234
1235 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1238 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1239 } else {
1240 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1241 }
1242 }
1243
1244 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1245 let (crate_name, stable_crate_id) = if def_id.is_local() {
1250 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1251 } else {
1252 let cstore = &*self.cstore_untracked();
1253 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1254 };
1255
1256 ::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!(
1257 "{}[{:04x}]{}",
1258 crate_name,
1259 stable_crate_id.as_u64() >> (8 * 6),
1262 self.def_path(def_id).to_string_no_crate_verbose()
1263 )
1264 }
1265
1266 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1267 self.sess.dcx()
1268 }
1269
1270 pub fn is_target_feature_call_safe(
1273 self,
1274 callee_features: &[TargetFeature],
1275 body_features: &[TargetFeature],
1276 ) -> bool {
1277 self.sess.target.options.is_like_wasm
1282 || callee_features
1283 .iter()
1284 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1285 }
1286
1287 pub fn adjust_target_feature_sig(
1290 self,
1291 fun_def: DefId,
1292 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1293 caller: DefId,
1294 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1295 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1296 let caller_features = &self.body_codegen_attrs(caller).target_features;
1297 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1298 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1299 fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1300 ..sig
1301 }));
1302 }
1303 None
1304 }
1305
1306 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1309 match self.env_var_os(key.as_ref()) {
1310 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1311 None => Err(VarError::NotPresent),
1312 }
1313 }
1314
1315 pub fn is_method(self, id: DefId) -> bool {
1316 self.opt_associated_item(id).is_some_and(|item| item.is_method())
1317 }
1318}
1319
1320impl<'tcx> TyCtxtAt<'tcx> {
1321 pub fn create_def(
1323 self,
1324 parent: LocalDefId,
1325 name: Option<Symbol>,
1326 def_kind: DefKind,
1327 override_def_path_data: Option<DefPathData>,
1328 disambiguator: &mut PerParentDisambiguatorState,
1329 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1330 let feed =
1331 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1332
1333 feed.def_span(self.span);
1334 feed
1335 }
1336}
1337
1338impl<'tcx> TyCtxt<'tcx> {
1339 pub fn create_def(
1341 self,
1342 parent: LocalDefId,
1343 name: Option<Symbol>,
1344 def_kind: DefKind,
1345 override_def_path_data: Option<DefPathData>,
1346 disambiguator: &mut PerParentDisambiguatorState,
1347 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1348 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1349 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1359
1360 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1365
1366 let feed = TyCtxtFeed { tcx: self, key: def_id };
1367 feed.def_kind(def_kind);
1368 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1373 let parent_mod = self.parent_module_from_def_id(def_id);
1374 feed.visibility(ty::Visibility::Restricted(parent_mod.to_mod_id()));
1375 }
1376
1377 feed
1378 }
1379
1380 pub fn create_crate_num(
1381 self,
1382 stable_crate_id: StableCrateId,
1383 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1384 let mut lock = self.untracked().stable_crate_ids.write();
1385 if let Some(&existing) = lock.get(&stable_crate_id) {
1386 return Err(existing);
1387 }
1388 let num = CrateNum::new(lock.len());
1389 lock.insert(stable_crate_id, num);
1390 Ok(TyCtxtFeed { key: num, tcx: self })
1391 }
1392
1393 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1394 self.ensure_ok().analysis(());
1396
1397 let definitions = &self.untracked.definitions;
1398 gen {
1399 let mut i = 0;
1400
1401 while i < { definitions.read().num_definitions() } {
1404 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1405 yield LocalDefId { local_def_index };
1406 i += 1;
1407 }
1408
1409 definitions.freeze();
1411 }
1412 }
1413
1414 pub fn definitions(self) -> &'tcx rustc_hir::definitions::Definitions {
1415 self.ensure_ok().analysis(());
1417
1418 self.untracked.definitions.freeze()
1421 }
1422
1423 pub fn def_path_hash_to_def_index_map(self) -> &'tcx rustc_hir::definitions::DefPathToIndexMap {
1424 self.ensure_ok().hir_crate_items(());
1427 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1430 }
1431
1432 #[inline]
1435 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1436 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1437 }
1438
1439 pub fn untracked(self) -> &'tcx Untracked {
1441 &self.untracked
1442 }
1443 #[inline]
1446 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1447 self.untracked.definitions.read()
1448 }
1449
1450 #[inline(always)]
1451 pub fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashState<'_>) -> R) -> R {
1452 f(StableHashState::new(self.sess, &self.untracked))
1453 }
1454
1455 #[inline]
1456 pub fn local_crate_exports_generics(self) -> bool {
1457 if self.is_compiler_builtins(LOCAL_CRATE) {
1461 return false;
1462 }
1463 self.crate_types().iter().any(|crate_type| {
1464 match crate_type {
1465 CrateType::Executable
1466 | CrateType::StaticLib
1467 | CrateType::ProcMacro
1468 | CrateType::Cdylib
1469 | CrateType::Sdylib => false,
1470
1471 CrateType::Dylib => true,
1476
1477 CrateType::Rlib => true,
1478 }
1479 })
1480 }
1481
1482 pub fn is_suitable_region(
1484 self,
1485 generic_param_scope: LocalDefId,
1486 mut region: Region<'tcx>,
1487 ) -> Option<FreeRegionInfo> {
1488 let (suitable_region_binding_scope, region_def_id) = loop {
1489 let def_id =
1490 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1491 let scope = self.local_parent(def_id);
1492 if self.def_kind(scope) == DefKind::OpaqueTy {
1493 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1496 continue;
1497 }
1498 break (scope, def_id.into());
1499 };
1500
1501 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1502 Node::Item(..) | Node::TraitItem(..) => false,
1503 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1504 hir::ImplItemImplKind::Trait { .. } => true,
1511 _ => false,
1512 },
1513 _ => false,
1514 };
1515
1516 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1517 }
1518
1519 pub fn return_type_impl_or_dyn_traits(
1521 self,
1522 scope_def_id: LocalDefId,
1523 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1524 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1525 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1526 self.hir_fn_decl_by_hir_id(hir_id)
1527 else {
1528 return ::alloc::vec::Vec::new()vec![];
1529 };
1530
1531 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1532 v.visit_ty_unambig(hir_output);
1533 v.0
1534 }
1535
1536 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1540 self,
1541 scope_def_id: LocalDefId,
1542 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1543 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1544 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1545 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1547 && let hir::TyKind::Path(hir::QPath::Resolved(
1548 None,
1549 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1550 && let Some(local_id) = def_id.as_local()
1551 && 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()
1553 {
1554 v.visit_ty_unambig(alias_ty);
1555 if !v.0.is_empty() {
1556 return Some((
1557 v.0,
1558 alias_generics.span,
1559 alias_generics.span_for_lifetime_suggestion(),
1560 ));
1561 }
1562 }
1563 None
1564 }
1565
1566 pub fn has_strict_asm_symbol_naming(self) -> bool {
1569 self.sess.target.llvm_target.starts_with("nvptx")
1570 }
1571
1572 pub fn caller_location_ty(self) -> Ty<'tcx> {
1574 Ty::new_imm_ref(
1575 self,
1576 self.lifetimes.re_static,
1577 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1578 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1579 .skip_norm_wip(),
1580 )
1581 }
1582
1583 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1585 let kind = self.def_kind(def_id);
1586 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1587 }
1588
1589 pub fn type_length_limit(self) -> Limit {
1590 self.limits(()).type_length_limit
1591 }
1592
1593 pub fn recursion_limit(self) -> Limit {
1594 self.limits(()).recursion_limit
1595 }
1596
1597 pub fn move_size_limit(self) -> Limit {
1598 self.limits(()).move_size_limit
1599 }
1600
1601 pub fn pattern_complexity_limit(self) -> Limit {
1602 self.limits(()).pattern_complexity_limit
1603 }
1604
1605 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1607 iter::once(LOCAL_CRATE)
1608 .chain(self.crates(()).iter().copied())
1609 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1610 }
1611
1612 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1614 let visible_crates =
1615 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1616
1617 iter::once(LOCAL_CRATE)
1618 .chain(visible_crates)
1619 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1620 }
1621
1622 #[inline]
1623 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1624 self.visibility(def_id).expect_local()
1625 }
1626
1627 {}
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/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1628u32),
::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/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_middle/src/ty/context.rs:1628",
"rustc_middle::ty::context", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1628u32),
::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)]
1629 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1630 self.hir_expect_opaque_ty(def_id).origin
1631 }
1632
1633 pub fn finish(self) {
1634 self.alloc_self_profile_query_strings();
1637
1638 self.save_dep_graph();
1639 self.verify_query_key_hashes();
1640
1641 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1642 self.sess
1643 .dcx()
1644 .emit_fatal(crate::diagnostics::FailedWritingFile { path: &path, error });
1645 }
1646 }
1647
1648 pub fn report_unused_features(self) {
1649 #[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)]
1650 #[diag("feature `{$feature}` is declared but not used")]
1651 struct UnusedFeature {
1652 feature: Symbol,
1653 }
1654
1655 let used_features = self.query_system.used_features.lock();
1657 let unused_features = self
1658 .features()
1659 .enabled_features_iter_stable_order()
1660 .filter(|(f, _)| {
1661 !used_features.contains_key(f)
1662 && f.as_str() != "restricted_std"
1669 && *f != sym::doc_cfg
1673 })
1674 .collect::<Vec<_>>();
1675
1676 for (feature, span) in unused_features {
1677 self.emit_node_span_lint(
1678 UNUSED_FEATURES,
1679 CRATE_HIR_ID,
1680 span,
1681 UnusedFeature { feature },
1682 );
1683 }
1684 }
1685}
1686
1687macro_rules! nop_lift {
1688 ($set:ident; $ty:ty => $lifted:ty) => {
1689 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1690 type Lifted = $lifted;
1691 #[track_caller]
1692 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1693 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1698 _x: Interned<'tcx, Inner>,
1699 ) -> InternedSet<'tcx, Inner> {
1700 unreachable!()
1701 }
1702 fn _type_eq<T>(_x: &T, _y: &T) {}
1703 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1704 let interner = _intern_set_ty_from_interned_ty(x.0);
1708 _type_eq(&interner, &tcx.interners.$set);
1710 }
1711
1712 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1713 unsafe { mem::transmute(self) }
1716 }
1717 }
1718 };
1719}
1720
1721macro_rules! nop_list_lift {
1722 ($set:ident; $ty:ty => $lifted:ty) => {
1723 nop_list_lift! { $set: List; $ty => $lifted }
1724 };
1725 ($set:ident: $list:ident; $ty:ty => $lifted:ty) => {
1727 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a $list<$ty> {
1728 type Lifted = &'tcx $list<$lifted>;
1729 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1730 if false {
1732 let _x: &InternedSet<'tcx, $list<$lifted>> = &tcx.interners.$set;
1733 }
1734
1735 if self.is_empty() {
1736 return $list::empty();
1737 }
1738 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1739 unsafe { mem::transmute(self) }
1742 }
1743 }
1744 };
1745}
1746
1747impl<'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> }
1748impl<'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> }
1749impl<'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> }
1750impl<'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> }
1751impl<'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> }
1752impl<'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> }
1753impl<'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> }
1754
1755impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, RegionKind<'a>> {
1756 type Lifted = Interned<'tcx, RegionKind<'tcx>>;
1757
1758 #[track_caller]
1759 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1760 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)));
1761 unsafe { mem::transmute(self) }
1764 }
1765}
1766
1767impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, WithCachedTypeInfo<ConstKind<'a>>> {
1769 type Lifted = Interned<'tcx, WithCachedTypeInfo<ConstKind<'tcx>>>;
1770
1771 #[track_caller]
1772 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1773 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)));
1774 unsafe { mem::transmute(self) }
1777 }
1778}
1779
1780impl<'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> }
1781impl<'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> }
1782impl<'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! {
1783 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1784}
1785impl<'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> }
1786impl<'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> }
1787impl<'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> }
1788
1789impl<'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> }
1791
1792macro_rules! sty_debug_print {
1793 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1794 #[allow(non_snake_case, reason = "we're using variant names as local variables")]
1795 mod inner {
1796 use crate::ty::{self, TyCtxt};
1797 use crate::ty::context::InternedInSet;
1798
1799 #[derive(Copy, Clone)]
1800 struct DebugStat {
1801 total: usize,
1802 lt_infer: usize,
1803 ty_infer: usize,
1804 ct_infer: usize,
1805 all_infer: usize,
1806 }
1807
1808 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1809 let mut total = DebugStat {
1810 total: 0,
1811 lt_infer: 0,
1812 ty_infer: 0,
1813 ct_infer: 0,
1814 all_infer: 0,
1815 };
1816 $(let mut $variant = total;)*
1817
1818 for shard in tcx.interners.type_.lock_shards() {
1819 #[allow(rustc::potential_query_instability)]
1821 let types = shard.iter();
1822 for &(InternedInSet(t), ()) in types {
1823 let variant = match t.internee {
1824 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1825 ty::Float(..) | ty::Str | ty::Never => continue,
1826 ty::Error(_) => continue,
1827 $(ty::$variant(..) => &mut $variant,)*
1828 };
1829 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1830 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1831 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1832
1833 variant.total += 1;
1834 total.total += 1;
1835 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1836 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1837 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1838 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1839 }
1840 }
1841 writeln!(fmt, "Ty interner total ty lt ct all")?;
1842 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1843 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1844 stringify!($variant),
1845 uses = $variant.total,
1846 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1847 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1848 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1849 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1850 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1851 )*
1852 writeln!(fmt, " total {uses:6} \
1853 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1854 uses = total.total,
1855 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1856 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1857 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1858 all = total.all_infer as f64 * 100.0 / total.total as f64)
1859 }
1860 }
1861
1862 inner::go($fmt, $ctxt)
1863 }}
1864}
1865
1866impl<'tcx> TyCtxt<'tcx> {
1867 pub fn debug_stats(self) -> impl fmt::Debug {
1868 fmt::from_fn(move |fmt| {
1869 {
#[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!(
1870 fmt,
1871 self,
1872 Adt,
1873 Array,
1874 Slice,
1875 RawPtr,
1876 Ref,
1877 FnDef,
1878 FnPtr,
1879 UnsafeBinder,
1880 Placeholder,
1881 Coroutine,
1882 CoroutineWitness,
1883 Dynamic,
1884 Closure,
1885 CoroutineClosure,
1886 Tuple,
1887 Bound,
1888 Param,
1889 Infer,
1890 Alias,
1891 Pat,
1892 Foreign
1893 )?;
1894
1895 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1896 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1897 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())?;
1898 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1899
1900 Ok(())
1901 })
1902 }
1903}
1904
1905struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1910
1911impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1912 fn clone(&self) -> Self {
1913 *self
1914 }
1915}
1916
1917impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1918
1919impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1920 fn into_pointer(&self) -> *const () {
1921 self.0 as *const _ as *const ()
1922 }
1923}
1924
1925#[allow(rustc::usage_of_ty_tykind)]
1926impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1927 fn borrow(&self) -> &T {
1928 &self.0.internee
1929 }
1930}
1931
1932impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1933 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1934 self.0.internee == other.0.internee
1937 }
1938}
1939
1940impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1941
1942impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1943 fn hash<H: Hasher>(&self, s: &mut H) {
1944 self.0.internee.hash(s)
1946 }
1947}
1948
1949impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1950 fn borrow(&self) -> &[T] {
1951 &self.0[..]
1952 }
1953}
1954
1955impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1956 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1957 self.0[..] == other.0[..]
1960 }
1961}
1962
1963impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1964
1965impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1966 fn hash<H: Hasher>(&self, s: &mut H) {
1967 self.0[..].hash(s)
1969 }
1970}
1971
1972impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1973 fn borrow(&self) -> &[T] {
1974 &self.0[..]
1975 }
1976}
1977
1978impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1979 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1980 self.0[..] == other.0[..]
1983 }
1984}
1985
1986impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1987
1988impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1989 fn hash<H: Hasher>(&self, s: &mut H) {
1990 self.0[..].hash(s)
1992 }
1993}
1994
1995macro_rules! direct_interners {
1996 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1997 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1998 fn borrow<'a>(&'a self) -> &'a $ty {
1999 &self.0
2000 }
2001 }
2002
2003 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2004 fn eq(&self, other: &Self) -> bool {
2005 self.0 == other.0
2008 }
2009 }
2010
2011 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2012
2013 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2014 fn hash<H: Hasher>(&self, s: &mut H) {
2015 self.0.hash(s)
2018 }
2019 }
2020
2021 impl<'tcx> TyCtxt<'tcx> {
2022 $vis fn $method(self, v: $ty) -> $ret_ty {
2023 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2024 InternedInSet(self.interners.arena.alloc(v))
2025 }).0))
2026 }
2027 })+
2028 }
2029}
2030
2031impl<'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! {
2035 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2036 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2037 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2038 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2039 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2040 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2041 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2042 ExternalConstraints -> ExternalConstraints<'tcx>,
2043 canonical_inputs: intern_canonical_input(CanonicalInputData<TyCtxt<'tcx>>): CanonicalInput -> CanonicalInput<'tcx>,
2044}
2045
2046macro_rules! slice_interners {
2047 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2048 impl<'tcx> TyCtxt<'tcx> {
2049 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2050 if v.is_empty() {
2051 List::empty()
2052 } else {
2053 self.interners.$field.intern_ref(v, || {
2054 InternedInSet(List::from_arena(&*self.arena, (), v))
2055 }).0
2056 }
2057 })+
2058 }
2059 );
2060}
2061
2062impl<'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!(
2066 const_lists: pub mk_const_list(Const<'tcx>),
2067 args: pub mk_args(GenericArg<'tcx>),
2068 type_lists: pub mk_type_list(Ty<'tcx>),
2069 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2070 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2071 projs: pub mk_projs(ProjectionKind),
2072 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2073 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2074 fields: pub mk_fields(FieldIdx),
2075 local_def_ids: intern_local_def_ids(LocalDefId),
2076 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2077 patterns: pub mk_patterns(Pattern<'tcx>),
2078 outlives: pub mk_outlives(ty::ArgOutlivesClause<'tcx>),
2079 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2080);
2081
2082impl<'tcx> TyCtxt<'tcx> {
2083 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2087 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2088 Ty::new_fn_ptr(
2089 self,
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
2097 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2101 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2102 sig.map_bound(|sig| ty::FnSig {
2103 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2104 ..sig
2105 })
2106 }
2107
2108 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2111 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2112 self.associated_items(trait_did)
2113 .filter_by_name_unhygienic(assoc_name.name)
2114 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2115 })
2116 }
2117
2118 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2120 let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2121 return false;
2122 };
2123 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2124
2125 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2126 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2127 return false;
2128 };
2129 trait_predicate.trait_ref.def_id == future_trait
2130 && trait_predicate.polarity == ClausePolarity::Positive
2131 })
2132 }
2133
2134 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2142 sig.map_bound(|s| {
2143 let params = match s.inputs()[0].kind() {
2144 ty::Tuple(params) => *params,
2145 _ => ::rustc_span::macros::bug_impl(None, format_args!("impossible case reached"),
Location::caller())bug!(),
2146 };
2147 if !s.splatted().is_none() {
::core::panicking::panic("assertion failed: s.splatted().is_none()")
};assert!(s.splatted().is_none());
2149 self.mk_fn_sig(
2150 params,
2151 s.output(),
2152 s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2153 )
2154 })
2155 }
2156
2157 #[inline]
2158 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2159 self.interners.intern_predicate(binder)
2160 }
2161
2162 #[inline]
2163 pub fn reuse_or_mk_predicate(
2164 self,
2165 pred: Predicate<'tcx>,
2166 binder: Binder<'tcx, PredicateKind<'tcx>>,
2167 ) -> Predicate<'tcx> {
2168 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2169 }
2170
2171 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2177 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)
2178 && #[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 });
2179 self.check_args_compatible_inner(def_id, args, is_inherent_assoc_ty)
2180 }
2181
2182 pub fn check_alias_term_args_compatible(
2183 self,
2184 kind: ty::AliasTermKind<'tcx>,
2185 args: &'tcx [ty::GenericArg<'tcx>],
2186 ) -> bool {
2187 let (def_id, is_self_args) = match kind {
2188 ty::AliasTermKind::ProjectionTy { def_id }
2189 | ty::AliasTermKind::OpaqueTy { def_id }
2190 | ty::AliasTermKind::FreeTy { def_id }
2191 | ty::AliasTermKind::AnonConst { def_id }
2192 | ty::AliasTermKind::ProjectionConst { def_id }
2193 | ty::AliasTermKind::FreeConst { def_id }
2194 | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2195 ty::AliasTermKind::InherentTy { def_id }
2196 | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2197 };
2198 self.check_args_compatible_inner(def_id, args, is_self_args)
2199 }
2200
2201 fn check_args_compatible_inner(
2202 self,
2203 def_id: DefId,
2204 args: &'tcx [ty::GenericArg<'tcx>],
2205 is_self_args: bool,
2206 ) -> bool {
2207 let generics = self.generics_of(def_id);
2208 let own_args = if is_self_args {
2209 if generics.own_params.len() + 1 != args.len() {
2210 return false;
2211 }
2212
2213 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2214 return false;
2215 }
2216
2217 &args[1..]
2218 } else {
2219 if generics.count() != args.len() {
2220 return false;
2221 }
2222
2223 let (parent_args, own_args) = args.split_at(generics.parent_count);
2224
2225 if let Some(parent) = generics.parent
2229 && !self.check_args_compatible_inner(parent, parent_args, false)
2230 {
2231 return false;
2232 }
2233
2234 own_args
2235 };
2236
2237 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2238 match (¶m.kind, arg.kind()) {
2239 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2240 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2241 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2242 _ => return false,
2243 }
2244 }
2245
2246 true
2247 }
2248
2249 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2256 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2257 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)
2258 && #[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 });
2259 self.emit_bug_args_compatible(def_id, args, is_inherent_assoc_ty);
2260 }
2261 }
2262
2263 pub fn debug_assert_alias_term_args_compatible(
2264 self,
2265 kind: ty::AliasTermKind<'tcx>,
2266 args: ty::GenericArgsRef<'tcx>,
2267 ) {
2268 if truecfg!(debug_assertions) {
2269 self.debug_assert_alias_term_kind_matches_def_kind(kind);
2270 if !self.check_alias_term_args_compatible(kind, args) {
2271 let (def_id, is_self_args) = match kind {
2272 ty::AliasTermKind::ProjectionTy { def_id }
2273 | ty::AliasTermKind::OpaqueTy { def_id }
2274 | ty::AliasTermKind::FreeTy { def_id }
2275 | ty::AliasTermKind::AnonConst { def_id }
2276 | ty::AliasTermKind::ProjectionConst { def_id }
2277 | ty::AliasTermKind::FreeConst { def_id }
2278 | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2279 ty::AliasTermKind::InherentTy { def_id }
2280 | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2281 };
2282 self.emit_bug_args_compatible(def_id, args, is_self_args);
2283 }
2284 }
2285 }
2286
2287 fn debug_assert_alias_term_kind_matches_def_kind(self, kind: ty::AliasTermKind<'tcx>) {
2288 match kind {
2289 ty::AliasTermKind::ProjectionTy { def_id } => {
2290 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);
2291 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!(
2292 self.def_kind(self.parent(def_id)),
2293 DefKind::Trait | DefKind::Impl { of_trait: true }
2294 );
2295 }
2296 ty::AliasTermKind::InherentTy { def_id } => {
2297 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);
2298 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!(
2299 self.def_kind(self.parent(def_id)),
2300 DefKind::Impl { of_trait: false }
2301 );
2302 }
2303 ty::AliasTermKind::OpaqueTy { def_id } => {
2304 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);
2305 }
2306 ty::AliasTermKind::FreeTy { def_id } => {
2307 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);
2308 }
2309 ty::AliasTermKind::AnonConst { def_id } => {
2310 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);
2311 }
2312 ty::AliasTermKind::ProjectionConst { def_id } => {
2313 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);
2314 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!(
2315 self.def_kind(self.parent(def_id)),
2316 DefKind::Trait | DefKind::Impl { of_trait: true }
2317 );
2318 }
2319 ty::AliasTermKind::InherentConstSelf { def_id }
2320 | ty::AliasTermKind::InherentConstImpl { def_id } => {
2321 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);
2322 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!(
2323 self.def_kind(self.parent(def_id)),
2324 DefKind::Impl { of_trait: false }
2325 );
2326 }
2327 ty::AliasTermKind::FreeConst { def_id } => {
2328 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);
2329 }
2330 }
2331 }
2332
2333 fn emit_bug_args_compatible(
2334 self,
2335 def_id: DefId,
2336 args: &'tcx [ty::GenericArg<'tcx>],
2337 is_self_args: bool,
2338 ) -> ! {
2339 if is_self_args {
2340 ::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!(
2341 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2342 self.def_path_str(def_id),
2343 args,
2344 self.mk_args_from_iter(
2346 [self.types.self_param.into()].into_iter().chain(
2347 self.generics_of(def_id)
2348 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2349 .iter()
2350 .copied()
2351 )
2352 )
2353 );
2354 } else {
2355 ::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!(
2356 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2357 self.def_path_str(def_id),
2358 args,
2359 ty::GenericArgs::identity_for_item(self, def_id)
2360 );
2361 }
2362 }
2363
2364 #[inline(always)]
2365 pub(crate) fn check_and_mk_args(
2366 self,
2367 def_id: DefId,
2368 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2369 ) -> GenericArgsRef<'tcx> {
2370 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2371 self.debug_assert_args_compatible(def_id, args);
2372 args
2373 }
2374
2375 #[inline]
2376 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2377 self.interners.intern_const(kind)
2378 }
2379
2380 #[allow(rustc::usage_of_ty_tykind)]
2382 #[inline]
2383 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2384 self.interners.intern_ty(st)
2385 }
2386
2387 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2388 match param.kind {
2389 GenericParamDefKind::Lifetime => {
2390 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2391 }
2392 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2393 GenericParamDefKind::Const { .. } => {
2394 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2395 .into()
2396 }
2397 }
2398 }
2399
2400 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2401 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2402 }
2403
2404 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2405 self.mk_place_elem(place, PlaceElem::Deref)
2406 }
2407
2408 pub fn mk_place_downcast(
2409 self,
2410 place: Place<'tcx>,
2411 adt_def: AdtDef<'tcx>,
2412 variant_index: VariantIdx,
2413 ) -> Place<'tcx> {
2414 self.mk_place_elem(
2415 place,
2416 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2417 )
2418 }
2419
2420 pub fn mk_place_downcast_unnamed(
2421 self,
2422 place: Place<'tcx>,
2423 variant_index: VariantIdx,
2424 ) -> Place<'tcx> {
2425 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2426 }
2427
2428 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2429 self.mk_place_elem(place, PlaceElem::Index(index))
2430 }
2431
2432 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2436 Place {
2437 local: place.local,
2438 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2439 }
2440 }
2441
2442 pub fn mk_poly_existential_predicates(
2443 self,
2444 eps: &[PolyExistentialPredicate<'tcx>],
2445 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2446 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2447 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!(
2448 eps.array_windows()
2449 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2450 != Ordering::Greater)
2451 );
2452 self.intern_poly_existential_predicates(eps)
2453 }
2454
2455 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2456 self.interners.intern_clauses(clauses)
2460 }
2461
2462 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2463 self.intern_local_def_ids(def_ids)
2467 }
2468
2469 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2470 where
2471 I: Iterator<Item = T>,
2472 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2473 {
2474 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2475 }
2476
2477 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2478 where
2479 I: Iterator<Item = T>,
2480 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2481 {
2482 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2483 }
2484
2485 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2486 where
2487 I: Iterator<Item = T>,
2488 T: CollectAndApply<
2489 &'tcx ty::CapturedPlace<'tcx>,
2490 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2491 >,
2492 {
2493 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2494 }
2495
2496 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2497 where
2498 I: Iterator<Item = T>,
2499 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2500 {
2501 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2502 }
2503
2504 pub fn mk_fn_sig<I, T>(
2509 self,
2510 inputs: I,
2511 output: I::Item,
2512 fn_sig_kind: FnSigKind<'tcx>,
2513 ) -> T::Output
2514 where
2515 I: IntoIterator<Item = T>,
2516 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2517 {
2518 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2519 inputs_and_output: self.mk_type_list(xs),
2520 fn_sig_kind,
2521 })
2522 }
2523
2524 pub fn mk_fn_sig_rust_abi<I, T>(
2526 self,
2527 inputs: I,
2528 output: I::Item,
2529 safety: hir::Safety,
2530 ) -> T::Output
2531 where
2532 I: IntoIterator<Item = T>,
2533 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2534 {
2535 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2536 }
2537
2538 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2540 where
2541 I: IntoIterator<Item = T>,
2542 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2543 {
2544 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2545 }
2546
2547 pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2549 where
2550 I: IntoIterator<Item = T>,
2551 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2552 {
2553 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2554 }
2555
2556 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2557 where
2558 I: Iterator<Item = T>,
2559 T: CollectAndApply<
2560 PolyExistentialPredicate<'tcx>,
2561 &'tcx List<PolyExistentialPredicate<'tcx>>,
2562 >,
2563 {
2564 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2565 }
2566
2567 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2568 where
2569 I: Iterator<Item = T>,
2570 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2571 {
2572 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2573 }
2574
2575 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2576 where
2577 I: Iterator<Item = T>,
2578 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2579 {
2580 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2581 }
2582
2583 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2584 where
2585 I: Iterator<Item = T>,
2586 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2587 {
2588 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2589 }
2590
2591 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2592 where
2593 I: Iterator<Item = T>,
2594 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2595 {
2596 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2597 }
2598
2599 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2600 where
2601 I: Iterator<Item = T>,
2602 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2603 {
2604 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2605 }
2606
2607 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2608 where
2609 I: Iterator<Item = T>,
2610 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2611 {
2612 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2613 }
2614
2615 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2616 where
2617 I: Iterator<Item = T>,
2618 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2619 {
2620 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2621 }
2622
2623 pub fn mk_args_trait(
2624 self,
2625 self_ty: Ty<'tcx>,
2626 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2627 ) -> GenericArgsRef<'tcx> {
2628 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2629 }
2630
2631 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2632 where
2633 I: Iterator<Item = T>,
2634 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2635 {
2636 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2637 }
2638
2639 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2640 where
2641 I: Iterator<Item = T>,
2642 T: CollectAndApply<
2643 ty::ArgOutlivesClause<'tcx>,
2644 &'tcx ty::List<ty::ArgOutlivesClause<'tcx>>,
2645 >,
2646 {
2647 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2648 }
2649
2650 #[track_caller]
2653 pub fn emit_node_span_lint(
2654 self,
2655 lint: &'static Lint,
2656 hir_id: HirId,
2657 span: impl Into<MultiSpan>,
2658 decorator: impl for<'a> Diagnostic<'a>,
2659 ) {
2660 let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2661 emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2662 }
2663
2664 pub fn crate_level_attribute_injection_span(self) -> Span {
2666 let node = self.hir_node(hir::CRATE_HIR_ID);
2667 let hir::Node::Crate(m) = node else { ::rustc_span::macros::bug_impl(None, format_args!("impossible case reached"),
Location::caller())bug!() };
2668 m.spans.inject_use_span.shrink_to_lo()
2669 }
2670
2671 pub fn disabled_nightly_features(
2672 self,
2673 diag: &mut Diag<'_>,
2674 features: impl IntoIterator<Item = (String, Symbol)>,
2675 ) {
2676 if !self.sess.is_nightly_build() {
2677 return;
2678 }
2679
2680 let span = self.crate_level_attribute_injection_span();
2681 for (desc, feature) in features {
2682 let msg =
2684 ::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}");
2685 diag.span_suggestion_verbose(
2686 span,
2687 msg,
2688 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2689 Applicability::MaybeIncorrect,
2690 );
2691 }
2692 }
2693
2694 #[track_caller]
2697 pub fn emit_node_lint(
2698 self,
2699 lint: &'static Lint,
2700 id: HirId,
2701 decorator: impl for<'a> Diagnostic<'a>,
2702 ) {
2703 let level_spec = self.lint_level_spec_at_node(lint, id);
2704 emit_lint_base(self.sess, lint, level_spec, None, decorator);
2705 }
2706
2707 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2708 let map = self.in_scope_traits_map(id.owner)?;
2709 let candidates = map.get(&id.local_id)?;
2710 Some(candidates)
2711 }
2712
2713 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2714 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_middle/src/ty/context.rs:2714",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(2714u32),
::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");
2715 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2716 }
2717
2718 pub fn is_late_bound(self, id: HirId) -> bool {
2719 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2720 }
2721
2722 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2723 self.mk_bound_variable_kinds(
2724 &self
2725 .late_bound_vars_map(id.owner)
2726 .get(&id.local_id)
2727 .cloned()
2728 .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))),
2729 )
2730 }
2731
2732 pub fn map_opaque_lifetime_to_parent_lifetime(
2740 self,
2741 mut opaque_lifetime_param_def_id: LocalDefId,
2742 ) -> ty::Region<'tcx> {
2743 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!(
2744 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2745 "{opaque_lifetime_param_def_id:?} is a {}",
2746 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2747 );
2748
2749 loop {
2750 let parent = self.local_parent(opaque_lifetime_param_def_id);
2751 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2752
2753 let Some((lifetime, _)) = lifetime_mapping
2754 .iter()
2755 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2756 else {
2757 ::rustc_span::macros::bug_impl(None,
format_args!("duplicated lifetime param should be present"),
Location::caller());bug!("duplicated lifetime param should be present");
2758 };
2759
2760 match *lifetime {
2761 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2762 let new_parent = self.local_parent(ebv);
2763
2764 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2767 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);
2768 opaque_lifetime_param_def_id = ebv;
2769 continue;
2770 }
2771
2772 let generics = self.generics_of(new_parent);
2773 return ty::Region::new_early_param(
2774 self,
2775 ty::EarlyParamRegion {
2776 index: generics
2777 .param_def_id_to_index(self, ebv.to_def_id())
2778 .expect("early-bound var should be present in fn generics"),
2779 name: self.item_name(ebv.to_def_id()),
2780 },
2781 );
2782 }
2783 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2784 let new_parent = self.local_parent(lbv);
2785 return ty::Region::new_late_param(
2786 self,
2787 new_parent.to_def_id(),
2788 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2789 );
2790 }
2791 resolve_bound_vars::ResolvedArg::Error(guar) => {
2792 return ty::Region::new_error(self, guar);
2793 }
2794 _ => {
2795 return ty::Region::new_error_with_message(
2796 self,
2797 self.def_span(opaque_lifetime_param_def_id),
2798 "cannot resolve lifetime",
2799 );
2800 }
2801 }
2802 }
2803 }
2804
2805 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2810 self.is_const_fn(def_id)
2811 && match self.lookup_const_stability(def_id) {
2812 None => true, Some(stability) if stability.is_const_stable() => true,
2814 _ => false,
2815 }
2816 }
2817
2818 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2820 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2821 && #[allow(non_exhaustive_omitted_patterns)] match self.impl_trait_header(def_id).constness
{
hir::Constness::Const { always: false } => true,
_ => false,
}matches!(
2822 self.impl_trait_header(def_id).constness,
2823 hir::Constness::Const { always: false }
2824 )
2825 }
2826
2827 pub fn is_sdylib_interface_build(self) -> bool {
2828 self.sess.opts.unstable_opts.build_sdylib_interface
2829 }
2830
2831 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2832 let def_id = def_id.into_query_key();
2833 match self.def_kind(def_id) {
2834 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2835 _ => None,
2836 }
2837 }
2838
2839 pub fn next_trait_solver_globally(self) -> bool {
2840 self.sess.opts.unstable_opts.next_solver == NextSolverConfig::Globally
2841 && !self.sess.opts.unstable_opts.higher_ranked_assumptions
2842 && !self.features().generic_const_exprs()
2843 }
2844
2845 pub fn disable_trait_solver_fast_paths(self) -> bool {
2846 self.sess.opts.unstable_opts.disable_fast_paths
2847 }
2848
2849 pub fn disable_param_env_normalization_hack(self) -> bool {
2850 self.sess.opts.unstable_opts.disable_param_env_normalization_hack
2851 }
2852
2853 pub fn renormalize_rigid_aliases(self) -> bool {
2854 self.sess.opts.unstable_opts.renormalize_rigid_aliases
2855 }
2856
2857 #[allow(rustc::bad_opt_access)]
2858 pub fn use_typing_mode_post_typeck_until_borrowck(self) -> bool {
2859 self.next_trait_solver_globally()
2860 || self.sess.opts.unstable_opts.typing_mode_post_typeck_until_borrowck
2861 }
2862
2863 pub fn assumptions_on_binders(self) -> bool {
2864 self.sess.opts.unstable_opts.assumptions_on_binders
2865 }
2866
2867 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2868 self.opt_rpitit_info(def_id).is_some()
2869 }
2870
2871 pub fn get_impl_future_output_ty(self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
2872 let (def_id, args) = match *ty.kind() {
2873 ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
2874 ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, args, .. })
2875 if self.is_impl_trait_in_trait(def_id) =>
2876 {
2877 (def_id, args)
2878 }
2879 _ => return None,
2880 };
2881
2882 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2883 let item_def_id = self.associated_item_def_ids(future_trait)[0];
2884
2885 self.explicit_item_self_bounds(def_id)
2886 .iter_instantiated_copied(self, args)
2887 .map(ty::Unnormalized::skip_norm_wip)
2888 .find_map(|(predicate, _)| {
2889 predicate
2890 .kind()
2891 .map_bound(|kind| match kind {
2892 ty::ClauseKind::Projection(projection_predicate)
2893 if projection_predicate.def_id() == item_def_id =>
2894 {
2895 projection_predicate.term.as_type()
2896 }
2897 _ => None,
2898 })
2899 .no_bound_vars()
2900 .flatten()
2901 })
2902 }
2903
2904 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2914 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2915 }
2916
2917 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2919 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2920 }
2921
2922 pub fn resolver_for_lowering(
2923 self,
2924 ) -> (&'tcx Steal<ResolverAstLowering<'tcx>>, &'tcx Steal<ast::Crate>) {
2925 let (resolver, krate, _) = self.resolver_for_lowering_raw(());
2926 (resolver, krate)
2927 }
2928
2929 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2930 make_metadata(self)
2931 }
2932
2933 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2934 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2935 self.coroutine_kind(def_id)
2936 && let ty::Coroutine(_, args) =
2937 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2938 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2939 {
2940 true
2941 } else {
2942 false
2943 }
2944 }
2945
2946 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2948 {
{
'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)
2949 }
2950
2951 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2952 let def_id = def_id.into_query_key();
2953 self.trivial_const(def_id).is_some()
2954 }
2955
2956 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2959 if self.is_lang_item(def_id, LangItem::Start) {
2960 return true;
2961 }
2962 if let Some((entry_def_id, _)) = self.entry_fn(())
2963 && entry_def_id == def_id
2964 {
2965 return true;
2966 }
2967 false
2968 }
2969}
2970
2971pub fn provide(providers: &mut Providers) {
2972 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);
2973 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);
2974 providers.has_panic_handler = |tcx, LocalCrate| {
2975 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2977 };
2978 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2979}