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, RegionUtilitiesExt};
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)]
1742 mod inner {
1743 use crate::ty::{self, TyCtxt};
1744 use crate::ty::context::InternedInSet;
1745
1746 #[derive(Copy, Clone)]
1747 struct DebugStat {
1748 total: usize,
1749 lt_infer: usize,
1750 ty_infer: usize,
1751 ct_infer: usize,
1752 all_infer: usize,
1753 }
1754
1755 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1756 let mut total = DebugStat {
1757 total: 0,
1758 lt_infer: 0,
1759 ty_infer: 0,
1760 ct_infer: 0,
1761 all_infer: 0,
1762 };
1763 $(let mut $variant = total;)*
1764
1765 for shard in tcx.interners.type_.lock_shards() {
1766 #[allow(rustc::potential_query_instability)]
1768 let types = shard.iter();
1769 for &(InternedInSet(t), ()) in types {
1770 let variant = match t.internee {
1771 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1772 ty::Float(..) | ty::Str | ty::Never => continue,
1773 ty::Error(_) => continue,
1774 $(ty::$variant(..) => &mut $variant,)*
1775 };
1776 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1777 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1778 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1779
1780 variant.total += 1;
1781 total.total += 1;
1782 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1783 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1784 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1785 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1786 }
1787 }
1788 writeln!(fmt, "Ty interner total ty lt ct all")?;
1789 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1790 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1791 stringify!($variant),
1792 uses = $variant.total,
1793 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1794 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1795 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1796 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1797 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1798 )*
1799 writeln!(fmt, " total {uses:6} \
1800 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1801 uses = total.total,
1802 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1803 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1804 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1805 all = total.all_infer as f64 * 100.0 / total.total as f64)
1806 }
1807 }
1808
1809 inner::go($fmt, $ctxt)
1810 }}
1811}
1812
1813impl<'tcx> TyCtxt<'tcx> {
1814 pub fn debug_stats(self) -> impl fmt::Debug {
1815 fmt::from_fn(move |fmt| {
1816 {
#[allow(non_snake_case)]
mod inner {
use crate::ty::{self, TyCtxt};
use crate::ty::context::InternedInSet;
struct DebugStat {
total: usize,
lt_infer: usize,
ty_infer: usize,
ct_infer: usize,
all_infer: usize,
}
#[automatically_derived]
impl ::core::marker::Copy for DebugStat { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DebugStat { }
#[automatically_derived]
impl ::core::clone::Clone for DebugStat {
#[inline]
fn clone(&self) -> DebugStat {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}
pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>)
-> std::fmt::Result {
let mut total =
DebugStat {
total: 0,
lt_infer: 0,
ty_infer: 0,
ct_infer: 0,
all_infer: 0,
};
let mut Adt = total;
let mut Array = total;
let mut Slice = total;
let mut RawPtr = total;
let mut Ref = total;
let mut FnDef = total;
let mut FnPtr = total;
let mut UnsafeBinder = total;
let mut Placeholder = total;
let mut Coroutine = total;
let mut CoroutineWitness = total;
let mut Dynamic = total;
let mut Closure = total;
let mut CoroutineClosure = total;
let mut Tuple = total;
let mut Bound = total;
let mut Param = total;
let mut Infer = total;
let mut Alias = total;
let mut Pat = total;
let mut Foreign = total;
for shard in tcx.interners.type_.lock_shards() {
#[allow(rustc :: potential_query_instability)]
let types = shard.iter();
for &(InternedInSet(t), ()) in types {
let variant =
match t.internee {
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
ty::Float(..) | ty::Str | ty::Never => continue,
ty::Error(_) => continue,
ty::Adt(..) => &mut Adt,
ty::Array(..) => &mut Array,
ty::Slice(..) => &mut Slice,
ty::RawPtr(..) => &mut RawPtr,
ty::Ref(..) => &mut Ref,
ty::FnDef(..) => &mut FnDef,
ty::FnPtr(..) => &mut FnPtr,
ty::UnsafeBinder(..) => &mut UnsafeBinder,
ty::Placeholder(..) => &mut Placeholder,
ty::Coroutine(..) => &mut Coroutine,
ty::CoroutineWitness(..) => &mut CoroutineWitness,
ty::Dynamic(..) => &mut Dynamic,
ty::Closure(..) => &mut Closure,
ty::CoroutineClosure(..) => &mut CoroutineClosure,
ty::Tuple(..) => &mut Tuple,
ty::Bound(..) => &mut Bound,
ty::Param(..) => &mut Param,
ty::Infer(..) => &mut Infer,
ty::Alias(..) => &mut Alias,
ty::Pat(..) => &mut Pat,
ty::Foreign(..) => &mut Foreign,
};
let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
variant.total += 1;
total.total += 1;
if lt { total.lt_infer += 1; variant.lt_infer += 1 }
if ty { total.ty_infer += 1; variant.ty_infer += 1 }
if ct { total.ct_infer += 1; variant.ct_infer += 1 }
if lt && ty && ct {
total.all_infer += 1;
variant.all_infer += 1
}
}
}
fmt.write_fmt(format_args!("Ty interner total ty lt ct all\n"))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Adt", Adt.total,
Adt.total as f64 * 100.0 / total.total as f64,
Adt.ty_infer as f64 * 100.0 / total.total as f64,
Adt.lt_infer as f64 * 100.0 / total.total as f64,
Adt.ct_infer as f64 * 100.0 / total.total as f64,
Adt.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Array", Array.total,
Array.total as f64 * 100.0 / total.total as f64,
Array.ty_infer as f64 * 100.0 / total.total as f64,
Array.lt_infer as f64 * 100.0 / total.total as f64,
Array.ct_infer as f64 * 100.0 / total.total as f64,
Array.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Slice", Slice.total,
Slice.total as f64 * 100.0 / total.total as f64,
Slice.ty_infer as f64 * 100.0 / total.total as f64,
Slice.lt_infer as f64 * 100.0 / total.total as f64,
Slice.ct_infer as f64 * 100.0 / total.total as f64,
Slice.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"RawPtr", RawPtr.total,
RawPtr.total as f64 * 100.0 / total.total as f64,
RawPtr.ty_infer as f64 * 100.0 / total.total as f64,
RawPtr.lt_infer as f64 * 100.0 / total.total as f64,
RawPtr.ct_infer as f64 * 100.0 / total.total as f64,
RawPtr.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Ref", Ref.total,
Ref.total as f64 * 100.0 / total.total as f64,
Ref.ty_infer as f64 * 100.0 / total.total as f64,
Ref.lt_infer as f64 * 100.0 / total.total as f64,
Ref.ct_infer as f64 * 100.0 / total.total as f64,
Ref.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"FnDef", FnDef.total,
FnDef.total as f64 * 100.0 / total.total as f64,
FnDef.ty_infer as f64 * 100.0 / total.total as f64,
FnDef.lt_infer as f64 * 100.0 / total.total as f64,
FnDef.ct_infer as f64 * 100.0 / total.total as f64,
FnDef.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"FnPtr", FnPtr.total,
FnPtr.total as f64 * 100.0 / total.total as f64,
FnPtr.ty_infer as f64 * 100.0 / total.total as f64,
FnPtr.lt_infer as f64 * 100.0 / total.total as f64,
FnPtr.ct_infer as f64 * 100.0 / total.total as f64,
FnPtr.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"UnsafeBinder", UnsafeBinder.total,
UnsafeBinder.total as f64 * 100.0 / total.total as f64,
UnsafeBinder.ty_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.lt_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.ct_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Placeholder", Placeholder.total,
Placeholder.total as f64 * 100.0 / total.total as f64,
Placeholder.ty_infer as f64 * 100.0 / total.total as f64,
Placeholder.lt_infer as f64 * 100.0 / total.total as f64,
Placeholder.ct_infer as f64 * 100.0 / total.total as f64,
Placeholder.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Coroutine", Coroutine.total,
Coroutine.total as f64 * 100.0 / total.total as f64,
Coroutine.ty_infer as f64 * 100.0 / total.total as f64,
Coroutine.lt_infer as f64 * 100.0 / total.total as f64,
Coroutine.ct_infer as f64 * 100.0 / total.total as f64,
Coroutine.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"CoroutineWitness", CoroutineWitness.total,
CoroutineWitness.total as f64 * 100.0 / total.total as f64,
CoroutineWitness.ty_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.lt_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.ct_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Dynamic", Dynamic.total,
Dynamic.total as f64 * 100.0 / total.total as f64,
Dynamic.ty_infer as f64 * 100.0 / total.total as f64,
Dynamic.lt_infer as f64 * 100.0 / total.total as f64,
Dynamic.ct_infer as f64 * 100.0 / total.total as f64,
Dynamic.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Closure", Closure.total,
Closure.total as f64 * 100.0 / total.total as f64,
Closure.ty_infer as f64 * 100.0 / total.total as f64,
Closure.lt_infer as f64 * 100.0 / total.total as f64,
Closure.ct_infer as f64 * 100.0 / total.total as f64,
Closure.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"CoroutineClosure", CoroutineClosure.total,
CoroutineClosure.total as f64 * 100.0 / total.total as f64,
CoroutineClosure.ty_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.lt_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.ct_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Tuple", Tuple.total,
Tuple.total as f64 * 100.0 / total.total as f64,
Tuple.ty_infer as f64 * 100.0 / total.total as f64,
Tuple.lt_infer as f64 * 100.0 / total.total as f64,
Tuple.ct_infer as f64 * 100.0 / total.total as f64,
Tuple.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Bound", Bound.total,
Bound.total as f64 * 100.0 / total.total as f64,
Bound.ty_infer as f64 * 100.0 / total.total as f64,
Bound.lt_infer as f64 * 100.0 / total.total as f64,
Bound.ct_infer as f64 * 100.0 / total.total as f64,
Bound.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Param", Param.total,
Param.total as f64 * 100.0 / total.total as f64,
Param.ty_infer as f64 * 100.0 / total.total as f64,
Param.lt_infer as f64 * 100.0 / total.total as f64,
Param.ct_infer as f64 * 100.0 / total.total as f64,
Param.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Infer", Infer.total,
Infer.total as f64 * 100.0 / total.total as f64,
Infer.ty_infer as f64 * 100.0 / total.total as f64,
Infer.lt_infer as f64 * 100.0 / total.total as f64,
Infer.ct_infer as f64 * 100.0 / total.total as f64,
Infer.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Alias", Alias.total,
Alias.total as f64 * 100.0 / total.total as f64,
Alias.ty_infer as f64 * 100.0 / total.total as f64,
Alias.lt_infer as f64 * 100.0 / total.total as f64,
Alias.ct_infer as f64 * 100.0 / total.total as f64,
Alias.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Pat", Pat.total,
Pat.total as f64 * 100.0 / total.total as f64,
Pat.ty_infer as f64 * 100.0 / total.total as f64,
Pat.lt_infer as f64 * 100.0 / total.total as f64,
Pat.ct_infer as f64 * 100.0 / total.total as f64,
Pat.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Foreign", Foreign.total,
Foreign.total as f64 * 100.0 / total.total as f64,
Foreign.ty_infer as f64 * 100.0 / total.total as f64,
Foreign.lt_infer as f64 * 100.0 / total.total as f64,
Foreign.ct_infer as f64 * 100.0 / total.total as f64,
Foreign.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" total {0:6} {1:4.1}% {2:5.1}% {3:4.1}% {4:4.1}%\n",
total.total,
total.ty_infer as f64 * 100.0 / total.total as f64,
total.lt_infer as f64 * 100.0 / total.total as f64,
total.ct_infer as f64 * 100.0 / total.total as f64,
total.all_infer as f64 * 100.0 / total.total as f64))
}
}
inner::go(fmt, self)
}sty_debug_print!(
1817 fmt,
1818 self,
1819 Adt,
1820 Array,
1821 Slice,
1822 RawPtr,
1823 Ref,
1824 FnDef,
1825 FnPtr,
1826 UnsafeBinder,
1827 Placeholder,
1828 Coroutine,
1829 CoroutineWitness,
1830 Dynamic,
1831 Closure,
1832 CoroutineClosure,
1833 Tuple,
1834 Bound,
1835 Param,
1836 Infer,
1837 Alias,
1838 Pat,
1839 Foreign
1840 )?;
1841
1842 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1843 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1844 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())?;
1845 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1846
1847 Ok(())
1848 })
1849 }
1850}
1851
1852struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1857
1858impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1859 fn clone(&self) -> Self {
1860 *self
1861 }
1862}
1863
1864impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1865
1866impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1867 fn into_pointer(&self) -> *const () {
1868 self.0 as *const _ as *const ()
1869 }
1870}
1871
1872#[allow(rustc::usage_of_ty_tykind)]
1873impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1874 fn borrow(&self) -> &T {
1875 &self.0.internee
1876 }
1877}
1878
1879impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1880 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1881 self.0.internee == other.0.internee
1884 }
1885}
1886
1887impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1888
1889impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1890 fn hash<H: Hasher>(&self, s: &mut H) {
1891 self.0.internee.hash(s)
1893 }
1894}
1895
1896impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1897 fn borrow(&self) -> &[T] {
1898 &self.0[..]
1899 }
1900}
1901
1902impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1903 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1904 self.0[..] == other.0[..]
1907 }
1908}
1909
1910impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1911
1912impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1913 fn hash<H: Hasher>(&self, s: &mut H) {
1914 self.0[..].hash(s)
1916 }
1917}
1918
1919impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1920 fn borrow(&self) -> &[T] {
1921 &self.0[..]
1922 }
1923}
1924
1925impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1926 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1927 self.0[..] == other.0[..]
1930 }
1931}
1932
1933impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1934
1935impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1936 fn hash<H: Hasher>(&self, s: &mut H) {
1937 self.0[..].hash(s)
1939 }
1940}
1941
1942macro_rules! direct_interners {
1943 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1944 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1945 fn borrow<'a>(&'a self) -> &'a $ty {
1946 &self.0
1947 }
1948 }
1949
1950 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1951 fn eq(&self, other: &Self) -> bool {
1952 self.0 == other.0
1955 }
1956 }
1957
1958 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1959
1960 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1961 fn hash<H: Hasher>(&self, s: &mut H) {
1962 self.0.hash(s)
1965 }
1966 }
1967
1968 impl<'tcx> TyCtxt<'tcx> {
1969 $vis fn $method(self, v: $ty) -> $ret_ty {
1970 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1971 InternedInSet(self.interners.arena.alloc(v))
1972 }).0))
1973 }
1974 })+
1975 }
1976}
1977
1978impl<'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! {
1982 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
1983 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
1984 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
1985 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
1986 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
1987 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
1988 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
1989 ExternalConstraints -> ExternalConstraints<'tcx>,
1990}
1991
1992macro_rules! slice_interners {
1993 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
1994 impl<'tcx> TyCtxt<'tcx> {
1995 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
1996 if v.is_empty() {
1997 List::empty()
1998 } else {
1999 self.interners.$field.intern_ref(v, || {
2000 InternedInSet(List::from_arena(&*self.arena, (), v))
2001 }).0
2002 }
2003 })+
2004 }
2005 );
2006}
2007
2008impl<'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!(
2012 const_lists: pub mk_const_list(Const<'tcx>),
2013 args: pub mk_args(GenericArg<'tcx>),
2014 type_lists: pub mk_type_list(Ty<'tcx>),
2015 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2016 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2017 projs: pub mk_projs(ProjectionKind),
2018 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2019 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2020 fields: pub mk_fields(FieldIdx),
2021 local_def_ids: intern_local_def_ids(LocalDefId),
2022 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2023 patterns: pub mk_patterns(Pattern<'tcx>),
2024 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2025 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2026);
2027
2028impl<'tcx> TyCtxt<'tcx> {
2029 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2033 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2034 Ty::new_fn_ptr(
2035 self,
2036 sig.map_bound(|sig| ty::FnSig {
2037 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2038 ..sig
2039 }),
2040 )
2041 }
2042
2043 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2047 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2048 sig.map_bound(|sig| ty::FnSig {
2049 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2050 ..sig
2051 })
2052 }
2053
2054 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2057 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2058 self.associated_items(trait_did)
2059 .filter_by_name_unhygienic(assoc_name.name)
2060 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2061 })
2062 }
2063
2064 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2066 let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2067 return false;
2068 };
2069 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2070
2071 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2072 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2073 return false;
2074 };
2075 trait_predicate.trait_ref.def_id == future_trait
2076 && trait_predicate.polarity == PredicatePolarity::Positive
2077 })
2078 }
2079
2080 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2088 sig.map_bound(|s| {
2089 let params = match s.inputs()[0].kind() {
2090 ty::Tuple(params) => *params,
2091 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2092 };
2093 if !s.splatted().is_none() {
::core::panicking::panic("assertion failed: s.splatted().is_none()")
};assert!(s.splatted().is_none());
2095 self.mk_fn_sig(
2096 params,
2097 s.output(),
2098 s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2099 )
2100 })
2101 }
2102
2103 #[inline]
2104 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2105 self.interners.intern_predicate(binder)
2106 }
2107
2108 #[inline]
2109 pub fn reuse_or_mk_predicate(
2110 self,
2111 pred: Predicate<'tcx>,
2112 binder: Binder<'tcx, PredicateKind<'tcx>>,
2113 ) -> Predicate<'tcx> {
2114 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2115 }
2116
2117 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2118 self.check_args_compatible_inner(def_id, args, false)
2119 }
2120
2121 fn check_args_compatible_inner(
2122 self,
2123 def_id: DefId,
2124 args: &'tcx [ty::GenericArg<'tcx>],
2125 nested: bool,
2126 ) -> bool {
2127 let generics = self.generics_of(def_id);
2128
2129 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)
2133 && #[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 });
2134 let is_inherent_assoc_type_const =
2135 #[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 })
2136 && #[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 });
2137 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2138 if generics.own_params.len() + 1 != args.len() {
2139 return false;
2140 }
2141
2142 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2143 return false;
2144 }
2145
2146 &args[1..]
2147 } else {
2148 if generics.count() != args.len() {
2149 return false;
2150 }
2151
2152 let (parent_args, own_args) = args.split_at(generics.parent_count);
2153
2154 if let Some(parent) = generics.parent
2155 && !self.check_args_compatible_inner(parent, parent_args, true)
2156 {
2157 return false;
2158 }
2159
2160 own_args
2161 };
2162
2163 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2164 match (¶m.kind, arg.kind()) {
2165 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2166 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2167 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2168 _ => return false,
2169 }
2170 }
2171
2172 true
2173 }
2174
2175 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2178 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2179 let is_inherent_assoc_ty = #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocTy => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocTy)
2180 && #[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 });
2181 let is_inherent_assoc_type_const =
2182 #[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 })
2183 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(
2184 self.def_kind(self.parent(def_id)),
2185 DefKind::Impl { of_trait: false }
2186 );
2187 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2188 crate::util::bug::bug_fmt(format_args!("args not compatible with generics for {0}: args={1:#?}, generics={2:#?}",
self.def_path_str(def_id), args,
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!(
2189 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2190 self.def_path_str(def_id),
2191 args,
2192 self.mk_args_from_iter(
2194 [self.types.self_param.into()].into_iter().chain(
2195 self.generics_of(def_id)
2196 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2197 .iter()
2198 .copied()
2199 )
2200 )
2201 );
2202 } else {
2203 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!(
2204 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2205 self.def_path_str(def_id),
2206 args,
2207 ty::GenericArgs::identity_for_item(self, def_id)
2208 );
2209 }
2210 }
2211 }
2212
2213 #[inline(always)]
2214 pub(crate) fn check_and_mk_args(
2215 self,
2216 def_id: DefId,
2217 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2218 ) -> GenericArgsRef<'tcx> {
2219 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2220 self.debug_assert_args_compatible(def_id, args);
2221 args
2222 }
2223
2224 #[inline]
2225 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2226 self.interners.intern_const(kind)
2227 }
2228
2229 #[allow(rustc::usage_of_ty_tykind)]
2231 #[inline]
2232 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2233 self.interners.intern_ty(st)
2234 }
2235
2236 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2237 match param.kind {
2238 GenericParamDefKind::Lifetime => {
2239 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2240 }
2241 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2242 GenericParamDefKind::Const { .. } => {
2243 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2244 .into()
2245 }
2246 }
2247 }
2248
2249 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2250 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2251 }
2252
2253 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2254 self.mk_place_elem(place, PlaceElem::Deref)
2255 }
2256
2257 pub fn mk_place_downcast(
2258 self,
2259 place: Place<'tcx>,
2260 adt_def: AdtDef<'tcx>,
2261 variant_index: VariantIdx,
2262 ) -> Place<'tcx> {
2263 self.mk_place_elem(
2264 place,
2265 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2266 )
2267 }
2268
2269 pub fn mk_place_downcast_unnamed(
2270 self,
2271 place: Place<'tcx>,
2272 variant_index: VariantIdx,
2273 ) -> Place<'tcx> {
2274 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2275 }
2276
2277 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2278 self.mk_place_elem(place, PlaceElem::Index(index))
2279 }
2280
2281 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2285 Place {
2286 local: place.local,
2287 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2288 }
2289 }
2290
2291 pub fn mk_poly_existential_predicates(
2292 self,
2293 eps: &[PolyExistentialPredicate<'tcx>],
2294 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2295 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2296 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!(
2297 eps.array_windows()
2298 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2299 != Ordering::Greater)
2300 );
2301 self.intern_poly_existential_predicates(eps)
2302 }
2303
2304 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2305 self.interners.intern_clauses(clauses)
2309 }
2310
2311 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2312 self.intern_local_def_ids(def_ids)
2316 }
2317
2318 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2319 where
2320 I: Iterator<Item = T>,
2321 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2322 {
2323 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2324 }
2325
2326 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2327 where
2328 I: Iterator<Item = T>,
2329 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2330 {
2331 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2332 }
2333
2334 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2335 where
2336 I: Iterator<Item = T>,
2337 T: CollectAndApply<
2338 &'tcx ty::CapturedPlace<'tcx>,
2339 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2340 >,
2341 {
2342 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2343 }
2344
2345 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2346 where
2347 I: Iterator<Item = T>,
2348 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2349 {
2350 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2351 }
2352
2353 pub fn mk_fn_sig<I, T>(
2358 self,
2359 inputs: I,
2360 output: I::Item,
2361 fn_sig_kind: FnSigKind<'tcx>,
2362 ) -> T::Output
2363 where
2364 I: IntoIterator<Item = T>,
2365 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2366 {
2367 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2368 inputs_and_output: self.mk_type_list(xs),
2369 fn_sig_kind,
2370 })
2371 }
2372
2373 pub fn mk_fn_sig_rust_abi<I, T>(
2375 self,
2376 inputs: I,
2377 output: I::Item,
2378 safety: hir::Safety,
2379 ) -> T::Output
2380 where
2381 I: IntoIterator<Item = T>,
2382 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2383 {
2384 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2385 }
2386
2387 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2389 where
2390 I: IntoIterator<Item = T>,
2391 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2392 {
2393 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2394 }
2395
2396 pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2398 where
2399 I: IntoIterator<Item = T>,
2400 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2401 {
2402 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2403 }
2404
2405 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2406 where
2407 I: Iterator<Item = T>,
2408 T: CollectAndApply<
2409 PolyExistentialPredicate<'tcx>,
2410 &'tcx List<PolyExistentialPredicate<'tcx>>,
2411 >,
2412 {
2413 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2414 }
2415
2416 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2417 where
2418 I: Iterator<Item = T>,
2419 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2420 {
2421 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2422 }
2423
2424 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2425 where
2426 I: Iterator<Item = T>,
2427 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2428 {
2429 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2430 }
2431
2432 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2433 where
2434 I: Iterator<Item = T>,
2435 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2436 {
2437 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2438 }
2439
2440 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2441 where
2442 I: Iterator<Item = T>,
2443 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2444 {
2445 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2446 }
2447
2448 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2449 where
2450 I: Iterator<Item = T>,
2451 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2452 {
2453 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2454 }
2455
2456 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2457 where
2458 I: Iterator<Item = T>,
2459 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2460 {
2461 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2462 }
2463
2464 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2465 where
2466 I: Iterator<Item = T>,
2467 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2468 {
2469 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2470 }
2471
2472 pub fn mk_args_trait(
2473 self,
2474 self_ty: Ty<'tcx>,
2475 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2476 ) -> GenericArgsRef<'tcx> {
2477 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2478 }
2479
2480 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2481 where
2482 I: Iterator<Item = T>,
2483 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2484 {
2485 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2486 }
2487
2488 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2489 where
2490 I: Iterator<Item = T>,
2491 T: CollectAndApply<
2492 ty::ArgOutlivesPredicate<'tcx>,
2493 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2494 >,
2495 {
2496 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2497 }
2498
2499 #[track_caller]
2502 pub fn emit_node_span_lint(
2503 self,
2504 lint: &'static Lint,
2505 hir_id: HirId,
2506 span: impl Into<MultiSpan>,
2507 decorator: impl for<'a> Diagnostic<'a, ()>,
2508 ) {
2509 let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2510 emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2511 }
2512
2513 pub fn crate_level_attribute_injection_span(self) -> Span {
2515 let node = self.hir_node(hir::CRATE_HIR_ID);
2516 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2517 m.spans.inject_use_span.shrink_to_lo()
2518 }
2519
2520 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2521 self,
2522 diag: &mut Diag<'_, E>,
2523 features: impl IntoIterator<Item = (String, Symbol)>,
2524 ) {
2525 if !self.sess.is_nightly_build() {
2526 return;
2527 }
2528
2529 let span = self.crate_level_attribute_injection_span();
2530 for (desc, feature) in features {
2531 let msg =
2533 ::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}");
2534 diag.span_suggestion_verbose(
2535 span,
2536 msg,
2537 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2538 Applicability::MaybeIncorrect,
2539 );
2540 }
2541 }
2542
2543 #[track_caller]
2546 pub fn emit_node_lint(
2547 self,
2548 lint: &'static Lint,
2549 id: HirId,
2550 decorator: impl for<'a> Diagnostic<'a, ()>,
2551 ) {
2552 let level_spec = self.lint_level_spec_at_node(lint, id);
2553 emit_lint_base(self.sess, lint, level_spec, None, decorator);
2554 }
2555
2556 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2557 let map = self.in_scope_traits_map(id.owner)?;
2558 let candidates = map.get(&id.local_id)?;
2559 Some(candidates)
2560 }
2561
2562 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2563 {
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:2563",
"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(2563u32),
::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");
2564 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2565 }
2566
2567 pub fn is_late_bound(self, id: HirId) -> bool {
2568 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2569 }
2570
2571 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2572 self.mk_bound_variable_kinds(
2573 &self
2574 .late_bound_vars_map(id.owner)
2575 .get(&id.local_id)
2576 .cloned()
2577 .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))),
2578 )
2579 }
2580
2581 pub fn map_opaque_lifetime_to_parent_lifetime(
2589 self,
2590 mut opaque_lifetime_param_def_id: LocalDefId,
2591 ) -> ty::Region<'tcx> {
2592 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!(
2593 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2594 "{opaque_lifetime_param_def_id:?} is a {}",
2595 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2596 );
2597
2598 loop {
2599 let parent = self.local_parent(opaque_lifetime_param_def_id);
2600 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2601
2602 let Some((lifetime, _)) = lifetime_mapping
2603 .iter()
2604 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2605 else {
2606 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2607 };
2608
2609 match *lifetime {
2610 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2611 let new_parent = self.local_parent(ebv);
2612
2613 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2616 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);
2617 opaque_lifetime_param_def_id = ebv;
2618 continue;
2619 }
2620
2621 let generics = self.generics_of(new_parent);
2622 return ty::Region::new_early_param(
2623 self,
2624 ty::EarlyParamRegion {
2625 index: generics
2626 .param_def_id_to_index(self, ebv.to_def_id())
2627 .expect("early-bound var should be present in fn generics"),
2628 name: self.item_name(ebv.to_def_id()),
2629 },
2630 );
2631 }
2632 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2633 let new_parent = self.local_parent(lbv);
2634 return ty::Region::new_late_param(
2635 self,
2636 new_parent.to_def_id(),
2637 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2638 );
2639 }
2640 resolve_bound_vars::ResolvedArg::Error(guar) => {
2641 return ty::Region::new_error(self, guar);
2642 }
2643 _ => {
2644 return ty::Region::new_error_with_message(
2645 self,
2646 self.def_span(opaque_lifetime_param_def_id),
2647 "cannot resolve lifetime",
2648 );
2649 }
2650 }
2651 }
2652 }
2653
2654 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2659 self.is_const_fn(def_id)
2660 && match self.lookup_const_stability(def_id) {
2661 None => true, Some(stability) if stability.is_const_stable() => true,
2663 _ => false,
2664 }
2665 }
2666
2667 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2669 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2670 && #[allow(non_exhaustive_omitted_patterns)] match self.impl_trait_header(def_id).constness
{
hir::Constness::Const { always: false } => true,
_ => false,
}matches!(
2671 self.impl_trait_header(def_id).constness,
2672 hir::Constness::Const { always: false }
2673 )
2674 }
2675
2676 pub fn is_sdylib_interface_build(self) -> bool {
2677 self.sess.opts.unstable_opts.build_sdylib_interface
2678 }
2679
2680 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2681 let def_id = def_id.into_query_key();
2682 match self.def_kind(def_id) {
2683 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2684 _ => None,
2685 }
2686 }
2687
2688 pub fn next_trait_solver_globally(self) -> bool {
2689 self.sess.opts.unstable_opts.next_solver.globally
2690 }
2691
2692 pub fn next_trait_solver_in_coherence(self) -> bool {
2693 self.sess.opts.unstable_opts.next_solver.coherence
2694 }
2695
2696 pub fn disable_trait_solver_fast_paths(self) -> bool {
2697 self.sess.opts.unstable_opts.disable_fast_paths
2698 }
2699
2700 pub fn disable_param_env_normalization_hack(self) -> bool {
2701 self.sess.opts.unstable_opts.disable_param_env_normalization_hack
2702 }
2703
2704 pub fn renormalize_rigid_aliases(self) -> bool {
2705 self.sess.opts.unstable_opts.renormalize_rigid_aliases
2706 }
2707
2708 #[allow(rustc::bad_opt_access)]
2709 pub fn use_typing_mode_post_typeck_until_borrowck(self) -> bool {
2710 self.next_trait_solver_globally()
2711 || self.sess.opts.unstable_opts.typing_mode_post_typeck_until_borrowck
2712 }
2713
2714 pub fn assumptions_on_binders(self) -> bool {
2715 self.sess.opts.unstable_opts.assumptions_on_binders
2716 }
2717
2718 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2719 self.opt_rpitit_info(def_id).is_some()
2720 }
2721
2722 pub fn get_impl_future_output_ty(self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
2723 let (def_id, args) = match *ty.kind() {
2724 ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
2725 ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, args, .. })
2726 if self.is_impl_trait_in_trait(def_id) =>
2727 {
2728 (def_id, args)
2729 }
2730 _ => return None,
2731 };
2732
2733 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2734 let item_def_id = self.associated_item_def_ids(future_trait)[0];
2735
2736 self.explicit_item_self_bounds(def_id)
2737 .iter_instantiated_copied(self, args)
2738 .map(ty::Unnormalized::skip_norm_wip)
2739 .find_map(|(predicate, _)| {
2740 predicate
2741 .kind()
2742 .map_bound(|kind| match kind {
2743 ty::ClauseKind::Projection(projection_predicate)
2744 if projection_predicate.def_id() == item_def_id =>
2745 {
2746 projection_predicate.term.as_type()
2747 }
2748 _ => None,
2749 })
2750 .no_bound_vars()
2751 .flatten()
2752 })
2753 }
2754
2755 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2765 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2766 }
2767
2768 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2770 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2771 }
2772
2773 pub fn resolver_for_lowering(
2774 self,
2775 ) -> (&'tcx Steal<ty::ResolverAstLowering<'tcx>>, &'tcx Steal<ast::Crate>) {
2776 let (resolver, krate, _) = self.resolver_for_lowering_raw(());
2777 (resolver, krate)
2778 }
2779
2780 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2781 make_metadata(self)
2782 }
2783
2784 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2785 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2786 self.coroutine_kind(def_id)
2787 && let ty::Coroutine(_, args) =
2788 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2789 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2790 {
2791 true
2792 } else {
2793 false
2794 }
2795 }
2796
2797 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2799 {
{
'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)
2800 }
2801
2802 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2803 let def_id = def_id.into_query_key();
2804 self.trivial_const(def_id).is_some()
2805 }
2806
2807 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2810 if self.is_lang_item(def_id, LangItem::Start) {
2811 return true;
2812 }
2813 if let Some((entry_def_id, _)) = self.entry_fn(())
2814 && entry_def_id == def_id
2815 {
2816 return true;
2817 }
2818 false
2819 }
2820}
2821
2822pub fn provide(providers: &mut Providers) {
2823 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);
2824 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);
2825 providers.has_panic_handler = |tcx, LocalCrate| {
2826 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2828 };
2829 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2830}