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