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_crate_store::{CrateStoreDyn, Untracked};
21use rustc_data_structures::fx::FxHashMap;
22use rustc_data_structures::intern::Interned;
23use rustc_data_structures::profiling::SelfProfilerRef;
24use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
25use rustc_data_structures::stable_hash::StableHash;
26use rustc_data_structures::steal::Steal;
27use rustc_data_structures::sync::{
28 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
29};
30use rustc_data_structures::{Limit, defer};
31use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
32use rustc_hir::attrs::lang_items::LangItem;
33use rustc_hir::def::DefKind;
34use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
35use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState};
36use rustc_hir::intravisit::VisitorExt;
37use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr};
38use rustc_index::IndexVec;
39use rustc_macros::Diagnostic;
40use rustc_session::config::CrateType;
41use rustc_session::lint::Lint;
42use rustc_session::{IncrCompSession, Session};
43use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
44use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
45use rustc_type_ir::TyKind::*;
46pub use rustc_type_ir::lift::Lift;
47use rustc_type_ir::{CollectAndApply, WithCachedTypeInfo, elaborate, search_graph};
48use tracing::{debug, instrument};
49
50use crate::arena::Arena;
51use crate::dep_graph::dep_node::make_metadata;
52use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
53use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo};
54use crate::ich::StableHashState;
55use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
56use crate::lint::emit_lint_base;
57use crate::metadata::ModChild;
58use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
59use crate::middle::resolve_bound_vars;
60use crate::mir::interpret::{self, Allocation, ConstAllocation};
61use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
62use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
63use crate::thir::Thir;
64use crate::traits;
65use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
66use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
67use crate::ty::region::RegionExt;
68use crate::ty::{
69 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, FnSigKind, GenericArg,
70 GenericArgs, GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst,
71 Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
72 PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
73 ValTree, ValTreeKind, Visibility,
74};
75
76impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
77 fn is_local(self) -> bool {
78 self.is_local()
79 }
80
81 fn as_local(self) -> Option<LocalDefId> {
82 self.as_local()
83 }
84}
85
86impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
87 fn safe() -> Self {
88 hir::Safety::Safe
89 }
90
91 fn unsafe_mode() -> Self {
92 hir::Safety::Unsafe
93 }
94
95 fn is_safe(self) -> bool {
96 self.is_safe()
97 }
98
99 fn prefix_str(self) -> &'static str {
100 self.prefix_str()
101 }
102}
103
104impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
105 fn generic_const_exprs(self) -> bool {
106 self.generic_const_exprs()
107 }
108
109 fn generic_const_args(self) -> bool {
110 self.generic_const_args()
111 }
112
113 fn coroutine_clone(self) -> bool {
114 self.coroutine_clone()
115 }
116
117 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
118 !self.staged_api() && self.enabled(symbol)
122 }
123}
124
125impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
126 fn dummy() -> Self {
127 DUMMY_SP
128 }
129}
130
131type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
132
133pub struct CtxtInterners<'tcx> {
134 arena: &'tcx WorkerLocal<Arena<'tcx>>,
136
137 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
140 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
141 args: InternedSet<'tcx, GenericArgs<'tcx>>,
142 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
143 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
144 region: InternedSet<'tcx, RegionKind<'tcx>>,
145 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
146 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
147 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
148 projs: InternedSet<'tcx, List<ProjectionKind>>,
149 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
150 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
151 pat: InternedSet<'tcx, PatternKind<'tcx>>,
152 const_allocation: InternedSet<'tcx, Allocation>,
153 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
154 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
155 adt_def: InternedSet<'tcx, AdtDefData>,
156 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
157 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
158 fields: InternedSet<'tcx, List<FieldIdx>>,
159 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
160 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
161 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
162 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
163 outlives: InternedSet<'tcx, List<ty::ArgOutlivesClause<'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 incr_comp_session: Option<&'tcx IncrCompSession>,
716 pub dep_graph: DepGraph,
717
718 pub prof: SelfProfilerRef,
719
720 pub types: CommonTypes<'tcx>,
722
723 pub lifetimes: CommonLifetimes<'tcx>,
725
726 pub consts: CommonConsts<'tcx>,
728
729 pub(crate) hooks: crate::hooks::Providers,
732
733 untracked: Untracked,
734
735 pub query_system: QuerySystem<'tcx>,
736 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
737
738 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
740
741 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
744
745 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
749
750 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
752 pub new_solver_canonical_param_env_cache: Lock<ty::CanonicalParamEnvCache<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 [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 incr_comp_session: Option<&'tcx IncrCompSession>,
939 dep_graph: DepGraph,
940 dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
941 query_system: QuerySystem<'tcx>,
942 hooks: crate::hooks::Providers,
943 current_gcx: CurrentGcx,
944 f: impl FnOnce(TyCtxt<'tcx>) -> T,
945 ) -> T {
946 let data_layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
947 sess.dcx().emit_fatal(err);
948 });
949 let interners = CtxtInterners::new(arena);
950 let common_types = CommonTypes::new(&interners);
951 let common_lifetimes = CommonLifetimes::new(&interners);
952 let common_consts = CommonConsts::new(&interners, &common_types);
953
954 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
955 sess,
956 crate_types,
957 stable_crate_id,
958 arena,
959 hir_arena,
960 interners,
961 incr_comp_session,
962 dep_graph,
963 hooks,
964 prof: sess.prof.clone(),
965 types: common_types,
966 lifetimes: common_lifetimes,
967 consts: common_consts,
968 untracked,
969 query_system,
970 dep_kind_vtables,
971 ty_rcache: Default::default(),
972 selection_cache: Default::default(),
973 evaluation_cache: Default::default(),
974 new_solver_evaluation_cache: Default::default(),
975 new_solver_canonical_param_env_cache: Default::default(),
976 canonical_param_env_cache: Default::default(),
977 highest_var_in_clauses_cache: Default::default(),
978 clauses_cache: Default::default(),
979 data_layout,
980 alloc_map: interpret::AllocMap::new(),
981 current_gcx,
982 });
983
984 gcx.enter(f)
986 }
987
988 pub fn lang_items(self) -> &'tcx rustc_hir::attrs::lang_items::LanguageItems {
990 self.get_lang_items(())
991 }
992
993 #[track_caller]
995 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
996 let ordering_enum = self.require_lang_item(LangItem::OrderingEnum, span);
997 self.type_of(ordering_enum).no_bound_vars().unwrap()
998 }
999
1000 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1003 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1004 }
1005
1006 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1008 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1009 }
1010
1011 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1013 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1014 }
1015
1016 pub fn is_coroutine(self, def_id: DefId) -> bool {
1017 self.coroutine_kind(def_id).is_some()
1018 }
1019
1020 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1021 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1022 }
1023
1024 pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1025 if !self.is_type_const(def_id) {
1026 return None;
1027 }
1028 Some(self.def_span(def_id))
1029 }
1030
1031 pub fn is_type_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1033 let def_id = def_id.into_query_key();
1034 match self.def_kind(def_id) {
1035 DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1036 is_type_const
1037 }
1038 _ => false,
1039 }
1040 }
1041
1042 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1045 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1046 }
1047
1048 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1050 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1051 self.coroutine_kind(def_id),
1052 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1053 )
1054 }
1055
1056 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1059 #[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)
1060 }
1061
1062 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1065 #[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(_)))
1066 }
1067
1068 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1070 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1071 self.coroutine_kind(def_id),
1072 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1073 )
1074 }
1075
1076 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1078 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1079 self.coroutine_kind(def_id),
1080 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1081 )
1082 }
1083
1084 pub fn features(self) -> &'tcx rustc_feature::Features {
1085 self.features_query(())
1086 }
1087
1088 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1089 let id = id.into_query_key();
1090 if let Some(id) = id.as_local() {
1092 self.definitions_untracked().def_key(id)
1093 } else {
1094 self.cstore_untracked().def_key(id)
1095 }
1096 }
1097
1098 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1104 if let Some(id) = id.as_local() {
1106 self.definitions_untracked().def_path(id)
1107 } else {
1108 self.cstore_untracked().def_path(id)
1109 }
1110 }
1111
1112 #[inline]
1113 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1114 if let Some(def_id) = def_id.as_local() {
1116 self.definitions_untracked().def_path_hash(def_id)
1117 } else {
1118 self.cstore_untracked().def_path_hash(def_id)
1119 }
1120 }
1121
1122 #[inline]
1123 pub fn crate_types(self) -> &'tcx [CrateType] {
1124 &self.crate_types
1125 }
1126
1127 pub fn needs_metadata(self) -> bool {
1128 self.crate_types().iter().any(|ty| match *ty {
1129 CrateType::Executable
1130 | CrateType::StaticLib
1131 | CrateType::Cdylib
1132 | CrateType::Sdylib => false,
1133 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1134 })
1135 }
1136
1137 pub fn needs_hir_hash(self) -> bool {
1138 truecfg!(debug_assertions)
1150 || self.sess.opts.incremental.is_some()
1151 || self.needs_metadata()
1152 || self.sess.instrument_coverage()
1153 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1154 }
1155
1156 #[inline]
1157 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1158 if crate_num == LOCAL_CRATE {
1159 self.stable_crate_id
1160 } else {
1161 self.cstore_untracked().stable_crate_id(crate_num)
1162 }
1163 }
1164
1165 #[inline]
1168 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1169 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1170 LOCAL_CRATE
1171 } else {
1172 *self
1173 .untracked()
1174 .stable_crate_ids
1175 .read()
1176 .get(&stable_crate_id)
1177 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1178 }
1179 }
1180
1181 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1185 {
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:1185",
"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(1185u32),
::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);
1186
1187 let stable_crate_id = hash.stable_crate_id();
1188
1189 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1192 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1193 } else {
1194 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1195 }
1196 }
1197
1198 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1199 let (crate_name, stable_crate_id) = if def_id.is_local() {
1204 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1205 } else {
1206 let cstore = &*self.cstore_untracked();
1207 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1208 };
1209
1210 ::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!(
1211 "{}[{:04x}]{}",
1212 crate_name,
1213 stable_crate_id.as_u64() >> (8 * 6),
1216 self.def_path(def_id).to_string_no_crate_verbose()
1217 )
1218 }
1219
1220 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1221 self.sess.dcx()
1222 }
1223
1224 pub fn is_target_feature_call_safe(
1227 self,
1228 callee_features: &[TargetFeature],
1229 body_features: &[TargetFeature],
1230 ) -> bool {
1231 self.sess.target.options.is_like_wasm
1236 || callee_features
1237 .iter()
1238 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1239 }
1240
1241 pub fn adjust_target_feature_sig(
1244 self,
1245 fun_def: DefId,
1246 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1247 caller: DefId,
1248 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1249 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1250 let caller_features = &self.body_codegen_attrs(caller).target_features;
1251 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1252 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1253 fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1254 ..sig
1255 }));
1256 }
1257 None
1258 }
1259
1260 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1263 match self.env_var_os(key.as_ref()) {
1264 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1265 None => Err(VarError::NotPresent),
1266 }
1267 }
1268}
1269
1270impl<'tcx> TyCtxtAt<'tcx> {
1271 pub fn create_def(
1273 self,
1274 parent: LocalDefId,
1275 name: Option<Symbol>,
1276 def_kind: DefKind,
1277 override_def_path_data: Option<DefPathData>,
1278 disambiguator: &mut PerParentDisambiguatorState,
1279 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1280 let feed =
1281 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1282
1283 feed.def_span(self.span);
1284 feed
1285 }
1286}
1287
1288impl<'tcx> TyCtxt<'tcx> {
1289 pub fn create_def(
1291 self,
1292 parent: LocalDefId,
1293 name: Option<Symbol>,
1294 def_kind: DefKind,
1295 override_def_path_data: Option<DefPathData>,
1296 disambiguator: &mut PerParentDisambiguatorState,
1297 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1298 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1299 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1309
1310 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1315
1316 let feed = TyCtxtFeed { tcx: self, key: def_id };
1317 feed.def_kind(def_kind);
1318 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1323 let parent_mod = self.parent_module_from_def_id(def_id);
1324 feed.visibility(ty::Visibility::Restricted(parent_mod.to_mod_id()));
1325 }
1326
1327 feed
1328 }
1329
1330 pub fn create_crate_num(
1331 self,
1332 stable_crate_id: StableCrateId,
1333 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1334 let mut lock = self.untracked().stable_crate_ids.write();
1335 if let Some(&existing) = lock.get(&stable_crate_id) {
1336 return Err(existing);
1337 }
1338 let num = CrateNum::new(lock.len());
1339 lock.insert(stable_crate_id, num);
1340 Ok(TyCtxtFeed { key: num, tcx: self })
1341 }
1342
1343 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1344 self.ensure_ok().analysis(());
1346
1347 let definitions = &self.untracked.definitions;
1348 gen {
1349 let mut i = 0;
1350
1351 while i < { definitions.read().num_definitions() } {
1354 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1355 yield LocalDefId { local_def_index };
1356 i += 1;
1357 }
1358
1359 definitions.freeze();
1361 }
1362 }
1363
1364 pub fn definitions(self) -> &'tcx rustc_hir::definitions::Definitions {
1365 self.ensure_ok().analysis(());
1367
1368 self.untracked.definitions.freeze()
1371 }
1372
1373 pub fn def_path_hash_to_def_index_map(
1374 self,
1375 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1376 self.ensure_ok().hir_crate_items(());
1379 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1382 }
1383
1384 #[inline]
1387 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1388 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1389 }
1390
1391 pub fn untracked(self) -> &'tcx Untracked {
1393 &self.untracked
1394 }
1395 #[inline]
1398 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1399 self.untracked.definitions.read()
1400 }
1401
1402 #[inline]
1405 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1406 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1407 }
1408
1409 #[inline(always)]
1410 pub fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashState<'_>) -> R) -> R {
1411 f(StableHashState::new(self.sess, &self.untracked))
1412 }
1413
1414 #[inline]
1415 pub fn local_crate_exports_generics(self) -> bool {
1416 if self.is_compiler_builtins(LOCAL_CRATE) {
1420 return false;
1421 }
1422 self.crate_types().iter().any(|crate_type| {
1423 match crate_type {
1424 CrateType::Executable
1425 | CrateType::StaticLib
1426 | CrateType::ProcMacro
1427 | CrateType::Cdylib
1428 | CrateType::Sdylib => false,
1429
1430 CrateType::Dylib => true,
1435
1436 CrateType::Rlib => true,
1437 }
1438 })
1439 }
1440
1441 pub fn is_suitable_region(
1443 self,
1444 generic_param_scope: LocalDefId,
1445 mut region: Region<'tcx>,
1446 ) -> Option<FreeRegionInfo> {
1447 let (suitable_region_binding_scope, region_def_id) = loop {
1448 let def_id =
1449 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1450 let scope = self.local_parent(def_id);
1451 if self.def_kind(scope) == DefKind::OpaqueTy {
1452 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1455 continue;
1456 }
1457 break (scope, def_id.into());
1458 };
1459
1460 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1461 Node::Item(..) | Node::TraitItem(..) => false,
1462 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1463 hir::ImplItemImplKind::Trait { .. } => true,
1470 _ => false,
1471 },
1472 _ => false,
1473 };
1474
1475 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1476 }
1477
1478 pub fn return_type_impl_or_dyn_traits(
1480 self,
1481 scope_def_id: LocalDefId,
1482 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1483 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1484 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1485 self.hir_fn_decl_by_hir_id(hir_id)
1486 else {
1487 return ::alloc::vec::Vec::new()vec![];
1488 };
1489
1490 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1491 v.visit_ty_unambig(hir_output);
1492 v.0
1493 }
1494
1495 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1499 self,
1500 scope_def_id: LocalDefId,
1501 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1502 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1503 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1504 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1506 && let hir::TyKind::Path(hir::QPath::Resolved(
1507 None,
1508 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1509 && let Some(local_id) = def_id.as_local()
1510 && 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()
1512 {
1513 v.visit_ty_unambig(alias_ty);
1514 if !v.0.is_empty() {
1515 return Some((
1516 v.0,
1517 alias_generics.span,
1518 alias_generics.span_for_lifetime_suggestion(),
1519 ));
1520 }
1521 }
1522 None
1523 }
1524
1525 pub fn has_strict_asm_symbol_naming(self) -> bool {
1528 self.sess.target.llvm_target.starts_with("nvptx")
1529 }
1530
1531 pub fn caller_location_ty(self) -> Ty<'tcx> {
1533 Ty::new_imm_ref(
1534 self,
1535 self.lifetimes.re_static,
1536 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1537 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1538 .skip_norm_wip(),
1539 )
1540 }
1541
1542 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1544 let kind = self.def_kind(def_id);
1545 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1546 }
1547
1548 pub fn type_length_limit(self) -> Limit {
1549 self.limits(()).type_length_limit
1550 }
1551
1552 pub fn recursion_limit(self) -> Limit {
1553 self.limits(()).recursion_limit
1554 }
1555
1556 pub fn move_size_limit(self) -> Limit {
1557 self.limits(()).move_size_limit
1558 }
1559
1560 pub fn pattern_complexity_limit(self) -> Limit {
1561 self.limits(()).pattern_complexity_limit
1562 }
1563
1564 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1566 iter::once(LOCAL_CRATE)
1567 .chain(self.crates(()).iter().copied())
1568 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1569 }
1570
1571 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1573 let visible_crates =
1574 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1575
1576 iter::once(LOCAL_CRATE)
1577 .chain(visible_crates)
1578 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1579 }
1580
1581 #[inline]
1582 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1583 self.visibility(def_id).expect_local()
1584 }
1585
1586 x;#[instrument(skip(self), level = "trace", ret)]
1588 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1589 self.hir_expect_opaque_ty(def_id).origin
1590 }
1591
1592 pub fn finish(self) {
1593 self.alloc_self_profile_query_strings();
1596
1597 self.save_dep_graph();
1598 self.verify_query_key_hashes();
1599
1600 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1601 self.sess
1602 .dcx()
1603 .emit_fatal(crate::diagnostics::FailedWritingFile { path: &path, error });
1604 }
1605 }
1606
1607 pub fn report_unused_features(self) {
1608 #[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)]
1609 #[diag("feature `{$feature}` is declared but not used")]
1610 struct UnusedFeature {
1611 feature: Symbol,
1612 }
1613
1614 let used_features = self.sess.used_features.lock();
1616 let unused_features = self
1617 .features()
1618 .enabled_features_iter_stable_order()
1619 .filter(|(f, _)| {
1620 !used_features.contains_key(f)
1621 && f.as_str() != "restricted_std"
1628 && *f != sym::doc_cfg
1632 })
1633 .collect::<Vec<_>>();
1634
1635 for (feature, span) in unused_features {
1636 self.emit_node_span_lint(
1637 rustc_session::lint::builtin::UNUSED_FEATURES,
1638 CRATE_HIR_ID,
1639 span,
1640 UnusedFeature { feature },
1641 );
1642 }
1643 }
1644}
1645
1646macro_rules! nop_lift {
1647 ($set:ident; $ty:ty => $lifted:ty) => {
1648 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1649 type Lifted = $lifted;
1650 #[track_caller]
1651 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1652 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1657 _x: Interned<'tcx, Inner>,
1658 ) -> InternedSet<'tcx, Inner> {
1659 unreachable!()
1660 }
1661 fn _type_eq<T>(_x: &T, _y: &T) {}
1662 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1663 let interner = _intern_set_ty_from_interned_ty(x.0);
1667 _type_eq(&interner, &tcx.interners.$set);
1669 }
1670
1671 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1672 unsafe { mem::transmute(self) }
1675 }
1676 }
1677 };
1678}
1679
1680macro_rules! nop_list_lift {
1681 ($set:ident; $ty:ty => $lifted:ty) => {
1682 nop_list_lift! { $set: List; $ty => $lifted }
1683 };
1684 ($set:ident: $list:ident; $ty:ty => $lifted:ty) => {
1686 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a $list<$ty> {
1687 type Lifted = &'tcx $list<$lifted>;
1688 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1689 if false {
1691 let _x: &InternedSet<'tcx, $list<$lifted>> = &tcx.interners.$set;
1692 }
1693
1694 if self.is_empty() {
1695 return $list::empty();
1696 }
1697 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1698 unsafe { mem::transmute(self) }
1701 }
1702 }
1703 };
1704}
1705
1706impl<'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> }
1707impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Const<'a> {
type Lifted = Const<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Const<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_);
}
if !tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { const_; Const<'a> => Const<'tcx> }
1708impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Pattern<'a> {
type Lifted = Pattern<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Pattern<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.pat);
}
if !tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
1709impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ConstAllocation<'a> {
type Lifted = ConstAllocation<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ConstAllocation<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_allocation);
}
if !tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
1710impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Predicate<'a> {
type Lifted = Predicate<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Predicate<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
1711impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Clause<'a> {
type Lifted = Clause<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Clause<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
1712impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Layout<'a> {
type Lifted = Layout<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Layout<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.layout);
}
if !tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { layout; Layout<'a> => Layout<'tcx> }
1713impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ValTree<'a> {
type Lifted = ValTree<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ValTree<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.valtree);
}
if !tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
1714
1715impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, RegionKind<'a>> {
1716 type Lifted = Interned<'tcx, RegionKind<'tcx>>;
1717
1718 #[track_caller]
1719 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1720 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)));
1721 unsafe { mem::transmute(self) }
1724 }
1725}
1726
1727impl<'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> }
1728impl<'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> }
1729impl<'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! {
1730 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1731}
1732impl<'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> }
1733impl<'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> }
1734impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<ty::ArgOutlivesClause<'a>> {
type Lifted = &'tcx List<ty::ArgOutlivesClause<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<ty::ArgOutlivesClause<'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! { outlives; ty::ArgOutlivesClause<'a> => ty::ArgOutlivesClause<'tcx> }
1735
1736impl<'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> }
1738
1739macro_rules! sty_debug_print {
1740 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1741 #[allow(non_snake_case, reason = "we're using variant names as local variables")]
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, reason =
"we're using variant names as local variables")]
mod inner {
use crate::ty::{self, TyCtxt};
use crate::ty::context::InternedInSet;
struct DebugStat {
total: usize,
lt_infer: usize,
ty_infer: usize,
ct_infer: usize,
all_infer: usize,
}
#[automatically_derived]
impl ::core::marker::Copy for DebugStat { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DebugStat { }
#[automatically_derived]
impl ::core::clone::Clone for DebugStat {
#[inline]
fn clone(&self) -> DebugStat {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}
pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>)
-> std::fmt::Result {
let mut total =
DebugStat {
total: 0,
lt_infer: 0,
ty_infer: 0,
ct_infer: 0,
all_infer: 0,
};
let mut Adt = total;
let mut Array = total;
let mut Slice = total;
let mut RawPtr = total;
let mut Ref = total;
let mut FnDef = total;
let mut FnPtr = total;
let mut UnsafeBinder = total;
let mut Placeholder = total;
let mut Coroutine = total;
let mut CoroutineWitness = total;
let mut Dynamic = total;
let mut Closure = total;
let mut CoroutineClosure = total;
let mut Tuple = total;
let mut Bound = total;
let mut Param = total;
let mut Infer = total;
let mut Alias = total;
let mut Pat = total;
let mut Foreign = total;
for shard in tcx.interners.type_.lock_shards() {
#[allow(rustc :: potential_query_instability)]
let types = shard.iter();
for &(InternedInSet(t), ()) in types {
let variant =
match t.internee {
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
ty::Float(..) | ty::Str | ty::Never => continue,
ty::Error(_) => continue,
ty::Adt(..) => &mut Adt,
ty::Array(..) => &mut Array,
ty::Slice(..) => &mut Slice,
ty::RawPtr(..) => &mut RawPtr,
ty::Ref(..) => &mut Ref,
ty::FnDef(..) => &mut FnDef,
ty::FnPtr(..) => &mut FnPtr,
ty::UnsafeBinder(..) => &mut UnsafeBinder,
ty::Placeholder(..) => &mut Placeholder,
ty::Coroutine(..) => &mut Coroutine,
ty::CoroutineWitness(..) => &mut CoroutineWitness,
ty::Dynamic(..) => &mut Dynamic,
ty::Closure(..) => &mut Closure,
ty::CoroutineClosure(..) => &mut CoroutineClosure,
ty::Tuple(..) => &mut Tuple,
ty::Bound(..) => &mut Bound,
ty::Param(..) => &mut Param,
ty::Infer(..) => &mut Infer,
ty::Alias(..) => &mut Alias,
ty::Pat(..) => &mut Pat,
ty::Foreign(..) => &mut Foreign,
};
let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
variant.total += 1;
total.total += 1;
if lt { total.lt_infer += 1; variant.lt_infer += 1 }
if ty { total.ty_infer += 1; variant.ty_infer += 1 }
if ct { total.ct_infer += 1; variant.ct_infer += 1 }
if lt && ty && ct {
total.all_infer += 1;
variant.all_infer += 1
}
}
}
fmt.write_fmt(format_args!("Ty interner total ty lt ct all\n"))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Adt", Adt.total,
Adt.total as f64 * 100.0 / total.total as f64,
Adt.ty_infer as f64 * 100.0 / total.total as f64,
Adt.lt_infer as f64 * 100.0 / total.total as f64,
Adt.ct_infer as f64 * 100.0 / total.total as f64,
Adt.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Array", Array.total,
Array.total as f64 * 100.0 / total.total as f64,
Array.ty_infer as f64 * 100.0 / total.total as f64,
Array.lt_infer as f64 * 100.0 / total.total as f64,
Array.ct_infer as f64 * 100.0 / total.total as f64,
Array.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Slice", Slice.total,
Slice.total as f64 * 100.0 / total.total as f64,
Slice.ty_infer as f64 * 100.0 / total.total as f64,
Slice.lt_infer as f64 * 100.0 / total.total as f64,
Slice.ct_infer as f64 * 100.0 / total.total as f64,
Slice.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"RawPtr", RawPtr.total,
RawPtr.total as f64 * 100.0 / total.total as f64,
RawPtr.ty_infer as f64 * 100.0 / total.total as f64,
RawPtr.lt_infer as f64 * 100.0 / total.total as f64,
RawPtr.ct_infer as f64 * 100.0 / total.total as f64,
RawPtr.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Ref", Ref.total,
Ref.total as f64 * 100.0 / total.total as f64,
Ref.ty_infer as f64 * 100.0 / total.total as f64,
Ref.lt_infer as f64 * 100.0 / total.total as f64,
Ref.ct_infer as f64 * 100.0 / total.total as f64,
Ref.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"FnDef", FnDef.total,
FnDef.total as f64 * 100.0 / total.total as f64,
FnDef.ty_infer as f64 * 100.0 / total.total as f64,
FnDef.lt_infer as f64 * 100.0 / total.total as f64,
FnDef.ct_infer as f64 * 100.0 / total.total as f64,
FnDef.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"FnPtr", FnPtr.total,
FnPtr.total as f64 * 100.0 / total.total as f64,
FnPtr.ty_infer as f64 * 100.0 / total.total as f64,
FnPtr.lt_infer as f64 * 100.0 / total.total as f64,
FnPtr.ct_infer as f64 * 100.0 / total.total as f64,
FnPtr.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"UnsafeBinder", UnsafeBinder.total,
UnsafeBinder.total as f64 * 100.0 / total.total as f64,
UnsafeBinder.ty_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.lt_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.ct_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Placeholder", Placeholder.total,
Placeholder.total as f64 * 100.0 / total.total as f64,
Placeholder.ty_infer as f64 * 100.0 / total.total as f64,
Placeholder.lt_infer as f64 * 100.0 / total.total as f64,
Placeholder.ct_infer as f64 * 100.0 / total.total as f64,
Placeholder.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Coroutine", Coroutine.total,
Coroutine.total as f64 * 100.0 / total.total as f64,
Coroutine.ty_infer as f64 * 100.0 / total.total as f64,
Coroutine.lt_infer as f64 * 100.0 / total.total as f64,
Coroutine.ct_infer as f64 * 100.0 / total.total as f64,
Coroutine.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"CoroutineWitness", CoroutineWitness.total,
CoroutineWitness.total as f64 * 100.0 / total.total as f64,
CoroutineWitness.ty_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.lt_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.ct_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Dynamic", Dynamic.total,
Dynamic.total as f64 * 100.0 / total.total as f64,
Dynamic.ty_infer as f64 * 100.0 / total.total as f64,
Dynamic.lt_infer as f64 * 100.0 / total.total as f64,
Dynamic.ct_infer as f64 * 100.0 / total.total as f64,
Dynamic.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Closure", Closure.total,
Closure.total as f64 * 100.0 / total.total as f64,
Closure.ty_infer as f64 * 100.0 / total.total as f64,
Closure.lt_infer as f64 * 100.0 / total.total as f64,
Closure.ct_infer as f64 * 100.0 / total.total as f64,
Closure.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"CoroutineClosure", CoroutineClosure.total,
CoroutineClosure.total as f64 * 100.0 / total.total as f64,
CoroutineClosure.ty_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.lt_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.ct_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Tuple", Tuple.total,
Tuple.total as f64 * 100.0 / total.total as f64,
Tuple.ty_infer as f64 * 100.0 / total.total as f64,
Tuple.lt_infer as f64 * 100.0 / total.total as f64,
Tuple.ct_infer as f64 * 100.0 / total.total as f64,
Tuple.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Bound", Bound.total,
Bound.total as f64 * 100.0 / total.total as f64,
Bound.ty_infer as f64 * 100.0 / total.total as f64,
Bound.lt_infer as f64 * 100.0 / total.total as f64,
Bound.ct_infer as f64 * 100.0 / total.total as f64,
Bound.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Param", Param.total,
Param.total as f64 * 100.0 / total.total as f64,
Param.ty_infer as f64 * 100.0 / total.total as f64,
Param.lt_infer as f64 * 100.0 / total.total as f64,
Param.ct_infer as f64 * 100.0 / total.total as f64,
Param.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Infer", Infer.total,
Infer.total as f64 * 100.0 / total.total as f64,
Infer.ty_infer as f64 * 100.0 / total.total as f64,
Infer.lt_infer as f64 * 100.0 / total.total as f64,
Infer.ct_infer as f64 * 100.0 / total.total as f64,
Infer.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Alias", Alias.total,
Alias.total as f64 * 100.0 / total.total as f64,
Alias.ty_infer as f64 * 100.0 / total.total as f64,
Alias.lt_infer as f64 * 100.0 / total.total as f64,
Alias.ct_infer as f64 * 100.0 / total.total as f64,
Alias.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Pat", Pat.total,
Pat.total as f64 * 100.0 / total.total as f64,
Pat.ty_infer as f64 * 100.0 / total.total as f64,
Pat.lt_infer as f64 * 100.0 / total.total as f64,
Pat.ct_infer as f64 * 100.0 / total.total as f64,
Pat.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Foreign", Foreign.total,
Foreign.total as f64 * 100.0 / total.total as f64,
Foreign.ty_infer as f64 * 100.0 / total.total as f64,
Foreign.lt_infer as f64 * 100.0 / total.total as f64,
Foreign.ct_infer as f64 * 100.0 / total.total as f64,
Foreign.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" total {0:6} {1:4.1}% {2:5.1}% {3:4.1}% {4:4.1}%\n",
total.total,
total.ty_infer as f64 * 100.0 / total.total as f64,
total.lt_infer as f64 * 100.0 / total.total as f64,
total.ct_infer as f64 * 100.0 / total.total as f64,
total.all_infer as f64 * 100.0 / total.total as f64))
}
}
inner::go(fmt, self)
}sty_debug_print!(
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::ArgOutlivesClause<'tcx>])
-> &'tcx List<ty::ArgOutlivesClause<'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::ArgOutlivesClause<'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::ArgOutlivesClause<'tcx>,
2493 &'tcx ty::List<ty::ArgOutlivesClause<'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_attr_ir::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(DoNotRecommend) => {
break 'done Some(());
}
::rustc_attr_ir::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_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(PanicRuntime) => {
break 'done Some(());
}
::rustc_attr_ir::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_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(CompilerBuiltins) => {
break 'done Some(());
}
::rustc_attr_ir::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}