1#![allow(rustc::usage_of_ty_tykind)]
4
5mod impl_interner;
6pub mod tls;
7
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::{PhantomData, PointeeSized};
14use std::ops::{Bound, Deref};
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::fingerprint::Fingerprint;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::jobserver::Proxy;
25use rustc_data_structures::profiling::SelfProfilerRef;
26use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
27use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
28use rustc_data_structures::steal::Steal;
29use rustc_data_structures::sync::{
30 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
31};
32use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
33use rustc_hir::def::DefKind;
34use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
35use rustc_hir::definitions::{DefPathData, Definitions, Disambiguator};
36use rustc_hir::intravisit::VisitorExt;
37use rustc_hir::lang_items::LangItem;
38use rustc_hir::limit::Limit;
39use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, MaybeOwner, Node, TraitCandidate, find_attr};
40use rustc_index::IndexVec;
41use rustc_macros::Diagnostic;
42use rustc_session::Session;
43use rustc_session::config::CrateType;
44use rustc_session::cstore::{CrateStoreDyn, Untracked};
45use rustc_session::lint::Lint;
46use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
47use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
48use rustc_type_ir::TyKind::*;
49pub use rustc_type_ir::lift::Lift;
50use rustc_type_ir::{CollectAndApply, TypeFlags, WithCachedTypeInfo, elaborate, search_graph};
51use tracing::{debug, instrument};
52
53use crate::arena::Arena;
54use crate::dep_graph::dep_node::make_metadata;
55use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
56use crate::ich::StableHashingContext;
57use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
58use crate::lint::emit_lint_base;
59use crate::metadata::ModChild;
60use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
61use crate::middle::resolve_bound_vars;
62use crate::mir::interpret::{self, Allocation, ConstAllocation};
63use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
64use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
65use crate::thir::Thir;
66use crate::traits;
67use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
68use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
69use crate::ty::{
70 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
71 GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, Pattern,
72 PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity,
73 Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, ValTree, ValTreeKind,
74 Visibility,
75};
76
77impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
78 fn is_local(self) -> bool {
79 self.is_local()
80 }
81
82 fn as_local(self) -> Option<LocalDefId> {
83 self.as_local()
84 }
85}
86
87impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
88 fn rust() -> Self {
89 ExternAbi::Rust
90 }
91
92 fn is_rust(self) -> bool {
93 #[allow(non_exhaustive_omitted_patterns)] match self {
ExternAbi::Rust => true,
_ => false,
}matches!(self, ExternAbi::Rust)
94 }
95}
96
97impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
98 fn safe() -> Self {
99 hir::Safety::Safe
100 }
101
102 fn is_safe(self) -> bool {
103 self.is_safe()
104 }
105
106 fn prefix_str(self) -> &'static str {
107 self.prefix_str()
108 }
109}
110
111impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
112 fn generic_const_exprs(self) -> bool {
113 self.generic_const_exprs()
114 }
115
116 fn coroutine_clone(self) -> bool {
117 self.coroutine_clone()
118 }
119
120 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
121 !self.staged_api() && self.enabled(symbol)
125 }
126}
127
128impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
129 fn dummy() -> Self {
130 DUMMY_SP
131 }
132}
133
134type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
135
136pub struct CtxtInterners<'tcx> {
137 arena: &'tcx WorkerLocal<Arena<'tcx>>,
139
140 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
143 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
144 args: InternedSet<'tcx, GenericArgs<'tcx>>,
145 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
146 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
147 region: InternedSet<'tcx, RegionKind<'tcx>>,
148 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
149 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
150 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
151 projs: InternedSet<'tcx, List<ProjectionKind>>,
152 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
153 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
154 pat: InternedSet<'tcx, PatternKind<'tcx>>,
155 const_allocation: InternedSet<'tcx, Allocation>,
156 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
157 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
158 adt_def: InternedSet<'tcx, AdtDefData>,
159 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
160 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
161 fields: InternedSet<'tcx, List<FieldIdx>>,
162 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
163 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
164 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
165 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
166 outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
167}
168
169impl<'tcx> CtxtInterners<'tcx> {
170 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
171 const N: usize = 2048;
174 CtxtInterners {
175 arena,
176 type_: InternedSet::with_capacity(N * 16),
180 const_lists: InternedSet::with_capacity(N * 4),
181 args: InternedSet::with_capacity(N * 4),
182 type_lists: InternedSet::with_capacity(N * 4),
183 region: InternedSet::with_capacity(N * 4),
184 poly_existential_predicates: InternedSet::with_capacity(N / 4),
185 canonical_var_kinds: InternedSet::with_capacity(N / 2),
186 predicate: InternedSet::with_capacity(N),
187 clauses: InternedSet::with_capacity(N),
188 projs: InternedSet::with_capacity(N * 4),
189 place_elems: InternedSet::with_capacity(N * 2),
190 const_: InternedSet::with_capacity(N * 2),
191 pat: InternedSet::with_capacity(N),
192 const_allocation: InternedSet::with_capacity(N),
193 bound_variable_kinds: InternedSet::with_capacity(N * 2),
194 layout: InternedSet::with_capacity(N),
195 adt_def: InternedSet::with_capacity(N),
196 external_constraints: InternedSet::with_capacity(N),
197 predefined_opaques_in_body: InternedSet::with_capacity(N),
198 fields: InternedSet::with_capacity(N * 4),
199 local_def_ids: InternedSet::with_capacity(N),
200 captures: InternedSet::with_capacity(N),
201 valtree: InternedSet::with_capacity(N),
202 patterns: InternedSet::with_capacity(N),
203 outlives: InternedSet::with_capacity(N),
204 }
205 }
206
207 #[allow(rustc::usage_of_ty_tykind)]
209 #[inline(never)]
210 fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
211 Ty(Interned::new_unchecked(
212 self.type_
213 .intern(kind, |kind| {
214 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
215 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
216
217 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
218 internee: kind,
219 stable_hash,
220 flags: flags.flags,
221 outer_exclusive_binder: flags.outer_exclusive_binder,
222 }))
223 })
224 .0,
225 ))
226 }
227
228 #[allow(rustc::usage_of_ty_tykind)]
230 #[inline(never)]
231 fn intern_const(
232 &self,
233 kind: ty::ConstKind<'tcx>,
234 sess: &Session,
235 untracked: &Untracked,
236 ) -> Const<'tcx> {
237 Const(Interned::new_unchecked(
238 self.const_
239 .intern(kind, |kind: ty::ConstKind<'_>| {
240 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
241 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
242
243 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
244 internee: kind,
245 stable_hash,
246 flags: flags.flags,
247 outer_exclusive_binder: flags.outer_exclusive_binder,
248 }))
249 })
250 .0,
251 ))
252 }
253
254 fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
255 &self,
256 flags: &ty::FlagComputation<TyCtxt<'tcx>>,
257 sess: &'a Session,
258 untracked: &'a Untracked,
259 val: &T,
260 ) -> Fingerprint {
261 if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
264 Fingerprint::ZERO
265 } else {
266 let mut hasher = StableHasher::new();
267 let mut hcx = StableHashingContext::new(sess, untracked);
268 val.hash_stable(&mut hcx, &mut hasher);
269 hasher.finish()
270 }
271 }
272
273 #[inline(never)]
275 fn intern_predicate(
276 &self,
277 kind: Binder<'tcx, PredicateKind<'tcx>>,
278 sess: &Session,
279 untracked: &Untracked,
280 ) -> Predicate<'tcx> {
281 Predicate(Interned::new_unchecked(
282 self.predicate
283 .intern(kind, |kind| {
284 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
285
286 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
287
288 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
289 internee: kind,
290 stable_hash,
291 flags: flags.flags,
292 outer_exclusive_binder: flags.outer_exclusive_binder,
293 }))
294 })
295 .0,
296 ))
297 }
298
299 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
300 if clauses.is_empty() {
301 ListWithCachedTypeInfo::empty()
302 } else {
303 self.clauses
304 .intern_ref(clauses, || {
305 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
306
307 InternedInSet(ListWithCachedTypeInfo::from_arena(
308 &*self.arena,
309 flags.into(),
310 clauses,
311 ))
312 })
313 .0
314 }
315 }
316}
317
318const NUM_PREINTERNED_TY_VARS: u32 = 100;
323const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
324const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
325const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
326const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
327
328const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
337
338const NUM_PREINTERNED_RE_VARS: u32 = 500;
340const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
341const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
342
343pub struct CommonTypes<'tcx> {
344 pub unit: Ty<'tcx>,
345 pub bool: Ty<'tcx>,
346 pub char: Ty<'tcx>,
347 pub isize: Ty<'tcx>,
348 pub i8: Ty<'tcx>,
349 pub i16: Ty<'tcx>,
350 pub i32: Ty<'tcx>,
351 pub i64: Ty<'tcx>,
352 pub i128: Ty<'tcx>,
353 pub usize: Ty<'tcx>,
354 pub u8: Ty<'tcx>,
355 pub u16: Ty<'tcx>,
356 pub u32: Ty<'tcx>,
357 pub u64: Ty<'tcx>,
358 pub u128: Ty<'tcx>,
359 pub f16: Ty<'tcx>,
360 pub f32: Ty<'tcx>,
361 pub f64: Ty<'tcx>,
362 pub f128: Ty<'tcx>,
363 pub str_: Ty<'tcx>,
364 pub never: Ty<'tcx>,
365 pub self_param: Ty<'tcx>,
366
367 pub trait_object_dummy_self: Ty<'tcx>,
372
373 pub ty_vars: Vec<Ty<'tcx>>,
375
376 pub fresh_tys: Vec<Ty<'tcx>>,
378
379 pub fresh_int_tys: Vec<Ty<'tcx>>,
381
382 pub fresh_float_tys: Vec<Ty<'tcx>>,
384
385 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
389
390 pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
394}
395
396pub struct CommonLifetimes<'tcx> {
397 pub re_static: Region<'tcx>,
399
400 pub re_erased: Region<'tcx>,
402
403 pub re_vars: Vec<Region<'tcx>>,
405
406 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
410
411 pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
415}
416
417pub struct CommonConsts<'tcx> {
418 pub unit: Const<'tcx>,
419 pub true_: Const<'tcx>,
420 pub false_: Const<'tcx>,
421 pub(crate) valtree_zst: ValTree<'tcx>,
423}
424
425impl<'tcx> CommonTypes<'tcx> {
426 fn new(
427 interners: &CtxtInterners<'tcx>,
428 sess: &Session,
429 untracked: &Untracked,
430 ) -> CommonTypes<'tcx> {
431 let mk = |ty| interners.intern_ty(ty, sess, untracked);
432
433 let ty_vars =
434 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
435 let fresh_tys: Vec<_> =
436 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
437 let fresh_int_tys: Vec<_> =
438 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
439 let fresh_float_tys: Vec<_> =
440 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
441
442 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
443 .map(|i| {
444 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
445 .map(|v| {
446 mk(ty::Bound(
447 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
448 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
449 ))
450 })
451 .collect()
452 })
453 .collect();
454
455 let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
456 .map(|v| {
457 mk(ty::Bound(
458 ty::BoundVarIndexKind::Canonical,
459 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
460 ))
461 })
462 .collect();
463
464 CommonTypes {
465 unit: mk(Tuple(List::empty())),
466 bool: mk(Bool),
467 char: mk(Char),
468 never: mk(Never),
469 isize: mk(Int(ty::IntTy::Isize)),
470 i8: mk(Int(ty::IntTy::I8)),
471 i16: mk(Int(ty::IntTy::I16)),
472 i32: mk(Int(ty::IntTy::I32)),
473 i64: mk(Int(ty::IntTy::I64)),
474 i128: mk(Int(ty::IntTy::I128)),
475 usize: mk(Uint(ty::UintTy::Usize)),
476 u8: mk(Uint(ty::UintTy::U8)),
477 u16: mk(Uint(ty::UintTy::U16)),
478 u32: mk(Uint(ty::UintTy::U32)),
479 u64: mk(Uint(ty::UintTy::U64)),
480 u128: mk(Uint(ty::UintTy::U128)),
481 f16: mk(Float(ty::FloatTy::F16)),
482 f32: mk(Float(ty::FloatTy::F32)),
483 f64: mk(Float(ty::FloatTy::F64)),
484 f128: mk(Float(ty::FloatTy::F128)),
485 str_: mk(Str),
486 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
487
488 trait_object_dummy_self: fresh_tys[0],
489
490 ty_vars,
491 fresh_tys,
492 fresh_int_tys,
493 fresh_float_tys,
494 anon_bound_tys,
495 anon_canonical_bound_tys,
496 }
497 }
498}
499
500impl<'tcx> CommonLifetimes<'tcx> {
501 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
502 let mk = |r| {
503 Region(Interned::new_unchecked(
504 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
505 ))
506 };
507
508 let re_vars =
509 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
510
511 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
512 .map(|i| {
513 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
514 .map(|v| {
515 mk(ty::ReBound(
516 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
517 ty::BoundRegion {
518 var: ty::BoundVar::from(v),
519 kind: ty::BoundRegionKind::Anon,
520 },
521 ))
522 })
523 .collect()
524 })
525 .collect();
526
527 let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
528 .map(|v| {
529 mk(ty::ReBound(
530 ty::BoundVarIndexKind::Canonical,
531 ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
532 ))
533 })
534 .collect();
535
536 CommonLifetimes {
537 re_static: mk(ty::ReStatic),
538 re_erased: mk(ty::ReErased),
539 re_vars,
540 anon_re_bounds,
541 anon_re_canonical_bounds,
542 }
543 }
544}
545
546impl<'tcx> CommonConsts<'tcx> {
547 fn new(
548 interners: &CtxtInterners<'tcx>,
549 types: &CommonTypes<'tcx>,
550 sess: &Session,
551 untracked: &Untracked,
552 ) -> CommonConsts<'tcx> {
553 let mk_const = |c| {
554 interners.intern_const(
555 c, sess, untracked,
557 )
558 };
559
560 let mk_valtree = |v| {
561 ty::ValTree(Interned::new_unchecked(
562 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
563 ))
564 };
565
566 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
567 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
568 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
569
570 CommonConsts {
571 unit: mk_const(ty::ConstKind::Value(ty::Value {
572 ty: types.unit,
573 valtree: valtree_zst,
574 })),
575 true_: mk_const(ty::ConstKind::Value(ty::Value {
576 ty: types.bool,
577 valtree: valtree_true,
578 })),
579 false_: mk_const(ty::ConstKind::Value(ty::Value {
580 ty: types.bool,
581 valtree: valtree_false,
582 })),
583 valtree_zst,
584 }
585 }
586}
587
588#[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)]
591pub struct FreeRegionInfo {
592 pub scope: LocalDefId,
594 pub region_def_id: DefId,
596 pub is_impl_item: bool,
598}
599
600#[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)]
602pub struct TyCtxtFeed<'tcx, KEY: Copy> {
603 pub tcx: TyCtxt<'tcx>,
604 key: KEY,
606}
607
608impl<KEY: Copy, Hcx> !HashStable<Hcx> for TyCtxtFeed<'_, KEY> {}
611
612#[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)]
617pub struct Feed<'tcx, KEY: Copy> {
618 _tcx: PhantomData<TyCtxt<'tcx>>,
619 key: KEY,
621}
622
623impl<KEY: Copy, Hcx> !HashStable<Hcx> for Feed<'_, KEY> {}
626
627impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
628 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
629 self.key.fmt(f)
630 }
631}
632
633impl<'tcx> TyCtxt<'tcx> {
638 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
641 self.dep_graph.assert_ignored();
642 TyCtxtFeed { tcx: self, key: () }
643 }
644
645 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
648 let key = self.untracked().source_span.push(span);
649 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);
650 TyCtxtFeed { tcx: self, key }
651 }
652
653 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
657 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);
658 TyCtxtFeed { tcx: self, key }.type_of(value)
659 }
660
661 pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) {
663 TyCtxtFeed { tcx: self, key }.delayed_owner(owner);
664 }
665}
666
667impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
668 #[inline(always)]
669 pub fn key(&self) -> KEY {
670 self.key
671 }
672
673 #[inline(always)]
674 pub fn downgrade(self) -> Feed<'tcx, KEY> {
675 Feed { _tcx: PhantomData, key: self.key }
676 }
677}
678
679impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
680 #[inline(always)]
681 pub fn key(&self) -> KEY {
682 self.key
683 }
684
685 #[inline(always)]
686 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
687 TyCtxtFeed { tcx, key: self.key }
688 }
689}
690
691impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
692 #[inline(always)]
693 pub fn def_id(&self) -> LocalDefId {
694 self.key
695 }
696
697 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
699 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
700 }
701
702 pub fn feed_hir(&self) {
704 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
705
706 let node = hir::OwnerNode::Synthetic;
707 let bodies = Default::default();
708 let attrs = hir::AttributeMap::EMPTY;
709
710 let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
711 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque);
712 let node = node.into();
713 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
714 opt_hash_including_bodies,
715 nodes: IndexVec::from_elem_n(
716 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
717 1,
718 ),
719 bodies,
720 })));
721 self.feed_owner_id().hir_attr_map(attrs);
722 }
723}
724
725#[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)]
743#[rustc_diagnostic_item = "TyCtxt"]
744#[rustc_pass_by_value]
745pub struct TyCtxt<'tcx> {
746 gcx: &'tcx GlobalCtxt<'tcx>,
747}
748
749unsafe impl DynSend for TyCtxt<'_> {}
753unsafe impl DynSync for TyCtxt<'_> {}
754fn _assert_tcx_fields() {
755 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
756 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
757}
758
759impl<'tcx> Deref for TyCtxt<'tcx> {
760 type Target = &'tcx GlobalCtxt<'tcx>;
761 #[inline(always)]
762 fn deref(&self) -> &Self::Target {
763 &self.gcx
764 }
765}
766
767pub struct GlobalCtxt<'tcx> {
769 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
770 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
771
772 interners: CtxtInterners<'tcx>,
773
774 pub sess: &'tcx Session,
775 crate_types: Vec<CrateType>,
776 stable_crate_id: StableCrateId,
782
783 pub dep_graph: DepGraph,
784
785 pub prof: SelfProfilerRef,
786
787 pub types: CommonTypes<'tcx>,
789
790 pub lifetimes: CommonLifetimes<'tcx>,
792
793 pub consts: CommonConsts<'tcx>,
795
796 pub(crate) hooks: crate::hooks::Providers,
799
800 untracked: Untracked,
801
802 pub query_system: QuerySystem<'tcx>,
803 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
804
805 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
807
808 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
811
812 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
816
817 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
819 pub new_solver_canonical_param_env_cache:
820 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
821
822 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
823
824 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
826 pub clauses_cache:
828 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
829
830 pub data_layout: TargetDataLayout,
832
833 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
835
836 current_gcx: CurrentGcx,
837
838 pub jobserver_proxy: Arc<Proxy>,
840}
841
842impl<'tcx> GlobalCtxt<'tcx> {
843 pub fn enter<F, R>(&'tcx self, f: F) -> R
846 where
847 F: FnOnce(TyCtxt<'tcx>) -> R,
848 {
849 let icx = tls::ImplicitCtxt::new(self);
850
851 let _on_drop = defer(move || {
853 *self.current_gcx.value.write() = None;
854 });
855
856 {
858 let mut guard = self.current_gcx.value.write();
859 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
860 *guard = Some(self as *const _ as *const ());
861 }
862
863 tls::enter_context(&icx, || f(icx.tcx))
864 }
865}
866
867#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
874pub struct CurrentGcx {
875 value: Arc<RwLock<Option<*const ()>>>,
878}
879
880unsafe impl DynSend for CurrentGcx {}
881unsafe impl DynSync for CurrentGcx {}
882
883impl CurrentGcx {
884 pub fn new() -> Self {
885 Self { value: Arc::new(RwLock::new(None)) }
886 }
887
888 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
889 let read_guard = self.value.read();
890 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
891 f(unsafe { &*gcx })
895 }
896}
897
898impl<'tcx> TyCtxt<'tcx> {
899 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
900 let root = self.typeck_root_def_id_local(def_id);
903 self.hir_node_by_def_id(root).body_id().is_some()
904 }
905
906 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
911 let def_kind = self.def_kind(def_id);
912 if def_kind.has_codegen_attrs() {
913 self.codegen_fn_attrs(def_id)
914 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
DefKind::InlineConst | DefKind::GlobalAsm => true,
_ => false,
}matches!(
915 def_kind,
916 DefKind::AnonConst
917 | DefKind::AssocConst { .. }
918 | DefKind::Const { .. }
919 | DefKind::InlineConst
920 | DefKind::GlobalAsm
921 ) {
922 CodegenFnAttrs::EMPTY
923 } else {
924 crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind))bug!(
925 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
926 def_id,
927 def_kind
928 )
929 }
930 }
931
932 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
933 self.arena.alloc(Steal::new(thir))
934 }
935
936 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
937 self.arena.alloc(Steal::new(mir))
938 }
939
940 pub fn alloc_steal_promoted(
941 self,
942 promoted: IndexVec<Promoted, Body<'tcx>>,
943 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
944 self.arena.alloc(Steal::new(promoted))
945 }
946
947 pub fn mk_adt_def(
948 self,
949 did: DefId,
950 kind: AdtKind,
951 variants: IndexVec<VariantIdx, ty::VariantDef>,
952 repr: ReprOptions,
953 ) -> ty::AdtDef<'tcx> {
954 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
955 }
956
957 pub fn allocate_bytes_dedup<'a>(
960 self,
961 bytes: impl Into<Cow<'a, [u8]>>,
962 salt: usize,
963 ) -> interpret::AllocId {
964 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
966 let alloc = self.mk_const_alloc(alloc);
967 self.reserve_and_set_memory_dedup(alloc, salt)
968 }
969
970 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
972 if self.sess.opts.unstable_opts.experimental_default_bounds {
973 &[
974 LangItem::DefaultTrait1,
975 LangItem::DefaultTrait2,
976 LangItem::DefaultTrait3,
977 LangItem::DefaultTrait4,
978 ]
979 } else {
980 &[]
981 }
982 }
983
984 pub fn is_default_trait(self, def_id: DefId) -> bool {
985 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
986 }
987
988 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
989 #[allow(non_exhaustive_omitted_patterns)] match self.as_lang_item(def_id) {
Some(LangItem::Sized | LangItem::MetaSized) => true,
_ => false,
}matches!(self.as_lang_item(def_id), Some(LangItem::Sized | LangItem::MetaSized))
990 }
991
992 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
996 let start = {
{
'done:
{
for i in ::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcLayoutScalarValidRangeStart(n,
_)) => {
break 'done Some(Bound::Included(**n));
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}find_attr!(self, def_id, RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
997 let end =
998 {
{
'done:
{
for i in ::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcLayoutScalarValidRangeEnd(n,
_)) => {
break 'done Some(Bound::Included(**n));
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}find_attr!(self, def_id, RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n))
999 .unwrap_or(Bound::Unbounded);
1000 (start, end)
1001 }
1002
1003 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1004 value.lift_to_interner(self)
1005 }
1006
1007 pub fn create_global_ctxt<T>(
1014 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1015 s: &'tcx Session,
1016 crate_types: Vec<CrateType>,
1017 stable_crate_id: StableCrateId,
1018 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1019 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1020 untracked: Untracked,
1021 dep_graph: DepGraph,
1022 dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
1023 query_system: QuerySystem<'tcx>,
1024 hooks: crate::hooks::Providers,
1025 current_gcx: CurrentGcx,
1026 jobserver_proxy: Arc<Proxy>,
1027 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1028 ) -> T {
1029 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1030 s.dcx().emit_fatal(err);
1031 });
1032 let interners = CtxtInterners::new(arena);
1033 let common_types = CommonTypes::new(&interners, s, &untracked);
1034 let common_lifetimes = CommonLifetimes::new(&interners);
1035 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1036
1037 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1038 sess: s,
1039 crate_types,
1040 stable_crate_id,
1041 arena,
1042 hir_arena,
1043 interners,
1044 dep_graph,
1045 hooks,
1046 prof: s.prof.clone(),
1047 types: common_types,
1048 lifetimes: common_lifetimes,
1049 consts: common_consts,
1050 untracked,
1051 query_system,
1052 dep_kind_vtables,
1053 ty_rcache: Default::default(),
1054 selection_cache: Default::default(),
1055 evaluation_cache: Default::default(),
1056 new_solver_evaluation_cache: Default::default(),
1057 new_solver_canonical_param_env_cache: Default::default(),
1058 canonical_param_env_cache: Default::default(),
1059 highest_var_in_clauses_cache: Default::default(),
1060 clauses_cache: Default::default(),
1061 data_layout,
1062 alloc_map: interpret::AllocMap::new(),
1063 current_gcx,
1064 jobserver_proxy,
1065 });
1066
1067 gcx.enter(f)
1069 }
1070
1071 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1073 self.get_lang_items(())
1074 }
1075
1076 #[track_caller]
1078 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1079 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1080 self.type_of(ordering_enum).no_bound_vars().unwrap()
1081 }
1082
1083 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1086 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1087 }
1088
1089 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1091 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1092 }
1093
1094 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1096 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1097 }
1098
1099 pub fn is_coroutine(self, def_id: DefId) -> bool {
1100 self.coroutine_kind(def_id).is_some()
1101 }
1102
1103 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1104 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1105 }
1106
1107 pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1108 if !self.is_type_const(def_id) {
1109 return None;
1110 }
1111 Some(self.def_span(def_id))
1112 }
1113
1114 pub fn is_type_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1116 let def_id = def_id.into_query_key();
1117 match self.def_kind(def_id) {
1118 DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1119 is_type_const
1120 }
1121 _ => false,
1122 }
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 IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1172 let id = id.into_query_key();
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 caller_features = &self.body_codegen_attrs(caller).target_features;
1334 if self.is_target_feature_call_safe(&fun_features, &caller_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 impl Disambiguator,
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 impl Disambiguator,
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 #[inline]
1498 pub fn local_crate_exports_generics(self) -> bool {
1499 if self.is_compiler_builtins(LOCAL_CRATE) {
1503 return false;
1504 }
1505 self.crate_types().iter().any(|crate_type| {
1506 match crate_type {
1507 CrateType::Executable
1508 | CrateType::StaticLib
1509 | CrateType::ProcMacro
1510 | CrateType::Cdylib
1511 | CrateType::Sdylib => false,
1512
1513 CrateType::Dylib => true,
1518
1519 CrateType::Rlib => true,
1520 }
1521 })
1522 }
1523
1524 pub fn is_suitable_region(
1526 self,
1527 generic_param_scope: LocalDefId,
1528 mut region: Region<'tcx>,
1529 ) -> Option<FreeRegionInfo> {
1530 let (suitable_region_binding_scope, region_def_id) = loop {
1531 let def_id =
1532 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1533 let scope = self.local_parent(def_id);
1534 if self.def_kind(scope) == DefKind::OpaqueTy {
1535 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1538 continue;
1539 }
1540 break (scope, def_id.into());
1541 };
1542
1543 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1544 Node::Item(..) | Node::TraitItem(..) => false,
1545 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1546 hir::ImplItemImplKind::Trait { .. } => true,
1553 _ => false,
1554 },
1555 _ => false,
1556 };
1557
1558 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1559 }
1560
1561 pub fn return_type_impl_or_dyn_traits(
1563 self,
1564 scope_def_id: LocalDefId,
1565 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1566 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1567 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1568 self.hir_fn_decl_by_hir_id(hir_id)
1569 else {
1570 return ::alloc::vec::Vec::new()vec![];
1571 };
1572
1573 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1574 v.visit_ty_unambig(hir_output);
1575 v.0
1576 }
1577
1578 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1582 self,
1583 scope_def_id: LocalDefId,
1584 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1585 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1586 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1587 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1589 && let hir::TyKind::Path(hir::QPath::Resolved(
1590 None,
1591 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1592 && let Some(local_id) = def_id.as_local()
1593 && 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()
1595 {
1596 v.visit_ty_unambig(alias_ty);
1597 if !v.0.is_empty() {
1598 return Some((
1599 v.0,
1600 alias_generics.span,
1601 alias_generics.span_for_lifetime_suggestion(),
1602 ));
1603 }
1604 }
1605 None
1606 }
1607
1608 pub fn has_strict_asm_symbol_naming(self) -> bool {
1611 self.sess.target.llvm_target.starts_with("nvptx")
1612 }
1613
1614 pub fn caller_location_ty(self) -> Ty<'tcx> {
1616 Ty::new_imm_ref(
1617 self,
1618 self.lifetimes.re_static,
1619 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1620 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
1621 )
1622 }
1623
1624 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1626 let kind = self.def_kind(def_id);
1627 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1628 }
1629
1630 pub fn type_length_limit(self) -> Limit {
1631 self.limits(()).type_length_limit
1632 }
1633
1634 pub fn recursion_limit(self) -> Limit {
1635 self.limits(()).recursion_limit
1636 }
1637
1638 pub fn move_size_limit(self) -> Limit {
1639 self.limits(()).move_size_limit
1640 }
1641
1642 pub fn pattern_complexity_limit(self) -> Limit {
1643 self.limits(()).pattern_complexity_limit
1644 }
1645
1646 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1648 iter::once(LOCAL_CRATE)
1649 .chain(self.crates(()).iter().copied())
1650 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1651 }
1652
1653 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1655 let visible_crates =
1656 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1657
1658 iter::once(LOCAL_CRATE)
1659 .chain(visible_crates)
1660 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1661 }
1662
1663 #[inline]
1664 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1665 self.visibility(def_id).expect_local()
1666 }
1667
1668 x;#[instrument(skip(self), level = "trace", ret)]
1670 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1671 self.hir_expect_opaque_ty(def_id).origin
1672 }
1673
1674 pub fn finish(self) {
1675 self.alloc_self_profile_query_strings();
1678
1679 self.save_dep_graph();
1680 self.verify_query_key_hashes();
1681
1682 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1683 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
1684 }
1685 }
1686
1687 pub fn report_unused_features(self) {
1688 #[derive(const _: () =
{
impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for UnusedFeature
where G: rustc_errors::EmissionGuarantee {
#[track_caller]
fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
match self {
UnusedFeature { feature: __binding_0 } => {
let mut diag =
rustc_errors::Diag::new(dcx, level,
rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("feature `{$feature}` is declared but not used")));
;
diag.arg("feature", __binding_0);
diag
}
}
}
}
};Diagnostic)]
1689 #[diag("feature `{$feature}` is declared but not used")]
1690 struct UnusedFeature {
1691 feature: Symbol,
1692 }
1693
1694 let used_features = self.sess.used_features.lock();
1696 let unused_features = self
1697 .features()
1698 .enabled_features_iter_stable_order()
1699 .filter(|(f, _)| {
1700 !used_features.contains_key(f)
1701 && f.as_str() != "restricted_std"
1708 && *f != sym::doc_cfg
1712 })
1713 .collect::<Vec<_>>();
1714
1715 for (feature, span) in unused_features {
1716 self.emit_node_span_lint(
1717 rustc_session::lint::builtin::UNUSED_FEATURES,
1718 CRATE_HIR_ID,
1719 span,
1720 UnusedFeature { feature },
1721 );
1722 }
1723 }
1724}
1725
1726macro_rules! nop_lift {
1727 ($set:ident; $ty:ty => $lifted:ty) => {
1728 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1729 type Lifted = $lifted;
1730 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1731 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1736 _x: Interned<'tcx, Inner>,
1737 ) -> InternedSet<'tcx, Inner> {
1738 unreachable!()
1739 }
1740 fn _type_eq<T>(_x: &T, _y: &T) {}
1741 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1742 let interner = _intern_set_ty_from_interned_ty(x.0);
1746 _type_eq(&interner, &tcx.interners.$set);
1748 }
1749
1750 tcx.interners
1751 .$set
1752 .contains_pointer_to(&InternedInSet(&*self.0.0))
1753 .then(|| unsafe { mem::transmute(self) })
1756 }
1757 }
1758 };
1759}
1760
1761macro_rules! nop_list_lift {
1762 ($set:ident; $ty:ty => $lifted:ty) => {
1763 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
1764 type Lifted = &'tcx List<$lifted>;
1765 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1766 if false {
1768 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
1769 }
1770
1771 if self.is_empty() {
1772 return Some(List::empty());
1773 }
1774 tcx.interners
1775 .$set
1776 .contains_pointer_to(&InternedInSet(self))
1777 .then(|| unsafe { mem::transmute(self) })
1778 }
1779 }
1780 };
1781}
1782
1783impl<'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> }
1784impl<'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> }
1785impl<'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> }
1786impl<'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> }
1787impl<'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> }
1788impl<'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> }
1789impl<'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> }
1790impl<'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> }
1791impl<'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> }
1792
1793impl<'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> }
1794impl<'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! {
1795 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1796}
1797impl<'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> }
1798
1799impl<'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> }
1801
1802macro_rules! sty_debug_print {
1803 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1804 #[allow(non_snake_case)]
1807 mod inner {
1808 use crate::ty::{self, TyCtxt};
1809 use crate::ty::context::InternedInSet;
1810
1811 #[derive(Copy, Clone)]
1812 struct DebugStat {
1813 total: usize,
1814 lt_infer: usize,
1815 ty_infer: usize,
1816 ct_infer: usize,
1817 all_infer: usize,
1818 }
1819
1820 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1821 let mut total = DebugStat {
1822 total: 0,
1823 lt_infer: 0,
1824 ty_infer: 0,
1825 ct_infer: 0,
1826 all_infer: 0,
1827 };
1828 $(let mut $variant = total;)*
1829
1830 for shard in tcx.interners.type_.lock_shards() {
1831 #[allow(rustc::potential_query_instability)]
1833 let types = shard.iter();
1834 for &(InternedInSet(t), ()) in types {
1835 let variant = match t.internee {
1836 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1837 ty::Float(..) | ty::Str | ty::Never => continue,
1838 ty::Error(_) => continue,
1839 $(ty::$variant(..) => &mut $variant,)*
1840 };
1841 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1842 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1843 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1844
1845 variant.total += 1;
1846 total.total += 1;
1847 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1848 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1849 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1850 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1851 }
1852 }
1853 writeln!(fmt, "Ty interner total ty lt ct all")?;
1854 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1855 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1856 stringify!($variant),
1857 uses = $variant.total,
1858 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1859 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1860 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1861 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1862 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1863 )*
1864 writeln!(fmt, " total {uses:6} \
1865 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1866 uses = total.total,
1867 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1868 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1869 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1870 all = total.all_infer as f64 * 100.0 / total.total as f64)
1871 }
1872 }
1873
1874 inner::go($fmt, $ctxt)
1875 }}
1876}
1877
1878impl<'tcx> TyCtxt<'tcx> {
1879 pub fn debug_stats(self) -> impl fmt::Debug {
1880 fmt::from_fn(move |fmt| {
1881 {
#[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!(
1882 fmt,
1883 self,
1884 Adt,
1885 Array,
1886 Slice,
1887 RawPtr,
1888 Ref,
1889 FnDef,
1890 FnPtr,
1891 UnsafeBinder,
1892 Placeholder,
1893 Coroutine,
1894 CoroutineWitness,
1895 Dynamic,
1896 Closure,
1897 CoroutineClosure,
1898 Tuple,
1899 Bound,
1900 Param,
1901 Infer,
1902 Alias,
1903 Pat,
1904 Foreign
1905 )?;
1906
1907 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1908 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1909 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())?;
1910 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1911
1912 Ok(())
1913 })
1914 }
1915}
1916
1917struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1922
1923impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1924 fn clone(&self) -> Self {
1925 *self
1926 }
1927}
1928
1929impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1930
1931impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1932 fn into_pointer(&self) -> *const () {
1933 self.0 as *const _ as *const ()
1934 }
1935}
1936
1937#[allow(rustc::usage_of_ty_tykind)]
1938impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1939 fn borrow(&self) -> &T {
1940 &self.0.internee
1941 }
1942}
1943
1944impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1945 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1946 self.0.internee == other.0.internee
1949 }
1950}
1951
1952impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1953
1954impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1955 fn hash<H: Hasher>(&self, s: &mut H) {
1956 self.0.internee.hash(s)
1958 }
1959}
1960
1961impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1962 fn borrow(&self) -> &[T] {
1963 &self.0[..]
1964 }
1965}
1966
1967impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1968 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1969 self.0[..] == other.0[..]
1972 }
1973}
1974
1975impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1976
1977impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1978 fn hash<H: Hasher>(&self, s: &mut H) {
1979 self.0[..].hash(s)
1981 }
1982}
1983
1984impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1985 fn borrow(&self) -> &[T] {
1986 &self.0[..]
1987 }
1988}
1989
1990impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1991 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1992 self.0[..] == other.0[..]
1995 }
1996}
1997
1998impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1999
2000impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2001 fn hash<H: Hasher>(&self, s: &mut H) {
2002 self.0[..].hash(s)
2004 }
2005}
2006
2007macro_rules! direct_interners {
2008 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2009 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2010 fn borrow<'a>(&'a self) -> &'a $ty {
2011 &self.0
2012 }
2013 }
2014
2015 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2016 fn eq(&self, other: &Self) -> bool {
2017 self.0 == other.0
2020 }
2021 }
2022
2023 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2024
2025 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2026 fn hash<H: Hasher>(&self, s: &mut H) {
2027 self.0.hash(s)
2030 }
2031 }
2032
2033 impl<'tcx> TyCtxt<'tcx> {
2034 $vis fn $method(self, v: $ty) -> $ret_ty {
2035 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2036 InternedInSet(self.interners.arena.alloc(v))
2037 }).0))
2038 }
2039 })+
2040 }
2041}
2042
2043impl<'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! {
2047 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2048 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2049 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2050 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2051 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2052 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2053 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2054 ExternalConstraints -> ExternalConstraints<'tcx>,
2055}
2056
2057macro_rules! slice_interners {
2058 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2059 impl<'tcx> TyCtxt<'tcx> {
2060 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2061 if v.is_empty() {
2062 List::empty()
2063 } else {
2064 self.interners.$field.intern_ref(v, || {
2065 InternedInSet(List::from_arena(&*self.arena, (), v))
2066 }).0
2067 }
2068 })+
2069 }
2070 );
2071}
2072
2073impl<'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!(
2077 const_lists: pub mk_const_list(Const<'tcx>),
2078 args: pub mk_args(GenericArg<'tcx>),
2079 type_lists: pub mk_type_list(Ty<'tcx>),
2080 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2081 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2082 projs: pub mk_projs(ProjectionKind),
2083 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2084 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2085 fields: pub mk_fields(FieldIdx),
2086 local_def_ids: intern_local_def_ids(LocalDefId),
2087 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2088 patterns: pub mk_patterns(Pattern<'tcx>),
2089 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2090 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2091);
2092
2093impl<'tcx> TyCtxt<'tcx> {
2094 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2098 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2099 Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
2100 }
2101
2102 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2106 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2107 sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig })
2108 }
2109
2110 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2113 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2114 self.associated_items(trait_did)
2115 .filter_by_name_unhygienic(assoc_name.name)
2116 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2117 })
2118 }
2119
2120 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2122 let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2123 return false;
2124 };
2125 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2126
2127 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2128 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2129 return false;
2130 };
2131 trait_predicate.trait_ref.def_id == future_trait
2132 && trait_predicate.polarity == PredicatePolarity::Positive
2133 })
2134 }
2135
2136 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2144 sig.map_bound(|s| {
2145 let params = match s.inputs()[0].kind() {
2146 ty::Tuple(params) => *params,
2147 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2148 };
2149 self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust)
2150 })
2151 }
2152
2153 #[inline]
2154 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2155 self.interners.intern_predicate(
2156 binder,
2157 self.sess,
2158 &self.untracked,
2160 )
2161 }
2162
2163 #[inline]
2164 pub fn reuse_or_mk_predicate(
2165 self,
2166 pred: Predicate<'tcx>,
2167 binder: Binder<'tcx, PredicateKind<'tcx>>,
2168 ) -> Predicate<'tcx> {
2169 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2170 }
2171
2172 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2173 self.check_args_compatible_inner(def_id, args, false)
2174 }
2175
2176 fn check_args_compatible_inner(
2177 self,
2178 def_id: DefId,
2179 args: &'tcx [ty::GenericArg<'tcx>],
2180 nested: bool,
2181 ) -> bool {
2182 let generics = self.generics_of(def_id);
2183
2184 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)
2188 && #[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 });
2189 let is_inherent_assoc_type_const =
2190 #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocConst { is_type_const: true } => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocConst { is_type_const: true })
2191 && #[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 });
2192 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2193 if generics.own_params.len() + 1 != args.len() {
2194 return false;
2195 }
2196
2197 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2198 return false;
2199 }
2200
2201 &args[1..]
2202 } else {
2203 if generics.count() != args.len() {
2204 return false;
2205 }
2206
2207 let (parent_args, own_args) = args.split_at(generics.parent_count);
2208
2209 if let Some(parent) = generics.parent
2210 && !self.check_args_compatible_inner(parent, parent_args, true)
2211 {
2212 return false;
2213 }
2214
2215 own_args
2216 };
2217
2218 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2219 match (¶m.kind, arg.kind()) {
2220 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2221 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2222 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2223 _ => return false,
2224 }
2225 }
2226
2227 true
2228 }
2229
2230 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2233 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2234 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)
2235 && #[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 });
2236 let is_inherent_assoc_type_const =
2237 #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocConst { is_type_const: true } => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocConst { is_type_const: true })
2238 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(
2239 self.def_kind(self.parent(def_id)),
2240 DefKind::Impl { of_trait: false }
2241 );
2242 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2243 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!(
2244 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2245 self.def_path_str(def_id),
2246 args,
2247 self.mk_args_from_iter(
2249 [self.types.self_param.into()].into_iter().chain(
2250 self.generics_of(def_id)
2251 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2252 .iter()
2253 .copied()
2254 )
2255 )
2256 );
2257 } else {
2258 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!(
2259 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2260 self.def_path_str(def_id),
2261 args,
2262 ty::GenericArgs::identity_for_item(self, def_id)
2263 );
2264 }
2265 }
2266 }
2267
2268 #[inline(always)]
2269 pub(crate) fn check_and_mk_args(
2270 self,
2271 def_id: DefId,
2272 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2273 ) -> GenericArgsRef<'tcx> {
2274 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2275 self.debug_assert_args_compatible(def_id, args);
2276 args
2277 }
2278
2279 #[inline]
2280 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2281 self.interners.intern_const(
2282 kind,
2283 self.sess,
2284 &self.untracked,
2286 )
2287 }
2288
2289 #[allow(rustc::usage_of_ty_tykind)]
2291 #[inline]
2292 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2293 self.interners.intern_ty(
2294 st,
2295 self.sess,
2296 &self.untracked,
2298 )
2299 }
2300
2301 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2302 match param.kind {
2303 GenericParamDefKind::Lifetime => {
2304 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2305 }
2306 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2307 GenericParamDefKind::Const { .. } => {
2308 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2309 .into()
2310 }
2311 }
2312 }
2313
2314 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2315 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2316 }
2317
2318 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2319 self.mk_place_elem(place, PlaceElem::Deref)
2320 }
2321
2322 pub fn mk_place_downcast(
2323 self,
2324 place: Place<'tcx>,
2325 adt_def: AdtDef<'tcx>,
2326 variant_index: VariantIdx,
2327 ) -> Place<'tcx> {
2328 self.mk_place_elem(
2329 place,
2330 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2331 )
2332 }
2333
2334 pub fn mk_place_downcast_unnamed(
2335 self,
2336 place: Place<'tcx>,
2337 variant_index: VariantIdx,
2338 ) -> Place<'tcx> {
2339 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2340 }
2341
2342 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2343 self.mk_place_elem(place, PlaceElem::Index(index))
2344 }
2345
2346 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2350 let mut projection = place.projection.to_vec();
2351 projection.push(elem);
2352
2353 Place { local: place.local, projection: self.mk_place_elems(&projection) }
2354 }
2355
2356 pub fn mk_poly_existential_predicates(
2357 self,
2358 eps: &[PolyExistentialPredicate<'tcx>],
2359 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2360 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2361 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!(
2362 eps.array_windows()
2363 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2364 != Ordering::Greater)
2365 );
2366 self.intern_poly_existential_predicates(eps)
2367 }
2368
2369 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2370 self.interners.intern_clauses(clauses)
2374 }
2375
2376 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2377 self.intern_local_def_ids(def_ids)
2381 }
2382
2383 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2384 where
2385 I: Iterator<Item = T>,
2386 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2387 {
2388 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2389 }
2390
2391 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2392 where
2393 I: Iterator<Item = T>,
2394 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2395 {
2396 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2397 }
2398
2399 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2400 where
2401 I: Iterator<Item = T>,
2402 T: CollectAndApply<
2403 &'tcx ty::CapturedPlace<'tcx>,
2404 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2405 >,
2406 {
2407 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2408 }
2409
2410 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2411 where
2412 I: Iterator<Item = T>,
2413 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2414 {
2415 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2416 }
2417
2418 pub fn mk_fn_sig<I, T>(
2423 self,
2424 inputs: I,
2425 output: I::Item,
2426 c_variadic: bool,
2427 safety: hir::Safety,
2428 abi: ExternAbi,
2429 ) -> T::Output
2430 where
2431 I: IntoIterator<Item = T>,
2432 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2433 {
2434 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2435 inputs_and_output: self.mk_type_list(xs),
2436 c_variadic,
2437 safety,
2438 abi,
2439 })
2440 }
2441
2442 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2443 where
2444 I: Iterator<Item = T>,
2445 T: CollectAndApply<
2446 PolyExistentialPredicate<'tcx>,
2447 &'tcx List<PolyExistentialPredicate<'tcx>>,
2448 >,
2449 {
2450 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2451 }
2452
2453 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2454 where
2455 I: Iterator<Item = T>,
2456 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2457 {
2458 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2459 }
2460
2461 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2462 where
2463 I: Iterator<Item = T>,
2464 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2465 {
2466 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2467 }
2468
2469 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2470 where
2471 I: Iterator<Item = T>,
2472 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2473 {
2474 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2475 }
2476
2477 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2478 where
2479 I: Iterator<Item = T>,
2480 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2481 {
2482 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2483 }
2484
2485 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2486 where
2487 I: Iterator<Item = T>,
2488 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2489 {
2490 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2491 }
2492
2493 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2494 where
2495 I: Iterator<Item = T>,
2496 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2497 {
2498 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2499 }
2500
2501 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2502 where
2503 I: Iterator<Item = T>,
2504 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2505 {
2506 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2507 }
2508
2509 pub fn mk_args_trait(
2510 self,
2511 self_ty: Ty<'tcx>,
2512 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2513 ) -> GenericArgsRef<'tcx> {
2514 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2515 }
2516
2517 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2518 where
2519 I: Iterator<Item = T>,
2520 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2521 {
2522 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2523 }
2524
2525 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2526 where
2527 I: Iterator<Item = T>,
2528 T: CollectAndApply<
2529 ty::ArgOutlivesPredicate<'tcx>,
2530 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2531 >,
2532 {
2533 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2534 }
2535
2536 #[track_caller]
2539 pub fn emit_node_span_lint(
2540 self,
2541 lint: &'static Lint,
2542 hir_id: HirId,
2543 span: impl Into<MultiSpan>,
2544 decorator: impl for<'a> Diagnostic<'a, ()>,
2545 ) {
2546 let level = self.lint_level_at_node(lint, hir_id);
2547 emit_lint_base(self.sess, lint, level, Some(span.into()), decorator)
2548 }
2549
2550 pub fn crate_level_attribute_injection_span(self) -> Span {
2552 let node = self.hir_node(hir::CRATE_HIR_ID);
2553 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2554 m.spans.inject_use_span.shrink_to_lo()
2555 }
2556
2557 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2558 self,
2559 diag: &mut Diag<'_, E>,
2560 features: impl IntoIterator<Item = (String, Symbol)>,
2561 ) {
2562 if !self.sess.is_nightly_build() {
2563 return;
2564 }
2565
2566 let span = self.crate_level_attribute_injection_span();
2567 for (desc, feature) in features {
2568 let msg =
2570 ::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}");
2571 diag.span_suggestion_verbose(
2572 span,
2573 msg,
2574 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2575 Applicability::MaybeIncorrect,
2576 );
2577 }
2578 }
2579
2580 #[track_caller]
2583 pub fn emit_node_lint(
2584 self,
2585 lint: &'static Lint,
2586 id: HirId,
2587 decorator: impl for<'a> Diagnostic<'a, ()>,
2588 ) {
2589 let level = self.lint_level_at_node(lint, id);
2590 emit_lint_base(self.sess, lint, level, None, decorator);
2591 }
2592
2593 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2594 let map = self.in_scope_traits_map(id.owner)?;
2595 let candidates = map.get(&id.local_id)?;
2596 Some(candidates)
2597 }
2598
2599 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2600 {
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:2600",
"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(2600u32),
::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");
2601 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2602 }
2603
2604 pub fn is_late_bound(self, id: HirId) -> bool {
2605 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2606 }
2607
2608 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2609 self.mk_bound_variable_kinds(
2610 &self
2611 .late_bound_vars_map(id.owner)
2612 .get(&id.local_id)
2613 .cloned()
2614 .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))),
2615 )
2616 }
2617
2618 pub fn map_opaque_lifetime_to_parent_lifetime(
2626 self,
2627 mut opaque_lifetime_param_def_id: LocalDefId,
2628 ) -> ty::Region<'tcx> {
2629 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!(
2630 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2631 "{opaque_lifetime_param_def_id:?} is a {}",
2632 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2633 );
2634
2635 loop {
2636 let parent = self.local_parent(opaque_lifetime_param_def_id);
2637 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2638
2639 let Some((lifetime, _)) = lifetime_mapping
2640 .iter()
2641 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2642 else {
2643 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2644 };
2645
2646 match *lifetime {
2647 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2648 let new_parent = self.local_parent(ebv);
2649
2650 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2653 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);
2654 opaque_lifetime_param_def_id = ebv;
2655 continue;
2656 }
2657
2658 let generics = self.generics_of(new_parent);
2659 return ty::Region::new_early_param(
2660 self,
2661 ty::EarlyParamRegion {
2662 index: generics
2663 .param_def_id_to_index(self, ebv.to_def_id())
2664 .expect("early-bound var should be present in fn generics"),
2665 name: self.item_name(ebv.to_def_id()),
2666 },
2667 );
2668 }
2669 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2670 let new_parent = self.local_parent(lbv);
2671 return ty::Region::new_late_param(
2672 self,
2673 new_parent.to_def_id(),
2674 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2675 );
2676 }
2677 resolve_bound_vars::ResolvedArg::Error(guar) => {
2678 return ty::Region::new_error(self, guar);
2679 }
2680 _ => {
2681 return ty::Region::new_error_with_message(
2682 self,
2683 self.def_span(opaque_lifetime_param_def_id),
2684 "cannot resolve lifetime",
2685 );
2686 }
2687 }
2688 }
2689 }
2690
2691 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2696 self.is_const_fn(def_id)
2697 && match self.lookup_const_stability(def_id) {
2698 None => true, Some(stability) if stability.is_const_stable() => true,
2700 _ => false,
2701 }
2702 }
2703
2704 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2706 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2707 && self.impl_trait_header(def_id).constness == hir::Constness::Const
2708 }
2709
2710 pub fn is_sdylib_interface_build(self) -> bool {
2711 self.sess.opts.unstable_opts.build_sdylib_interface
2712 }
2713
2714 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2715 let def_id = def_id.into_query_key();
2716 match self.def_kind(def_id) {
2717 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2718 _ => None,
2719 }
2720 }
2721
2722 pub fn next_trait_solver_globally(self) -> bool {
2723 self.sess.opts.unstable_opts.next_solver.globally
2724 }
2725
2726 pub fn next_trait_solver_in_coherence(self) -> bool {
2727 self.sess.opts.unstable_opts.next_solver.coherence
2728 }
2729
2730 #[allow(rustc::bad_opt_access)]
2731 pub fn use_typing_mode_borrowck(self) -> bool {
2732 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
2733 }
2734
2735 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2736 self.opt_rpitit_info(def_id).is_some()
2737 }
2738
2739 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2749 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2750 }
2751
2752 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2754 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2755 }
2756
2757 pub fn resolver_for_lowering(
2758 self,
2759 ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc<ast::Crate>)> {
2760 self.resolver_for_lowering_raw(()).0
2761 }
2762
2763 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2764 make_metadata(self)
2765 }
2766
2767 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2768 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2769 self.coroutine_kind(def_id)
2770 && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
2771 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2772 {
2773 true
2774 } else {
2775 false
2776 }
2777 }
2778
2779 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2781 {
{
'done:
{
for i in
::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(DoNotRecommend { .. }) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(self, def_id, DoNotRecommend { .. })
2782 }
2783
2784 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2785 let def_id = def_id.into_query_key();
2786 self.trivial_const(def_id).is_some()
2787 }
2788
2789 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2792 if self.is_lang_item(def_id, LangItem::Start) {
2793 return true;
2794 }
2795 if let Some((entry_def_id, _)) = self.entry_fn(())
2796 && entry_def_id == def_id
2797 {
2798 return true;
2799 }
2800 false
2801 }
2802}
2803
2804pub fn provide(providers: &mut Providers) {
2805 providers.is_panic_runtime = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(PanicRuntime) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, PanicRuntime);
2806 providers.is_compiler_builtins = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(CompilerBuiltins) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, CompilerBuiltins);
2807 providers.has_panic_handler = |tcx, LocalCrate| {
2808 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2810 };
2811 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2812}