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::{PhantomData, PointeeSized};
14use std::ops::{Bound, Deref};
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::fingerprint::Fingerprint;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::jobserver::Proxy;
25use rustc_data_structures::profiling::SelfProfilerRef;
26use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
27use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
28use rustc_data_structures::steal::Steal;
29use rustc_data_structures::sync::{
30 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
31};
32use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
33use rustc_hir::def::DefKind;
34use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
35use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
36use rustc_hir::intravisit::VisitorExt;
37use rustc_hir::lang_items::LangItem;
38use rustc_hir::limit::Limit;
39use rustc_hir::{self as hir, HirId, Node, TraitCandidate, find_attr};
40use rustc_index::IndexVec;
41use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
42use rustc_session::Session;
43use rustc_session::config::CrateType;
44use rustc_session::cstore::{CrateStoreDyn, Untracked};
45use rustc_session::lint::Lint;
46use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
47use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw};
48use rustc_type_ir::TyKind::*;
49pub use rustc_type_ir::lift::Lift;
50use rustc_type_ir::{CollectAndApply, TypeFlags, WithCachedTypeInfo, elaborate, search_graph};
51use tracing::{debug, instrument};
52
53use crate::arena::Arena;
54use crate::dep_graph::dep_node::make_metadata;
55use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
56use crate::ich::StableHashingContext;
57use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
58use crate::lint::{diag_lint_level, lint_level};
59use crate::metadata::ModChild;
60use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
61use crate::middle::resolve_bound_vars;
62use crate::mir::interpret::{self, Allocation, ConstAllocation};
63use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
64use crate::query::plumbing::QuerySystem;
65use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
66use crate::thir::Thir;
67use crate::traits;
68use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
69use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
70use crate::ty::{
71 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
72 GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, Pattern,
73 PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity,
74 Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, ValTree, ValTreeKind,
75 Visibility,
76};
77
78impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
79 fn is_local(self) -> bool {
80 self.is_local()
81 }
82
83 fn as_local(self) -> Option<LocalDefId> {
84 self.as_local()
85 }
86}
87
88impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
89 fn rust() -> Self {
90 ExternAbi::Rust
91 }
92
93 fn is_rust(self) -> bool {
94 #[allow(non_exhaustive_omitted_patterns)] match self {
ExternAbi::Rust => true,
_ => false,
}matches!(self, ExternAbi::Rust)
95 }
96}
97
98impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
99 fn safe() -> Self {
100 hir::Safety::Safe
101 }
102
103 fn is_safe(self) -> bool {
104 self.is_safe()
105 }
106
107 fn prefix_str(self) -> &'static str {
108 self.prefix_str()
109 }
110}
111
112impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
113 fn generic_const_exprs(self) -> bool {
114 self.generic_const_exprs()
115 }
116
117 fn coroutine_clone(self) -> bool {
118 self.coroutine_clone()
119 }
120
121 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
122 !self.staged_api() && self.enabled(symbol)
126 }
127}
128
129impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
130 fn dummy() -> Self {
131 DUMMY_SP
132 }
133}
134
135type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
136
137pub struct CtxtInterners<'tcx> {
138 arena: &'tcx WorkerLocal<Arena<'tcx>>,
140
141 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
144 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
145 args: InternedSet<'tcx, GenericArgs<'tcx>>,
146 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
147 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
148 region: InternedSet<'tcx, RegionKind<'tcx>>,
149 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
150 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
151 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
152 projs: InternedSet<'tcx, List<ProjectionKind>>,
153 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
154 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
155 pat: InternedSet<'tcx, PatternKind<'tcx>>,
156 const_allocation: InternedSet<'tcx, Allocation>,
157 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
158 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
159 adt_def: InternedSet<'tcx, AdtDefData>,
160 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
161 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
162 fields: InternedSet<'tcx, List<FieldIdx>>,
163 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
164 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
165 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
166 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
167 outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
168}
169
170impl<'tcx> CtxtInterners<'tcx> {
171 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
172 const N: usize = 2048;
175 CtxtInterners {
176 arena,
177 type_: InternedSet::with_capacity(N * 16),
181 const_lists: InternedSet::with_capacity(N * 4),
182 args: InternedSet::with_capacity(N * 4),
183 type_lists: InternedSet::with_capacity(N * 4),
184 region: InternedSet::with_capacity(N * 4),
185 poly_existential_predicates: InternedSet::with_capacity(N / 4),
186 canonical_var_kinds: InternedSet::with_capacity(N / 2),
187 predicate: InternedSet::with_capacity(N),
188 clauses: InternedSet::with_capacity(N),
189 projs: InternedSet::with_capacity(N * 4),
190 place_elems: InternedSet::with_capacity(N * 2),
191 const_: InternedSet::with_capacity(N * 2),
192 pat: InternedSet::with_capacity(N),
193 const_allocation: InternedSet::with_capacity(N),
194 bound_variable_kinds: InternedSet::with_capacity(N * 2),
195 layout: InternedSet::with_capacity(N),
196 adt_def: InternedSet::with_capacity(N),
197 external_constraints: InternedSet::with_capacity(N),
198 predefined_opaques_in_body: InternedSet::with_capacity(N),
199 fields: InternedSet::with_capacity(N * 4),
200 local_def_ids: InternedSet::with_capacity(N),
201 captures: InternedSet::with_capacity(N),
202 valtree: InternedSet::with_capacity(N),
203 patterns: InternedSet::with_capacity(N),
204 outlives: InternedSet::with_capacity(N),
205 }
206 }
207
208 #[allow(rustc::usage_of_ty_tykind)]
210 #[inline(never)]
211 fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
212 Ty(Interned::new_unchecked(
213 self.type_
214 .intern(kind, |kind| {
215 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
216 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
217
218 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
219 internee: kind,
220 stable_hash,
221 flags: flags.flags,
222 outer_exclusive_binder: flags.outer_exclusive_binder,
223 }))
224 })
225 .0,
226 ))
227 }
228
229 #[allow(rustc::usage_of_ty_tykind)]
231 #[inline(never)]
232 fn intern_const(
233 &self,
234 kind: ty::ConstKind<'tcx>,
235 sess: &Session,
236 untracked: &Untracked,
237 ) -> Const<'tcx> {
238 Const(Interned::new_unchecked(
239 self.const_
240 .intern(kind, |kind: ty::ConstKind<'_>| {
241 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
242 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
243
244 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
245 internee: kind,
246 stable_hash,
247 flags: flags.flags,
248 outer_exclusive_binder: flags.outer_exclusive_binder,
249 }))
250 })
251 .0,
252 ))
253 }
254
255 fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
256 &self,
257 flags: &ty::FlagComputation<TyCtxt<'tcx>>,
258 sess: &'a Session,
259 untracked: &'a Untracked,
260 val: &T,
261 ) -> Fingerprint {
262 if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
265 Fingerprint::ZERO
266 } else {
267 let mut hasher = StableHasher::new();
268 let mut hcx = StableHashingContext::new(sess, untracked);
269 val.hash_stable(&mut hcx, &mut hasher);
270 hasher.finish()
271 }
272 }
273
274 #[inline(never)]
276 fn intern_predicate(
277 &self,
278 kind: Binder<'tcx, PredicateKind<'tcx>>,
279 sess: &Session,
280 untracked: &Untracked,
281 ) -> Predicate<'tcx> {
282 Predicate(Interned::new_unchecked(
283 self.predicate
284 .intern(kind, |kind| {
285 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
286
287 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
288
289 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
290 internee: kind,
291 stable_hash,
292 flags: flags.flags,
293 outer_exclusive_binder: flags.outer_exclusive_binder,
294 }))
295 })
296 .0,
297 ))
298 }
299
300 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
301 if clauses.is_empty() {
302 ListWithCachedTypeInfo::empty()
303 } else {
304 self.clauses
305 .intern_ref(clauses, || {
306 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
307
308 InternedInSet(ListWithCachedTypeInfo::from_arena(
309 &*self.arena,
310 flags.into(),
311 clauses,
312 ))
313 })
314 .0
315 }
316 }
317}
318
319const NUM_PREINTERNED_TY_VARS: u32 = 100;
324const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
325const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
326const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
327const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
328
329const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
338
339const NUM_PREINTERNED_RE_VARS: u32 = 500;
341const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
342const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
343
344pub struct CommonTypes<'tcx> {
345 pub unit: Ty<'tcx>,
346 pub bool: Ty<'tcx>,
347 pub char: Ty<'tcx>,
348 pub isize: Ty<'tcx>,
349 pub i8: Ty<'tcx>,
350 pub i16: Ty<'tcx>,
351 pub i32: Ty<'tcx>,
352 pub i64: Ty<'tcx>,
353 pub i128: Ty<'tcx>,
354 pub usize: Ty<'tcx>,
355 pub u8: Ty<'tcx>,
356 pub u16: Ty<'tcx>,
357 pub u32: Ty<'tcx>,
358 pub u64: Ty<'tcx>,
359 pub u128: Ty<'tcx>,
360 pub f16: Ty<'tcx>,
361 pub f32: Ty<'tcx>,
362 pub f64: Ty<'tcx>,
363 pub f128: Ty<'tcx>,
364 pub str_: Ty<'tcx>,
365 pub never: Ty<'tcx>,
366 pub self_param: Ty<'tcx>,
367
368 pub trait_object_dummy_self: Ty<'tcx>,
373
374 pub ty_vars: Vec<Ty<'tcx>>,
376
377 pub fresh_tys: Vec<Ty<'tcx>>,
379
380 pub fresh_int_tys: Vec<Ty<'tcx>>,
382
383 pub fresh_float_tys: Vec<Ty<'tcx>>,
385
386 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
390
391 pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
395}
396
397pub struct CommonLifetimes<'tcx> {
398 pub re_static: Region<'tcx>,
400
401 pub re_erased: Region<'tcx>,
403
404 pub re_vars: Vec<Region<'tcx>>,
406
407 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
411
412 pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
416}
417
418pub struct CommonConsts<'tcx> {
419 pub unit: Const<'tcx>,
420 pub true_: Const<'tcx>,
421 pub false_: Const<'tcx>,
422 pub(crate) valtree_zst: ValTree<'tcx>,
424}
425
426impl<'tcx> CommonTypes<'tcx> {
427 fn new(
428 interners: &CtxtInterners<'tcx>,
429 sess: &Session,
430 untracked: &Untracked,
431 ) -> CommonTypes<'tcx> {
432 let mk = |ty| interners.intern_ty(ty, sess, untracked);
433
434 let ty_vars =
435 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
436 let fresh_tys: Vec<_> =
437 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
438 let fresh_int_tys: Vec<_> =
439 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
440 let fresh_float_tys: Vec<_> =
441 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
442
443 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
444 .map(|i| {
445 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
446 .map(|v| {
447 mk(ty::Bound(
448 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
449 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
450 ))
451 })
452 .collect()
453 })
454 .collect();
455
456 let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
457 .map(|v| {
458 mk(ty::Bound(
459 ty::BoundVarIndexKind::Canonical,
460 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
461 ))
462 })
463 .collect();
464
465 CommonTypes {
466 unit: mk(Tuple(List::empty())),
467 bool: mk(Bool),
468 char: mk(Char),
469 never: mk(Never),
470 isize: mk(Int(ty::IntTy::Isize)),
471 i8: mk(Int(ty::IntTy::I8)),
472 i16: mk(Int(ty::IntTy::I16)),
473 i32: mk(Int(ty::IntTy::I32)),
474 i64: mk(Int(ty::IntTy::I64)),
475 i128: mk(Int(ty::IntTy::I128)),
476 usize: mk(Uint(ty::UintTy::Usize)),
477 u8: mk(Uint(ty::UintTy::U8)),
478 u16: mk(Uint(ty::UintTy::U16)),
479 u32: mk(Uint(ty::UintTy::U32)),
480 u64: mk(Uint(ty::UintTy::U64)),
481 u128: mk(Uint(ty::UintTy::U128)),
482 f16: mk(Float(ty::FloatTy::F16)),
483 f32: mk(Float(ty::FloatTy::F32)),
484 f64: mk(Float(ty::FloatTy::F64)),
485 f128: mk(Float(ty::FloatTy::F128)),
486 str_: mk(Str),
487 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
488
489 trait_object_dummy_self: fresh_tys[0],
490
491 ty_vars,
492 fresh_tys,
493 fresh_int_tys,
494 fresh_float_tys,
495 anon_bound_tys,
496 anon_canonical_bound_tys,
497 }
498 }
499}
500
501impl<'tcx> CommonLifetimes<'tcx> {
502 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
503 let mk = |r| {
504 Region(Interned::new_unchecked(
505 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
506 ))
507 };
508
509 let re_vars =
510 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
511
512 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
513 .map(|i| {
514 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
515 .map(|v| {
516 mk(ty::ReBound(
517 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
518 ty::BoundRegion {
519 var: ty::BoundVar::from(v),
520 kind: ty::BoundRegionKind::Anon,
521 },
522 ))
523 })
524 .collect()
525 })
526 .collect();
527
528 let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
529 .map(|v| {
530 mk(ty::ReBound(
531 ty::BoundVarIndexKind::Canonical,
532 ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
533 ))
534 })
535 .collect();
536
537 CommonLifetimes {
538 re_static: mk(ty::ReStatic),
539 re_erased: mk(ty::ReErased),
540 re_vars,
541 anon_re_bounds,
542 anon_re_canonical_bounds,
543 }
544 }
545}
546
547impl<'tcx> CommonConsts<'tcx> {
548 fn new(
549 interners: &CtxtInterners<'tcx>,
550 types: &CommonTypes<'tcx>,
551 sess: &Session,
552 untracked: &Untracked,
553 ) -> CommonConsts<'tcx> {
554 let mk_const = |c| {
555 interners.intern_const(
556 c, sess, untracked,
558 )
559 };
560
561 let mk_valtree = |v| {
562 ty::ValTree(Interned::new_unchecked(
563 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
564 ))
565 };
566
567 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(Box::default()));
568 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
569 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
570
571 CommonConsts {
572 unit: mk_const(ty::ConstKind::Value(ty::Value {
573 ty: types.unit,
574 valtree: valtree_zst,
575 })),
576 true_: mk_const(ty::ConstKind::Value(ty::Value {
577 ty: types.bool,
578 valtree: valtree_true,
579 })),
580 false_: mk_const(ty::ConstKind::Value(ty::Value {
581 ty: types.bool,
582 valtree: valtree_false,
583 })),
584 valtree_zst,
585 }
586 }
587}
588
589#[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)]
592pub struct FreeRegionInfo {
593 pub scope: LocalDefId,
595 pub region_def_id: DefId,
597 pub is_impl_item: bool,
599}
600
601#[derive(#[automatically_derived]
impl<'tcx, KEY: ::core::marker::Copy + Copy> ::core::marker::Copy for
TyCtxtFeed<'tcx, KEY> {
}Copy, #[automatically_derived]
impl<'tcx, KEY: ::core::clone::Clone + Copy> ::core::clone::Clone for
TyCtxtFeed<'tcx, KEY> {
#[inline]
fn clone(&self) -> TyCtxtFeed<'tcx, KEY> {
TyCtxtFeed {
tcx: ::core::clone::Clone::clone(&self.tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
603pub struct TyCtxtFeed<'tcx, KEY: Copy> {
604 pub tcx: TyCtxt<'tcx>,
605 key: KEY,
607}
608
609impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
612
613#[derive(#[automatically_derived]
impl<'tcx, KEY: ::core::marker::Copy + Copy> ::core::marker::Copy for
Feed<'tcx, KEY> {
}Copy, #[automatically_derived]
impl<'tcx, KEY: ::core::clone::Clone + Copy> ::core::clone::Clone for
Feed<'tcx, KEY> {
#[inline]
fn clone(&self) -> Feed<'tcx, KEY> {
Feed {
_tcx: ::core::clone::Clone::clone(&self._tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
618pub struct Feed<'tcx, KEY: Copy> {
619 _tcx: PhantomData<TyCtxt<'tcx>>,
620 key: KEY,
622}
623
624impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
627
628impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
629 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
630 self.key.fmt(f)
631 }
632}
633
634impl<'tcx> TyCtxt<'tcx> {
639 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
642 self.dep_graph.assert_ignored();
643 TyCtxtFeed { tcx: self, key: () }
644 }
645
646 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
649 let key = self.untracked().source_span.push(span);
650 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);
651 TyCtxtFeed { tcx: self, key }
652 }
653
654 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
658 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);
659 TyCtxtFeed { tcx: self, key }.type_of(value)
660 }
661}
662
663impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
664 #[inline(always)]
665 pub fn key(&self) -> KEY {
666 self.key
667 }
668
669 #[inline(always)]
670 pub fn downgrade(self) -> Feed<'tcx, KEY> {
671 Feed { _tcx: PhantomData, key: self.key }
672 }
673}
674
675impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
676 #[inline(always)]
677 pub fn key(&self) -> KEY {
678 self.key
679 }
680
681 #[inline(always)]
682 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
683 TyCtxtFeed { tcx, key: self.key }
684 }
685}
686
687impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
688 #[inline(always)]
689 pub fn def_id(&self) -> LocalDefId {
690 self.key
691 }
692
693 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
695 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
696 }
697
698 pub fn feed_hir(&self) {
700 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
701
702 let node = hir::OwnerNode::Synthetic;
703 let bodies = Default::default();
704 let attrs = hir::AttributeMap::EMPTY;
705
706 let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
707 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, &[], attrs.define_opaque);
708 let node = node.into();
709 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
710 opt_hash_including_bodies,
711 nodes: IndexVec::from_elem_n(
712 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
713 1,
714 ),
715 bodies,
716 })));
717 self.feed_owner_id().hir_attr_map(attrs);
718 }
719}
720
721#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for TyCtxt<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for TyCtxt<'tcx> {
#[inline]
fn clone(&self) -> TyCtxt<'tcx> {
let _: ::core::clone::AssertParamIsClone<&'tcx GlobalCtxt<'tcx>>;
*self
}
}Clone)]
739#[rustc_diagnostic_item = "TyCtxt"]
740#[rustc_pass_by_value]
741pub struct TyCtxt<'tcx> {
742 gcx: &'tcx GlobalCtxt<'tcx>,
743}
744
745unsafe impl DynSend for TyCtxt<'_> {}
749unsafe impl DynSync for TyCtxt<'_> {}
750fn _assert_tcx_fields() {
751 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
752 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
753}
754
755impl<'tcx> Deref for TyCtxt<'tcx> {
756 type Target = &'tcx GlobalCtxt<'tcx>;
757 #[inline(always)]
758 fn deref(&self) -> &Self::Target {
759 &self.gcx
760 }
761}
762
763pub struct GlobalCtxt<'tcx> {
765 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
766 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
767
768 interners: CtxtInterners<'tcx>,
769
770 pub sess: &'tcx Session,
771 crate_types: Vec<CrateType>,
772 stable_crate_id: StableCrateId,
778
779 pub dep_graph: DepGraph,
780
781 pub prof: SelfProfilerRef,
782
783 pub types: CommonTypes<'tcx>,
785
786 pub lifetimes: CommonLifetimes<'tcx>,
788
789 pub consts: CommonConsts<'tcx>,
791
792 pub(crate) hooks: crate::hooks::Providers,
795
796 untracked: Untracked,
797
798 pub query_system: QuerySystem<'tcx>,
799 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
800
801 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
803
804 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
807
808 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
812
813 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
815 pub new_solver_canonical_param_env_cache:
816 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
817
818 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
819
820 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
822 pub clauses_cache:
824 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
825
826 pub data_layout: TargetDataLayout,
828
829 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
831
832 current_gcx: CurrentGcx,
833
834 pub jobserver_proxy: Arc<Proxy>,
836}
837
838impl<'tcx> GlobalCtxt<'tcx> {
839 pub fn enter<F, R>(&'tcx self, f: F) -> R
842 where
843 F: FnOnce(TyCtxt<'tcx>) -> R,
844 {
845 let icx = tls::ImplicitCtxt::new(self);
846
847 let _on_drop = defer(move || {
849 *self.current_gcx.value.write() = None;
850 });
851
852 {
854 let mut guard = self.current_gcx.value.write();
855 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
856 *guard = Some(self as *const _ as *const ());
857 }
858
859 tls::enter_context(&icx, || f(icx.tcx))
860 }
861}
862
863#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
870pub struct CurrentGcx {
871 value: Arc<RwLock<Option<*const ()>>>,
874}
875
876unsafe impl DynSend for CurrentGcx {}
877unsafe impl DynSync for CurrentGcx {}
878
879impl CurrentGcx {
880 pub fn new() -> Self {
881 Self { value: Arc::new(RwLock::new(None)) }
882 }
883
884 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
885 let read_guard = self.value.read();
886 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
887 f(unsafe { &*gcx })
891 }
892}
893
894impl<'tcx> TyCtxt<'tcx> {
895 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
896 let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id());
899 if typeck_root_def_id != def_id.to_def_id() {
900 return self.has_typeck_results(typeck_root_def_id.expect_local());
901 }
902
903 self.hir_node_by_def_id(def_id).body_id().is_some()
904 }
905
906 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
911 let def_kind = self.def_kind(def_id);
912 if def_kind.has_codegen_attrs() {
913 self.codegen_fn_attrs(def_id)
914 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst | DefKind::Const |
DefKind::InlineConst | DefKind::GlobalAsm => true,
_ => false,
}matches!(
915 def_kind,
916 DefKind::AnonConst
917 | DefKind::AssocConst
918 | DefKind::Const
919 | DefKind::InlineConst
920 | DefKind::GlobalAsm
921 ) {
922 CodegenFnAttrs::EMPTY
923 } else {
924 crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind))bug!(
925 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
926 def_id,
927 def_kind
928 )
929 }
930 }
931
932 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
933 self.arena.alloc(Steal::new(thir))
934 }
935
936 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
937 self.arena.alloc(Steal::new(mir))
938 }
939
940 pub fn alloc_steal_promoted(
941 self,
942 promoted: IndexVec<Promoted, Body<'tcx>>,
943 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
944 self.arena.alloc(Steal::new(promoted))
945 }
946
947 pub fn mk_adt_def(
948 self,
949 did: DefId,
950 kind: AdtKind,
951 variants: IndexVec<VariantIdx, ty::VariantDef>,
952 repr: ReprOptions,
953 ) -> ty::AdtDef<'tcx> {
954 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
955 }
956
957 pub fn allocate_bytes_dedup<'a>(
960 self,
961 bytes: impl Into<Cow<'a, [u8]>>,
962 salt: usize,
963 ) -> interpret::AllocId {
964 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
966 let alloc = self.mk_const_alloc(alloc);
967 self.reserve_and_set_memory_dedup(alloc, salt)
968 }
969
970 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
972 if self.sess.opts.unstable_opts.experimental_default_bounds {
973 &[
974 LangItem::DefaultTrait1,
975 LangItem::DefaultTrait2,
976 LangItem::DefaultTrait3,
977 LangItem::DefaultTrait4,
978 ]
979 } else {
980 &[]
981 }
982 }
983
984 pub fn is_default_trait(self, def_id: DefId) -> bool {
985 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
986 }
987
988 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
989 #[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))
990 }
991
992 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
996 let start = {
#[allow(deprecated)]
{
{
'done:
{
for i in self.get_all_attrs(def_id) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcLayoutScalarValidRangeStart(n,
_)) => {
break 'done Some(Bound::Included(**n));
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}
}find_attr!(self, def_id, RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
997 let end =
998 {
#[allow(deprecated)]
{
{
'done:
{
for i in self.get_all_attrs(def_id) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcLayoutScalarValidRangeEnd(n,
_)) => {
break 'done Some(Bound::Included(**n));
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}
}find_attr!(self, def_id, RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n))
999 .unwrap_or(Bound::Unbounded);
1000 (start, end)
1001 }
1002
1003 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1004 value.lift_to_interner(self)
1005 }
1006
1007 pub fn create_global_ctxt<T>(
1014 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1015 s: &'tcx Session,
1016 crate_types: Vec<CrateType>,
1017 stable_crate_id: StableCrateId,
1018 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1019 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1020 untracked: Untracked,
1021 dep_graph: DepGraph,
1022 dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
1023 query_system: QuerySystem<'tcx>,
1024 hooks: crate::hooks::Providers,
1025 current_gcx: CurrentGcx,
1026 jobserver_proxy: Arc<Proxy>,
1027 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1028 ) -> T {
1029 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1030 s.dcx().emit_fatal(err);
1031 });
1032 let interners = CtxtInterners::new(arena);
1033 let common_types = CommonTypes::new(&interners, s, &untracked);
1034 let common_lifetimes = CommonLifetimes::new(&interners);
1035 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1036
1037 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1038 sess: s,
1039 crate_types,
1040 stable_crate_id,
1041 arena,
1042 hir_arena,
1043 interners,
1044 dep_graph,
1045 hooks,
1046 prof: s.prof.clone(),
1047 types: common_types,
1048 lifetimes: common_lifetimes,
1049 consts: common_consts,
1050 untracked,
1051 query_system,
1052 dep_kind_vtables,
1053 ty_rcache: Default::default(),
1054 selection_cache: Default::default(),
1055 evaluation_cache: Default::default(),
1056 new_solver_evaluation_cache: Default::default(),
1057 new_solver_canonical_param_env_cache: Default::default(),
1058 canonical_param_env_cache: Default::default(),
1059 highest_var_in_clauses_cache: Default::default(),
1060 clauses_cache: Default::default(),
1061 data_layout,
1062 alloc_map: interpret::AllocMap::new(),
1063 current_gcx,
1064 jobserver_proxy,
1065 });
1066
1067 gcx.enter(f)
1069 }
1070
1071 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1073 self.get_lang_items(())
1074 }
1075
1076 #[track_caller]
1078 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1079 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1080 self.type_of(ordering_enum).no_bound_vars().unwrap()
1081 }
1082
1083 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1086 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1087 }
1088
1089 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1091 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1092 }
1093
1094 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1096 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1097 }
1098
1099 pub fn is_coroutine(self, def_id: DefId) -> bool {
1100 self.coroutine_kind(def_id).is_some()
1101 }
1102
1103 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1104 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1105 }
1106
1107 pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1108 if !self.is_type_const(def_id) {
1109 return None;
1110 }
1111 Some(self.def_span(def_id))
1112 }
1113
1114 pub fn is_type_const<I: Copy + IntoQueryParam<DefId>>(self, def_id: I) -> bool {
1116 if !(#[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id.into_query_param())
{
DefKind::Const | DefKind::AssocConst => true,
_ => false,
}matches!(
1118 self.def_kind(def_id.into_query_param()),
1119 DefKind::Const | DefKind::AssocConst
1120 )) {
1121 return false;
1122 }
1123 self.is_rhs_type_const(def_id)
1124 }
1125
1126 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1129 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1130 }
1131
1132 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1134 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1135 self.coroutine_kind(def_id),
1136 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1137 )
1138 }
1139
1140 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1143 #[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)
1144 }
1145
1146 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1149 #[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(_)))
1150 }
1151
1152 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1154 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1155 self.coroutine_kind(def_id),
1156 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1157 )
1158 }
1159
1160 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1162 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1163 self.coroutine_kind(def_id),
1164 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1165 )
1166 }
1167
1168 pub fn features(self) -> &'tcx rustc_feature::Features {
1169 self.features_query(())
1170 }
1171
1172 pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey {
1173 let id = id.into_query_param();
1174 if let Some(id) = id.as_local() {
1176 self.definitions_untracked().def_key(id)
1177 } else {
1178 self.cstore_untracked().def_key(id)
1179 }
1180 }
1181
1182 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1188 if let Some(id) = id.as_local() {
1190 self.definitions_untracked().def_path(id)
1191 } else {
1192 self.cstore_untracked().def_path(id)
1193 }
1194 }
1195
1196 #[inline]
1197 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1198 if let Some(def_id) = def_id.as_local() {
1200 self.definitions_untracked().def_path_hash(def_id)
1201 } else {
1202 self.cstore_untracked().def_path_hash(def_id)
1203 }
1204 }
1205
1206 #[inline]
1207 pub fn crate_types(self) -> &'tcx [CrateType] {
1208 &self.crate_types
1209 }
1210
1211 pub fn needs_metadata(self) -> bool {
1212 self.crate_types().iter().any(|ty| match *ty {
1213 CrateType::Executable
1214 | CrateType::StaticLib
1215 | CrateType::Cdylib
1216 | CrateType::Sdylib => false,
1217 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1218 })
1219 }
1220
1221 pub fn needs_crate_hash(self) -> bool {
1222 truecfg!(debug_assertions)
1234 || self.sess.opts.incremental.is_some()
1235 || self.needs_metadata()
1236 || self.sess.instrument_coverage()
1237 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1238 }
1239
1240 #[inline]
1241 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1242 if crate_num == LOCAL_CRATE {
1243 self.stable_crate_id
1244 } else {
1245 self.cstore_untracked().stable_crate_id(crate_num)
1246 }
1247 }
1248
1249 #[inline]
1252 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1253 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1254 LOCAL_CRATE
1255 } else {
1256 *self
1257 .untracked()
1258 .stable_crate_ids
1259 .read()
1260 .get(&stable_crate_id)
1261 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1262 }
1263 }
1264
1265 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1269 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/context.rs:1269",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1269u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("def_path_hash_to_def_id({0:?})",
hash) as &dyn Value))])
});
} else { ; }
};debug!("def_path_hash_to_def_id({:?})", hash);
1270
1271 let stable_crate_id = hash.stable_crate_id();
1272
1273 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1276 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1277 } else {
1278 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1279 }
1280 }
1281
1282 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1283 let (crate_name, stable_crate_id) = if def_id.is_local() {
1288 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1289 } else {
1290 let cstore = &*self.cstore_untracked();
1291 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1292 };
1293
1294 ::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!(
1295 "{}[{:04x}]{}",
1296 crate_name,
1297 stable_crate_id.as_u64() >> (8 * 6),
1300 self.def_path(def_id).to_string_no_crate_verbose()
1301 )
1302 }
1303
1304 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1305 self.sess.dcx()
1306 }
1307
1308 pub fn is_target_feature_call_safe(
1311 self,
1312 callee_features: &[TargetFeature],
1313 body_features: &[TargetFeature],
1314 ) -> bool {
1315 self.sess.target.options.is_like_wasm
1320 || callee_features
1321 .iter()
1322 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1323 }
1324
1325 pub fn adjust_target_feature_sig(
1328 self,
1329 fun_def: DefId,
1330 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1331 caller: DefId,
1332 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1333 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1334 let caller_features = &self.body_codegen_attrs(caller).target_features;
1335 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1336 return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
1337 }
1338 None
1339 }
1340
1341 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1344 match self.env_var_os(key.as_ref()) {
1345 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1346 None => Err(VarError::NotPresent),
1347 }
1348 }
1349}
1350
1351impl<'tcx> TyCtxtAt<'tcx> {
1352 pub fn create_def(
1354 self,
1355 parent: LocalDefId,
1356 name: Option<Symbol>,
1357 def_kind: DefKind,
1358 override_def_path_data: Option<DefPathData>,
1359 disambiguator: &mut DisambiguatorState,
1360 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1361 let feed =
1362 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1363
1364 feed.def_span(self.span);
1365 feed
1366 }
1367}
1368
1369impl<'tcx> TyCtxt<'tcx> {
1370 pub fn create_def(
1372 self,
1373 parent: LocalDefId,
1374 name: Option<Symbol>,
1375 def_kind: DefKind,
1376 override_def_path_data: Option<DefPathData>,
1377 disambiguator: &mut DisambiguatorState,
1378 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1379 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1380 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1390
1391 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1396
1397 let feed = TyCtxtFeed { tcx: self, key: def_id };
1398 feed.def_kind(def_kind);
1399 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1404 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1405 feed.visibility(ty::Visibility::Restricted(parent_mod));
1406 }
1407
1408 feed
1409 }
1410
1411 pub fn create_crate_num(
1412 self,
1413 stable_crate_id: StableCrateId,
1414 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1415 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
1416 return Err(existing);
1417 }
1418
1419 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
1420 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
1421 Ok(TyCtxtFeed { key: num, tcx: self })
1422 }
1423
1424 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1425 self.ensure_ok().analysis(());
1427
1428 let definitions = &self.untracked.definitions;
1429 gen {
1430 let mut i = 0;
1431
1432 while i < { definitions.read().num_definitions() } {
1435 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1436 yield LocalDefId { local_def_index };
1437 i += 1;
1438 }
1439
1440 definitions.freeze();
1442 }
1443 }
1444
1445 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1446 self.ensure_ok().analysis(());
1448
1449 self.untracked.definitions.freeze().def_path_table()
1452 }
1453
1454 pub fn def_path_hash_to_def_index_map(
1455 self,
1456 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1457 self.ensure_ok().hir_crate_items(());
1460 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1463 }
1464
1465 #[inline]
1468 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1469 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1470 }
1471
1472 pub fn untracked(self) -> &'tcx Untracked {
1474 &self.untracked
1475 }
1476 #[inline]
1479 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1480 self.untracked.definitions.read()
1481 }
1482
1483 #[inline]
1486 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1487 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1488 }
1489
1490 #[inline(always)]
1491 pub fn with_stable_hashing_context<R>(
1492 self,
1493 f: impl FnOnce(StableHashingContext<'_>) -> R,
1494 ) -> R {
1495 f(StableHashingContext::new(self.sess, &self.untracked))
1496 }
1497
1498 pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
1499 self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
1500 }
1501
1502 #[inline]
1503 pub fn local_crate_exports_generics(self) -> bool {
1504 if self.is_compiler_builtins(LOCAL_CRATE) {
1508 return false;
1509 }
1510 self.crate_types().iter().any(|crate_type| {
1511 match crate_type {
1512 CrateType::Executable
1513 | CrateType::StaticLib
1514 | CrateType::ProcMacro
1515 | CrateType::Cdylib
1516 | CrateType::Sdylib => false,
1517
1518 CrateType::Dylib => true,
1523
1524 CrateType::Rlib => true,
1525 }
1526 })
1527 }
1528
1529 pub fn is_suitable_region(
1531 self,
1532 generic_param_scope: LocalDefId,
1533 mut region: Region<'tcx>,
1534 ) -> Option<FreeRegionInfo> {
1535 let (suitable_region_binding_scope, region_def_id) = loop {
1536 let def_id =
1537 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1538 let scope = self.local_parent(def_id);
1539 if self.def_kind(scope) == DefKind::OpaqueTy {
1540 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1543 continue;
1544 }
1545 break (scope, def_id.into());
1546 };
1547
1548 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1549 Node::Item(..) | Node::TraitItem(..) => false,
1550 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1551 hir::ImplItemImplKind::Trait { .. } => true,
1558 _ => false,
1559 },
1560 _ => false,
1561 };
1562
1563 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1564 }
1565
1566 pub fn return_type_impl_or_dyn_traits(
1568 self,
1569 scope_def_id: LocalDefId,
1570 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1571 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1572 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1573 self.hir_fn_decl_by_hir_id(hir_id)
1574 else {
1575 return ::alloc::vec::Vec::new()vec![];
1576 };
1577
1578 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1579 v.visit_ty_unambig(hir_output);
1580 v.0
1581 }
1582
1583 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1587 self,
1588 scope_def_id: LocalDefId,
1589 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1590 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1591 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1592 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1594 && let hir::TyKind::Path(hir::QPath::Resolved(
1595 None,
1596 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1597 && let Some(local_id) = def_id.as_local()
1598 && 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()
1600 {
1601 v.visit_ty_unambig(alias_ty);
1602 if !v.0.is_empty() {
1603 return Some((
1604 v.0,
1605 alias_generics.span,
1606 alias_generics.span_for_lifetime_suggestion(),
1607 ));
1608 }
1609 }
1610 None
1611 }
1612
1613 pub fn has_strict_asm_symbol_naming(self) -> bool {
1616 self.sess.target.llvm_target.starts_with("nvptx")
1617 }
1618
1619 pub fn caller_location_ty(self) -> Ty<'tcx> {
1621 Ty::new_imm_ref(
1622 self,
1623 self.lifetimes.re_static,
1624 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1625 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
1626 )
1627 }
1628
1629 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1631 let kind = self.def_kind(def_id);
1632 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1633 }
1634
1635 pub fn type_length_limit(self) -> Limit {
1636 self.limits(()).type_length_limit
1637 }
1638
1639 pub fn recursion_limit(self) -> Limit {
1640 self.limits(()).recursion_limit
1641 }
1642
1643 pub fn move_size_limit(self) -> Limit {
1644 self.limits(()).move_size_limit
1645 }
1646
1647 pub fn pattern_complexity_limit(self) -> Limit {
1648 self.limits(()).pattern_complexity_limit
1649 }
1650
1651 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1653 iter::once(LOCAL_CRATE)
1654 .chain(self.crates(()).iter().copied())
1655 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1656 }
1657
1658 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1660 let visible_crates =
1661 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1662
1663 iter::once(LOCAL_CRATE)
1664 .chain(visible_crates)
1665 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1666 }
1667
1668 #[inline]
1669 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1670 self.visibility(def_id).expect_local()
1671 }
1672
1673 x;#[instrument(skip(self), level = "trace", ret)]
1675 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1676 self.hir_expect_opaque_ty(def_id).origin
1677 }
1678
1679 pub fn finish(self) {
1680 self.alloc_self_profile_query_strings();
1683
1684 self.save_dep_graph();
1685 self.query_key_hash_verify_all();
1686
1687 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1688 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
1689 }
1690 }
1691}
1692
1693macro_rules! nop_lift {
1694 ($set:ident; $ty:ty => $lifted:ty) => {
1695 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1696 type Lifted = $lifted;
1697 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1698 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1703 _x: Interned<'tcx, Inner>,
1704 ) -> InternedSet<'tcx, Inner> {
1705 unreachable!()
1706 }
1707 fn _type_eq<T>(_x: &T, _y: &T) {}
1708 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1709 let interner = _intern_set_ty_from_interned_ty(x.0);
1713 _type_eq(&interner, &tcx.interners.$set);
1715 }
1716
1717 tcx.interners
1718 .$set
1719 .contains_pointer_to(&InternedInSet(&*self.0.0))
1720 .then(|| unsafe { mem::transmute(self) })
1723 }
1724 }
1725 };
1726}
1727
1728macro_rules! nop_list_lift {
1729 ($set:ident; $ty:ty => $lifted:ty) => {
1730 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
1731 type Lifted = &'tcx List<$lifted>;
1732 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1733 if false {
1735 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
1736 }
1737
1738 if self.is_empty() {
1739 return Some(List::empty());
1740 }
1741 tcx.interners
1742 .$set
1743 .contains_pointer_to(&InternedInSet(self))
1744 .then(|| unsafe { mem::transmute(self) })
1745 }
1746 }
1747 };
1748}
1749
1750impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Ty<'a> {
type Lifted = Ty<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Ty<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.type_);
}
tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { type_; Ty<'a> => Ty<'tcx> }
1751impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Region<'a> {
type Lifted = Region<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Region<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.region);
}
tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { region; Region<'a> => Region<'tcx> }
1752impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Const<'a> {
type Lifted = Const<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Const<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_);
}
tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { const_; Const<'a> => Const<'tcx> }
1753impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Pattern<'a> {
type Lifted = Pattern<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Pattern<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.pat);
}
tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
1754impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ConstAllocation<'a> {
type Lifted = ConstAllocation<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ConstAllocation<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_allocation);
}
tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
1755impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Predicate<'a> {
type Lifted = Predicate<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Predicate<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
1756impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Clause<'a> {
type Lifted = Clause<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Clause<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
1757impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Layout<'a> {
type Lifted = Layout<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Layout<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.layout);
}
tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { layout; Layout<'a> => Layout<'tcx> }
1758impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ValTree<'a> {
type Lifted = ValTree<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ValTree<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.valtree);
}
tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
1759
1760impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Ty<'a>> {
type Lifted = &'tcx List<Ty<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<Ty<'tcx>>> =
&tcx.interners.type_lists;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
1761impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<PolyExistentialPredicate<'a>> {
type Lifted = &'tcx List<PolyExistentialPredicate<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>> =
&tcx.interners.poly_existential_predicates;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! {
1762 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1763}
1764impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<ty::BoundVariableKind<'a>> {
type Lifted = &'tcx List<ty::BoundVariableKind<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>> =
&tcx.interners.bound_variable_kinds;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind<'a> => ty::BoundVariableKind<'tcx> }
1765
1766impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<GenericArg<'a>> {
type Lifted = &'tcx List<GenericArg<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<GenericArg<'tcx>>> =
&tcx.interners.args;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.args.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
1768
1769macro_rules! sty_debug_print {
1770 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1771 #[allow(non_snake_case)]
1774 mod inner {
1775 use crate::ty::{self, TyCtxt};
1776 use crate::ty::context::InternedInSet;
1777
1778 #[derive(Copy, Clone)]
1779 struct DebugStat {
1780 total: usize,
1781 lt_infer: usize,
1782 ty_infer: usize,
1783 ct_infer: usize,
1784 all_infer: usize,
1785 }
1786
1787 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1788 let mut total = DebugStat {
1789 total: 0,
1790 lt_infer: 0,
1791 ty_infer: 0,
1792 ct_infer: 0,
1793 all_infer: 0,
1794 };
1795 $(let mut $variant = total;)*
1796
1797 for shard in tcx.interners.type_.lock_shards() {
1798 #[allow(rustc::potential_query_instability)]
1800 let types = shard.iter();
1801 for &(InternedInSet(t), ()) in types {
1802 let variant = match t.internee {
1803 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1804 ty::Float(..) | ty::Str | ty::Never => continue,
1805 ty::Error(_) => continue,
1806 $(ty::$variant(..) => &mut $variant,)*
1807 };
1808 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1809 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1810 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1811
1812 variant.total += 1;
1813 total.total += 1;
1814 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1815 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1816 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1817 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1818 }
1819 }
1820 writeln!(fmt, "Ty interner total ty lt ct all")?;
1821 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1822 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1823 stringify!($variant),
1824 uses = $variant.total,
1825 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1826 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1827 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1828 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1829 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1830 )*
1831 writeln!(fmt, " total {uses:6} \
1832 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1833 uses = total.total,
1834 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1835 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1836 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1837 all = total.all_infer as f64 * 100.0 / total.total as f64)
1838 }
1839 }
1840
1841 inner::go($fmt, $ctxt)
1842 }}
1843}
1844
1845impl<'tcx> TyCtxt<'tcx> {
1846 pub fn debug_stats(self) -> impl fmt::Debug {
1847 fmt::from_fn(move |fmt| {
1848 {
#[allow(non_snake_case)]
mod inner {
use crate::ty::{self, TyCtxt};
use crate::ty::context::InternedInSet;
struct DebugStat {
total: usize,
lt_infer: usize,
ty_infer: usize,
ct_infer: usize,
all_infer: usize,
}
#[automatically_derived]
impl ::core::marker::Copy for DebugStat { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DebugStat { }
#[automatically_derived]
impl ::core::clone::Clone for DebugStat {
#[inline]
fn clone(&self) -> DebugStat {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}
pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>)
-> std::fmt::Result {
let mut total =
DebugStat {
total: 0,
lt_infer: 0,
ty_infer: 0,
ct_infer: 0,
all_infer: 0,
};
let mut Adt = total;
let mut Array = total;
let mut Slice = total;
let mut RawPtr = total;
let mut Ref = total;
let mut FnDef = total;
let mut FnPtr = total;
let mut UnsafeBinder = total;
let mut Placeholder = total;
let mut Coroutine = total;
let mut CoroutineWitness = total;
let mut Dynamic = total;
let mut Closure = total;
let mut CoroutineClosure = total;
let mut Tuple = total;
let mut Bound = total;
let mut Param = total;
let mut Infer = total;
let mut Alias = total;
let mut Pat = total;
let mut Foreign = total;
for shard in tcx.interners.type_.lock_shards() {
#[allow(rustc :: potential_query_instability)]
let types = shard.iter();
for &(InternedInSet(t), ()) in types {
let variant =
match t.internee {
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
ty::Float(..) | ty::Str | ty::Never => continue,
ty::Error(_) => continue,
ty::Adt(..) => &mut Adt,
ty::Array(..) => &mut Array,
ty::Slice(..) => &mut Slice,
ty::RawPtr(..) => &mut RawPtr,
ty::Ref(..) => &mut Ref,
ty::FnDef(..) => &mut FnDef,
ty::FnPtr(..) => &mut FnPtr,
ty::UnsafeBinder(..) => &mut UnsafeBinder,
ty::Placeholder(..) => &mut Placeholder,
ty::Coroutine(..) => &mut Coroutine,
ty::CoroutineWitness(..) => &mut CoroutineWitness,
ty::Dynamic(..) => &mut Dynamic,
ty::Closure(..) => &mut Closure,
ty::CoroutineClosure(..) => &mut CoroutineClosure,
ty::Tuple(..) => &mut Tuple,
ty::Bound(..) => &mut Bound,
ty::Param(..) => &mut Param,
ty::Infer(..) => &mut Infer,
ty::Alias(..) => &mut Alias,
ty::Pat(..) => &mut Pat,
ty::Foreign(..) => &mut Foreign,
};
let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
variant.total += 1;
total.total += 1;
if lt { total.lt_infer += 1; variant.lt_infer += 1 }
if ty { total.ty_infer += 1; variant.ty_infer += 1 }
if ct { total.ct_infer += 1; variant.ct_infer += 1 }
if lt && ty && ct {
total.all_infer += 1;
variant.all_infer += 1
}
}
}
fmt.write_fmt(format_args!("Ty interner total ty lt ct all\n"))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Adt", Adt.total,
Adt.total as f64 * 100.0 / total.total as f64,
Adt.ty_infer as f64 * 100.0 / total.total as f64,
Adt.lt_infer as f64 * 100.0 / total.total as f64,
Adt.ct_infer as f64 * 100.0 / total.total as f64,
Adt.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Array", Array.total,
Array.total as f64 * 100.0 / total.total as f64,
Array.ty_infer as f64 * 100.0 / total.total as f64,
Array.lt_infer as f64 * 100.0 / total.total as f64,
Array.ct_infer as f64 * 100.0 / total.total as f64,
Array.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Slice", Slice.total,
Slice.total as f64 * 100.0 / total.total as f64,
Slice.ty_infer as f64 * 100.0 / total.total as f64,
Slice.lt_infer as f64 * 100.0 / total.total as f64,
Slice.ct_infer as f64 * 100.0 / total.total as f64,
Slice.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"RawPtr", RawPtr.total,
RawPtr.total as f64 * 100.0 / total.total as f64,
RawPtr.ty_infer as f64 * 100.0 / total.total as f64,
RawPtr.lt_infer as f64 * 100.0 / total.total as f64,
RawPtr.ct_infer as f64 * 100.0 / total.total as f64,
RawPtr.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Ref", Ref.total,
Ref.total as f64 * 100.0 / total.total as f64,
Ref.ty_infer as f64 * 100.0 / total.total as f64,
Ref.lt_infer as f64 * 100.0 / total.total as f64,
Ref.ct_infer as f64 * 100.0 / total.total as f64,
Ref.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"FnDef", FnDef.total,
FnDef.total as f64 * 100.0 / total.total as f64,
FnDef.ty_infer as f64 * 100.0 / total.total as f64,
FnDef.lt_infer as f64 * 100.0 / total.total as f64,
FnDef.ct_infer as f64 * 100.0 / total.total as f64,
FnDef.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"FnPtr", FnPtr.total,
FnPtr.total as f64 * 100.0 / total.total as f64,
FnPtr.ty_infer as f64 * 100.0 / total.total as f64,
FnPtr.lt_infer as f64 * 100.0 / total.total as f64,
FnPtr.ct_infer as f64 * 100.0 / total.total as f64,
FnPtr.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"UnsafeBinder", UnsafeBinder.total,
UnsafeBinder.total as f64 * 100.0 / total.total as f64,
UnsafeBinder.ty_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.lt_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.ct_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Placeholder", Placeholder.total,
Placeholder.total as f64 * 100.0 / total.total as f64,
Placeholder.ty_infer as f64 * 100.0 / total.total as f64,
Placeholder.lt_infer as f64 * 100.0 / total.total as f64,
Placeholder.ct_infer as f64 * 100.0 / total.total as f64,
Placeholder.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Coroutine", Coroutine.total,
Coroutine.total as f64 * 100.0 / total.total as f64,
Coroutine.ty_infer as f64 * 100.0 / total.total as f64,
Coroutine.lt_infer as f64 * 100.0 / total.total as f64,
Coroutine.ct_infer as f64 * 100.0 / total.total as f64,
Coroutine.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"CoroutineWitness", CoroutineWitness.total,
CoroutineWitness.total as f64 * 100.0 / total.total as f64,
CoroutineWitness.ty_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.lt_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.ct_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Dynamic", Dynamic.total,
Dynamic.total as f64 * 100.0 / total.total as f64,
Dynamic.ty_infer as f64 * 100.0 / total.total as f64,
Dynamic.lt_infer as f64 * 100.0 / total.total as f64,
Dynamic.ct_infer as f64 * 100.0 / total.total as f64,
Dynamic.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Closure", Closure.total,
Closure.total as f64 * 100.0 / total.total as f64,
Closure.ty_infer as f64 * 100.0 / total.total as f64,
Closure.lt_infer as f64 * 100.0 / total.total as f64,
Closure.ct_infer as f64 * 100.0 / total.total as f64,
Closure.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"CoroutineClosure", CoroutineClosure.total,
CoroutineClosure.total as f64 * 100.0 / total.total as f64,
CoroutineClosure.ty_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.lt_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.ct_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Tuple", Tuple.total,
Tuple.total as f64 * 100.0 / total.total as f64,
Tuple.ty_infer as f64 * 100.0 / total.total as f64,
Tuple.lt_infer as f64 * 100.0 / total.total as f64,
Tuple.ct_infer as f64 * 100.0 / total.total as f64,
Tuple.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Bound", Bound.total,
Bound.total as f64 * 100.0 / total.total as f64,
Bound.ty_infer as f64 * 100.0 / total.total as f64,
Bound.lt_infer as f64 * 100.0 / total.total as f64,
Bound.ct_infer as f64 * 100.0 / total.total as f64,
Bound.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Param", Param.total,
Param.total as f64 * 100.0 / total.total as f64,
Param.ty_infer as f64 * 100.0 / total.total as f64,
Param.lt_infer as f64 * 100.0 / total.total as f64,
Param.ct_infer as f64 * 100.0 / total.total as f64,
Param.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Infer", Infer.total,
Infer.total as f64 * 100.0 / total.total as f64,
Infer.ty_infer as f64 * 100.0 / total.total as f64,
Infer.lt_infer as f64 * 100.0 / total.total as f64,
Infer.ct_infer as f64 * 100.0 / total.total as f64,
Infer.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Alias", Alias.total,
Alias.total as f64 * 100.0 / total.total as f64,
Alias.ty_infer as f64 * 100.0 / total.total as f64,
Alias.lt_infer as f64 * 100.0 / total.total as f64,
Alias.ct_infer as f64 * 100.0 / total.total as f64,
Alias.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Pat", Pat.total,
Pat.total as f64 * 100.0 / total.total as f64,
Pat.ty_infer as f64 * 100.0 / total.total as f64,
Pat.lt_infer as f64 * 100.0 / total.total as f64,
Pat.ct_infer as f64 * 100.0 / total.total as f64,
Pat.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Foreign", Foreign.total,
Foreign.total as f64 * 100.0 / total.total as f64,
Foreign.ty_infer as f64 * 100.0 / total.total as f64,
Foreign.lt_infer as f64 * 100.0 / total.total as f64,
Foreign.ct_infer as f64 * 100.0 / total.total as f64,
Foreign.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" total {0:6} {1:4.1}% {2:5.1}% {3:4.1}% {4:4.1}%\n",
total.total,
total.ty_infer as f64 * 100.0 / total.total as f64,
total.lt_infer as f64 * 100.0 / total.total as f64,
total.ct_infer as f64 * 100.0 / total.total as f64,
total.all_infer as f64 * 100.0 / total.total as f64))
}
}
inner::go(fmt, self)
}sty_debug_print!(
1849 fmt,
1850 self,
1851 Adt,
1852 Array,
1853 Slice,
1854 RawPtr,
1855 Ref,
1856 FnDef,
1857 FnPtr,
1858 UnsafeBinder,
1859 Placeholder,
1860 Coroutine,
1861 CoroutineWitness,
1862 Dynamic,
1863 Closure,
1864 CoroutineClosure,
1865 Tuple,
1866 Bound,
1867 Param,
1868 Infer,
1869 Alias,
1870 Pat,
1871 Foreign
1872 )?;
1873
1874 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1875 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1876 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())?;
1877 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1878
1879 Ok(())
1880 })
1881 }
1882}
1883
1884struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1889
1890impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1891 fn clone(&self) -> Self {
1892 *self
1893 }
1894}
1895
1896impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1897
1898impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1899 fn into_pointer(&self) -> *const () {
1900 self.0 as *const _ as *const ()
1901 }
1902}
1903
1904#[allow(rustc::usage_of_ty_tykind)]
1905impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1906 fn borrow(&self) -> &T {
1907 &self.0.internee
1908 }
1909}
1910
1911impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1912 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1913 self.0.internee == other.0.internee
1916 }
1917}
1918
1919impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1920
1921impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1922 fn hash<H: Hasher>(&self, s: &mut H) {
1923 self.0.internee.hash(s)
1925 }
1926}
1927
1928impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1929 fn borrow(&self) -> &[T] {
1930 &self.0[..]
1931 }
1932}
1933
1934impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1935 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1936 self.0[..] == other.0[..]
1939 }
1940}
1941
1942impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1943
1944impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1945 fn hash<H: Hasher>(&self, s: &mut H) {
1946 self.0[..].hash(s)
1948 }
1949}
1950
1951impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1952 fn borrow(&self) -> &[T] {
1953 &self.0[..]
1954 }
1955}
1956
1957impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1958 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1959 self.0[..] == other.0[..]
1962 }
1963}
1964
1965impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1966
1967impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1968 fn hash<H: Hasher>(&self, s: &mut H) {
1969 self.0[..].hash(s)
1971 }
1972}
1973
1974macro_rules! direct_interners {
1975 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1976 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1977 fn borrow<'a>(&'a self) -> &'a $ty {
1978 &self.0
1979 }
1980 }
1981
1982 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1983 fn eq(&self, other: &Self) -> bool {
1984 self.0 == other.0
1987 }
1988 }
1989
1990 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1991
1992 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1993 fn hash<H: Hasher>(&self, s: &mut H) {
1994 self.0.hash(s)
1997 }
1998 }
1999
2000 impl<'tcx> TyCtxt<'tcx> {
2001 $vis fn $method(self, v: $ty) -> $ret_ty {
2002 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2003 InternedInSet(self.interners.arena.alloc(v))
2004 }).0))
2005 }
2006 })+
2007 }
2008}
2009
2010impl<'tcx> Borrow<ExternalConstraintsData<TyCtxt<'tcx>>> for
InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a ExternalConstraintsData<TyCtxt<'tcx>> {
&self.0
}
}
impl<'tcx> PartialEq for
InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>
{}
impl<'tcx> Hash for InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>
{
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_external_constraints(self,
v: ExternalConstraintsData<TyCtxt<'tcx>>)
-> ExternalConstraints<'tcx> {
ExternalConstraints(Interned::new_unchecked(self.interners.external_constraints.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}direct_interners! {
2014 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2015 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2016 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2017 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2018 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2019 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2020 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2021 ExternalConstraints -> ExternalConstraints<'tcx>,
2022}
2023
2024macro_rules! slice_interners {
2025 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2026 impl<'tcx> TyCtxt<'tcx> {
2027 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2028 if v.is_empty() {
2029 List::empty()
2030 } else {
2031 self.interners.$field.intern_ref(v, || {
2032 InternedInSet(List::from_arena(&*self.arena, (), v))
2033 }).0
2034 }
2035 })+
2036 }
2037 );
2038}
2039
2040impl<'tcx> TyCtxt<'tcx> {
pub fn mk_const_list(self, v: &[Const<'tcx>]) -> &'tcx List<Const<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.const_lists.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_args(self, v: &[GenericArg<'tcx>])
-> &'tcx List<GenericArg<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.args.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.type_lists.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_canonical_var_kinds(self, v: &[CanonicalVarKind<'tcx>])
-> &'tcx List<CanonicalVarKind<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.canonical_var_kinds.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_poly_existential_predicates(self,
v: &[PolyExistentialPredicate<'tcx>])
-> &'tcx List<PolyExistentialPredicate<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.poly_existential_predicates.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_projs(self, v: &[ProjectionKind])
-> &'tcx List<ProjectionKind> {
if v.is_empty() {
List::empty()
} else {
self.interners.projs.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_place_elems(self, v: &[PlaceElem<'tcx>])
-> &'tcx List<PlaceElem<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.place_elems.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_bound_variable_kinds(self, v: &[ty::BoundVariableKind<'tcx>])
-> &'tcx List<ty::BoundVariableKind<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.bound_variable_kinds.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_fields(self, v: &[FieldIdx]) -> &'tcx List<FieldIdx> {
if v.is_empty() {
List::empty()
} else {
self.interners.fields.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_local_def_ids(self, v: &[LocalDefId])
-> &'tcx List<LocalDefId> {
if v.is_empty() {
List::empty()
} else {
self.interners.local_def_ids.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_captures(self, v: &[&'tcx ty::CapturedPlace<'tcx>])
-> &'tcx List<&'tcx ty::CapturedPlace<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.captures.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_patterns(self, v: &[Pattern<'tcx>])
-> &'tcx List<Pattern<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.patterns.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_outlives(self, v: &[ty::ArgOutlivesPredicate<'tcx>])
-> &'tcx List<ty::ArgOutlivesPredicate<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.outlives.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_predefined_opaques_in_body(self,
v: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)])
-> &'tcx List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
if v.is_empty() {
List::empty()
} else {
self.interners.predefined_opaques_in_body.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
}slice_interners!(
2044 const_lists: pub mk_const_list(Const<'tcx>),
2045 args: pub mk_args(GenericArg<'tcx>),
2046 type_lists: pub mk_type_list(Ty<'tcx>),
2047 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2048 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2049 projs: pub mk_projs(ProjectionKind),
2050 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2051 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2052 fields: pub mk_fields(FieldIdx),
2053 local_def_ids: intern_local_def_ids(LocalDefId),
2054 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2055 patterns: pub mk_patterns(Pattern<'tcx>),
2056 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2057 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2058);
2059
2060impl<'tcx> TyCtxt<'tcx> {
2061 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2065 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2066 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2067 }
2068
2069 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2073 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2074 sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig })
2075 }
2076
2077 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2080 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2081 self.associated_items(trait_did)
2082 .filter_by_name_unhygienic(assoc_name.name)
2083 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2084 })
2085 }
2086
2087 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2089 let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *ty.kind() else { return false };
2090 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2091
2092 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2093 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2094 return false;
2095 };
2096 trait_predicate.trait_ref.def_id == future_trait
2097 && trait_predicate.polarity == PredicatePolarity::Positive
2098 })
2099 }
2100
2101 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2109 sig.map_bound(|s| {
2110 let params = match s.inputs()[0].kind() {
2111 ty::Tuple(params) => *params,
2112 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2113 };
2114 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2115 })
2116 }
2117
2118 #[inline]
2119 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2120 self.interners.intern_predicate(
2121 binder,
2122 self.sess,
2123 &self.untracked,
2125 )
2126 }
2127
2128 #[inline]
2129 pub fn reuse_or_mk_predicate(
2130 self,
2131 pred: Predicate<'tcx>,
2132 binder: Binder<'tcx, PredicateKind<'tcx>>,
2133 ) -> Predicate<'tcx> {
2134 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2135 }
2136
2137 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2138 self.check_args_compatible_inner(def_id, args, false)
2139 }
2140
2141 fn check_args_compatible_inner(
2142 self,
2143 def_id: DefId,
2144 args: &'tcx [ty::GenericArg<'tcx>],
2145 nested: bool,
2146 ) -> bool {
2147 let generics = self.generics_of(def_id);
2148
2149 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)
2153 && #[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 });
2154 let is_inherent_assoc_type_const = #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocConst => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocConst)
2155 && #[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 })
2156 && self.is_type_const(def_id);
2157 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2158 if generics.own_params.len() + 1 != args.len() {
2159 return false;
2160 }
2161
2162 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2163 return false;
2164 }
2165
2166 &args[1..]
2167 } else {
2168 if generics.count() != args.len() {
2169 return false;
2170 }
2171
2172 let (parent_args, own_args) = args.split_at(generics.parent_count);
2173
2174 if let Some(parent) = generics.parent
2175 && !self.check_args_compatible_inner(parent, parent_args, true)
2176 {
2177 return false;
2178 }
2179
2180 own_args
2181 };
2182
2183 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2184 match (¶m.kind, arg.kind()) {
2185 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2186 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2187 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2188 _ => return false,
2189 }
2190 }
2191
2192 true
2193 }
2194
2195 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2198 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2199 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)
2200 && #[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 });
2201 let is_inherent_assoc_type_const = #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocConst => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocConst)
2202 && #[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 })
2203 && self.is_type_const(def_id);
2204 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2205 crate::util::bug::bug_fmt(format_args!("args not compatible with generics for {0}: args={1:#?}, generics={2:#?}",
self.def_path_str(def_id), args,
self.mk_args_from_iter([self.types.self_param.into()].into_iter().chain(self.generics_of(def_id).own_args(ty::GenericArgs::identity_for_item(self,
def_id)).iter().copied()))));bug!(
2206 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2207 self.def_path_str(def_id),
2208 args,
2209 self.mk_args_from_iter(
2211 [self.types.self_param.into()].into_iter().chain(
2212 self.generics_of(def_id)
2213 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2214 .iter()
2215 .copied()
2216 )
2217 )
2218 );
2219 } else {
2220 crate::util::bug::bug_fmt(format_args!("args not compatible with generics for {0}: args={1:#?}, generics={2:#?}",
self.def_path_str(def_id), args,
ty::GenericArgs::identity_for_item(self, def_id)));bug!(
2221 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2222 self.def_path_str(def_id),
2223 args,
2224 ty::GenericArgs::identity_for_item(self, def_id)
2225 );
2226 }
2227 }
2228 }
2229
2230 #[inline(always)]
2231 pub(crate) fn check_and_mk_args(
2232 self,
2233 def_id: DefId,
2234 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2235 ) -> GenericArgsRef<'tcx> {
2236 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2237 self.debug_assert_args_compatible(def_id, args);
2238 args
2239 }
2240
2241 #[inline]
2242 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2243 self.interners.intern_const(
2244 kind,
2245 self.sess,
2246 &self.untracked,
2248 )
2249 }
2250
2251 #[allow(rustc::usage_of_ty_tykind)]
2253 #[inline]
2254 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2255 self.interners.intern_ty(
2256 st,
2257 self.sess,
2258 &self.untracked,
2260 )
2261 }
2262
2263 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2264 match param.kind {
2265 GenericParamDefKind::Lifetime => {
2266 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2267 }
2268 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2269 GenericParamDefKind::Const { .. } => {
2270 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2271 .into()
2272 }
2273 }
2274 }
2275
2276 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2277 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2278 }
2279
2280 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2281 self.mk_place_elem(place, PlaceElem::Deref)
2282 }
2283
2284 pub fn mk_place_downcast(
2285 self,
2286 place: Place<'tcx>,
2287 adt_def: AdtDef<'tcx>,
2288 variant_index: VariantIdx,
2289 ) -> Place<'tcx> {
2290 self.mk_place_elem(
2291 place,
2292 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2293 )
2294 }
2295
2296 pub fn mk_place_downcast_unnamed(
2297 self,
2298 place: Place<'tcx>,
2299 variant_index: VariantIdx,
2300 ) -> Place<'tcx> {
2301 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2302 }
2303
2304 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2305 self.mk_place_elem(place, PlaceElem::Index(index))
2306 }
2307
2308 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2312 let mut projection = place.projection.to_vec();
2313 projection.push(elem);
2314
2315 Place { local: place.local, projection: self.mk_place_elems(&projection) }
2316 }
2317
2318 pub fn mk_poly_existential_predicates(
2319 self,
2320 eps: &[PolyExistentialPredicate<'tcx>],
2321 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2322 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2323 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!(
2324 eps.array_windows()
2325 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2326 != Ordering::Greater)
2327 );
2328 self.intern_poly_existential_predicates(eps)
2329 }
2330
2331 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2332 self.interners.intern_clauses(clauses)
2336 }
2337
2338 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2339 self.intern_local_def_ids(def_ids)
2343 }
2344
2345 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2346 where
2347 I: Iterator<Item = T>,
2348 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2349 {
2350 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2351 }
2352
2353 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2354 where
2355 I: Iterator<Item = T>,
2356 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2357 {
2358 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2359 }
2360
2361 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2362 where
2363 I: Iterator<Item = T>,
2364 T: CollectAndApply<
2365 &'tcx ty::CapturedPlace<'tcx>,
2366 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2367 >,
2368 {
2369 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2370 }
2371
2372 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2373 where
2374 I: Iterator<Item = T>,
2375 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2376 {
2377 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2378 }
2379
2380 pub fn mk_fn_sig<I, T>(
2385 self,
2386 inputs: I,
2387 output: I::Item,
2388 c_variadic: bool,
2389 safety: hir::Safety,
2390 abi: ExternAbi,
2391 ) -> T::Output
2392 where
2393 I: IntoIterator<Item = T>,
2394 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2395 {
2396 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2397 inputs_and_output: self.mk_type_list(xs),
2398 c_variadic,
2399 safety,
2400 abi,
2401 })
2402 }
2403
2404 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2405 where
2406 I: Iterator<Item = T>,
2407 T: CollectAndApply<
2408 PolyExistentialPredicate<'tcx>,
2409 &'tcx List<PolyExistentialPredicate<'tcx>>,
2410 >,
2411 {
2412 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2413 }
2414
2415 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2416 where
2417 I: Iterator<Item = T>,
2418 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2419 {
2420 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2421 }
2422
2423 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2424 where
2425 I: Iterator<Item = T>,
2426 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2427 {
2428 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2429 }
2430
2431 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2432 where
2433 I: Iterator<Item = T>,
2434 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2435 {
2436 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2437 }
2438
2439 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2440 where
2441 I: Iterator<Item = T>,
2442 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2443 {
2444 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2445 }
2446
2447 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2448 where
2449 I: Iterator<Item = T>,
2450 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2451 {
2452 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2453 }
2454
2455 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2456 where
2457 I: Iterator<Item = T>,
2458 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2459 {
2460 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2461 }
2462
2463 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2464 where
2465 I: Iterator<Item = T>,
2466 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2467 {
2468 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2469 }
2470
2471 pub fn mk_args_trait(
2472 self,
2473 self_ty: Ty<'tcx>,
2474 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2475 ) -> GenericArgsRef<'tcx> {
2476 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2477 }
2478
2479 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2480 where
2481 I: Iterator<Item = T>,
2482 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2483 {
2484 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2485 }
2486
2487 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2488 where
2489 I: Iterator<Item = T>,
2490 T: CollectAndApply<
2491 ty::ArgOutlivesPredicate<'tcx>,
2492 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2493 >,
2494 {
2495 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2496 }
2497
2498 #[track_caller]
2501 pub fn emit_node_span_lint(
2502 self,
2503 lint: &'static Lint,
2504 hir_id: HirId,
2505 span: impl Into<MultiSpan>,
2506 decorator: impl for<'a> Diagnostic<'a, ()>,
2507 ) {
2508 let level = self.lint_level_at_node(lint, hir_id);
2509 diag_lint_level(self.sess, lint, level, Some(span.into()), decorator)
2510 }
2511
2512 #[track_caller]
2516 pub fn node_span_lint(
2517 self,
2518 lint: &'static Lint,
2519 hir_id: HirId,
2520 span: impl Into<MultiSpan>,
2521 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
2522 ) {
2523 let level = self.lint_level_at_node(lint, hir_id);
2524 lint_level(self.sess, lint, level, Some(span.into()), decorate);
2525 }
2526
2527 pub fn crate_level_attribute_injection_span(self) -> Span {
2529 let node = self.hir_node(hir::CRATE_HIR_ID);
2530 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2531 m.spans.inject_use_span.shrink_to_lo()
2532 }
2533
2534 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2535 self,
2536 diag: &mut Diag<'_, E>,
2537 features: impl IntoIterator<Item = (String, Symbol)>,
2538 ) {
2539 if !self.sess.is_nightly_build() {
2540 return;
2541 }
2542
2543 let span = self.crate_level_attribute_injection_span();
2544 for (desc, feature) in features {
2545 let msg =
2547 ::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}");
2548 diag.span_suggestion_verbose(
2549 span,
2550 msg,
2551 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2552 Applicability::MaybeIncorrect,
2553 );
2554 }
2555 }
2556
2557 #[track_caller]
2560 pub fn emit_node_lint(
2561 self,
2562 lint: &'static Lint,
2563 id: HirId,
2564 decorator: impl for<'a> Diagnostic<'a, ()>,
2565 ) {
2566 let level = self.lint_level_at_node(lint, id);
2567 diag_lint_level(self.sess, lint, level, None, decorator);
2568 }
2569
2570 #[track_caller]
2574 pub fn node_lint(
2575 self,
2576 lint: &'static Lint,
2577 id: HirId,
2578 decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
2579 ) {
2580 let level = self.lint_level_at_node(lint, id);
2581 lint_level(self.sess, lint, level, None, decorate);
2582 }
2583
2584 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
2585 let map = self.in_scope_traits_map(id.owner)?;
2586 let candidates = map.get(&id.local_id)?;
2587 Some(candidates)
2588 }
2589
2590 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2591 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/context.rs:2591",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(2591u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&["message", "id"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("named_region")
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&id) as
&dyn Value))])
});
} else { ; }
};debug!(?id, "named_region");
2592 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2593 }
2594
2595 pub fn is_late_bound(self, id: HirId) -> bool {
2596 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2597 }
2598
2599 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2600 self.mk_bound_variable_kinds(
2601 &self
2602 .late_bound_vars_map(id.owner)
2603 .get(&id.local_id)
2604 .cloned()
2605 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("No bound vars found for {0}",
self.hir_id_to_string(id)))bug!("No bound vars found for {}", self.hir_id_to_string(id))),
2606 )
2607 }
2608
2609 pub fn map_opaque_lifetime_to_parent_lifetime(
2617 self,
2618 mut opaque_lifetime_param_def_id: LocalDefId,
2619 ) -> ty::Region<'tcx> {
2620 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!(
2621 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2622 "{opaque_lifetime_param_def_id:?} is a {}",
2623 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2624 );
2625
2626 loop {
2627 let parent = self.local_parent(opaque_lifetime_param_def_id);
2628 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2629
2630 let Some((lifetime, _)) = lifetime_mapping
2631 .iter()
2632 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2633 else {
2634 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2635 };
2636
2637 match *lifetime {
2638 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2639 let new_parent = self.local_parent(ebv);
2640
2641 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2644 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);
2645 opaque_lifetime_param_def_id = ebv;
2646 continue;
2647 }
2648
2649 let generics = self.generics_of(new_parent);
2650 return ty::Region::new_early_param(
2651 self,
2652 ty::EarlyParamRegion {
2653 index: generics
2654 .param_def_id_to_index(self, ebv.to_def_id())
2655 .expect("early-bound var should be present in fn generics"),
2656 name: self.item_name(ebv.to_def_id()),
2657 },
2658 );
2659 }
2660 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2661 let new_parent = self.local_parent(lbv);
2662 return ty::Region::new_late_param(
2663 self,
2664 new_parent.to_def_id(),
2665 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2666 );
2667 }
2668 resolve_bound_vars::ResolvedArg::Error(guar) => {
2669 return ty::Region::new_error(self, guar);
2670 }
2671 _ => {
2672 return ty::Region::new_error_with_message(
2673 self,
2674 self.def_span(opaque_lifetime_param_def_id),
2675 "cannot resolve lifetime",
2676 );
2677 }
2678 }
2679 }
2680 }
2681
2682 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2687 self.is_const_fn(def_id)
2688 && match self.lookup_const_stability(def_id) {
2689 None => true, Some(stability) if stability.is_const_stable() => true,
2691 _ => false,
2692 }
2693 }
2694
2695 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2697 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2698 && self.impl_trait_header(def_id).constness == hir::Constness::Const
2699 }
2700
2701 pub fn is_sdylib_interface_build(self) -> bool {
2702 self.sess.opts.unstable_opts.build_sdylib_interface
2703 }
2704
2705 pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
2706 match self.def_kind(def_id) {
2707 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2708 _ => None,
2709 }
2710 }
2711
2712 pub fn next_trait_solver_globally(self) -> bool {
2713 self.sess.opts.unstable_opts.next_solver.globally
2714 }
2715
2716 pub fn next_trait_solver_in_coherence(self) -> bool {
2717 self.sess.opts.unstable_opts.next_solver.coherence
2718 }
2719
2720 #[allow(rustc::bad_opt_access)]
2721 pub fn use_typing_mode_borrowck(self) -> bool {
2722 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
2723 }
2724
2725 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2726 self.opt_rpitit_info(def_id).is_some()
2727 }
2728
2729 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2739 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2740 }
2741
2742 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2744 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2745 }
2746
2747 pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
2748 self.resolver_for_lowering_raw(()).0
2749 }
2750
2751 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2752 make_metadata(self)
2753 }
2754
2755 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2756 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2757 self.coroutine_kind(def_id)
2758 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
2759 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2760 {
2761 true
2762 } else {
2763 false
2764 }
2765 }
2766
2767 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2769 {
#[allow(deprecated)]
{
{
'done:
{
for i in self.get_all_attrs(def_id) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(DoNotRecommend { .. }) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}
}.is_some()find_attr!(self, def_id, DoNotRecommend { .. })
2770 }
2771
2772 pub fn is_trivial_const<P>(self, def_id: P) -> bool
2773 where
2774 P: IntoQueryParam<DefId>,
2775 {
2776 self.trivial_const(def_id).is_some()
2777 }
2778
2779 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2782 if self.is_lang_item(def_id, LangItem::Start) {
2783 return true;
2784 }
2785 if let Some((entry_def_id, _)) = self.entry_fn(())
2786 && entry_def_id == def_id
2787 {
2788 return true;
2789 }
2790 false
2791 }
2792}
2793
2794pub fn provide(providers: &mut Providers) {
2795 providers.is_panic_runtime = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(PanicRuntime) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, PanicRuntime);
2796 providers.is_compiler_builtins = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(CompilerBuiltins) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, CompilerBuiltins);
2797 providers.has_panic_handler = |tcx, LocalCrate| {
2798 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2800 };
2801 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2802}