1#![allow(rustc::usage_of_ty_tykind)]
4
5mod impl_interner;
6pub mod tls;
7
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::PointeeSized;
14use std::ops::{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::fx::FxHashMap;
22use rustc_data_structures::intern::Interned;
23use rustc_data_structures::jobserver::Proxy;
24use rustc_data_structures::profiling::SelfProfilerRef;
25use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
26use rustc_data_structures::stable_hasher::StableHash;
27use rustc_data_structures::steal::Steal;
28use rustc_data_structures::sync::{
29 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
30};
31use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
32use rustc_hir::def::DefKind;
33use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
34use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState};
35use rustc_hir::intravisit::VisitorExt;
36use rustc_hir::lang_items::LangItem;
37use rustc_hir::limit::Limit;
38use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, MaybeOwner, Node, TraitCandidate, find_attr};
39use rustc_index::IndexVec;
40use rustc_macros::Diagnostic;
41use rustc_session::Session;
42use rustc_session::config::CrateType;
43use rustc_session::cstore::{CrateStoreDyn, Untracked};
44use rustc_session::lint::Lint;
45use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
46use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
47use rustc_type_ir::TyKind::*;
48pub use rustc_type_ir::lift::Lift;
49use rustc_type_ir::{CollectAndApply, WithCachedTypeInfo, elaborate, search_graph};
50use tracing::{debug, instrument};
51
52use crate::arena::Arena;
53use crate::dep_graph::dep_node::make_metadata;
54use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
55use crate::ich::StableHashingContext;
56use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
57use crate::lint::emit_lint_base;
58use crate::metadata::ModChild;
59use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
60use crate::middle::resolve_bound_vars;
61use crate::mir::interpret::{self, Allocation, ConstAllocation};
62use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
63use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
64use crate::thir::Thir;
65use crate::traits;
66use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
67use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
68use crate::ty::{
69 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, FnSigKind, GenericArg,
70 GenericArgs, GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst,
71 Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
72 PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
73 ValTree, ValTreeKind, Visibility,
74};
75
76impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
77 fn is_local(self) -> bool {
78 self.is_local()
79 }
80
81 fn as_local(self) -> Option<LocalDefId> {
82 self.as_local()
83 }
84}
85
86impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
87 fn safe() -> Self {
88 hir::Safety::Safe
89 }
90
91 fn unsafe_mode() -> Self {
92 hir::Safety::Unsafe
93 }
94
95 fn is_safe(self) -> bool {
96 self.is_safe()
97 }
98
99 fn prefix_str(self) -> &'static str {
100 self.prefix_str()
101 }
102}
103
104impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
105 fn generic_const_exprs(self) -> bool {
106 self.generic_const_exprs()
107 }
108
109 fn coroutine_clone(self) -> bool {
110 self.coroutine_clone()
111 }
112
113 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
114 !self.staged_api() && self.enabled(symbol)
118 }
119}
120
121impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
122 fn dummy() -> Self {
123 DUMMY_SP
124 }
125}
126
127type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
128
129pub struct CtxtInterners<'tcx> {
130 arena: &'tcx WorkerLocal<Arena<'tcx>>,
132
133 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
136 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
137 args: InternedSet<'tcx, GenericArgs<'tcx>>,
138 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
139 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
140 region: InternedSet<'tcx, RegionKind<'tcx>>,
141 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
142 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
143 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
144 projs: InternedSet<'tcx, List<ProjectionKind>>,
145 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
146 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
147 pat: InternedSet<'tcx, PatternKind<'tcx>>,
148 const_allocation: InternedSet<'tcx, Allocation>,
149 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
150 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
151 adt_def: InternedSet<'tcx, AdtDefData>,
152 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
153 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
154 fields: InternedSet<'tcx, List<FieldIdx>>,
155 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
156 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
157 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
158 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
159 outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
160}
161
162impl<'tcx> CtxtInterners<'tcx> {
163 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
164 const N: usize = 2048;
167 CtxtInterners {
168 arena,
169 type_: InternedSet::with_capacity(N * 16),
173 const_lists: InternedSet::with_capacity(N * 4),
174 args: InternedSet::with_capacity(N * 4),
175 type_lists: InternedSet::with_capacity(N * 4),
176 region: InternedSet::with_capacity(N * 4),
177 poly_existential_predicates: InternedSet::with_capacity(N / 4),
178 canonical_var_kinds: InternedSet::with_capacity(N / 2),
179 predicate: InternedSet::with_capacity(N),
180 clauses: InternedSet::with_capacity(N),
181 projs: InternedSet::with_capacity(N * 4),
182 place_elems: InternedSet::with_capacity(N * 2),
183 const_: InternedSet::with_capacity(N * 2),
184 pat: InternedSet::with_capacity(N),
185 const_allocation: InternedSet::with_capacity(N),
186 bound_variable_kinds: InternedSet::with_capacity(N * 2),
187 layout: InternedSet::with_capacity(N),
188 adt_def: InternedSet::with_capacity(N),
189 external_constraints: InternedSet::with_capacity(N),
190 predefined_opaques_in_body: InternedSet::with_capacity(N),
191 fields: InternedSet::with_capacity(N * 4),
192 local_def_ids: InternedSet::with_capacity(N),
193 captures: InternedSet::with_capacity(N),
194 valtree: InternedSet::with_capacity(N),
195 patterns: InternedSet::with_capacity(N),
196 outlives: InternedSet::with_capacity(N),
197 }
198 }
199
200 #[allow(rustc::usage_of_ty_tykind)]
202 #[inline(never)]
203 fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
204 Ty(Interned::new_unchecked(
205 self.type_
206 .intern(kind, |kind| {
207 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
208 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
209 internee: kind,
210 flags: flags.flags,
211 outer_exclusive_binder: flags.outer_exclusive_binder,
212 }))
213 })
214 .0,
215 ))
216 }
217
218 #[allow(rustc::usage_of_ty_tykind)]
220 #[inline(never)]
221 fn intern_const(&self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
222 Const(Interned::new_unchecked(
223 self.const_
224 .intern(kind, |kind: ty::ConstKind<'_>| {
225 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
226 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
227 internee: kind,
228 flags: flags.flags,
229 outer_exclusive_binder: flags.outer_exclusive_binder,
230 }))
231 })
232 .0,
233 ))
234 }
235
236 #[inline(never)]
238 fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
239 Predicate(Interned::new_unchecked(
240 self.predicate
241 .intern(kind, |kind| {
242 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
243 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
244 internee: kind,
245 flags: flags.flags,
246 outer_exclusive_binder: flags.outer_exclusive_binder,
247 }))
248 })
249 .0,
250 ))
251 }
252
253 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
254 if clauses.is_empty() {
255 ListWithCachedTypeInfo::empty()
256 } else {
257 self.clauses
258 .intern_ref(clauses, || {
259 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
260
261 InternedInSet(ListWithCachedTypeInfo::from_arena(
262 &*self.arena,
263 flags.into(),
264 clauses,
265 ))
266 })
267 .0
268 }
269 }
270}
271
272const NUM_PREINTERNED_TY_VARS: u32 = 100;
277const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
278const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
279const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
280const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
281
282const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
291
292const NUM_PREINTERNED_RE_VARS: u32 = 500;
294const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
295const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
296
297pub struct CommonTypes<'tcx> {
298 pub unit: Ty<'tcx>,
299 pub bool: Ty<'tcx>,
300 pub char: Ty<'tcx>,
301 pub isize: Ty<'tcx>,
302 pub i8: Ty<'tcx>,
303 pub i16: Ty<'tcx>,
304 pub i32: Ty<'tcx>,
305 pub i64: Ty<'tcx>,
306 pub i128: Ty<'tcx>,
307 pub usize: Ty<'tcx>,
308 pub u8: Ty<'tcx>,
309 pub u16: Ty<'tcx>,
310 pub u32: Ty<'tcx>,
311 pub u64: Ty<'tcx>,
312 pub u128: Ty<'tcx>,
313 pub f16: Ty<'tcx>,
314 pub f32: Ty<'tcx>,
315 pub f64: Ty<'tcx>,
316 pub f128: Ty<'tcx>,
317 pub str_: Ty<'tcx>,
318 pub never: Ty<'tcx>,
319 pub self_param: Ty<'tcx>,
320
321 pub trait_object_dummy_self: Ty<'tcx>,
326
327 pub ty_vars: Vec<Ty<'tcx>>,
329
330 pub fresh_tys: Vec<Ty<'tcx>>,
332
333 pub fresh_int_tys: Vec<Ty<'tcx>>,
335
336 pub fresh_float_tys: Vec<Ty<'tcx>>,
338
339 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
343
344 pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
348}
349
350pub struct CommonLifetimes<'tcx> {
351 pub re_static: Region<'tcx>,
353
354 pub re_erased: Region<'tcx>,
356
357 pub re_vars: Vec<Region<'tcx>>,
359
360 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
364
365 pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
369}
370
371pub struct CommonConsts<'tcx> {
372 pub unit: Const<'tcx>,
373 pub true_: Const<'tcx>,
374 pub false_: Const<'tcx>,
375 pub(crate) valtree_zst: ValTree<'tcx>,
377}
378
379impl<'tcx> CommonTypes<'tcx> {
380 fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
381 let mk = |ty| interners.intern_ty(ty);
382
383 let ty_vars =
384 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
385 let fresh_tys: Vec<_> =
386 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
387 let fresh_int_tys: Vec<_> =
388 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
389 let fresh_float_tys: Vec<_> =
390 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
391
392 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
393 .map(|i| {
394 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
395 .map(|v| {
396 mk(ty::Bound(
397 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
398 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
399 ))
400 })
401 .collect()
402 })
403 .collect();
404
405 let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
406 .map(|v| {
407 mk(ty::Bound(
408 ty::BoundVarIndexKind::Canonical,
409 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
410 ))
411 })
412 .collect();
413
414 CommonTypes {
415 unit: mk(Tuple(List::empty())),
416 bool: mk(Bool),
417 char: mk(Char),
418 never: mk(Never),
419 isize: mk(Int(ty::IntTy::Isize)),
420 i8: mk(Int(ty::IntTy::I8)),
421 i16: mk(Int(ty::IntTy::I16)),
422 i32: mk(Int(ty::IntTy::I32)),
423 i64: mk(Int(ty::IntTy::I64)),
424 i128: mk(Int(ty::IntTy::I128)),
425 usize: mk(Uint(ty::UintTy::Usize)),
426 u8: mk(Uint(ty::UintTy::U8)),
427 u16: mk(Uint(ty::UintTy::U16)),
428 u32: mk(Uint(ty::UintTy::U32)),
429 u64: mk(Uint(ty::UintTy::U64)),
430 u128: mk(Uint(ty::UintTy::U128)),
431 f16: mk(Float(ty::FloatTy::F16)),
432 f32: mk(Float(ty::FloatTy::F32)),
433 f64: mk(Float(ty::FloatTy::F64)),
434 f128: mk(Float(ty::FloatTy::F128)),
435 str_: mk(Str),
436 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
437
438 trait_object_dummy_self: fresh_tys[0],
439
440 ty_vars,
441 fresh_tys,
442 fresh_int_tys,
443 fresh_float_tys,
444 anon_bound_tys,
445 anon_canonical_bound_tys,
446 }
447 }
448}
449
450impl<'tcx> CommonLifetimes<'tcx> {
451 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
452 let mk = |r| {
453 Region(Interned::new_unchecked(
454 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
455 ))
456 };
457
458 let re_vars =
459 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
460
461 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
462 .map(|i| {
463 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
464 .map(|v| {
465 mk(ty::ReBound(
466 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
467 ty::BoundRegion {
468 var: ty::BoundVar::from(v),
469 kind: ty::BoundRegionKind::Anon,
470 },
471 ))
472 })
473 .collect()
474 })
475 .collect();
476
477 let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
478 .map(|v| {
479 mk(ty::ReBound(
480 ty::BoundVarIndexKind::Canonical,
481 ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
482 ))
483 })
484 .collect();
485
486 CommonLifetimes {
487 re_static: mk(ty::ReStatic),
488 re_erased: mk(ty::ReErased),
489 re_vars,
490 anon_re_bounds,
491 anon_re_canonical_bounds,
492 }
493 }
494}
495
496impl<'tcx> CommonConsts<'tcx> {
497 fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
498 let mk_const = |c| interners.intern_const(c);
499
500 let mk_valtree = |v| {
501 ty::ValTree(Interned::new_unchecked(
502 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
503 ))
504 };
505
506 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
507 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
508 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
509
510 CommonConsts {
511 unit: mk_const(ty::ConstKind::Value(ty::Value {
512 ty: types.unit,
513 valtree: valtree_zst,
514 })),
515 true_: mk_const(ty::ConstKind::Value(ty::Value {
516 ty: types.bool,
517 valtree: valtree_true,
518 })),
519 false_: mk_const(ty::ConstKind::Value(ty::Value {
520 ty: types.bool,
521 valtree: valtree_false,
522 })),
523 valtree_zst,
524 }
525 }
526}
527
528#[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)]
531pub struct FreeRegionInfo {
532 pub scope: LocalDefId,
534 pub region_def_id: DefId,
536 pub is_impl_item: bool,
538}
539
540#[derive(#[automatically_derived]
impl<'tcx, K: ::core::marker::Copy + Copy> ::core::marker::Copy for
TyCtxtFeed<'tcx, K> {
}Copy, #[automatically_derived]
impl<'tcx, K: ::core::clone::Clone + Copy> ::core::clone::Clone for
TyCtxtFeed<'tcx, K> {
#[inline]
fn clone(&self) -> TyCtxtFeed<'tcx, K> {
TyCtxtFeed {
tcx: ::core::clone::Clone::clone(&self.tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
542pub struct TyCtxtFeed<'tcx, K: Copy> {
543 pub tcx: TyCtxt<'tcx>,
544 key: K,
546}
547
548impl<K: Copy> !StableHash for TyCtxtFeed<'_, K> {}
550
551impl<'tcx> TyCtxt<'tcx> {
556 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
559 self.dep_graph.assert_ignored();
560 TyCtxtFeed { tcx: self, key: () }
561 }
562
563 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
566 let key = self.untracked().source_span.push(span);
567 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);
568 TyCtxtFeed { tcx: self, key }
569 }
570
571 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
575 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);
576 TyCtxtFeed { tcx: self, key }.type_of(value)
577 }
578
579 pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) {
581 self.dep_graph.assert_ignored();
582 TyCtxtFeed { tcx: self, key }.delayed_owner(owner);
583 }
584
585 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
593 if truecfg!(debug_assertions) {
594 match self.def_kind(self.local_parent(key)) {
595 DefKind::Impl { of_trait: true } => {}
596 other => crate::util::bug::bug_fmt(format_args!("{0:?} is not an assoc item of a trait impl: {1:?}",
key, other))bug!("{key:?} is not an assoc item of a trait impl: {other:?}"),
597 }
598 }
599 TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id())
600 }
601}
602
603impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> {
604 #[inline(always)]
605 pub fn key(&self) -> K {
606 self.key
607 }
608}
609
610impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
611 #[inline(always)]
612 pub fn def_id(&self) -> LocalDefId {
613 self.key
614 }
615
616 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
618 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
619 }
620
621 pub fn feed_hir(&self) {
623 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
624
625 let node = hir::OwnerNode::Synthetic;
626 let bodies = Default::default();
627 let attrs = hir::AttributeMap::EMPTY;
628
629 let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
630 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque);
631 let node = node.into();
632 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
633 opt_hash_including_bodies,
634 nodes: IndexVec::from_elem_n(
635 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
636 1,
637 ),
638 bodies,
639 })));
640 self.feed_owner_id().hir_attr_map(attrs);
641 }
642}
643
644#[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)]
662#[rustc_diagnostic_item = "TyCtxt"]
663#[rustc_pass_by_value]
664pub struct TyCtxt<'tcx> {
665 gcx: &'tcx GlobalCtxt<'tcx>,
666}
667
668unsafe impl DynSend for TyCtxt<'_> {}
672unsafe impl DynSync for TyCtxt<'_> {}
673fn _assert_tcx_fields() {
674 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
675 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
676}
677
678impl<'tcx> Deref for TyCtxt<'tcx> {
679 type Target = &'tcx GlobalCtxt<'tcx>;
680 #[inline(always)]
681 fn deref(&self) -> &Self::Target {
682 &self.gcx
683 }
684}
685
686pub struct GlobalCtxt<'tcx> {
688 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
689 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
690
691 interners: CtxtInterners<'tcx>,
692
693 pub sess: &'tcx Session,
694 crate_types: Vec<CrateType>,
695 stable_crate_id: StableCrateId,
701
702 pub dep_graph: DepGraph,
703
704 pub prof: SelfProfilerRef,
705
706 pub types: CommonTypes<'tcx>,
708
709 pub lifetimes: CommonLifetimes<'tcx>,
711
712 pub consts: CommonConsts<'tcx>,
714
715 pub(crate) hooks: crate::hooks::Providers,
718
719 untracked: Untracked,
720
721 pub query_system: QuerySystem<'tcx>,
722 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
723
724 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
726
727 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
730
731 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
735
736 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
738 pub new_solver_canonical_param_env_cache:
739 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
740
741 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
742
743 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
745 pub clauses_cache:
747 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
748
749 pub data_layout: TargetDataLayout,
751
752 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
754
755 current_gcx: CurrentGcx,
756
757 pub jobserver_proxy: Arc<Proxy>,
759}
760
761impl<'tcx> GlobalCtxt<'tcx> {
762 pub fn enter<F, R>(&'tcx self, f: F) -> R
765 where
766 F: FnOnce(TyCtxt<'tcx>) -> R,
767 {
768 let icx = tls::ImplicitCtxt::new(self);
769
770 let _on_drop = defer(move || {
772 *self.current_gcx.value.write() = None;
773 });
774
775 {
777 let mut guard = self.current_gcx.value.write();
778 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
779 *guard = Some(self as *const _ as *const ());
780 }
781
782 tls::enter_context(&icx, || f(icx.tcx))
783 }
784}
785
786#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
793pub struct CurrentGcx {
794 value: Arc<RwLock<Option<*const ()>>>,
797}
798
799unsafe impl DynSend for CurrentGcx {}
800unsafe impl DynSync for CurrentGcx {}
801
802impl CurrentGcx {
803 pub fn new() -> Self {
804 Self { value: Arc::new(RwLock::new(None)) }
805 }
806
807 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
808 let read_guard = self.value.read();
809 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
810 f(unsafe { &*gcx })
814 }
815}
816
817impl<'tcx> TyCtxt<'tcx> {
818 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
819 let root = self.typeck_root_def_id_local(def_id);
822 self.hir_node_by_def_id(root).body_id().is_some()
823 }
824
825 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
830 let def_kind = self.def_kind(def_id);
831 if def_kind.has_codegen_attrs() {
832 self.codegen_fn_attrs(def_id)
833 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
DefKind::InlineConst | DefKind::GlobalAsm => true,
_ => false,
}matches!(
834 def_kind,
835 DefKind::AnonConst
836 | DefKind::AssocConst { .. }
837 | DefKind::Const { .. }
838 | DefKind::InlineConst
839 | DefKind::GlobalAsm
840 ) {
841 CodegenFnAttrs::EMPTY
842 } else {
843 crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind))bug!(
844 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
845 def_id,
846 def_kind
847 )
848 }
849 }
850
851 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
852 self.arena.alloc(Steal::new(thir))
853 }
854
855 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
856 self.arena.alloc(Steal::new(mir))
857 }
858
859 pub fn alloc_steal_promoted(
860 self,
861 promoted: IndexVec<Promoted, Body<'tcx>>,
862 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
863 self.arena.alloc(Steal::new(promoted))
864 }
865
866 pub fn mk_adt_def(
867 self,
868 did: DefId,
869 kind: AdtKind,
870 variants: IndexVec<VariantIdx, ty::VariantDef>,
871 repr: ReprOptions,
872 ) -> ty::AdtDef<'tcx> {
873 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
874 }
875
876 pub fn allocate_bytes_dedup<'a>(
879 self,
880 bytes: impl Into<Cow<'a, [u8]>>,
881 salt: usize,
882 ) -> interpret::AllocId {
883 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
885 let alloc = self.mk_const_alloc(alloc);
886 self.reserve_and_set_memory_dedup(alloc, salt)
887 }
888
889 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
891 if self.sess.opts.unstable_opts.experimental_default_bounds {
892 &[
893 LangItem::DefaultTrait1,
894 LangItem::DefaultTrait2,
895 LangItem::DefaultTrait3,
896 LangItem::DefaultTrait4,
897 ]
898 } else {
899 &[]
900 }
901 }
902
903 pub fn is_default_trait(self, def_id: DefId) -> bool {
904 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
905 }
906
907 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
908 #[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))
909 }
910
911 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
915 let start = {
{
'done:
{
for i in ::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcLayoutScalarValidRangeStart(n,
_)) => {
break 'done Some(Bound::Included(**n));
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}find_attr!(self, def_id, RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
916 let end =
917 {
{
'done:
{
for i in ::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcLayoutScalarValidRangeEnd(n,
_)) => {
break 'done Some(Bound::Included(**n));
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}find_attr!(self, def_id, RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n))
918 .unwrap_or(Bound::Unbounded);
919 (start, end)
920 }
921
922 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> T::Lifted {
923 value.lift_to_interner(self)
924 }
925
926 pub fn create_global_ctxt<T>(
933 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
934 s: &'tcx Session,
935 crate_types: Vec<CrateType>,
936 stable_crate_id: StableCrateId,
937 arena: &'tcx WorkerLocal<Arena<'tcx>>,
938 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
939 untracked: Untracked,
940 dep_graph: DepGraph,
941 dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
942 query_system: QuerySystem<'tcx>,
943 hooks: crate::hooks::Providers,
944 current_gcx: CurrentGcx,
945 jobserver_proxy: Arc<Proxy>,
946 f: impl FnOnce(TyCtxt<'tcx>) -> T,
947 ) -> T {
948 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
949 s.dcx().emit_fatal(err);
950 });
951 let interners = CtxtInterners::new(arena);
952 let common_types = CommonTypes::new(&interners);
953 let common_lifetimes = CommonLifetimes::new(&interners);
954 let common_consts = CommonConsts::new(&interners, &common_types);
955
956 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
957 sess: s,
958 crate_types,
959 stable_crate_id,
960 arena,
961 hir_arena,
962 interners,
963 dep_graph,
964 hooks,
965 prof: s.prof.clone(),
966 types: common_types,
967 lifetimes: common_lifetimes,
968 consts: common_consts,
969 untracked,
970 query_system,
971 dep_kind_vtables,
972 ty_rcache: Default::default(),
973 selection_cache: Default::default(),
974 evaluation_cache: Default::default(),
975 new_solver_evaluation_cache: Default::default(),
976 new_solver_canonical_param_env_cache: Default::default(),
977 canonical_param_env_cache: Default::default(),
978 highest_var_in_clauses_cache: Default::default(),
979 clauses_cache: Default::default(),
980 data_layout,
981 alloc_map: interpret::AllocMap::new(),
982 current_gcx,
983 jobserver_proxy,
984 });
985
986 gcx.enter(f)
988 }
989
990 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
992 self.get_lang_items(())
993 }
994
995 #[track_caller]
997 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
998 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
999 self.type_of(ordering_enum).no_bound_vars().unwrap()
1000 }
1001
1002 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1005 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1006 }
1007
1008 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1010 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1011 }
1012
1013 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1015 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1016 }
1017
1018 pub fn is_coroutine(self, def_id: DefId) -> bool {
1019 self.coroutine_kind(def_id).is_some()
1020 }
1021
1022 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1023 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1024 }
1025
1026 pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1027 if !self.is_type_const(def_id) {
1028 return None;
1029 }
1030 Some(self.def_span(def_id))
1031 }
1032
1033 pub fn is_type_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1035 let def_id = def_id.into_query_key();
1036 match self.def_kind(def_id) {
1037 DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1038 is_type_const
1039 }
1040 _ => false,
1041 }
1042 }
1043
1044 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1047 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1048 }
1049
1050 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1052 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1053 self.coroutine_kind(def_id),
1054 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1055 )
1056 }
1057
1058 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1061 #[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)
1062 }
1063
1064 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1067 #[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(_)))
1068 }
1069
1070 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1072 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1073 self.coroutine_kind(def_id),
1074 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1075 )
1076 }
1077
1078 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1080 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1081 self.coroutine_kind(def_id),
1082 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1083 )
1084 }
1085
1086 pub fn features(self) -> &'tcx rustc_feature::Features {
1087 self.features_query(())
1088 }
1089
1090 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1091 let id = id.into_query_key();
1092 if let Some(id) = id.as_local() {
1094 self.definitions_untracked().def_key(id)
1095 } else {
1096 self.cstore_untracked().def_key(id)
1097 }
1098 }
1099
1100 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1106 if let Some(id) = id.as_local() {
1108 self.definitions_untracked().def_path(id)
1109 } else {
1110 self.cstore_untracked().def_path(id)
1111 }
1112 }
1113
1114 #[inline]
1115 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1116 if let Some(def_id) = def_id.as_local() {
1118 self.definitions_untracked().def_path_hash(def_id)
1119 } else {
1120 self.cstore_untracked().def_path_hash(def_id)
1121 }
1122 }
1123
1124 #[inline]
1125 pub fn crate_types(self) -> &'tcx [CrateType] {
1126 &self.crate_types
1127 }
1128
1129 pub fn needs_metadata(self) -> bool {
1130 self.crate_types().iter().any(|ty| match *ty {
1131 CrateType::Executable
1132 | CrateType::StaticLib
1133 | CrateType::Cdylib
1134 | CrateType::Sdylib => false,
1135 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1136 })
1137 }
1138
1139 pub fn needs_crate_hash(self) -> bool {
1140 truecfg!(debug_assertions)
1152 || self.sess.opts.incremental.is_some()
1153 || self.needs_metadata()
1154 || self.sess.instrument_coverage()
1155 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1156 }
1157
1158 #[inline]
1159 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1160 if crate_num == LOCAL_CRATE {
1161 self.stable_crate_id
1162 } else {
1163 self.cstore_untracked().stable_crate_id(crate_num)
1164 }
1165 }
1166
1167 #[inline]
1170 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1171 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1172 LOCAL_CRATE
1173 } else {
1174 *self
1175 .untracked()
1176 .stable_crate_ids
1177 .read()
1178 .get(&stable_crate_id)
1179 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1180 }
1181 }
1182
1183 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1187 {
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:1187",
"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(1187u32),
::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);
1188
1189 let stable_crate_id = hash.stable_crate_id();
1190
1191 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1194 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1195 } else {
1196 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1197 }
1198 }
1199
1200 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1201 let (crate_name, stable_crate_id) = if def_id.is_local() {
1206 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1207 } else {
1208 let cstore = &*self.cstore_untracked();
1209 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1210 };
1211
1212 ::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!(
1213 "{}[{:04x}]{}",
1214 crate_name,
1215 stable_crate_id.as_u64() >> (8 * 6),
1218 self.def_path(def_id).to_string_no_crate_verbose()
1219 )
1220 }
1221
1222 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1223 self.sess.dcx()
1224 }
1225
1226 pub fn is_target_feature_call_safe(
1229 self,
1230 callee_features: &[TargetFeature],
1231 body_features: &[TargetFeature],
1232 ) -> bool {
1233 self.sess.target.options.is_like_wasm
1238 || callee_features
1239 .iter()
1240 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1241 }
1242
1243 pub fn adjust_target_feature_sig(
1246 self,
1247 fun_def: DefId,
1248 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1249 caller: DefId,
1250 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1251 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1252 let caller_features = &self.body_codegen_attrs(caller).target_features;
1253 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1254 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1255 fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1256 ..sig
1257 }));
1258 }
1259 None
1260 }
1261
1262 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1265 match self.env_var_os(key.as_ref()) {
1266 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1267 None => Err(VarError::NotPresent),
1268 }
1269 }
1270}
1271
1272impl<'tcx> TyCtxtAt<'tcx> {
1273 pub fn create_def(
1275 self,
1276 parent: LocalDefId,
1277 name: Option<Symbol>,
1278 def_kind: DefKind,
1279 override_def_path_data: Option<DefPathData>,
1280 disambiguator: &mut PerParentDisambiguatorState,
1281 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1282 let feed =
1283 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1284
1285 feed.def_span(self.span);
1286 feed
1287 }
1288}
1289
1290impl<'tcx> TyCtxt<'tcx> {
1291 pub fn create_def(
1293 self,
1294 parent: LocalDefId,
1295 name: Option<Symbol>,
1296 def_kind: DefKind,
1297 override_def_path_data: Option<DefPathData>,
1298 disambiguator: &mut PerParentDisambiguatorState,
1299 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1300 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1301 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1311
1312 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1317
1318 let feed = TyCtxtFeed { tcx: self, key: def_id };
1319 feed.def_kind(def_kind);
1320 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1325 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1326 feed.visibility(ty::Visibility::Restricted(parent_mod));
1327 }
1328
1329 feed
1330 }
1331
1332 pub fn create_crate_num(
1333 self,
1334 stable_crate_id: StableCrateId,
1335 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1336 let mut lock = self.untracked().stable_crate_ids.write();
1337 if let Some(&existing) = lock.get(&stable_crate_id) {
1338 return Err(existing);
1339 }
1340 let num = CrateNum::new(lock.len());
1341 lock.insert(stable_crate_id, num);
1342 Ok(TyCtxtFeed { key: num, tcx: self })
1343 }
1344
1345 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1346 self.ensure_ok().analysis(());
1348
1349 let definitions = &self.untracked.definitions;
1350 gen {
1351 let mut i = 0;
1352
1353 while i < { definitions.read().num_definitions() } {
1356 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1357 yield LocalDefId { local_def_index };
1358 i += 1;
1359 }
1360
1361 definitions.freeze();
1363 }
1364 }
1365
1366 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1367 self.ensure_ok().analysis(());
1369
1370 self.untracked.definitions.freeze().def_path_table()
1373 }
1374
1375 pub fn def_path_hash_to_def_index_map(
1376 self,
1377 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1378 self.ensure_ok().hir_crate_items(());
1381 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1384 }
1385
1386 #[inline]
1389 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1390 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1391 }
1392
1393 pub fn untracked(self) -> &'tcx Untracked {
1395 &self.untracked
1396 }
1397 #[inline]
1400 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1401 self.untracked.definitions.read()
1402 }
1403
1404 #[inline]
1407 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1408 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1409 }
1410
1411 #[inline(always)]
1412 pub fn with_stable_hashing_context<R>(
1413 self,
1414 f: impl FnOnce(StableHashingContext<'_>) -> R,
1415 ) -> R {
1416 f(StableHashingContext::new(self.sess, &self.untracked))
1417 }
1418
1419 #[inline]
1420 pub fn local_crate_exports_generics(self) -> bool {
1421 if self.is_compiler_builtins(LOCAL_CRATE) {
1425 return false;
1426 }
1427 self.crate_types().iter().any(|crate_type| {
1428 match crate_type {
1429 CrateType::Executable
1430 | CrateType::StaticLib
1431 | CrateType::ProcMacro
1432 | CrateType::Cdylib
1433 | CrateType::Sdylib => false,
1434
1435 CrateType::Dylib => true,
1440
1441 CrateType::Rlib => true,
1442 }
1443 })
1444 }
1445
1446 pub fn is_suitable_region(
1448 self,
1449 generic_param_scope: LocalDefId,
1450 mut region: Region<'tcx>,
1451 ) -> Option<FreeRegionInfo> {
1452 let (suitable_region_binding_scope, region_def_id) = loop {
1453 let def_id =
1454 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1455 let scope = self.local_parent(def_id);
1456 if self.def_kind(scope) == DefKind::OpaqueTy {
1457 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1460 continue;
1461 }
1462 break (scope, def_id.into());
1463 };
1464
1465 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1466 Node::Item(..) | Node::TraitItem(..) => false,
1467 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1468 hir::ImplItemImplKind::Trait { .. } => true,
1475 _ => false,
1476 },
1477 _ => false,
1478 };
1479
1480 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1481 }
1482
1483 pub fn return_type_impl_or_dyn_traits(
1485 self,
1486 scope_def_id: LocalDefId,
1487 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1488 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1489 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1490 self.hir_fn_decl_by_hir_id(hir_id)
1491 else {
1492 return ::alloc::vec::Vec::new()vec![];
1493 };
1494
1495 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1496 v.visit_ty_unambig(hir_output);
1497 v.0
1498 }
1499
1500 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1504 self,
1505 scope_def_id: LocalDefId,
1506 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1507 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1508 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1509 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1511 && let hir::TyKind::Path(hir::QPath::Resolved(
1512 None,
1513 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1514 && let Some(local_id) = def_id.as_local()
1515 && 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()
1517 {
1518 v.visit_ty_unambig(alias_ty);
1519 if !v.0.is_empty() {
1520 return Some((
1521 v.0,
1522 alias_generics.span,
1523 alias_generics.span_for_lifetime_suggestion(),
1524 ));
1525 }
1526 }
1527 None
1528 }
1529
1530 pub fn has_strict_asm_symbol_naming(self) -> bool {
1533 self.sess.target.llvm_target.starts_with("nvptx")
1534 }
1535
1536 pub fn caller_location_ty(self) -> Ty<'tcx> {
1538 Ty::new_imm_ref(
1539 self,
1540 self.lifetimes.re_static,
1541 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1542 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1543 .skip_norm_wip(),
1544 )
1545 }
1546
1547 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1549 let kind = self.def_kind(def_id);
1550 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1551 }
1552
1553 pub fn type_length_limit(self) -> Limit {
1554 self.limits(()).type_length_limit
1555 }
1556
1557 pub fn recursion_limit(self) -> Limit {
1558 self.limits(()).recursion_limit
1559 }
1560
1561 pub fn move_size_limit(self) -> Limit {
1562 self.limits(()).move_size_limit
1563 }
1564
1565 pub fn pattern_complexity_limit(self) -> Limit {
1566 self.limits(()).pattern_complexity_limit
1567 }
1568
1569 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1571 iter::once(LOCAL_CRATE)
1572 .chain(self.crates(()).iter().copied())
1573 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1574 }
1575
1576 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1578 let visible_crates =
1579 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1580
1581 iter::once(LOCAL_CRATE)
1582 .chain(visible_crates)
1583 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1584 }
1585
1586 #[inline]
1587 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1588 self.visibility(def_id).expect_local()
1589 }
1590
1591 x;#[instrument(skip(self), level = "trace", ret)]
1593 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1594 self.hir_expect_opaque_ty(def_id).origin
1595 }
1596
1597 pub fn finish(self) {
1598 self.alloc_self_profile_query_strings();
1601
1602 self.save_dep_graph();
1603 self.verify_query_key_hashes();
1604
1605 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1606 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
1607 }
1608 }
1609
1610 pub fn report_unused_features(self) {
1611 #[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)]
1612 #[diag("feature `{$feature}` is declared but not used")]
1613 struct UnusedFeature {
1614 feature: Symbol,
1615 }
1616
1617 let used_features = self.sess.used_features.lock();
1619 let unused_features = self
1620 .features()
1621 .enabled_features_iter_stable_order()
1622 .filter(|(f, _)| {
1623 !used_features.contains_key(f)
1624 && f.as_str() != "restricted_std"
1631 && *f != sym::doc_cfg
1635 })
1636 .collect::<Vec<_>>();
1637
1638 for (feature, span) in unused_features {
1639 self.emit_node_span_lint(
1640 rustc_session::lint::builtin::UNUSED_FEATURES,
1641 CRATE_HIR_ID,
1642 span,
1643 UnusedFeature { feature },
1644 );
1645 }
1646 }
1647}
1648
1649macro_rules! nop_lift {
1650 ($set:ident; $ty:ty => $lifted:ty) => {
1651 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1652 type Lifted = $lifted;
1653 #[track_caller]
1654 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1655 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1660 _x: Interned<'tcx, Inner>,
1661 ) -> InternedSet<'tcx, Inner> {
1662 unreachable!()
1663 }
1664 fn _type_eq<T>(_x: &T, _y: &T) {}
1665 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1666 let interner = _intern_set_ty_from_interned_ty(x.0);
1670 _type_eq(&interner, &tcx.interners.$set);
1672 }
1673
1674 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1675 unsafe { mem::transmute(self) }
1678 }
1679 }
1680 };
1681}
1682
1683macro_rules! nop_list_lift {
1684 ($set:ident; $ty:ty => $lifted:ty) => {
1685 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
1686 type Lifted = &'tcx List<$lifted>;
1687 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1688 if false {
1690 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
1691 }
1692
1693 if self.is_empty() {
1694 return List::empty();
1695 }
1696 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1697 unsafe { mem::transmute(self) }
1700 }
1701 }
1702 };
1703}
1704
1705impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Ty<'a> {
type Lifted = Ty<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Ty<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.type_);
}
if !tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { type_; Ty<'a> => Ty<'tcx> }
1706impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Region<'a> {
type Lifted = Region<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Region<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.region);
}
if !tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { region; Region<'a> => Region<'tcx> }
1707impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Const<'a> {
type Lifted = Const<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Const<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_);
}
if !tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { const_; Const<'a> => Const<'tcx> }
1708impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Pattern<'a> {
type Lifted = Pattern<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Pattern<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.pat);
}
if !tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
1709impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ConstAllocation<'a> {
type Lifted = ConstAllocation<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ConstAllocation<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_allocation);
}
if !tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
1710impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Predicate<'a> {
type Lifted = Predicate<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Predicate<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
1711impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Clause<'a> {
type Lifted = Clause<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Clause<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
1712impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Layout<'a> {
type Lifted = Layout<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Layout<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.layout);
}
if !tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { layout; Layout<'a> => Layout<'tcx> }
1713impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ValTree<'a> {
type Lifted = ValTree<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ValTree<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.valtree);
}
if !tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
1714
1715impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Ty<'a>> {
type Lifted = &'tcx List<Ty<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<Ty<'tcx>>> =
&tcx.interners.type_lists;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self))
{
::core::panicking::panic("assertion failed: tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
1716impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<PolyExistentialPredicate<'a>> {
type Lifted = &'tcx List<PolyExistentialPredicate<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>> =
&tcx.interners.poly_existential_predicates;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self))
{
::core::panicking::panic("assertion failed: tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! {
1717 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1718}
1719impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<ty::BoundVariableKind<'a>> {
type Lifted = &'tcx List<ty::BoundVariableKind<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>> =
&tcx.interners.bound_variable_kinds;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self))
{
::core::panicking::panic("assertion failed: tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind<'a> => ty::BoundVariableKind<'tcx> }
1720
1721impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<GenericArg<'a>> {
type Lifted = &'tcx List<GenericArg<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<GenericArg<'tcx>>> =
&tcx.interners.args;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.args.contains_pointer_to(&InternedInSet(self)) {
::core::panicking::panic("assertion failed: tcx.interners.args.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
1723
1724macro_rules! sty_debug_print {
1725 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1726 #[allow(non_snake_case)]
1729 mod inner {
1730 use crate::ty::{self, TyCtxt};
1731 use crate::ty::context::InternedInSet;
1732
1733 #[derive(Copy, Clone)]
1734 struct DebugStat {
1735 total: usize,
1736 lt_infer: usize,
1737 ty_infer: usize,
1738 ct_infer: usize,
1739 all_infer: usize,
1740 }
1741
1742 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1743 let mut total = DebugStat {
1744 total: 0,
1745 lt_infer: 0,
1746 ty_infer: 0,
1747 ct_infer: 0,
1748 all_infer: 0,
1749 };
1750 $(let mut $variant = total;)*
1751
1752 for shard in tcx.interners.type_.lock_shards() {
1753 #[allow(rustc::potential_query_instability)]
1755 let types = shard.iter();
1756 for &(InternedInSet(t), ()) in types {
1757 let variant = match t.internee {
1758 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1759 ty::Float(..) | ty::Str | ty::Never => continue,
1760 ty::Error(_) => continue,
1761 $(ty::$variant(..) => &mut $variant,)*
1762 };
1763 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1764 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1765 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1766
1767 variant.total += 1;
1768 total.total += 1;
1769 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1770 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1771 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1772 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1773 }
1774 }
1775 writeln!(fmt, "Ty interner total ty lt ct all")?;
1776 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1777 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1778 stringify!($variant),
1779 uses = $variant.total,
1780 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1781 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1782 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1783 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1784 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1785 )*
1786 writeln!(fmt, " total {uses:6} \
1787 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1788 uses = total.total,
1789 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1790 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1791 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1792 all = total.all_infer as f64 * 100.0 / total.total as f64)
1793 }
1794 }
1795
1796 inner::go($fmt, $ctxt)
1797 }}
1798}
1799
1800impl<'tcx> TyCtxt<'tcx> {
1801 pub fn debug_stats(self) -> impl fmt::Debug {
1802 fmt::from_fn(move |fmt| {
1803 {
#[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!(
1804 fmt,
1805 self,
1806 Adt,
1807 Array,
1808 Slice,
1809 RawPtr,
1810 Ref,
1811 FnDef,
1812 FnPtr,
1813 UnsafeBinder,
1814 Placeholder,
1815 Coroutine,
1816 CoroutineWitness,
1817 Dynamic,
1818 Closure,
1819 CoroutineClosure,
1820 Tuple,
1821 Bound,
1822 Param,
1823 Infer,
1824 Alias,
1825 Pat,
1826 Foreign
1827 )?;
1828
1829 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1830 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1831 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())?;
1832 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1833
1834 Ok(())
1835 })
1836 }
1837}
1838
1839struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1844
1845impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1846 fn clone(&self) -> Self {
1847 *self
1848 }
1849}
1850
1851impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1852
1853impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1854 fn into_pointer(&self) -> *const () {
1855 self.0 as *const _ as *const ()
1856 }
1857}
1858
1859#[allow(rustc::usage_of_ty_tykind)]
1860impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1861 fn borrow(&self) -> &T {
1862 &self.0.internee
1863 }
1864}
1865
1866impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1867 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1868 self.0.internee == other.0.internee
1871 }
1872}
1873
1874impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1875
1876impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1877 fn hash<H: Hasher>(&self, s: &mut H) {
1878 self.0.internee.hash(s)
1880 }
1881}
1882
1883impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1884 fn borrow(&self) -> &[T] {
1885 &self.0[..]
1886 }
1887}
1888
1889impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1890 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1891 self.0[..] == other.0[..]
1894 }
1895}
1896
1897impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1898
1899impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1900 fn hash<H: Hasher>(&self, s: &mut H) {
1901 self.0[..].hash(s)
1903 }
1904}
1905
1906impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1907 fn borrow(&self) -> &[T] {
1908 &self.0[..]
1909 }
1910}
1911
1912impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1913 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1914 self.0[..] == other.0[..]
1917 }
1918}
1919
1920impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1921
1922impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1923 fn hash<H: Hasher>(&self, s: &mut H) {
1924 self.0[..].hash(s)
1926 }
1927}
1928
1929macro_rules! direct_interners {
1930 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1931 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1932 fn borrow<'a>(&'a self) -> &'a $ty {
1933 &self.0
1934 }
1935 }
1936
1937 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1938 fn eq(&self, other: &Self) -> bool {
1939 self.0 == other.0
1942 }
1943 }
1944
1945 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1946
1947 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1948 fn hash<H: Hasher>(&self, s: &mut H) {
1949 self.0.hash(s)
1952 }
1953 }
1954
1955 impl<'tcx> TyCtxt<'tcx> {
1956 $vis fn $method(self, v: $ty) -> $ret_ty {
1957 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1958 InternedInSet(self.interners.arena.alloc(v))
1959 }).0))
1960 }
1961 })+
1962 }
1963}
1964
1965impl<'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! {
1969 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
1970 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
1971 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
1972 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
1973 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
1974 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
1975 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
1976 ExternalConstraints -> ExternalConstraints<'tcx>,
1977}
1978
1979macro_rules! slice_interners {
1980 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
1981 impl<'tcx> TyCtxt<'tcx> {
1982 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
1983 if v.is_empty() {
1984 List::empty()
1985 } else {
1986 self.interners.$field.intern_ref(v, || {
1987 InternedInSet(List::from_arena(&*self.arena, (), v))
1988 }).0
1989 }
1990 })+
1991 }
1992 );
1993}
1994
1995impl<'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!(
1999 const_lists: pub mk_const_list(Const<'tcx>),
2000 args: pub mk_args(GenericArg<'tcx>),
2001 type_lists: pub mk_type_list(Ty<'tcx>),
2002 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2003 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2004 projs: pub mk_projs(ProjectionKind),
2005 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2006 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2007 fields: pub mk_fields(FieldIdx),
2008 local_def_ids: intern_local_def_ids(LocalDefId),
2009 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2010 patterns: pub mk_patterns(Pattern<'tcx>),
2011 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2012 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2013);
2014
2015impl<'tcx> TyCtxt<'tcx> {
2016 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2020 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2021 Ty::new_fn_ptr(
2022 self,
2023 sig.map_bound(|sig| ty::FnSig {
2024 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2025 ..sig
2026 }),
2027 )
2028 }
2029
2030 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2034 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2035 sig.map_bound(|sig| ty::FnSig {
2036 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2037 ..sig
2038 })
2039 }
2040
2041 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2044 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2045 self.associated_items(trait_did)
2046 .filter_by_name_unhygienic(assoc_name.name)
2047 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2048 })
2049 }
2050
2051 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2053 let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2054 return false;
2055 };
2056 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2057
2058 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2059 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2060 return false;
2061 };
2062 trait_predicate.trait_ref.def_id == future_trait
2063 && trait_predicate.polarity == PredicatePolarity::Positive
2064 })
2065 }
2066
2067 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2075 sig.map_bound(|s| {
2076 let params = match s.inputs()[0].kind() {
2077 ty::Tuple(params) => *params,
2078 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2079 };
2080 self.mk_fn_sig(
2081 params,
2082 s.output(),
2083 s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2084 )
2085 })
2086 }
2087
2088 #[inline]
2089 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2090 self.interners.intern_predicate(binder)
2091 }
2092
2093 #[inline]
2094 pub fn reuse_or_mk_predicate(
2095 self,
2096 pred: Predicate<'tcx>,
2097 binder: Binder<'tcx, PredicateKind<'tcx>>,
2098 ) -> Predicate<'tcx> {
2099 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2100 }
2101
2102 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2103 self.check_args_compatible_inner(def_id, args, false)
2104 }
2105
2106 fn check_args_compatible_inner(
2107 self,
2108 def_id: DefId,
2109 args: &'tcx [ty::GenericArg<'tcx>],
2110 nested: bool,
2111 ) -> bool {
2112 let generics = self.generics_of(def_id);
2113
2114 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)
2118 && #[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 });
2119 let is_inherent_assoc_type_const =
2120 #[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 })
2121 && #[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 });
2122 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2123 if generics.own_params.len() + 1 != args.len() {
2124 return false;
2125 }
2126
2127 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2128 return false;
2129 }
2130
2131 &args[1..]
2132 } else {
2133 if generics.count() != args.len() {
2134 return false;
2135 }
2136
2137 let (parent_args, own_args) = args.split_at(generics.parent_count);
2138
2139 if let Some(parent) = generics.parent
2140 && !self.check_args_compatible_inner(parent, parent_args, true)
2141 {
2142 return false;
2143 }
2144
2145 own_args
2146 };
2147
2148 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2149 match (¶m.kind, arg.kind()) {
2150 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2151 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2152 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2153 _ => return false,
2154 }
2155 }
2156
2157 true
2158 }
2159
2160 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2163 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2164 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)
2165 && #[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 });
2166 let is_inherent_assoc_type_const =
2167 #[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 })
2168 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(
2169 self.def_kind(self.parent(def_id)),
2170 DefKind::Impl { of_trait: false }
2171 );
2172 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2173 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!(
2174 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2175 self.def_path_str(def_id),
2176 args,
2177 self.mk_args_from_iter(
2179 [self.types.self_param.into()].into_iter().chain(
2180 self.generics_of(def_id)
2181 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2182 .iter()
2183 .copied()
2184 )
2185 )
2186 );
2187 } else {
2188 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!(
2189 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2190 self.def_path_str(def_id),
2191 args,
2192 ty::GenericArgs::identity_for_item(self, def_id)
2193 );
2194 }
2195 }
2196 }
2197
2198 #[inline(always)]
2199 pub(crate) fn check_and_mk_args(
2200 self,
2201 def_id: DefId,
2202 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2203 ) -> GenericArgsRef<'tcx> {
2204 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2205 self.debug_assert_args_compatible(def_id, args);
2206 args
2207 }
2208
2209 #[inline]
2210 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2211 self.interners.intern_const(kind)
2212 }
2213
2214 #[allow(rustc::usage_of_ty_tykind)]
2216 #[inline]
2217 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2218 self.interners.intern_ty(st)
2219 }
2220
2221 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2222 match param.kind {
2223 GenericParamDefKind::Lifetime => {
2224 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2225 }
2226 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2227 GenericParamDefKind::Const { .. } => {
2228 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2229 .into()
2230 }
2231 }
2232 }
2233
2234 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2235 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2236 }
2237
2238 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2239 self.mk_place_elem(place, PlaceElem::Deref)
2240 }
2241
2242 pub fn mk_place_downcast(
2243 self,
2244 place: Place<'tcx>,
2245 adt_def: AdtDef<'tcx>,
2246 variant_index: VariantIdx,
2247 ) -> Place<'tcx> {
2248 self.mk_place_elem(
2249 place,
2250 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2251 )
2252 }
2253
2254 pub fn mk_place_downcast_unnamed(
2255 self,
2256 place: Place<'tcx>,
2257 variant_index: VariantIdx,
2258 ) -> Place<'tcx> {
2259 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2260 }
2261
2262 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2263 self.mk_place_elem(place, PlaceElem::Index(index))
2264 }
2265
2266 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2270 Place {
2271 local: place.local,
2272 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2273 }
2274 }
2275
2276 pub fn mk_poly_existential_predicates(
2277 self,
2278 eps: &[PolyExistentialPredicate<'tcx>],
2279 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2280 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2281 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!(
2282 eps.array_windows()
2283 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2284 != Ordering::Greater)
2285 );
2286 self.intern_poly_existential_predicates(eps)
2287 }
2288
2289 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2290 self.interners.intern_clauses(clauses)
2294 }
2295
2296 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2297 self.intern_local_def_ids(def_ids)
2301 }
2302
2303 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2304 where
2305 I: Iterator<Item = T>,
2306 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2307 {
2308 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2309 }
2310
2311 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2312 where
2313 I: Iterator<Item = T>,
2314 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2315 {
2316 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2317 }
2318
2319 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2320 where
2321 I: Iterator<Item = T>,
2322 T: CollectAndApply<
2323 &'tcx ty::CapturedPlace<'tcx>,
2324 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2325 >,
2326 {
2327 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2328 }
2329
2330 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2331 where
2332 I: Iterator<Item = T>,
2333 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2334 {
2335 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2336 }
2337
2338 pub fn mk_fn_sig<I, T>(
2343 self,
2344 inputs: I,
2345 output: I::Item,
2346 fn_sig_kind: FnSigKind<'tcx>,
2347 ) -> T::Output
2348 where
2349 I: IntoIterator<Item = T>,
2350 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2351 {
2352 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2353 inputs_and_output: self.mk_type_list(xs),
2354 fn_sig_kind,
2355 })
2356 }
2357
2358 pub fn mk_fn_sig_rust_abi<I, T>(
2360 self,
2361 inputs: I,
2362 output: I::Item,
2363 safety: hir::Safety,
2364 ) -> T::Output
2365 where
2366 I: IntoIterator<Item = T>,
2367 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2368 {
2369 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2370 }
2371
2372 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2374 where
2375 I: IntoIterator<Item = T>,
2376 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2377 {
2378 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2379 }
2380
2381 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2382 where
2383 I: Iterator<Item = T>,
2384 T: CollectAndApply<
2385 PolyExistentialPredicate<'tcx>,
2386 &'tcx List<PolyExistentialPredicate<'tcx>>,
2387 >,
2388 {
2389 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2390 }
2391
2392 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2393 where
2394 I: Iterator<Item = T>,
2395 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2396 {
2397 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2398 }
2399
2400 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2401 where
2402 I: Iterator<Item = T>,
2403 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2404 {
2405 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2406 }
2407
2408 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2409 where
2410 I: Iterator<Item = T>,
2411 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2412 {
2413 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2414 }
2415
2416 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2417 where
2418 I: Iterator<Item = T>,
2419 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2420 {
2421 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2422 }
2423
2424 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2425 where
2426 I: Iterator<Item = T>,
2427 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2428 {
2429 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2430 }
2431
2432 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2433 where
2434 I: Iterator<Item = T>,
2435 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2436 {
2437 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2438 }
2439
2440 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2441 where
2442 I: Iterator<Item = T>,
2443 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2444 {
2445 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2446 }
2447
2448 pub fn mk_args_trait(
2449 self,
2450 self_ty: Ty<'tcx>,
2451 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2452 ) -> GenericArgsRef<'tcx> {
2453 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2454 }
2455
2456 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2457 where
2458 I: Iterator<Item = T>,
2459 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2460 {
2461 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2462 }
2463
2464 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2465 where
2466 I: Iterator<Item = T>,
2467 T: CollectAndApply<
2468 ty::ArgOutlivesPredicate<'tcx>,
2469 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2470 >,
2471 {
2472 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2473 }
2474
2475 #[track_caller]
2478 pub fn emit_node_span_lint(
2479 self,
2480 lint: &'static Lint,
2481 hir_id: HirId,
2482 span: impl Into<MultiSpan>,
2483 decorator: impl for<'a> Diagnostic<'a, ()>,
2484 ) {
2485 let level = self.lint_level_at_node(lint, hir_id);
2486 emit_lint_base(self.sess, lint, level, Some(span.into()), decorator)
2487 }
2488
2489 pub fn crate_level_attribute_injection_span(self) -> Span {
2491 let node = self.hir_node(hir::CRATE_HIR_ID);
2492 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2493 m.spans.inject_use_span.shrink_to_lo()
2494 }
2495
2496 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2497 self,
2498 diag: &mut Diag<'_, E>,
2499 features: impl IntoIterator<Item = (String, Symbol)>,
2500 ) {
2501 if !self.sess.is_nightly_build() {
2502 return;
2503 }
2504
2505 let span = self.crate_level_attribute_injection_span();
2506 for (desc, feature) in features {
2507 let msg =
2509 ::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}");
2510 diag.span_suggestion_verbose(
2511 span,
2512 msg,
2513 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2514 Applicability::MaybeIncorrect,
2515 );
2516 }
2517 }
2518
2519 #[track_caller]
2522 pub fn emit_node_lint(
2523 self,
2524 lint: &'static Lint,
2525 id: HirId,
2526 decorator: impl for<'a> Diagnostic<'a, ()>,
2527 ) {
2528 let level = self.lint_level_at_node(lint, id);
2529 emit_lint_base(self.sess, lint, level, None, decorator);
2530 }
2531
2532 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2533 let map = self.in_scope_traits_map(id.owner)?;
2534 let candidates = map.get(&id.local_id)?;
2535 Some(candidates)
2536 }
2537
2538 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2539 {
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:2539",
"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(2539u32),
::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");
2540 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2541 }
2542
2543 pub fn is_late_bound(self, id: HirId) -> bool {
2544 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2545 }
2546
2547 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2548 self.mk_bound_variable_kinds(
2549 &self
2550 .late_bound_vars_map(id.owner)
2551 .get(&id.local_id)
2552 .cloned()
2553 .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))),
2554 )
2555 }
2556
2557 pub fn map_opaque_lifetime_to_parent_lifetime(
2565 self,
2566 mut opaque_lifetime_param_def_id: LocalDefId,
2567 ) -> ty::Region<'tcx> {
2568 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!(
2569 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2570 "{opaque_lifetime_param_def_id:?} is a {}",
2571 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2572 );
2573
2574 loop {
2575 let parent = self.local_parent(opaque_lifetime_param_def_id);
2576 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2577
2578 let Some((lifetime, _)) = lifetime_mapping
2579 .iter()
2580 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2581 else {
2582 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2583 };
2584
2585 match *lifetime {
2586 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2587 let new_parent = self.local_parent(ebv);
2588
2589 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2592 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);
2593 opaque_lifetime_param_def_id = ebv;
2594 continue;
2595 }
2596
2597 let generics = self.generics_of(new_parent);
2598 return ty::Region::new_early_param(
2599 self,
2600 ty::EarlyParamRegion {
2601 index: generics
2602 .param_def_id_to_index(self, ebv.to_def_id())
2603 .expect("early-bound var should be present in fn generics"),
2604 name: self.item_name(ebv.to_def_id()),
2605 },
2606 );
2607 }
2608 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2609 let new_parent = self.local_parent(lbv);
2610 return ty::Region::new_late_param(
2611 self,
2612 new_parent.to_def_id(),
2613 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2614 );
2615 }
2616 resolve_bound_vars::ResolvedArg::Error(guar) => {
2617 return ty::Region::new_error(self, guar);
2618 }
2619 _ => {
2620 return ty::Region::new_error_with_message(
2621 self,
2622 self.def_span(opaque_lifetime_param_def_id),
2623 "cannot resolve lifetime",
2624 );
2625 }
2626 }
2627 }
2628 }
2629
2630 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2635 self.is_const_fn(def_id)
2636 && match self.lookup_const_stability(def_id) {
2637 None => true, Some(stability) if stability.is_const_stable() => true,
2639 _ => false,
2640 }
2641 }
2642
2643 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2645 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2646 && self.impl_trait_header(def_id).constness == hir::Constness::Const
2647 }
2648
2649 pub fn is_sdylib_interface_build(self) -> bool {
2650 self.sess.opts.unstable_opts.build_sdylib_interface
2651 }
2652
2653 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2654 let def_id = def_id.into_query_key();
2655 match self.def_kind(def_id) {
2656 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2657 _ => None,
2658 }
2659 }
2660
2661 pub fn next_trait_solver_globally(self) -> bool {
2662 self.sess.opts.unstable_opts.next_solver.globally
2663 }
2664
2665 pub fn next_trait_solver_in_coherence(self) -> bool {
2666 self.sess.opts.unstable_opts.next_solver.coherence
2667 }
2668
2669 #[allow(rustc::bad_opt_access)]
2670 pub fn use_typing_mode_borrowck(self) -> bool {
2671 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
2672 }
2673
2674 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2675 self.opt_rpitit_info(def_id).is_some()
2676 }
2677
2678 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2688 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2689 }
2690
2691 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2693 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2694 }
2695
2696 pub fn resolver_for_lowering(
2697 self,
2698 ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc<ast::Crate>)> {
2699 self.resolver_for_lowering_raw(()).0
2700 }
2701
2702 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2703 make_metadata(self)
2704 }
2705
2706 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2707 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2708 self.coroutine_kind(def_id)
2709 && let ty::Coroutine(_, args) =
2710 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2711 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2712 {
2713 true
2714 } else {
2715 false
2716 }
2717 }
2718
2719 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2721 {
{
'done:
{
for i in
::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(DoNotRecommend { .. }) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(self, def_id, DoNotRecommend { .. })
2722 }
2723
2724 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2725 let def_id = def_id.into_query_key();
2726 self.trivial_const(def_id).is_some()
2727 }
2728
2729 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2732 if self.is_lang_item(def_id, LangItem::Start) {
2733 return true;
2734 }
2735 if let Some((entry_def_id, _)) = self.entry_fn(())
2736 && entry_def_id == def_id
2737 {
2738 return true;
2739 }
2740 false
2741 }
2742}
2743
2744pub fn provide(providers: &mut Providers) {
2745 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);
2746 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);
2747 providers.has_panic_handler = |tcx, LocalCrate| {
2748 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2750 };
2751 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2752}