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