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