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