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 true {
{
match (&self.def_kind(key), &DefKind::AnonConst) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
};debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
605 if true {
if !(self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline)
{
::core::panicking::panic("assertion failed: self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline")
};
};debug_assert!(self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline);
606 TyCtxtFeed { tcx: self, key }.type_of(value)
607 }
608
609 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
617 if truecfg!(debug_assertions) {
618 match self.def_kind(self.local_parent(key)) {
619 DefKind::Impl { of_trait: true } => {}
620 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:?}"),
621 }
622 }
623 TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id())
624 }
625}
626
627impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> {
628 #[inline(always)]
629 pub fn key(&self) -> K {
630 self.key
631 }
632}
633
634impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
635 #[inline(always)]
636 pub fn def_id(&self) -> LocalDefId {
637 self.key
638 }
639
640 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
642 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
643 }
644
645 pub fn feed_hir(&self) {
647 self.hir_owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo::new(
648 self.tcx.arena.alloc(hir::OwnerNodes::synthetic()),
649 self.tcx.arena.alloc(Default::default()),
650 self.tcx.arena.alloc(Default::default()),
651 self.tcx.arena.alloc(Steal::new(Default::default())),
652 )));
653
654 self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
655 }
656}
657
658#[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)]
676#[rustc_diagnostic_item = "TyCtxt"]
677#[rustc_pass_by_value]
678pub struct TyCtxt<'tcx> {
679 gcx: &'tcx GlobalCtxt<'tcx>,
680}
681
682unsafe impl DynSend for TyCtxt<'_> {}
686unsafe impl DynSync for TyCtxt<'_> {}
687fn _assert_tcx_fields() {
688 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
689 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
690}
691
692impl<'tcx> Deref for TyCtxt<'tcx> {
693 type Target = &'tcx GlobalCtxt<'tcx>;
694 #[inline(always)]
695 fn deref(&self) -> &Self::Target {
696 &self.gcx
697 }
698}
699
700pub struct GlobalCtxt<'tcx> {
702 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
703 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
704
705 interners: CtxtInterners<'tcx>,
706
707 pub sess: &'tcx Session,
708 crate_types: Vec<CrateType>,
709 stable_crate_id: StableCrateId,
715
716 pub dep_graph: DepGraph,
717
718 pub prof: SelfProfilerRef,
719
720 pub types: CommonTypes<'tcx>,
722
723 pub lifetimes: CommonLifetimes<'tcx>,
725
726 pub consts: CommonConsts<'tcx>,
728
729 pub(crate) hooks: crate::hooks::Providers,
732
733 untracked: Untracked,
734
735 pub query_system: QuerySystem<'tcx>,
736 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
737
738 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
740
741 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
744
745 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
749
750 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
752 pub new_solver_canonical_param_env_cache:
753 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
754
755 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
756
757 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
759 pub clauses_cache:
761 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
762
763 pub data_layout: TargetDataLayout,
765
766 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
768
769 current_gcx: CurrentGcx,
770
771 pub jobserver_proxy: Arc<Proxy>,
773}
774
775impl<'tcx> GlobalCtxt<'tcx> {
776 pub fn enter<F, R>(&'tcx self, f: F) -> R
779 where
780 F: FnOnce(TyCtxt<'tcx>) -> R,
781 {
782 let icx = tls::ImplicitCtxt::new(self);
783
784 let _on_drop = defer(move || {
786 *self.current_gcx.value.write() = None;
787 });
788
789 {
791 let mut guard = self.current_gcx.value.write();
792 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
793 *guard = Some(self as *const _ as *const ());
794 }
795
796 tls::enter_context(&icx, || f(icx.tcx))
797 }
798}
799
800#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
807pub struct CurrentGcx {
808 value: Arc<RwLock<Option<*const ()>>>,
811}
812
813unsafe impl DynSend for CurrentGcx {}
814unsafe impl DynSync for CurrentGcx {}
815
816impl CurrentGcx {
817 pub fn new() -> Self {
818 Self { value: Arc::new(RwLock::new(None)) }
819 }
820
821 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
822 let read_guard = self.value.read();
823 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
824 f(unsafe { &*gcx })
828 }
829}
830
831impl<'tcx> TyCtxt<'tcx> {
832 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
833 let root = self.typeck_root_def_id_local(def_id);
836 self.hir_node_by_def_id(root).body_id().is_some()
837 }
838
839 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
844 let def_kind = self.def_kind(def_id);
845 if def_kind.has_codegen_attrs() {
846 self.codegen_fn_attrs(def_id)
847 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
DefKind::GlobalAsm => true,
_ => false,
}matches!(
848 def_kind,
849 DefKind::AnonConst
850 | DefKind::AssocConst { .. }
851 | DefKind::Const { .. }
852 | DefKind::GlobalAsm
853 ) {
854 CodegenFnAttrs::EMPTY
855 } else {
856 crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind))bug!(
857 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
858 def_id,
859 def_kind
860 )
861 }
862 }
863
864 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
865 self.arena.alloc(Steal::new(thir))
866 }
867
868 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
869 self.arena.alloc(Steal::new(mir))
870 }
871
872 pub fn alloc_steal_promoted(
873 self,
874 promoted: IndexVec<Promoted, Body<'tcx>>,
875 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
876 self.arena.alloc(Steal::new(promoted))
877 }
878
879 pub fn mk_adt_def(
880 self,
881 did: DefId,
882 kind: AdtKind,
883 variants: IndexVec<VariantIdx, ty::VariantDef>,
884 repr: ReprOptions,
885 ) -> ty::AdtDef<'tcx> {
886 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
887 }
888
889 pub fn allocate_bytes_dedup<'a>(
892 self,
893 bytes: impl Into<Cow<'a, [u8]>>,
894 salt: usize,
895 ) -> interpret::AllocId {
896 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
898 let alloc = self.mk_const_alloc(alloc);
899 self.reserve_and_set_memory_dedup(alloc, salt)
900 }
901
902 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
904 if self.sess.opts.unstable_opts.experimental_default_bounds {
905 &[
906 LangItem::DefaultTrait1,
907 LangItem::DefaultTrait2,
908 LangItem::DefaultTrait3,
909 LangItem::DefaultTrait4,
910 ]
911 } else {
912 &[]
913 }
914 }
915
916 pub fn is_default_trait(self, def_id: DefId) -> bool {
917 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
918 }
919
920 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
921 #[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))
922 }
923
924 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> T::Lifted {
925 value.lift_to_interner(self)
926 }
927
928 pub fn create_global_ctxt<T>(
935 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
936 sess: &'tcx Session,
937 crate_types: Vec<CrateType>,
938 stable_crate_id: StableCrateId,
939 arena: &'tcx WorkerLocal<Arena<'tcx>>,
940 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
941 untracked: Untracked,
942 dep_graph: DepGraph,
943 dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
944 query_system: QuerySystem<'tcx>,
945 hooks: crate::hooks::Providers,
946 current_gcx: CurrentGcx,
947 jobserver_proxy: Arc<Proxy>,
948 f: impl FnOnce(TyCtxt<'tcx>) -> T,
949 ) -> T {
950 let data_layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
951 sess.dcx().emit_fatal(err);
952 });
953 let interners = CtxtInterners::new(arena);
954 let common_types = CommonTypes::new(&interners);
955 let common_lifetimes = CommonLifetimes::new(&interners);
956 let common_consts = CommonConsts::new(&interners, &common_types);
957
958 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
959 sess,
960 crate_types,
961 stable_crate_id,
962 arena,
963 hir_arena,
964 interners,
965 dep_graph,
966 hooks,
967 prof: sess.prof.clone(),
968 types: common_types,
969 lifetimes: common_lifetimes,
970 consts: common_consts,
971 untracked,
972 query_system,
973 dep_kind_vtables,
974 ty_rcache: Default::default(),
975 selection_cache: Default::default(),
976 evaluation_cache: Default::default(),
977 new_solver_evaluation_cache: Default::default(),
978 new_solver_canonical_param_env_cache: Default::default(),
979 canonical_param_env_cache: Default::default(),
980 highest_var_in_clauses_cache: Default::default(),
981 clauses_cache: Default::default(),
982 data_layout,
983 alloc_map: interpret::AllocMap::new(),
984 current_gcx,
985 jobserver_proxy,
986 });
987
988 gcx.enter(f)
990 }
991
992 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
994 self.get_lang_items(())
995 }
996
997 #[track_caller]
999 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1000 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1001 self.type_of(ordering_enum).no_bound_vars().unwrap()
1002 }
1003
1004 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1007 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1008 }
1009
1010 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1012 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1013 }
1014
1015 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1017 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1018 }
1019
1020 pub fn is_coroutine(self, def_id: DefId) -> bool {
1021 self.coroutine_kind(def_id).is_some()
1022 }
1023
1024 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1025 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1026 }
1027
1028 pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1029 if !self.is_type_const(def_id) {
1030 return None;
1031 }
1032 Some(self.def_span(def_id))
1033 }
1034
1035 pub fn is_type_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1037 let def_id = def_id.into_query_key();
1038 match self.def_kind(def_id) {
1039 DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1040 is_type_const
1041 }
1042 _ => false,
1043 }
1044 }
1045
1046 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1049 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1050 }
1051
1052 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1054 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1055 self.coroutine_kind(def_id),
1056 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1057 )
1058 }
1059
1060 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1063 #[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)
1064 }
1065
1066 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1069 #[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(_)))
1070 }
1071
1072 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1074 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1075 self.coroutine_kind(def_id),
1076 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1077 )
1078 }
1079
1080 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1082 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1083 self.coroutine_kind(def_id),
1084 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1085 )
1086 }
1087
1088 pub fn features(self) -> &'tcx rustc_feature::Features {
1089 self.features_query(())
1090 }
1091
1092 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1093 let id = id.into_query_key();
1094 if let Some(id) = id.as_local() {
1096 self.definitions_untracked().def_key(id)
1097 } else {
1098 self.cstore_untracked().def_key(id)
1099 }
1100 }
1101
1102 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1108 if let Some(id) = id.as_local() {
1110 self.definitions_untracked().def_path(id)
1111 } else {
1112 self.cstore_untracked().def_path(id)
1113 }
1114 }
1115
1116 #[inline]
1117 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1118 if let Some(def_id) = def_id.as_local() {
1120 self.definitions_untracked().def_path_hash(def_id)
1121 } else {
1122 self.cstore_untracked().def_path_hash(def_id)
1123 }
1124 }
1125
1126 #[inline]
1127 pub fn crate_types(self) -> &'tcx [CrateType] {
1128 &self.crate_types
1129 }
1130
1131 pub fn needs_metadata(self) -> bool {
1132 self.crate_types().iter().any(|ty| match *ty {
1133 CrateType::Executable
1134 | CrateType::StaticLib
1135 | CrateType::Cdylib
1136 | CrateType::Sdylib => false,
1137 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1138 })
1139 }
1140
1141 pub fn needs_hir_hash(self) -> bool {
1142 truecfg!(debug_assertions)
1154 || self.sess.opts.incremental.is_some()
1155 || self.needs_metadata()
1156 || self.sess.instrument_coverage()
1157 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1158 }
1159
1160 #[inline]
1161 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1162 if crate_num == LOCAL_CRATE {
1163 self.stable_crate_id
1164 } else {
1165 self.cstore_untracked().stable_crate_id(crate_num)
1166 }
1167 }
1168
1169 #[inline]
1172 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1173 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1174 LOCAL_CRATE
1175 } else {
1176 *self
1177 .untracked()
1178 .stable_crate_ids
1179 .read()
1180 .get(&stable_crate_id)
1181 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1182 }
1183 }
1184
1185 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1189 {
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:1189",
"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(1189u32),
::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);
1190
1191 let stable_crate_id = hash.stable_crate_id();
1192
1193 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1196 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1197 } else {
1198 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1199 }
1200 }
1201
1202 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1203 let (crate_name, stable_crate_id) = if def_id.is_local() {
1208 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1209 } else {
1210 let cstore = &*self.cstore_untracked();
1211 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1212 };
1213
1214 ::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!(
1215 "{}[{:04x}]{}",
1216 crate_name,
1217 stable_crate_id.as_u64() >> (8 * 6),
1220 self.def_path(def_id).to_string_no_crate_verbose()
1221 )
1222 }
1223
1224 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1225 self.sess.dcx()
1226 }
1227
1228 pub fn is_target_feature_call_safe(
1231 self,
1232 callee_features: &[TargetFeature],
1233 body_features: &[TargetFeature],
1234 ) -> bool {
1235 self.sess.target.options.is_like_wasm
1240 || callee_features
1241 .iter()
1242 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1243 }
1244
1245 pub fn adjust_target_feature_sig(
1248 self,
1249 fun_def: DefId,
1250 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1251 caller: DefId,
1252 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1253 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1254 let caller_features = &self.body_codegen_attrs(caller).target_features;
1255 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1256 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1257 fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1258 ..sig
1259 }));
1260 }
1261 None
1262 }
1263
1264 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1267 match self.env_var_os(key.as_ref()) {
1268 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1269 None => Err(VarError::NotPresent),
1270 }
1271 }
1272}
1273
1274impl<'tcx> TyCtxtAt<'tcx> {
1275 pub fn create_def(
1277 self,
1278 parent: LocalDefId,
1279 name: Option<Symbol>,
1280 def_kind: DefKind,
1281 override_def_path_data: Option<DefPathData>,
1282 disambiguator: &mut PerParentDisambiguatorState,
1283 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1284 let feed =
1285 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1286
1287 feed.def_span(self.span);
1288 feed
1289 }
1290}
1291
1292impl<'tcx> TyCtxt<'tcx> {
1293 pub fn create_def(
1295 self,
1296 parent: LocalDefId,
1297 name: Option<Symbol>,
1298 def_kind: DefKind,
1299 override_def_path_data: Option<DefPathData>,
1300 disambiguator: &mut PerParentDisambiguatorState,
1301 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1302 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1303 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1313
1314 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1319
1320 let feed = TyCtxtFeed { tcx: self, key: def_id };
1321 feed.def_kind(def_kind);
1322 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1327 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1328 feed.visibility(ty::Visibility::Restricted(parent_mod));
1329 }
1330
1331 feed
1332 }
1333
1334 pub fn create_crate_num(
1335 self,
1336 stable_crate_id: StableCrateId,
1337 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1338 let mut lock = self.untracked().stable_crate_ids.write();
1339 if let Some(&existing) = lock.get(&stable_crate_id) {
1340 return Err(existing);
1341 }
1342 let num = CrateNum::new(lock.len());
1343 lock.insert(stable_crate_id, num);
1344 Ok(TyCtxtFeed { key: num, tcx: self })
1345 }
1346
1347 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1348 self.ensure_ok().analysis(());
1350
1351 let definitions = &self.untracked.definitions;
1352 gen {
1353 let mut i = 0;
1354
1355 while i < { definitions.read().num_definitions() } {
1358 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1359 yield LocalDefId { local_def_index };
1360 i += 1;
1361 }
1362
1363 definitions.freeze();
1365 }
1366 }
1367
1368 pub fn definitions(self) -> &'tcx rustc_hir::definitions::Definitions {
1369 self.ensure_ok().analysis(());
1371
1372 self.untracked.definitions.freeze()
1375 }
1376
1377 pub fn def_path_hash_to_def_index_map(
1378 self,
1379 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1380 self.ensure_ok().hir_crate_items(());
1383 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1386 }
1387
1388 #[inline]
1391 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1392 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1393 }
1394
1395 pub fn untracked(self) -> &'tcx Untracked {
1397 &self.untracked
1398 }
1399 #[inline]
1402 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1403 self.untracked.definitions.read()
1404 }
1405
1406 #[inline]
1409 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1410 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1411 }
1412
1413 #[inline(always)]
1414 pub fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashState<'_>) -> R) -> R {
1415 f(StableHashState::new(self.sess, &self.untracked))
1416 }
1417
1418 #[inline]
1419 pub fn local_crate_exports_generics(self) -> bool {
1420 if self.is_compiler_builtins(LOCAL_CRATE) {
1424 return false;
1425 }
1426 self.crate_types().iter().any(|crate_type| {
1427 match crate_type {
1428 CrateType::Executable
1429 | CrateType::StaticLib
1430 | CrateType::ProcMacro
1431 | CrateType::Cdylib
1432 | CrateType::Sdylib => false,
1433
1434 CrateType::Dylib => true,
1439
1440 CrateType::Rlib => true,
1441 }
1442 })
1443 }
1444
1445 pub fn is_suitable_region(
1447 self,
1448 generic_param_scope: LocalDefId,
1449 mut region: Region<'tcx>,
1450 ) -> Option<FreeRegionInfo> {
1451 let (suitable_region_binding_scope, region_def_id) = loop {
1452 let def_id =
1453 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1454 let scope = self.local_parent(def_id);
1455 if self.def_kind(scope) == DefKind::OpaqueTy {
1456 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1459 continue;
1460 }
1461 break (scope, def_id.into());
1462 };
1463
1464 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1465 Node::Item(..) | Node::TraitItem(..) => false,
1466 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1467 hir::ImplItemImplKind::Trait { .. } => true,
1474 _ => false,
1475 },
1476 _ => false,
1477 };
1478
1479 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1480 }
1481
1482 pub fn return_type_impl_or_dyn_traits(
1484 self,
1485 scope_def_id: LocalDefId,
1486 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1487 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1488 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1489 self.hir_fn_decl_by_hir_id(hir_id)
1490 else {
1491 return ::alloc::vec::Vec::new()vec![];
1492 };
1493
1494 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1495 v.visit_ty_unambig(hir_output);
1496 v.0
1497 }
1498
1499 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1503 self,
1504 scope_def_id: LocalDefId,
1505 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1506 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1507 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1508 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1510 && let hir::TyKind::Path(hir::QPath::Resolved(
1511 None,
1512 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1513 && let Some(local_id) = def_id.as_local()
1514 && 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()
1516 {
1517 v.visit_ty_unambig(alias_ty);
1518 if !v.0.is_empty() {
1519 return Some((
1520 v.0,
1521 alias_generics.span,
1522 alias_generics.span_for_lifetime_suggestion(),
1523 ));
1524 }
1525 }
1526 None
1527 }
1528
1529 pub fn has_strict_asm_symbol_naming(self) -> bool {
1532 self.sess.target.llvm_target.starts_with("nvptx")
1533 }
1534
1535 pub fn caller_location_ty(self) -> Ty<'tcx> {
1537 Ty::new_imm_ref(
1538 self,
1539 self.lifetimes.re_static,
1540 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1541 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1542 .skip_norm_wip(),
1543 )
1544 }
1545
1546 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1548 let kind = self.def_kind(def_id);
1549 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1550 }
1551
1552 pub fn type_length_limit(self) -> Limit {
1553 self.limits(()).type_length_limit
1554 }
1555
1556 pub fn recursion_limit(self) -> Limit {
1557 self.limits(()).recursion_limit
1558 }
1559
1560 pub fn move_size_limit(self) -> Limit {
1561 self.limits(()).move_size_limit
1562 }
1563
1564 pub fn pattern_complexity_limit(self) -> Limit {
1565 self.limits(()).pattern_complexity_limit
1566 }
1567
1568 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1570 iter::once(LOCAL_CRATE)
1571 .chain(self.crates(()).iter().copied())
1572 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1573 }
1574
1575 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1577 let visible_crates =
1578 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1579
1580 iter::once(LOCAL_CRATE)
1581 .chain(visible_crates)
1582 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1583 }
1584
1585 #[inline]
1586 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1587 self.visibility(def_id).expect_local()
1588 }
1589
1590 x;#[instrument(skip(self), level = "trace", ret)]
1592 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1593 self.hir_expect_opaque_ty(def_id).origin
1594 }
1595
1596 pub fn finish(self) {
1597 self.alloc_self_profile_query_strings();
1600
1601 self.save_dep_graph();
1602 self.verify_query_key_hashes();
1603
1604 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1605 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
1606 }
1607 }
1608
1609 pub fn report_unused_features(self) {
1610 #[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)]
1611 #[diag("feature `{$feature}` is declared but not used")]
1612 struct UnusedFeature {
1613 feature: Symbol,
1614 }
1615
1616 let used_features = self.sess.used_features.lock();
1618 let unused_features = self
1619 .features()
1620 .enabled_features_iter_stable_order()
1621 .filter(|(f, _)| {
1622 !used_features.contains_key(f)
1623 && f.as_str() != "restricted_std"
1630 && *f != sym::doc_cfg
1634 })
1635 .collect::<Vec<_>>();
1636
1637 for (feature, span) in unused_features {
1638 self.emit_node_span_lint(
1639 rustc_session::lint::builtin::UNUSED_FEATURES,
1640 CRATE_HIR_ID,
1641 span,
1642 UnusedFeature { feature },
1643 );
1644 }
1645 }
1646}
1647
1648macro_rules! nop_lift {
1649 ($set:ident; $ty:ty => $lifted:ty) => {
1650 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1651 type Lifted = $lifted;
1652 #[track_caller]
1653 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1654 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1659 _x: Interned<'tcx, Inner>,
1660 ) -> InternedSet<'tcx, Inner> {
1661 unreachable!()
1662 }
1663 fn _type_eq<T>(_x: &T, _y: &T) {}
1664 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1665 let interner = _intern_set_ty_from_interned_ty(x.0);
1669 _type_eq(&interner, &tcx.interners.$set);
1671 }
1672
1673 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1674 unsafe { mem::transmute(self) }
1677 }
1678 }
1679 };
1680}
1681
1682macro_rules! nop_list_lift {
1683 ($set:ident; $ty:ty => $lifted:ty) => {
1684 nop_list_lift! { $set: List; $ty => $lifted }
1685 };
1686 ($set:ident: $list:ident; $ty:ty => $lifted:ty) => {
1688 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a $list<$ty> {
1689 type Lifted = &'tcx $list<$lifted>;
1690 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1691 if false {
1693 let _x: &InternedSet<'tcx, $list<$lifted>> = &tcx.interners.$set;
1694 }
1695
1696 if self.is_empty() {
1697 return $list::empty();
1698 }
1699 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1700 unsafe { mem::transmute(self) }
1703 }
1704 }
1705 };
1706}
1707
1708impl<'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> }
1709impl<'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> }
1710impl<'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> }
1711impl<'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> }
1712impl<'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> }
1713impl<'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> }
1714impl<'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> }
1715impl<'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> }
1716impl<'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> }
1717
1718impl<'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> }
1719impl<'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> }
1720impl<'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! {
1721 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1722}
1723impl<'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> }
1724impl<'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> }
1725impl<'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! {
1726 outlives; ty::ArgOutlivesPredicate<'a> => ty::ArgOutlivesPredicate<'tcx>
1727}
1728
1729impl<'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> }
1731
1732macro_rules! sty_debug_print {
1733 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1734 #[allow(non_snake_case)]
1737 mod inner {
1738 use crate::ty::{self, TyCtxt};
1739 use crate::ty::context::InternedInSet;
1740
1741 #[derive(Copy, Clone)]
1742 struct DebugStat {
1743 total: usize,
1744 lt_infer: usize,
1745 ty_infer: usize,
1746 ct_infer: usize,
1747 all_infer: usize,
1748 }
1749
1750 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1751 let mut total = DebugStat {
1752 total: 0,
1753 lt_infer: 0,
1754 ty_infer: 0,
1755 ct_infer: 0,
1756 all_infer: 0,
1757 };
1758 $(let mut $variant = total;)*
1759
1760 for shard in tcx.interners.type_.lock_shards() {
1761 #[allow(rustc::potential_query_instability)]
1763 let types = shard.iter();
1764 for &(InternedInSet(t), ()) in types {
1765 let variant = match t.internee {
1766 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1767 ty::Float(..) | ty::Str | ty::Never => continue,
1768 ty::Error(_) => continue,
1769 $(ty::$variant(..) => &mut $variant,)*
1770 };
1771 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1772 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1773 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1774
1775 variant.total += 1;
1776 total.total += 1;
1777 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1778 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1779 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1780 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1781 }
1782 }
1783 writeln!(fmt, "Ty interner total ty lt ct all")?;
1784 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1785 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1786 stringify!($variant),
1787 uses = $variant.total,
1788 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1789 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1790 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1791 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1792 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1793 )*
1794 writeln!(fmt, " total {uses:6} \
1795 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1796 uses = total.total,
1797 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1798 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1799 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1800 all = total.all_infer as f64 * 100.0 / total.total as f64)
1801 }
1802 }
1803
1804 inner::go($fmt, $ctxt)
1805 }}
1806}
1807
1808impl<'tcx> TyCtxt<'tcx> {
1809 pub fn debug_stats(self) -> impl fmt::Debug {
1810 fmt::from_fn(move |fmt| {
1811 {
#[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!(
1812 fmt,
1813 self,
1814 Adt,
1815 Array,
1816 Slice,
1817 RawPtr,
1818 Ref,
1819 FnDef,
1820 FnPtr,
1821 UnsafeBinder,
1822 Placeholder,
1823 Coroutine,
1824 CoroutineWitness,
1825 Dynamic,
1826 Closure,
1827 CoroutineClosure,
1828 Tuple,
1829 Bound,
1830 Param,
1831 Infer,
1832 Alias,
1833 Pat,
1834 Foreign
1835 )?;
1836
1837 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1838 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1839 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())?;
1840 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1841
1842 Ok(())
1843 })
1844 }
1845}
1846
1847struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1852
1853impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1854 fn clone(&self) -> Self {
1855 *self
1856 }
1857}
1858
1859impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1860
1861impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1862 fn into_pointer(&self) -> *const () {
1863 self.0 as *const _ as *const ()
1864 }
1865}
1866
1867#[allow(rustc::usage_of_ty_tykind)]
1868impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1869 fn borrow(&self) -> &T {
1870 &self.0.internee
1871 }
1872}
1873
1874impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1875 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1876 self.0.internee == other.0.internee
1879 }
1880}
1881
1882impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1883
1884impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1885 fn hash<H: Hasher>(&self, s: &mut H) {
1886 self.0.internee.hash(s)
1888 }
1889}
1890
1891impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1892 fn borrow(&self) -> &[T] {
1893 &self.0[..]
1894 }
1895}
1896
1897impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1898 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1899 self.0[..] == other.0[..]
1902 }
1903}
1904
1905impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1906
1907impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1908 fn hash<H: Hasher>(&self, s: &mut H) {
1909 self.0[..].hash(s)
1911 }
1912}
1913
1914impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1915 fn borrow(&self) -> &[T] {
1916 &self.0[..]
1917 }
1918}
1919
1920impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1921 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1922 self.0[..] == other.0[..]
1925 }
1926}
1927
1928impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1929
1930impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1931 fn hash<H: Hasher>(&self, s: &mut H) {
1932 self.0[..].hash(s)
1934 }
1935}
1936
1937macro_rules! direct_interners {
1938 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1939 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1940 fn borrow<'a>(&'a self) -> &'a $ty {
1941 &self.0
1942 }
1943 }
1944
1945 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1946 fn eq(&self, other: &Self) -> bool {
1947 self.0 == other.0
1950 }
1951 }
1952
1953 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1954
1955 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1956 fn hash<H: Hasher>(&self, s: &mut H) {
1957 self.0.hash(s)
1960 }
1961 }
1962
1963 impl<'tcx> TyCtxt<'tcx> {
1964 $vis fn $method(self, v: $ty) -> $ret_ty {
1965 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1966 InternedInSet(self.interners.arena.alloc(v))
1967 }).0))
1968 }
1969 })+
1970 }
1971}
1972
1973impl<'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! {
1977 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
1978 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
1979 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
1980 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
1981 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
1982 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
1983 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
1984 ExternalConstraints -> ExternalConstraints<'tcx>,
1985}
1986
1987macro_rules! slice_interners {
1988 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
1989 impl<'tcx> TyCtxt<'tcx> {
1990 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
1991 if v.is_empty() {
1992 List::empty()
1993 } else {
1994 self.interners.$field.intern_ref(v, || {
1995 InternedInSet(List::from_arena(&*self.arena, (), v))
1996 }).0
1997 }
1998 })+
1999 }
2000 );
2001}
2002
2003impl<'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!(
2007 const_lists: pub mk_const_list(Const<'tcx>),
2008 args: pub mk_args(GenericArg<'tcx>),
2009 type_lists: pub mk_type_list(Ty<'tcx>),
2010 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2011 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2012 projs: pub mk_projs(ProjectionKind),
2013 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2014 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2015 fields: pub mk_fields(FieldIdx),
2016 local_def_ids: intern_local_def_ids(LocalDefId),
2017 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2018 patterns: pub mk_patterns(Pattern<'tcx>),
2019 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2020 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2021);
2022
2023impl<'tcx> TyCtxt<'tcx> {
2024 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2028 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2029 Ty::new_fn_ptr(
2030 self,
2031 sig.map_bound(|sig| ty::FnSig {
2032 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2033 ..sig
2034 }),
2035 )
2036 }
2037
2038 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2042 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2043 sig.map_bound(|sig| ty::FnSig {
2044 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2045 ..sig
2046 })
2047 }
2048
2049 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2052 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2053 self.associated_items(trait_did)
2054 .filter_by_name_unhygienic(assoc_name.name)
2055 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2056 })
2057 }
2058
2059 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2061 let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2062 return false;
2063 };
2064 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2065
2066 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2067 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2068 return false;
2069 };
2070 trait_predicate.trait_ref.def_id == future_trait
2071 && trait_predicate.polarity == PredicatePolarity::Positive
2072 })
2073 }
2074
2075 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2083 sig.map_bound(|s| {
2084 let params = match s.inputs()[0].kind() {
2085 ty::Tuple(params) => *params,
2086 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2087 };
2088 if !s.splatted().is_none() {
::core::panicking::panic("assertion failed: s.splatted().is_none()")
};assert!(s.splatted().is_none());
2090 self.mk_fn_sig(
2091 params,
2092 s.output(),
2093 s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2094 )
2095 })
2096 }
2097
2098 #[inline]
2099 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2100 self.interners.intern_predicate(binder)
2101 }
2102
2103 #[inline]
2104 pub fn reuse_or_mk_predicate(
2105 self,
2106 pred: Predicate<'tcx>,
2107 binder: Binder<'tcx, PredicateKind<'tcx>>,
2108 ) -> Predicate<'tcx> {
2109 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2110 }
2111
2112 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2113 self.check_args_compatible_inner(def_id, args, false)
2114 }
2115
2116 fn check_args_compatible_inner(
2117 self,
2118 def_id: DefId,
2119 args: &'tcx [ty::GenericArg<'tcx>],
2120 nested: bool,
2121 ) -> bool {
2122 let generics = self.generics_of(def_id);
2123
2124 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)
2128 && #[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 });
2129 let is_inherent_assoc_type_const =
2130 #[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 })
2131 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(self.def_kind(self.parent(def_id)), DefKind::Impl { of_trait: false });
2132 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2133 if generics.own_params.len() + 1 != args.len() {
2134 return false;
2135 }
2136
2137 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2138 return false;
2139 }
2140
2141 &args[1..]
2142 } else {
2143 if generics.count() != args.len() {
2144 return false;
2145 }
2146
2147 let (parent_args, own_args) = args.split_at(generics.parent_count);
2148
2149 if let Some(parent) = generics.parent
2150 && !self.check_args_compatible_inner(parent, parent_args, true)
2151 {
2152 return false;
2153 }
2154
2155 own_args
2156 };
2157
2158 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2159 match (¶m.kind, arg.kind()) {
2160 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2161 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2162 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2163 _ => return false,
2164 }
2165 }
2166
2167 true
2168 }
2169
2170 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2173 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2174 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)
2175 && #[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 });
2176 let is_inherent_assoc_type_const =
2177 #[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 })
2178 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(
2179 self.def_kind(self.parent(def_id)),
2180 DefKind::Impl { of_trait: false }
2181 );
2182 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2183 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!(
2184 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2185 self.def_path_str(def_id),
2186 args,
2187 self.mk_args_from_iter(
2189 [self.types.self_param.into()].into_iter().chain(
2190 self.generics_of(def_id)
2191 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2192 .iter()
2193 .copied()
2194 )
2195 )
2196 );
2197 } else {
2198 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!(
2199 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2200 self.def_path_str(def_id),
2201 args,
2202 ty::GenericArgs::identity_for_item(self, def_id)
2203 );
2204 }
2205 }
2206 }
2207
2208 #[inline(always)]
2209 pub(crate) fn check_and_mk_args(
2210 self,
2211 def_id: DefId,
2212 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2213 ) -> GenericArgsRef<'tcx> {
2214 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2215 self.debug_assert_args_compatible(def_id, args);
2216 args
2217 }
2218
2219 #[inline]
2220 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2221 self.interners.intern_const(kind)
2222 }
2223
2224 #[allow(rustc::usage_of_ty_tykind)]
2226 #[inline]
2227 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2228 self.interners.intern_ty(st)
2229 }
2230
2231 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2232 match param.kind {
2233 GenericParamDefKind::Lifetime => {
2234 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2235 }
2236 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2237 GenericParamDefKind::Const { .. } => {
2238 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2239 .into()
2240 }
2241 }
2242 }
2243
2244 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2245 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2246 }
2247
2248 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2249 self.mk_place_elem(place, PlaceElem::Deref)
2250 }
2251
2252 pub fn mk_place_downcast(
2253 self,
2254 place: Place<'tcx>,
2255 adt_def: AdtDef<'tcx>,
2256 variant_index: VariantIdx,
2257 ) -> Place<'tcx> {
2258 self.mk_place_elem(
2259 place,
2260 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2261 )
2262 }
2263
2264 pub fn mk_place_downcast_unnamed(
2265 self,
2266 place: Place<'tcx>,
2267 variant_index: VariantIdx,
2268 ) -> Place<'tcx> {
2269 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2270 }
2271
2272 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2273 self.mk_place_elem(place, PlaceElem::Index(index))
2274 }
2275
2276 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2280 Place {
2281 local: place.local,
2282 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2283 }
2284 }
2285
2286 pub fn mk_poly_existential_predicates(
2287 self,
2288 eps: &[PolyExistentialPredicate<'tcx>],
2289 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2290 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2291 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!(
2292 eps.array_windows()
2293 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2294 != Ordering::Greater)
2295 );
2296 self.intern_poly_existential_predicates(eps)
2297 }
2298
2299 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2300 self.interners.intern_clauses(clauses)
2304 }
2305
2306 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2307 self.intern_local_def_ids(def_ids)
2311 }
2312
2313 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2314 where
2315 I: Iterator<Item = T>,
2316 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2317 {
2318 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2319 }
2320
2321 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2322 where
2323 I: Iterator<Item = T>,
2324 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2325 {
2326 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2327 }
2328
2329 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2330 where
2331 I: Iterator<Item = T>,
2332 T: CollectAndApply<
2333 &'tcx ty::CapturedPlace<'tcx>,
2334 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2335 >,
2336 {
2337 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2338 }
2339
2340 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2341 where
2342 I: Iterator<Item = T>,
2343 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2344 {
2345 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2346 }
2347
2348 pub fn mk_fn_sig<I, T>(
2353 self,
2354 inputs: I,
2355 output: I::Item,
2356 fn_sig_kind: FnSigKind<'tcx>,
2357 ) -> T::Output
2358 where
2359 I: IntoIterator<Item = T>,
2360 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2361 {
2362 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2363 inputs_and_output: self.mk_type_list(xs),
2364 fn_sig_kind,
2365 })
2366 }
2367
2368 pub fn mk_fn_sig_rust_abi<I, T>(
2370 self,
2371 inputs: I,
2372 output: I::Item,
2373 safety: hir::Safety,
2374 ) -> T::Output
2375 where
2376 I: IntoIterator<Item = T>,
2377 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2378 {
2379 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2380 }
2381
2382 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2384 where
2385 I: IntoIterator<Item = T>,
2386 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2387 {
2388 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2389 }
2390
2391 pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2393 where
2394 I: IntoIterator<Item = T>,
2395 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2396 {
2397 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2398 }
2399
2400 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2401 where
2402 I: Iterator<Item = T>,
2403 T: CollectAndApply<
2404 PolyExistentialPredicate<'tcx>,
2405 &'tcx List<PolyExistentialPredicate<'tcx>>,
2406 >,
2407 {
2408 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2409 }
2410
2411 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2412 where
2413 I: Iterator<Item = T>,
2414 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2415 {
2416 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2417 }
2418
2419 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2420 where
2421 I: Iterator<Item = T>,
2422 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2423 {
2424 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2425 }
2426
2427 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2428 where
2429 I: Iterator<Item = T>,
2430 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2431 {
2432 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2433 }
2434
2435 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2436 where
2437 I: Iterator<Item = T>,
2438 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2439 {
2440 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2441 }
2442
2443 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2444 where
2445 I: Iterator<Item = T>,
2446 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2447 {
2448 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2449 }
2450
2451 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2452 where
2453 I: Iterator<Item = T>,
2454 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2455 {
2456 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2457 }
2458
2459 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2460 where
2461 I: Iterator<Item = T>,
2462 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2463 {
2464 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2465 }
2466
2467 pub fn mk_args_trait(
2468 self,
2469 self_ty: Ty<'tcx>,
2470 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2471 ) -> GenericArgsRef<'tcx> {
2472 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2473 }
2474
2475 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2476 where
2477 I: Iterator<Item = T>,
2478 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2479 {
2480 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2481 }
2482
2483 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2484 where
2485 I: Iterator<Item = T>,
2486 T: CollectAndApply<
2487 ty::ArgOutlivesPredicate<'tcx>,
2488 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2489 >,
2490 {
2491 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2492 }
2493
2494 #[track_caller]
2497 pub fn emit_node_span_lint(
2498 self,
2499 lint: &'static Lint,
2500 hir_id: HirId,
2501 span: impl Into<MultiSpan>,
2502 decorator: impl for<'a> Diagnostic<'a, ()>,
2503 ) {
2504 let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2505 emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2506 }
2507
2508 pub fn crate_level_attribute_injection_span(self) -> Span {
2510 let node = self.hir_node(hir::CRATE_HIR_ID);
2511 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2512 m.spans.inject_use_span.shrink_to_lo()
2513 }
2514
2515 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2516 self,
2517 diag: &mut Diag<'_, E>,
2518 features: impl IntoIterator<Item = (String, Symbol)>,
2519 ) {
2520 if !self.sess.is_nightly_build() {
2521 return;
2522 }
2523
2524 let span = self.crate_level_attribute_injection_span();
2525 for (desc, feature) in features {
2526 let msg =
2528 ::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}");
2529 diag.span_suggestion_verbose(
2530 span,
2531 msg,
2532 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2533 Applicability::MaybeIncorrect,
2534 );
2535 }
2536 }
2537
2538 #[track_caller]
2541 pub fn emit_node_lint(
2542 self,
2543 lint: &'static Lint,
2544 id: HirId,
2545 decorator: impl for<'a> Diagnostic<'a, ()>,
2546 ) {
2547 let level_spec = self.lint_level_spec_at_node(lint, id);
2548 emit_lint_base(self.sess, lint, level_spec, None, decorator);
2549 }
2550
2551 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2552 let map = self.in_scope_traits_map(id.owner)?;
2553 let candidates = map.get(&id.local_id)?;
2554 Some(candidates)
2555 }
2556
2557 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2558 {
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:2558",
"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(2558u32),
::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");
2559 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2560 }
2561
2562 pub fn is_late_bound(self, id: HirId) -> bool {
2563 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2564 }
2565
2566 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2567 self.mk_bound_variable_kinds(
2568 &self
2569 .late_bound_vars_map(id.owner)
2570 .get(&id.local_id)
2571 .cloned()
2572 .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))),
2573 )
2574 }
2575
2576 pub fn map_opaque_lifetime_to_parent_lifetime(
2584 self,
2585 mut opaque_lifetime_param_def_id: LocalDefId,
2586 ) -> ty::Region<'tcx> {
2587 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!(
2588 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2589 "{opaque_lifetime_param_def_id:?} is a {}",
2590 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2591 );
2592
2593 loop {
2594 let parent = self.local_parent(opaque_lifetime_param_def_id);
2595 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2596
2597 let Some((lifetime, _)) = lifetime_mapping
2598 .iter()
2599 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2600 else {
2601 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2602 };
2603
2604 match *lifetime {
2605 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2606 let new_parent = self.local_parent(ebv);
2607
2608 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2611 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);
2612 opaque_lifetime_param_def_id = ebv;
2613 continue;
2614 }
2615
2616 let generics = self.generics_of(new_parent);
2617 return ty::Region::new_early_param(
2618 self,
2619 ty::EarlyParamRegion {
2620 index: generics
2621 .param_def_id_to_index(self, ebv.to_def_id())
2622 .expect("early-bound var should be present in fn generics"),
2623 name: self.item_name(ebv.to_def_id()),
2624 },
2625 );
2626 }
2627 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2628 let new_parent = self.local_parent(lbv);
2629 return ty::Region::new_late_param(
2630 self,
2631 new_parent.to_def_id(),
2632 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2633 );
2634 }
2635 resolve_bound_vars::ResolvedArg::Error(guar) => {
2636 return ty::Region::new_error(self, guar);
2637 }
2638 _ => {
2639 return ty::Region::new_error_with_message(
2640 self,
2641 self.def_span(opaque_lifetime_param_def_id),
2642 "cannot resolve lifetime",
2643 );
2644 }
2645 }
2646 }
2647 }
2648
2649 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2654 self.is_const_fn(def_id)
2655 && match self.lookup_const_stability(def_id) {
2656 None => true, Some(stability) if stability.is_const_stable() => true,
2658 _ => false,
2659 }
2660 }
2661
2662 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2664 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2665 && #[allow(non_exhaustive_omitted_patterns)] match self.impl_trait_header(def_id).constness
{
hir::Constness::Const { always: false } => true,
_ => false,
}matches!(
2666 self.impl_trait_header(def_id).constness,
2667 hir::Constness::Const { always: false }
2668 )
2669 }
2670
2671 pub fn is_sdylib_interface_build(self) -> bool {
2672 self.sess.opts.unstable_opts.build_sdylib_interface
2673 }
2674
2675 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2676 let def_id = def_id.into_query_key();
2677 match self.def_kind(def_id) {
2678 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2679 _ => None,
2680 }
2681 }
2682
2683 pub fn next_trait_solver_globally(self) -> bool {
2684 self.sess.opts.unstable_opts.next_solver.globally
2685 }
2686
2687 pub fn next_trait_solver_in_coherence(self) -> bool {
2688 self.sess.opts.unstable_opts.next_solver.coherence
2689 }
2690
2691 pub fn disable_trait_solver_fast_paths(self) -> bool {
2692 self.sess.opts.unstable_opts.disable_fast_paths
2693 }
2694
2695 pub fn disable_param_env_normalization_hack(self) -> bool {
2696 self.sess.opts.unstable_opts.disable_param_env_normalization_hack
2697 }
2698
2699 pub fn renormalize_rigid_aliases(self) -> bool {
2700 self.sess.opts.unstable_opts.renormalize_rigid_aliases
2701 }
2702
2703 #[allow(rustc::bad_opt_access)]
2704 pub fn use_typing_mode_post_typeck_until_borrowck(self) -> bool {
2705 self.next_trait_solver_globally()
2706 || self.sess.opts.unstable_opts.typing_mode_post_typeck_until_borrowck
2707 }
2708
2709 pub fn assumptions_on_binders(self) -> bool {
2710 self.sess.opts.unstable_opts.assumptions_on_binders
2711 }
2712
2713 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2714 self.opt_rpitit_info(def_id).is_some()
2715 }
2716
2717 pub fn get_impl_future_output_ty(self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
2718 let (def_id, args) = match *ty.kind() {
2719 ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
2720 ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, args, .. })
2721 if self.is_impl_trait_in_trait(def_id) =>
2722 {
2723 (def_id, args)
2724 }
2725 _ => return None,
2726 };
2727
2728 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2729 let item_def_id = self.associated_item_def_ids(future_trait)[0];
2730
2731 self.explicit_item_self_bounds(def_id)
2732 .iter_instantiated_copied(self, args)
2733 .map(ty::Unnormalized::skip_norm_wip)
2734 .find_map(|(predicate, _)| {
2735 predicate
2736 .kind()
2737 .map_bound(|kind| match kind {
2738 ty::ClauseKind::Projection(projection_predicate)
2739 if projection_predicate.def_id() == item_def_id =>
2740 {
2741 projection_predicate.term.as_type()
2742 }
2743 _ => None,
2744 })
2745 .no_bound_vars()
2746 .flatten()
2747 })
2748 }
2749
2750 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2760 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2761 }
2762
2763 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2765 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2766 }
2767
2768 pub fn resolver_for_lowering(
2769 self,
2770 ) -> (&'tcx Steal<ty::ResolverAstLowering<'tcx>>, &'tcx Steal<ast::Crate>) {
2771 let (resolver, krate, _) = self.resolver_for_lowering_raw(());
2772 (resolver, krate)
2773 }
2774
2775 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2776 make_metadata(self)
2777 }
2778
2779 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2780 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2781 self.coroutine_kind(def_id)
2782 && let ty::Coroutine(_, args) =
2783 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2784 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2785 {
2786 true
2787 } else {
2788 false
2789 }
2790 }
2791
2792 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2794 {
{
'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)
2795 }
2796
2797 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2798 let def_id = def_id.into_query_key();
2799 self.trivial_const(def_id).is_some()
2800 }
2801
2802 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2805 if self.is_lang_item(def_id, LangItem::Start) {
2806 return true;
2807 }
2808 if let Some((entry_def_id, _)) = self.entry_fn(())
2809 && entry_def_id == def_id
2810 {
2811 return true;
2812 }
2813 false
2814 }
2815}
2816
2817pub fn provide(providers: &mut Providers) {
2818 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);
2819 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);
2820 providers.has_panic_handler = |tcx, LocalCrate| {
2821 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2823 };
2824 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2825}