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