1#![allow(rustc::usage_of_ty_tykind)]
4
5mod impl_interner;
6pub mod tls;
7
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::{PhantomData, PointeeSized};
14use std::ops::{Bound, Deref};
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::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::HashStable;
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, KEY: ::core::marker::Copy + Copy> ::core::marker::Copy for
TyCtxtFeed<'tcx, KEY> {
}Copy, #[automatically_derived]
impl<'tcx, KEY: ::core::clone::Clone + Copy> ::core::clone::Clone for
TyCtxtFeed<'tcx, KEY> {
#[inline]
fn clone(&self) -> TyCtxtFeed<'tcx, KEY> {
TyCtxtFeed {
tcx: ::core::clone::Clone::clone(&self.tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
542pub struct TyCtxtFeed<'tcx, KEY: Copy> {
543 pub tcx: TyCtxt<'tcx>,
544 key: KEY,
546}
547
548impl<KEY: Copy> !HashStable for TyCtxtFeed<'_, KEY> {}
551
552#[derive(#[automatically_derived]
impl<'tcx, KEY: ::core::marker::Copy + Copy> ::core::marker::Copy for
Feed<'tcx, KEY> {
}Copy, #[automatically_derived]
impl<'tcx, KEY: ::core::clone::Clone + Copy> ::core::clone::Clone for
Feed<'tcx, KEY> {
#[inline]
fn clone(&self) -> Feed<'tcx, KEY> {
Feed {
_tcx: ::core::clone::Clone::clone(&self._tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
557pub struct Feed<'tcx, KEY: Copy> {
558 _tcx: PhantomData<TyCtxt<'tcx>>,
559 key: KEY,
561}
562
563impl<KEY: Copy> !HashStable for Feed<'_, KEY> {}
566
567impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
568 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
569 self.key.fmt(f)
570 }
571}
572
573impl<'tcx> TyCtxt<'tcx> {
578 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
581 self.dep_graph.assert_ignored();
582 TyCtxtFeed { tcx: self, key: () }
583 }
584
585 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
588 let key = self.untracked().source_span.push(span);
589 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);
590 TyCtxtFeed { tcx: self, key }
591 }
592
593 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
597 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);
598 TyCtxtFeed { tcx: self, key }.type_of(value)
599 }
600
601 pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) {
603 self.dep_graph.assert_ignored();
604 TyCtxtFeed { tcx: self, key }.delayed_owner(owner);
605 }
606
607 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
615 if truecfg!(debug_assertions) {
616 match self.def_kind(self.local_parent(key)) {
617 DefKind::Impl { of_trait: true } => {}
618 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:?}"),
619 }
620 }
621 TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id())
622 }
623}
624
625impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
626 #[inline(always)]
627 pub fn key(&self) -> KEY {
628 self.key
629 }
630
631 #[inline(always)]
632 pub fn downgrade(self) -> Feed<'tcx, KEY> {
633 Feed { _tcx: PhantomData, key: self.key }
634 }
635}
636
637impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
638 #[inline(always)]
639 pub fn key(&self) -> KEY {
640 self.key
641 }
642
643 #[inline(always)]
644 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
645 TyCtxtFeed { tcx, key: self.key }
646 }
647}
648
649impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
650 #[inline(always)]
651 pub fn def_id(&self) -> LocalDefId {
652 self.key
653 }
654
655 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
657 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
658 }
659
660 pub fn feed_hir(&self) {
662 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
663
664 let node = hir::OwnerNode::Synthetic;
665 let bodies = Default::default();
666 let attrs = hir::AttributeMap::EMPTY;
667
668 let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
669 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque);
670 let node = node.into();
671 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
672 opt_hash_including_bodies,
673 nodes: IndexVec::from_elem_n(
674 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
675 1,
676 ),
677 bodies,
678 })));
679 self.feed_owner_id().hir_attr_map(attrs);
680 }
681}
682
683#[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)]
701#[rustc_diagnostic_item = "TyCtxt"]
702#[rustc_pass_by_value]
703pub struct TyCtxt<'tcx> {
704 gcx: &'tcx GlobalCtxt<'tcx>,
705}
706
707unsafe impl DynSend for TyCtxt<'_> {}
711unsafe impl DynSync for TyCtxt<'_> {}
712fn _assert_tcx_fields() {
713 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
714 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
715}
716
717impl<'tcx> Deref for TyCtxt<'tcx> {
718 type Target = &'tcx GlobalCtxt<'tcx>;
719 #[inline(always)]
720 fn deref(&self) -> &Self::Target {
721 &self.gcx
722 }
723}
724
725pub struct GlobalCtxt<'tcx> {
727 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
728 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
729
730 interners: CtxtInterners<'tcx>,
731
732 pub sess: &'tcx Session,
733 crate_types: Vec<CrateType>,
734 stable_crate_id: StableCrateId,
740
741 pub dep_graph: DepGraph,
742
743 pub prof: SelfProfilerRef,
744
745 pub types: CommonTypes<'tcx>,
747
748 pub lifetimes: CommonLifetimes<'tcx>,
750
751 pub consts: CommonConsts<'tcx>,
753
754 pub(crate) hooks: crate::hooks::Providers,
757
758 untracked: Untracked,
759
760 pub query_system: QuerySystem<'tcx>,
761 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
762
763 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
765
766 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
769
770 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
774
775 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
777 pub new_solver_canonical_param_env_cache:
778 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
779
780 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
781
782 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
784 pub clauses_cache:
786 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
787
788 pub data_layout: TargetDataLayout,
790
791 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
793
794 current_gcx: CurrentGcx,
795
796 pub jobserver_proxy: Arc<Proxy>,
798}
799
800impl<'tcx> GlobalCtxt<'tcx> {
801 pub fn enter<F, R>(&'tcx self, f: F) -> R
804 where
805 F: FnOnce(TyCtxt<'tcx>) -> R,
806 {
807 let icx = tls::ImplicitCtxt::new(self);
808
809 let _on_drop = defer(move || {
811 *self.current_gcx.value.write() = None;
812 });
813
814 {
816 let mut guard = self.current_gcx.value.write();
817 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
818 *guard = Some(self as *const _ as *const ());
819 }
820
821 tls::enter_context(&icx, || f(icx.tcx))
822 }
823}
824
825#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
832pub struct CurrentGcx {
833 value: Arc<RwLock<Option<*const ()>>>,
836}
837
838unsafe impl DynSend for CurrentGcx {}
839unsafe impl DynSync for CurrentGcx {}
840
841impl CurrentGcx {
842 pub fn new() -> Self {
843 Self { value: Arc::new(RwLock::new(None)) }
844 }
845
846 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
847 let read_guard = self.value.read();
848 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
849 f(unsafe { &*gcx })
853 }
854}
855
856impl<'tcx> TyCtxt<'tcx> {
857 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
858 let root = self.typeck_root_def_id_local(def_id);
861 self.hir_node_by_def_id(root).body_id().is_some()
862 }
863
864 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
869 let def_kind = self.def_kind(def_id);
870 if def_kind.has_codegen_attrs() {
871 self.codegen_fn_attrs(def_id)
872 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
DefKind::InlineConst | DefKind::GlobalAsm => true,
_ => false,
}matches!(
873 def_kind,
874 DefKind::AnonConst
875 | DefKind::AssocConst { .. }
876 | DefKind::Const { .. }
877 | DefKind::InlineConst
878 | DefKind::GlobalAsm
879 ) {
880 CodegenFnAttrs::EMPTY
881 } else {
882 crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind))bug!(
883 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
884 def_id,
885 def_kind
886 )
887 }
888 }
889
890 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
891 self.arena.alloc(Steal::new(thir))
892 }
893
894 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
895 self.arena.alloc(Steal::new(mir))
896 }
897
898 pub fn alloc_steal_promoted(
899 self,
900 promoted: IndexVec<Promoted, Body<'tcx>>,
901 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
902 self.arena.alloc(Steal::new(promoted))
903 }
904
905 pub fn mk_adt_def(
906 self,
907 did: DefId,
908 kind: AdtKind,
909 variants: IndexVec<VariantIdx, ty::VariantDef>,
910 repr: ReprOptions,
911 ) -> ty::AdtDef<'tcx> {
912 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
913 }
914
915 pub fn allocate_bytes_dedup<'a>(
918 self,
919 bytes: impl Into<Cow<'a, [u8]>>,
920 salt: usize,
921 ) -> interpret::AllocId {
922 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
924 let alloc = self.mk_const_alloc(alloc);
925 self.reserve_and_set_memory_dedup(alloc, salt)
926 }
927
928 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
930 if self.sess.opts.unstable_opts.experimental_default_bounds {
931 &[
932 LangItem::DefaultTrait1,
933 LangItem::DefaultTrait2,
934 LangItem::DefaultTrait3,
935 LangItem::DefaultTrait4,
936 ]
937 } else {
938 &[]
939 }
940 }
941
942 pub fn is_default_trait(self, def_id: DefId) -> bool {
943 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
944 }
945
946 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
947 #[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))
948 }
949
950 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
954 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);
955 let end =
956 {
{
'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))
957 .unwrap_or(Bound::Unbounded);
958 (start, end)
959 }
960
961 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
962 value.lift_to_interner(self)
963 }
964
965 pub fn create_global_ctxt<T>(
972 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
973 s: &'tcx Session,
974 crate_types: Vec<CrateType>,
975 stable_crate_id: StableCrateId,
976 arena: &'tcx WorkerLocal<Arena<'tcx>>,
977 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
978 untracked: Untracked,
979 dep_graph: DepGraph,
980 dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
981 query_system: QuerySystem<'tcx>,
982 hooks: crate::hooks::Providers,
983 current_gcx: CurrentGcx,
984 jobserver_proxy: Arc<Proxy>,
985 f: impl FnOnce(TyCtxt<'tcx>) -> T,
986 ) -> T {
987 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
988 s.dcx().emit_fatal(err);
989 });
990 let interners = CtxtInterners::new(arena);
991 let common_types = CommonTypes::new(&interners);
992 let common_lifetimes = CommonLifetimes::new(&interners);
993 let common_consts = CommonConsts::new(&interners, &common_types);
994
995 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
996 sess: s,
997 crate_types,
998 stable_crate_id,
999 arena,
1000 hir_arena,
1001 interners,
1002 dep_graph,
1003 hooks,
1004 prof: s.prof.clone(),
1005 types: common_types,
1006 lifetimes: common_lifetimes,
1007 consts: common_consts,
1008 untracked,
1009 query_system,
1010 dep_kind_vtables,
1011 ty_rcache: Default::default(),
1012 selection_cache: Default::default(),
1013 evaluation_cache: Default::default(),
1014 new_solver_evaluation_cache: Default::default(),
1015 new_solver_canonical_param_env_cache: Default::default(),
1016 canonical_param_env_cache: Default::default(),
1017 highest_var_in_clauses_cache: Default::default(),
1018 clauses_cache: Default::default(),
1019 data_layout,
1020 alloc_map: interpret::AllocMap::new(),
1021 current_gcx,
1022 jobserver_proxy,
1023 });
1024
1025 gcx.enter(f)
1027 }
1028
1029 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1031 self.get_lang_items(())
1032 }
1033
1034 #[track_caller]
1036 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1037 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1038 self.type_of(ordering_enum).no_bound_vars().unwrap()
1039 }
1040
1041 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1044 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1045 }
1046
1047 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1049 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1050 }
1051
1052 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1054 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1055 }
1056
1057 pub fn is_coroutine(self, def_id: DefId) -> bool {
1058 self.coroutine_kind(def_id).is_some()
1059 }
1060
1061 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1062 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1063 }
1064
1065 pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1066 if !self.is_type_const(def_id) {
1067 return None;
1068 }
1069 Some(self.def_span(def_id))
1070 }
1071
1072 pub fn is_type_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1074 let def_id = def_id.into_query_key();
1075 match self.def_kind(def_id) {
1076 DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1077 is_type_const
1078 }
1079 _ => false,
1080 }
1081 }
1082
1083 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1086 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1087 }
1088
1089 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1091 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1092 self.coroutine_kind(def_id),
1093 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1094 )
1095 }
1096
1097 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1100 #[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)
1101 }
1102
1103 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1106 #[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(_)))
1107 }
1108
1109 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1111 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1112 self.coroutine_kind(def_id),
1113 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1114 )
1115 }
1116
1117 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1119 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1120 self.coroutine_kind(def_id),
1121 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1122 )
1123 }
1124
1125 pub fn features(self) -> &'tcx rustc_feature::Features {
1126 self.features_query(())
1127 }
1128
1129 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1130 let id = id.into_query_key();
1131 if let Some(id) = id.as_local() {
1133 self.definitions_untracked().def_key(id)
1134 } else {
1135 self.cstore_untracked().def_key(id)
1136 }
1137 }
1138
1139 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1145 if let Some(id) = id.as_local() {
1147 self.definitions_untracked().def_path(id)
1148 } else {
1149 self.cstore_untracked().def_path(id)
1150 }
1151 }
1152
1153 #[inline]
1154 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1155 if let Some(def_id) = def_id.as_local() {
1157 self.definitions_untracked().def_path_hash(def_id)
1158 } else {
1159 self.cstore_untracked().def_path_hash(def_id)
1160 }
1161 }
1162
1163 #[inline]
1164 pub fn crate_types(self) -> &'tcx [CrateType] {
1165 &self.crate_types
1166 }
1167
1168 pub fn needs_metadata(self) -> bool {
1169 self.crate_types().iter().any(|ty| match *ty {
1170 CrateType::Executable
1171 | CrateType::StaticLib
1172 | CrateType::Cdylib
1173 | CrateType::Sdylib => false,
1174 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1175 })
1176 }
1177
1178 pub fn needs_crate_hash(self) -> bool {
1179 truecfg!(debug_assertions)
1191 || self.sess.opts.incremental.is_some()
1192 || self.needs_metadata()
1193 || self.sess.instrument_coverage()
1194 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1195 }
1196
1197 #[inline]
1198 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1199 if crate_num == LOCAL_CRATE {
1200 self.stable_crate_id
1201 } else {
1202 self.cstore_untracked().stable_crate_id(crate_num)
1203 }
1204 }
1205
1206 #[inline]
1209 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1210 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1211 LOCAL_CRATE
1212 } else {
1213 *self
1214 .untracked()
1215 .stable_crate_ids
1216 .read()
1217 .get(&stable_crate_id)
1218 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1219 }
1220 }
1221
1222 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1226 {
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:1226",
"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(1226u32),
::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);
1227
1228 let stable_crate_id = hash.stable_crate_id();
1229
1230 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1233 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1234 } else {
1235 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1236 }
1237 }
1238
1239 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1240 let (crate_name, stable_crate_id) = if def_id.is_local() {
1245 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1246 } else {
1247 let cstore = &*self.cstore_untracked();
1248 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1249 };
1250
1251 ::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!(
1252 "{}[{:04x}]{}",
1253 crate_name,
1254 stable_crate_id.as_u64() >> (8 * 6),
1257 self.def_path(def_id).to_string_no_crate_verbose()
1258 )
1259 }
1260
1261 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1262 self.sess.dcx()
1263 }
1264
1265 pub fn is_target_feature_call_safe(
1268 self,
1269 callee_features: &[TargetFeature],
1270 body_features: &[TargetFeature],
1271 ) -> bool {
1272 self.sess.target.options.is_like_wasm
1277 || callee_features
1278 .iter()
1279 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1280 }
1281
1282 pub fn adjust_target_feature_sig(
1285 self,
1286 fun_def: DefId,
1287 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1288 caller: DefId,
1289 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1290 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1291 let caller_features = &self.body_codegen_attrs(caller).target_features;
1292 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1293 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1294 fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1295 ..sig
1296 }));
1297 }
1298 None
1299 }
1300
1301 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1304 match self.env_var_os(key.as_ref()) {
1305 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1306 None => Err(VarError::NotPresent),
1307 }
1308 }
1309}
1310
1311impl<'tcx> TyCtxtAt<'tcx> {
1312 pub fn create_def(
1314 self,
1315 parent: LocalDefId,
1316 name: Option<Symbol>,
1317 def_kind: DefKind,
1318 override_def_path_data: Option<DefPathData>,
1319 disambiguator: &mut PerParentDisambiguatorState,
1320 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1321 let feed =
1322 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1323
1324 feed.def_span(self.span);
1325 feed
1326 }
1327}
1328
1329impl<'tcx> TyCtxt<'tcx> {
1330 pub fn create_def(
1332 self,
1333 parent: LocalDefId,
1334 name: Option<Symbol>,
1335 def_kind: DefKind,
1336 override_def_path_data: Option<DefPathData>,
1337 disambiguator: &mut PerParentDisambiguatorState,
1338 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1339 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1340 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1350
1351 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1356
1357 let feed = TyCtxtFeed { tcx: self, key: def_id };
1358 feed.def_kind(def_kind);
1359 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1364 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1365 feed.visibility(ty::Visibility::Restricted(parent_mod));
1366 }
1367
1368 feed
1369 }
1370
1371 pub fn create_crate_num(
1372 self,
1373 stable_crate_id: StableCrateId,
1374 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1375 let mut lock = self.untracked().stable_crate_ids.write();
1376 if let Some(&existing) = lock.get(&stable_crate_id) {
1377 return Err(existing);
1378 }
1379 let num = CrateNum::new(lock.len());
1380 lock.insert(stable_crate_id, num);
1381 Ok(TyCtxtFeed { key: num, tcx: self })
1382 }
1383
1384 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1385 self.ensure_ok().analysis(());
1387
1388 let definitions = &self.untracked.definitions;
1389 gen {
1390 let mut i = 0;
1391
1392 while i < { definitions.read().num_definitions() } {
1395 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1396 yield LocalDefId { local_def_index };
1397 i += 1;
1398 }
1399
1400 definitions.freeze();
1402 }
1403 }
1404
1405 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1406 self.ensure_ok().analysis(());
1408
1409 self.untracked.definitions.freeze().def_path_table()
1412 }
1413
1414 pub fn def_path_hash_to_def_index_map(
1415 self,
1416 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1417 self.ensure_ok().hir_crate_items(());
1420 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1423 }
1424
1425 #[inline]
1428 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1429 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1430 }
1431
1432 pub fn untracked(self) -> &'tcx Untracked {
1434 &self.untracked
1435 }
1436 #[inline]
1439 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1440 self.untracked.definitions.read()
1441 }
1442
1443 #[inline]
1446 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1447 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1448 }
1449
1450 #[inline(always)]
1451 pub fn with_stable_hashing_context<R>(
1452 self,
1453 f: impl FnOnce(StableHashingContext<'_>) -> R,
1454 ) -> R {
1455 f(StableHashingContext::new(self.sess, &self.untracked))
1456 }
1457
1458 #[inline]
1459 pub fn local_crate_exports_generics(self) -> bool {
1460 if self.is_compiler_builtins(LOCAL_CRATE) {
1464 return false;
1465 }
1466 self.crate_types().iter().any(|crate_type| {
1467 match crate_type {
1468 CrateType::Executable
1469 | CrateType::StaticLib
1470 | CrateType::ProcMacro
1471 | CrateType::Cdylib
1472 | CrateType::Sdylib => false,
1473
1474 CrateType::Dylib => true,
1479
1480 CrateType::Rlib => true,
1481 }
1482 })
1483 }
1484
1485 pub fn is_suitable_region(
1487 self,
1488 generic_param_scope: LocalDefId,
1489 mut region: Region<'tcx>,
1490 ) -> Option<FreeRegionInfo> {
1491 let (suitable_region_binding_scope, region_def_id) = loop {
1492 let def_id =
1493 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1494 let scope = self.local_parent(def_id);
1495 if self.def_kind(scope) == DefKind::OpaqueTy {
1496 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1499 continue;
1500 }
1501 break (scope, def_id.into());
1502 };
1503
1504 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1505 Node::Item(..) | Node::TraitItem(..) => false,
1506 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1507 hir::ImplItemImplKind::Trait { .. } => true,
1514 _ => false,
1515 },
1516 _ => false,
1517 };
1518
1519 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1520 }
1521
1522 pub fn return_type_impl_or_dyn_traits(
1524 self,
1525 scope_def_id: LocalDefId,
1526 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1527 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1528 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1529 self.hir_fn_decl_by_hir_id(hir_id)
1530 else {
1531 return ::alloc::vec::Vec::new()vec![];
1532 };
1533
1534 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1535 v.visit_ty_unambig(hir_output);
1536 v.0
1537 }
1538
1539 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1543 self,
1544 scope_def_id: LocalDefId,
1545 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1546 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1547 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1548 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1550 && let hir::TyKind::Path(hir::QPath::Resolved(
1551 None,
1552 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1553 && let Some(local_id) = def_id.as_local()
1554 && 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()
1556 {
1557 v.visit_ty_unambig(alias_ty);
1558 if !v.0.is_empty() {
1559 return Some((
1560 v.0,
1561 alias_generics.span,
1562 alias_generics.span_for_lifetime_suggestion(),
1563 ));
1564 }
1565 }
1566 None
1567 }
1568
1569 pub fn has_strict_asm_symbol_naming(self) -> bool {
1572 self.sess.target.llvm_target.starts_with("nvptx")
1573 }
1574
1575 pub fn caller_location_ty(self) -> Ty<'tcx> {
1577 Ty::new_imm_ref(
1578 self,
1579 self.lifetimes.re_static,
1580 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1581 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1582 .skip_norm_wip(),
1583 )
1584 }
1585
1586 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1588 let kind = self.def_kind(def_id);
1589 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1590 }
1591
1592 pub fn type_length_limit(self) -> Limit {
1593 self.limits(()).type_length_limit
1594 }
1595
1596 pub fn recursion_limit(self) -> Limit {
1597 self.limits(()).recursion_limit
1598 }
1599
1600 pub fn move_size_limit(self) -> Limit {
1601 self.limits(()).move_size_limit
1602 }
1603
1604 pub fn pattern_complexity_limit(self) -> Limit {
1605 self.limits(()).pattern_complexity_limit
1606 }
1607
1608 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1610 iter::once(LOCAL_CRATE)
1611 .chain(self.crates(()).iter().copied())
1612 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1613 }
1614
1615 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1617 let visible_crates =
1618 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1619
1620 iter::once(LOCAL_CRATE)
1621 .chain(visible_crates)
1622 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1623 }
1624
1625 #[inline]
1626 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1627 self.visibility(def_id).expect_local()
1628 }
1629
1630 x;#[instrument(skip(self), level = "trace", ret)]
1632 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1633 self.hir_expect_opaque_ty(def_id).origin
1634 }
1635
1636 pub fn finish(self) {
1637 self.alloc_self_profile_query_strings();
1640
1641 self.save_dep_graph();
1642 self.verify_query_key_hashes();
1643
1644 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1645 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
1646 }
1647 }
1648
1649 pub fn report_unused_features(self) {
1650 #[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)]
1651 #[diag("feature `{$feature}` is declared but not used")]
1652 struct UnusedFeature {
1653 feature: Symbol,
1654 }
1655
1656 let used_features = self.sess.used_features.lock();
1658 let unused_features = self
1659 .features()
1660 .enabled_features_iter_stable_order()
1661 .filter(|(f, _)| {
1662 !used_features.contains_key(f)
1663 && f.as_str() != "restricted_std"
1670 && *f != sym::doc_cfg
1674 })
1675 .collect::<Vec<_>>();
1676
1677 for (feature, span) in unused_features {
1678 self.emit_node_span_lint(
1679 rustc_session::lint::builtin::UNUSED_FEATURES,
1680 CRATE_HIR_ID,
1681 span,
1682 UnusedFeature { feature },
1683 );
1684 }
1685 }
1686}
1687
1688macro_rules! nop_lift {
1689 ($set:ident; $ty:ty => $lifted:ty) => {
1690 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1691 type Lifted = $lifted;
1692 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1693 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1698 _x: Interned<'tcx, Inner>,
1699 ) -> InternedSet<'tcx, Inner> {
1700 unreachable!()
1701 }
1702 fn _type_eq<T>(_x: &T, _y: &T) {}
1703 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1704 let interner = _intern_set_ty_from_interned_ty(x.0);
1708 _type_eq(&interner, &tcx.interners.$set);
1710 }
1711
1712 tcx.interners
1713 .$set
1714 .contains_pointer_to(&InternedInSet(&*self.0.0))
1715 .then(|| unsafe { mem::transmute(self) })
1718 }
1719 }
1720 };
1721}
1722
1723macro_rules! nop_list_lift {
1724 ($set:ident; $ty:ty => $lifted:ty) => {
1725 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
1726 type Lifted = &'tcx List<$lifted>;
1727 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1728 if false {
1730 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
1731 }
1732
1733 if self.is_empty() {
1734 return Some(List::empty());
1735 }
1736 tcx.interners
1737 .$set
1738 .contains_pointer_to(&InternedInSet(self))
1739 .then(|| unsafe { mem::transmute(self) })
1740 }
1741 }
1742 };
1743}
1744
1745impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Ty<'a> {
type Lifted = Ty<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Ty<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.type_);
}
tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { type_; Ty<'a> => Ty<'tcx> }
1746impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Region<'a> {
type Lifted = Region<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Region<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.region);
}
tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { region; Region<'a> => Region<'tcx> }
1747impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Const<'a> {
type Lifted = Const<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Const<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_);
}
tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { const_; Const<'a> => Const<'tcx> }
1748impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Pattern<'a> {
type Lifted = Pattern<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Pattern<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.pat);
}
tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
1749impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ConstAllocation<'a> {
type Lifted = ConstAllocation<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ConstAllocation<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_allocation);
}
tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
1750impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Predicate<'a> {
type Lifted = Predicate<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Predicate<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
1751impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Clause<'a> {
type Lifted = Clause<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Clause<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
1752impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Layout<'a> {
type Lifted = Layout<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Layout<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.layout);
}
tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { layout; Layout<'a> => Layout<'tcx> }
1753impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ValTree<'a> {
type Lifted = ValTree<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ValTree<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.valtree);
}
tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
1754
1755impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Ty<'a>> {
type Lifted = &'tcx List<Ty<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<Ty<'tcx>>> =
&tcx.interners.type_lists;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
1756impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<PolyExistentialPredicate<'a>> {
type Lifted = &'tcx List<PolyExistentialPredicate<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>> =
&tcx.interners.poly_existential_predicates;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! {
1757 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1758}
1759impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<ty::BoundVariableKind<'a>> {
type Lifted = &'tcx List<ty::BoundVariableKind<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>> =
&tcx.interners.bound_variable_kinds;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind<'a> => ty::BoundVariableKind<'tcx> }
1760
1761impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<GenericArg<'a>> {
type Lifted = &'tcx List<GenericArg<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<GenericArg<'tcx>>> =
&tcx.interners.args;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.args.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
1763
1764macro_rules! sty_debug_print {
1765 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1766 #[allow(non_snake_case)]
1769 mod inner {
1770 use crate::ty::{self, TyCtxt};
1771 use crate::ty::context::InternedInSet;
1772
1773 #[derive(Copy, Clone)]
1774 struct DebugStat {
1775 total: usize,
1776 lt_infer: usize,
1777 ty_infer: usize,
1778 ct_infer: usize,
1779 all_infer: usize,
1780 }
1781
1782 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1783 let mut total = DebugStat {
1784 total: 0,
1785 lt_infer: 0,
1786 ty_infer: 0,
1787 ct_infer: 0,
1788 all_infer: 0,
1789 };
1790 $(let mut $variant = total;)*
1791
1792 for shard in tcx.interners.type_.lock_shards() {
1793 #[allow(rustc::potential_query_instability)]
1795 let types = shard.iter();
1796 for &(InternedInSet(t), ()) in types {
1797 let variant = match t.internee {
1798 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1799 ty::Float(..) | ty::Str | ty::Never => continue,
1800 ty::Error(_) => continue,
1801 $(ty::$variant(..) => &mut $variant,)*
1802 };
1803 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1804 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1805 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1806
1807 variant.total += 1;
1808 total.total += 1;
1809 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1810 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1811 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1812 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1813 }
1814 }
1815 writeln!(fmt, "Ty interner total ty lt ct all")?;
1816 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1817 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1818 stringify!($variant),
1819 uses = $variant.total,
1820 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1821 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1822 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1823 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1824 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1825 )*
1826 writeln!(fmt, " total {uses:6} \
1827 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1828 uses = total.total,
1829 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1830 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1831 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1832 all = total.all_infer as f64 * 100.0 / total.total as f64)
1833 }
1834 }
1835
1836 inner::go($fmt, $ctxt)
1837 }}
1838}
1839
1840impl<'tcx> TyCtxt<'tcx> {
1841 pub fn debug_stats(self) -> impl fmt::Debug {
1842 fmt::from_fn(move |fmt| {
1843 {
#[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!(
1844 fmt,
1845 self,
1846 Adt,
1847 Array,
1848 Slice,
1849 RawPtr,
1850 Ref,
1851 FnDef,
1852 FnPtr,
1853 UnsafeBinder,
1854 Placeholder,
1855 Coroutine,
1856 CoroutineWitness,
1857 Dynamic,
1858 Closure,
1859 CoroutineClosure,
1860 Tuple,
1861 Bound,
1862 Param,
1863 Infer,
1864 Alias,
1865 Pat,
1866 Foreign
1867 )?;
1868
1869 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1870 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1871 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())?;
1872 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1873
1874 Ok(())
1875 })
1876 }
1877}
1878
1879struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1884
1885impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1886 fn clone(&self) -> Self {
1887 *self
1888 }
1889}
1890
1891impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1892
1893impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1894 fn into_pointer(&self) -> *const () {
1895 self.0 as *const _ as *const ()
1896 }
1897}
1898
1899#[allow(rustc::usage_of_ty_tykind)]
1900impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1901 fn borrow(&self) -> &T {
1902 &self.0.internee
1903 }
1904}
1905
1906impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1907 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1908 self.0.internee == other.0.internee
1911 }
1912}
1913
1914impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1915
1916impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1917 fn hash<H: Hasher>(&self, s: &mut H) {
1918 self.0.internee.hash(s)
1920 }
1921}
1922
1923impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1924 fn borrow(&self) -> &[T] {
1925 &self.0[..]
1926 }
1927}
1928
1929impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1930 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1931 self.0[..] == other.0[..]
1934 }
1935}
1936
1937impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1938
1939impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1940 fn hash<H: Hasher>(&self, s: &mut H) {
1941 self.0[..].hash(s)
1943 }
1944}
1945
1946impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1947 fn borrow(&self) -> &[T] {
1948 &self.0[..]
1949 }
1950}
1951
1952impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1953 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1954 self.0[..] == other.0[..]
1957 }
1958}
1959
1960impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1961
1962impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1963 fn hash<H: Hasher>(&self, s: &mut H) {
1964 self.0[..].hash(s)
1966 }
1967}
1968
1969macro_rules! direct_interners {
1970 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1971 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1972 fn borrow<'a>(&'a self) -> &'a $ty {
1973 &self.0
1974 }
1975 }
1976
1977 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1978 fn eq(&self, other: &Self) -> bool {
1979 self.0 == other.0
1982 }
1983 }
1984
1985 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1986
1987 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1988 fn hash<H: Hasher>(&self, s: &mut H) {
1989 self.0.hash(s)
1992 }
1993 }
1994
1995 impl<'tcx> TyCtxt<'tcx> {
1996 $vis fn $method(self, v: $ty) -> $ret_ty {
1997 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1998 InternedInSet(self.interners.arena.alloc(v))
1999 }).0))
2000 }
2001 })+
2002 }
2003}
2004
2005impl<'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! {
2009 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2010 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2011 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2012 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2013 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2014 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2015 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2016 ExternalConstraints -> ExternalConstraints<'tcx>,
2017}
2018
2019macro_rules! slice_interners {
2020 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2021 impl<'tcx> TyCtxt<'tcx> {
2022 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2023 if v.is_empty() {
2024 List::empty()
2025 } else {
2026 self.interners.$field.intern_ref(v, || {
2027 InternedInSet(List::from_arena(&*self.arena, (), v))
2028 }).0
2029 }
2030 })+
2031 }
2032 );
2033}
2034
2035impl<'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!(
2039 const_lists: pub mk_const_list(Const<'tcx>),
2040 args: pub mk_args(GenericArg<'tcx>),
2041 type_lists: pub mk_type_list(Ty<'tcx>),
2042 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2043 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2044 projs: pub mk_projs(ProjectionKind),
2045 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2046 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2047 fields: pub mk_fields(FieldIdx),
2048 local_def_ids: intern_local_def_ids(LocalDefId),
2049 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2050 patterns: pub mk_patterns(Pattern<'tcx>),
2051 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2052 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2053);
2054
2055impl<'tcx> TyCtxt<'tcx> {
2056 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2060 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2061 Ty::new_fn_ptr(
2062 self,
2063 sig.map_bound(|sig| ty::FnSig {
2064 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2065 ..sig
2066 }),
2067 )
2068 }
2069
2070 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2074 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2075 sig.map_bound(|sig| ty::FnSig {
2076 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2077 ..sig
2078 })
2079 }
2080
2081 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2084 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2085 self.associated_items(trait_did)
2086 .filter_by_name_unhygienic(assoc_name.name)
2087 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2088 })
2089 }
2090
2091 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2093 let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2094 return false;
2095 };
2096 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2097
2098 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2099 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2100 return false;
2101 };
2102 trait_predicate.trait_ref.def_id == future_trait
2103 && trait_predicate.polarity == PredicatePolarity::Positive
2104 })
2105 }
2106
2107 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2115 sig.map_bound(|s| {
2116 let params = match s.inputs()[0].kind() {
2117 ty::Tuple(params) => *params,
2118 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2119 };
2120 self.mk_fn_sig(
2121 params,
2122 s.output(),
2123 s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2124 )
2125 })
2126 }
2127
2128 #[inline]
2129 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2130 self.interners.intern_predicate(binder)
2131 }
2132
2133 #[inline]
2134 pub fn reuse_or_mk_predicate(
2135 self,
2136 pred: Predicate<'tcx>,
2137 binder: Binder<'tcx, PredicateKind<'tcx>>,
2138 ) -> Predicate<'tcx> {
2139 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2140 }
2141
2142 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2143 self.check_args_compatible_inner(def_id, args, false)
2144 }
2145
2146 fn check_args_compatible_inner(
2147 self,
2148 def_id: DefId,
2149 args: &'tcx [ty::GenericArg<'tcx>],
2150 nested: bool,
2151 ) -> bool {
2152 let generics = self.generics_of(def_id);
2153
2154 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)
2158 && #[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 });
2159 let is_inherent_assoc_type_const =
2160 #[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 })
2161 && #[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 });
2162 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2163 if generics.own_params.len() + 1 != args.len() {
2164 return false;
2165 }
2166
2167 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2168 return false;
2169 }
2170
2171 &args[1..]
2172 } else {
2173 if generics.count() != args.len() {
2174 return false;
2175 }
2176
2177 let (parent_args, own_args) = args.split_at(generics.parent_count);
2178
2179 if let Some(parent) = generics.parent
2180 && !self.check_args_compatible_inner(parent, parent_args, true)
2181 {
2182 return false;
2183 }
2184
2185 own_args
2186 };
2187
2188 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2189 match (¶m.kind, arg.kind()) {
2190 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2191 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2192 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2193 _ => return false,
2194 }
2195 }
2196
2197 true
2198 }
2199
2200 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2203 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2204 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)
2205 && #[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 });
2206 let is_inherent_assoc_type_const =
2207 #[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 })
2208 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(
2209 self.def_kind(self.parent(def_id)),
2210 DefKind::Impl { of_trait: false }
2211 );
2212 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2213 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!(
2214 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2215 self.def_path_str(def_id),
2216 args,
2217 self.mk_args_from_iter(
2219 [self.types.self_param.into()].into_iter().chain(
2220 self.generics_of(def_id)
2221 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2222 .iter()
2223 .copied()
2224 )
2225 )
2226 );
2227 } else {
2228 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!(
2229 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2230 self.def_path_str(def_id),
2231 args,
2232 ty::GenericArgs::identity_for_item(self, def_id)
2233 );
2234 }
2235 }
2236 }
2237
2238 #[inline(always)]
2239 pub(crate) fn check_and_mk_args(
2240 self,
2241 def_id: DefId,
2242 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2243 ) -> GenericArgsRef<'tcx> {
2244 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2245 self.debug_assert_args_compatible(def_id, args);
2246 args
2247 }
2248
2249 #[inline]
2250 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2251 self.interners.intern_const(kind)
2252 }
2253
2254 #[allow(rustc::usage_of_ty_tykind)]
2256 #[inline]
2257 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2258 self.interners.intern_ty(st)
2259 }
2260
2261 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2262 match param.kind {
2263 GenericParamDefKind::Lifetime => {
2264 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2265 }
2266 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2267 GenericParamDefKind::Const { .. } => {
2268 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2269 .into()
2270 }
2271 }
2272 }
2273
2274 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2275 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2276 }
2277
2278 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2279 self.mk_place_elem(place, PlaceElem::Deref)
2280 }
2281
2282 pub fn mk_place_downcast(
2283 self,
2284 place: Place<'tcx>,
2285 adt_def: AdtDef<'tcx>,
2286 variant_index: VariantIdx,
2287 ) -> Place<'tcx> {
2288 self.mk_place_elem(
2289 place,
2290 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2291 )
2292 }
2293
2294 pub fn mk_place_downcast_unnamed(
2295 self,
2296 place: Place<'tcx>,
2297 variant_index: VariantIdx,
2298 ) -> Place<'tcx> {
2299 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2300 }
2301
2302 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2303 self.mk_place_elem(place, PlaceElem::Index(index))
2304 }
2305
2306 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2310 Place {
2311 local: place.local,
2312 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2313 }
2314 }
2315
2316 pub fn mk_poly_existential_predicates(
2317 self,
2318 eps: &[PolyExistentialPredicate<'tcx>],
2319 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2320 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2321 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!(
2322 eps.array_windows()
2323 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2324 != Ordering::Greater)
2325 );
2326 self.intern_poly_existential_predicates(eps)
2327 }
2328
2329 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2330 self.interners.intern_clauses(clauses)
2334 }
2335
2336 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2337 self.intern_local_def_ids(def_ids)
2341 }
2342
2343 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2344 where
2345 I: Iterator<Item = T>,
2346 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2347 {
2348 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2349 }
2350
2351 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2352 where
2353 I: Iterator<Item = T>,
2354 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2355 {
2356 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2357 }
2358
2359 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2360 where
2361 I: Iterator<Item = T>,
2362 T: CollectAndApply<
2363 &'tcx ty::CapturedPlace<'tcx>,
2364 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2365 >,
2366 {
2367 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2368 }
2369
2370 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2371 where
2372 I: Iterator<Item = T>,
2373 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2374 {
2375 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2376 }
2377
2378 pub fn mk_fn_sig<I, T>(
2383 self,
2384 inputs: I,
2385 output: I::Item,
2386 fn_sig_kind: FnSigKind<'tcx>,
2387 ) -> T::Output
2388 where
2389 I: IntoIterator<Item = T>,
2390 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2391 {
2392 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2393 inputs_and_output: self.mk_type_list(xs),
2394 fn_sig_kind,
2395 })
2396 }
2397
2398 pub fn mk_fn_sig_rust_abi<I, T>(
2400 self,
2401 inputs: I,
2402 output: I::Item,
2403 safety: hir::Safety,
2404 ) -> T::Output
2405 where
2406 I: IntoIterator<Item = T>,
2407 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2408 {
2409 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2410 }
2411
2412 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2414 where
2415 I: IntoIterator<Item = T>,
2416 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2417 {
2418 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2419 }
2420
2421 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2422 where
2423 I: Iterator<Item = T>,
2424 T: CollectAndApply<
2425 PolyExistentialPredicate<'tcx>,
2426 &'tcx List<PolyExistentialPredicate<'tcx>>,
2427 >,
2428 {
2429 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2430 }
2431
2432 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2433 where
2434 I: Iterator<Item = T>,
2435 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2436 {
2437 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2438 }
2439
2440 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2441 where
2442 I: Iterator<Item = T>,
2443 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2444 {
2445 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2446 }
2447
2448 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2449 where
2450 I: Iterator<Item = T>,
2451 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2452 {
2453 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2454 }
2455
2456 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2457 where
2458 I: Iterator<Item = T>,
2459 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2460 {
2461 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2462 }
2463
2464 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2465 where
2466 I: Iterator<Item = T>,
2467 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2468 {
2469 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2470 }
2471
2472 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2473 where
2474 I: Iterator<Item = T>,
2475 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2476 {
2477 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2478 }
2479
2480 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2481 where
2482 I: Iterator<Item = T>,
2483 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2484 {
2485 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2486 }
2487
2488 pub fn mk_args_trait(
2489 self,
2490 self_ty: Ty<'tcx>,
2491 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2492 ) -> GenericArgsRef<'tcx> {
2493 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2494 }
2495
2496 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2497 where
2498 I: Iterator<Item = T>,
2499 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2500 {
2501 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2502 }
2503
2504 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2505 where
2506 I: Iterator<Item = T>,
2507 T: CollectAndApply<
2508 ty::ArgOutlivesPredicate<'tcx>,
2509 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2510 >,
2511 {
2512 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2513 }
2514
2515 #[track_caller]
2518 pub fn emit_node_span_lint(
2519 self,
2520 lint: &'static Lint,
2521 hir_id: HirId,
2522 span: impl Into<MultiSpan>,
2523 decorator: impl for<'a> Diagnostic<'a, ()>,
2524 ) {
2525 let level = self.lint_level_at_node(lint, hir_id);
2526 emit_lint_base(self.sess, lint, level, Some(span.into()), decorator)
2527 }
2528
2529 pub fn crate_level_attribute_injection_span(self) -> Span {
2531 let node = self.hir_node(hir::CRATE_HIR_ID);
2532 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2533 m.spans.inject_use_span.shrink_to_lo()
2534 }
2535
2536 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2537 self,
2538 diag: &mut Diag<'_, E>,
2539 features: impl IntoIterator<Item = (String, Symbol)>,
2540 ) {
2541 if !self.sess.is_nightly_build() {
2542 return;
2543 }
2544
2545 let span = self.crate_level_attribute_injection_span();
2546 for (desc, feature) in features {
2547 let msg =
2549 ::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}");
2550 diag.span_suggestion_verbose(
2551 span,
2552 msg,
2553 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2554 Applicability::MaybeIncorrect,
2555 );
2556 }
2557 }
2558
2559 #[track_caller]
2562 pub fn emit_node_lint(
2563 self,
2564 lint: &'static Lint,
2565 id: HirId,
2566 decorator: impl for<'a> Diagnostic<'a, ()>,
2567 ) {
2568 let level = self.lint_level_at_node(lint, id);
2569 emit_lint_base(self.sess, lint, level, None, decorator);
2570 }
2571
2572 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2573 let map = self.in_scope_traits_map(id.owner)?;
2574 let candidates = map.get(&id.local_id)?;
2575 Some(candidates)
2576 }
2577
2578 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2579 {
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:2579",
"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(2579u32),
::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");
2580 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2581 }
2582
2583 pub fn is_late_bound(self, id: HirId) -> bool {
2584 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2585 }
2586
2587 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2588 self.mk_bound_variable_kinds(
2589 &self
2590 .late_bound_vars_map(id.owner)
2591 .get(&id.local_id)
2592 .cloned()
2593 .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))),
2594 )
2595 }
2596
2597 pub fn map_opaque_lifetime_to_parent_lifetime(
2605 self,
2606 mut opaque_lifetime_param_def_id: LocalDefId,
2607 ) -> ty::Region<'tcx> {
2608 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!(
2609 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2610 "{opaque_lifetime_param_def_id:?} is a {}",
2611 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2612 );
2613
2614 loop {
2615 let parent = self.local_parent(opaque_lifetime_param_def_id);
2616 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2617
2618 let Some((lifetime, _)) = lifetime_mapping
2619 .iter()
2620 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2621 else {
2622 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2623 };
2624
2625 match *lifetime {
2626 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2627 let new_parent = self.local_parent(ebv);
2628
2629 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2632 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);
2633 opaque_lifetime_param_def_id = ebv;
2634 continue;
2635 }
2636
2637 let generics = self.generics_of(new_parent);
2638 return ty::Region::new_early_param(
2639 self,
2640 ty::EarlyParamRegion {
2641 index: generics
2642 .param_def_id_to_index(self, ebv.to_def_id())
2643 .expect("early-bound var should be present in fn generics"),
2644 name: self.item_name(ebv.to_def_id()),
2645 },
2646 );
2647 }
2648 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2649 let new_parent = self.local_parent(lbv);
2650 return ty::Region::new_late_param(
2651 self,
2652 new_parent.to_def_id(),
2653 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2654 );
2655 }
2656 resolve_bound_vars::ResolvedArg::Error(guar) => {
2657 return ty::Region::new_error(self, guar);
2658 }
2659 _ => {
2660 return ty::Region::new_error_with_message(
2661 self,
2662 self.def_span(opaque_lifetime_param_def_id),
2663 "cannot resolve lifetime",
2664 );
2665 }
2666 }
2667 }
2668 }
2669
2670 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2675 self.is_const_fn(def_id)
2676 && match self.lookup_const_stability(def_id) {
2677 None => true, Some(stability) if stability.is_const_stable() => true,
2679 _ => false,
2680 }
2681 }
2682
2683 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2685 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2686 && self.impl_trait_header(def_id).constness == hir::Constness::Const
2687 }
2688
2689 pub fn is_sdylib_interface_build(self) -> bool {
2690 self.sess.opts.unstable_opts.build_sdylib_interface
2691 }
2692
2693 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2694 let def_id = def_id.into_query_key();
2695 match self.def_kind(def_id) {
2696 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2697 _ => None,
2698 }
2699 }
2700
2701 pub fn next_trait_solver_globally(self) -> bool {
2702 self.sess.opts.unstable_opts.next_solver.globally
2703 }
2704
2705 pub fn next_trait_solver_in_coherence(self) -> bool {
2706 self.sess.opts.unstable_opts.next_solver.coherence
2707 }
2708
2709 #[allow(rustc::bad_opt_access)]
2710 pub fn use_typing_mode_borrowck(self) -> bool {
2711 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
2712 }
2713
2714 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2715 self.opt_rpitit_info(def_id).is_some()
2716 }
2717
2718 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2728 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2729 }
2730
2731 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2733 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2734 }
2735
2736 pub fn resolver_for_lowering(
2737 self,
2738 ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc<ast::Crate>)> {
2739 self.resolver_for_lowering_raw(()).0
2740 }
2741
2742 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2743 make_metadata(self)
2744 }
2745
2746 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2747 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2748 self.coroutine_kind(def_id)
2749 && let ty::Coroutine(_, args) =
2750 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2751 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2752 {
2753 true
2754 } else {
2755 false
2756 }
2757 }
2758
2759 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2761 {
{
'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 { .. })
2762 }
2763
2764 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2765 let def_id = def_id.into_query_key();
2766 self.trivial_const(def_id).is_some()
2767 }
2768
2769 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2772 if self.is_lang_item(def_id, LangItem::Start) {
2773 return true;
2774 }
2775 if let Some((entry_def_id, _)) = self.entry_fn(())
2776 && entry_def_id == def_id
2777 {
2778 return true;
2779 }
2780 false
2781 }
2782}
2783
2784pub fn provide(providers: &mut Providers) {
2785 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);
2786 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);
2787 providers.has_panic_handler = |tcx, LocalCrate| {
2788 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2790 };
2791 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2792}