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