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 TyCtxtFeed { tcx: self, key }.type_of(value)
606 }
607
608 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
616 if truecfg!(debug_assertions) {
617 match self.def_kind(self.local_parent(key)) {
618 DefKind::Impl { of_trait: true } => {}
619 other => crate::util::bug::bug_fmt(format_args!("{0:?} is not an assoc item of a trait impl: {1:?}",
key, other))bug!("{key:?} is not an assoc item of a trait impl: {other:?}"),
620 }
621 }
622 TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id())
623 }
624}
625
626impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> {
627 #[inline(always)]
628 pub fn key(&self) -> K {
629 self.key
630 }
631}
632
633impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
634 #[inline(always)]
635 pub fn def_id(&self) -> LocalDefId {
636 self.key
637 }
638
639 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
641 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
642 }
643
644 pub fn feed_hir(&self) {
646 self.hir_owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo::new(
647 self.tcx.arena.alloc(hir::OwnerNodes::synthetic()),
648 self.tcx.arena.alloc(Default::default()),
649 self.tcx.arena.alloc(Default::default()),
650 self.tcx.arena.alloc(Steal::new(Default::default())),
651 )));
652
653 self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
654 }
655}
656
657#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for TyCtxt<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for TyCtxt<'tcx> {
#[inline]
fn clone(&self) -> TyCtxt<'tcx> {
let _: ::core::clone::AssertParamIsClone<&'tcx GlobalCtxt<'tcx>>;
*self
}
}Clone)]
675#[rustc_diagnostic_item = "TyCtxt"]
676#[rustc_pass_by_value]
677pub struct TyCtxt<'tcx> {
678 gcx: &'tcx GlobalCtxt<'tcx>,
679}
680
681unsafe impl DynSend for TyCtxt<'_> {}
685unsafe impl DynSync for TyCtxt<'_> {}
686fn _assert_tcx_fields() {
687 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
688 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
689}
690
691impl<'tcx> Deref for TyCtxt<'tcx> {
692 type Target = &'tcx GlobalCtxt<'tcx>;
693 #[inline(always)]
694 fn deref(&self) -> &Self::Target {
695 &self.gcx
696 }
697}
698
699pub struct GlobalCtxt<'tcx> {
701 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
702 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
703
704 interners: CtxtInterners<'tcx>,
705
706 pub sess: &'tcx Session,
707 crate_types: Vec<CrateType>,
708 stable_crate_id: StableCrateId,
714
715 pub dep_graph: DepGraph,
716
717 pub prof: SelfProfilerRef,
718
719 pub types: CommonTypes<'tcx>,
721
722 pub lifetimes: CommonLifetimes<'tcx>,
724
725 pub consts: CommonConsts<'tcx>,
727
728 pub(crate) hooks: crate::hooks::Providers,
731
732 untracked: Untracked,
733
734 pub query_system: QuerySystem<'tcx>,
735 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
736
737 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
739
740 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
743
744 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
748
749 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
751 pub new_solver_canonical_param_env_cache:
752 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
753
754 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
755
756 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
758 pub clauses_cache:
760 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
761
762 pub data_layout: TargetDataLayout,
764
765 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
767
768 current_gcx: CurrentGcx,
769
770 pub jobserver_proxy: Arc<Proxy>,
772}
773
774impl<'tcx> GlobalCtxt<'tcx> {
775 pub fn enter<F, R>(&'tcx self, f: F) -> R
778 where
779 F: FnOnce(TyCtxt<'tcx>) -> R,
780 {
781 let icx = tls::ImplicitCtxt::new(self);
782
783 let _on_drop = defer(move || {
785 *self.current_gcx.value.write() = None;
786 });
787
788 {
790 let mut guard = self.current_gcx.value.write();
791 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
792 *guard = Some(self as *const _ as *const ());
793 }
794
795 tls::enter_context(&icx, || f(icx.tcx))
796 }
797}
798
799#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
806pub struct CurrentGcx {
807 value: Arc<RwLock<Option<*const ()>>>,
810}
811
812unsafe impl DynSend for CurrentGcx {}
813unsafe impl DynSync for CurrentGcx {}
814
815impl CurrentGcx {
816 pub fn new() -> Self {
817 Self { value: Arc::new(RwLock::new(None)) }
818 }
819
820 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
821 let read_guard = self.value.read();
822 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
823 f(unsafe { &*gcx })
827 }
828}
829
830impl<'tcx> TyCtxt<'tcx> {
831 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
832 let root = self.typeck_root_def_id_local(def_id);
835 self.hir_node_by_def_id(root).body_id().is_some()
836 }
837
838 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
843 let def_kind = self.def_kind(def_id);
844 if def_kind.has_codegen_attrs() {
845 self.codegen_fn_attrs(def_id)
846 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
DefKind::InlineConst | DefKind::GlobalAsm => true,
_ => false,
}matches!(
847 def_kind,
848 DefKind::AnonConst
849 | DefKind::AssocConst { .. }
850 | DefKind::Const { .. }
851 | DefKind::InlineConst
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 self.mk_fn_sig(
2089 params,
2090 s.output(),
2091 s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2092 )
2093 })
2094 }
2095
2096 #[inline]
2097 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2098 self.interners.intern_predicate(binder)
2099 }
2100
2101 #[inline]
2102 pub fn reuse_or_mk_predicate(
2103 self,
2104 pred: Predicate<'tcx>,
2105 binder: Binder<'tcx, PredicateKind<'tcx>>,
2106 ) -> Predicate<'tcx> {
2107 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2108 }
2109
2110 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2111 self.check_args_compatible_inner(def_id, args, false)
2112 }
2113
2114 fn check_args_compatible_inner(
2115 self,
2116 def_id: DefId,
2117 args: &'tcx [ty::GenericArg<'tcx>],
2118 nested: bool,
2119 ) -> bool {
2120 let generics = self.generics_of(def_id);
2121
2122 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)
2126 && #[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 });
2127 let is_inherent_assoc_type_const =
2128 #[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 })
2129 && #[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 });
2130 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2131 if generics.own_params.len() + 1 != args.len() {
2132 return false;
2133 }
2134
2135 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2136 return false;
2137 }
2138
2139 &args[1..]
2140 } else {
2141 if generics.count() != args.len() {
2142 return false;
2143 }
2144
2145 let (parent_args, own_args) = args.split_at(generics.parent_count);
2146
2147 if let Some(parent) = generics.parent
2148 && !self.check_args_compatible_inner(parent, parent_args, true)
2149 {
2150 return false;
2151 }
2152
2153 own_args
2154 };
2155
2156 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2157 match (¶m.kind, arg.kind()) {
2158 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2159 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2160 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2161 _ => return false,
2162 }
2163 }
2164
2165 true
2166 }
2167
2168 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2171 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2172 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)
2173 && #[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 });
2174 let is_inherent_assoc_type_const =
2175 #[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 })
2176 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(
2177 self.def_kind(self.parent(def_id)),
2178 DefKind::Impl { of_trait: false }
2179 );
2180 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2181 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!(
2182 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2183 self.def_path_str(def_id),
2184 args,
2185 self.mk_args_from_iter(
2187 [self.types.self_param.into()].into_iter().chain(
2188 self.generics_of(def_id)
2189 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2190 .iter()
2191 .copied()
2192 )
2193 )
2194 );
2195 } else {
2196 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!(
2197 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2198 self.def_path_str(def_id),
2199 args,
2200 ty::GenericArgs::identity_for_item(self, def_id)
2201 );
2202 }
2203 }
2204 }
2205
2206 #[inline(always)]
2207 pub(crate) fn check_and_mk_args(
2208 self,
2209 def_id: DefId,
2210 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2211 ) -> GenericArgsRef<'tcx> {
2212 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2213 self.debug_assert_args_compatible(def_id, args);
2214 args
2215 }
2216
2217 #[inline]
2218 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2219 self.interners.intern_const(kind)
2220 }
2221
2222 #[allow(rustc::usage_of_ty_tykind)]
2224 #[inline]
2225 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2226 self.interners.intern_ty(st)
2227 }
2228
2229 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2230 match param.kind {
2231 GenericParamDefKind::Lifetime => {
2232 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2233 }
2234 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2235 GenericParamDefKind::Const { .. } => {
2236 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2237 .into()
2238 }
2239 }
2240 }
2241
2242 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2243 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2244 }
2245
2246 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2247 self.mk_place_elem(place, PlaceElem::Deref)
2248 }
2249
2250 pub fn mk_place_downcast(
2251 self,
2252 place: Place<'tcx>,
2253 adt_def: AdtDef<'tcx>,
2254 variant_index: VariantIdx,
2255 ) -> Place<'tcx> {
2256 self.mk_place_elem(
2257 place,
2258 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2259 )
2260 }
2261
2262 pub fn mk_place_downcast_unnamed(
2263 self,
2264 place: Place<'tcx>,
2265 variant_index: VariantIdx,
2266 ) -> Place<'tcx> {
2267 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2268 }
2269
2270 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2271 self.mk_place_elem(place, PlaceElem::Index(index))
2272 }
2273
2274 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2278 Place {
2279 local: place.local,
2280 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2281 }
2282 }
2283
2284 pub fn mk_poly_existential_predicates(
2285 self,
2286 eps: &[PolyExistentialPredicate<'tcx>],
2287 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2288 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2289 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!(
2290 eps.array_windows()
2291 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2292 != Ordering::Greater)
2293 );
2294 self.intern_poly_existential_predicates(eps)
2295 }
2296
2297 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2298 self.interners.intern_clauses(clauses)
2302 }
2303
2304 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2305 self.intern_local_def_ids(def_ids)
2309 }
2310
2311 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2312 where
2313 I: Iterator<Item = T>,
2314 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2315 {
2316 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2317 }
2318
2319 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2320 where
2321 I: Iterator<Item = T>,
2322 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2323 {
2324 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2325 }
2326
2327 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2328 where
2329 I: Iterator<Item = T>,
2330 T: CollectAndApply<
2331 &'tcx ty::CapturedPlace<'tcx>,
2332 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2333 >,
2334 {
2335 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2336 }
2337
2338 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2339 where
2340 I: Iterator<Item = T>,
2341 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2342 {
2343 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2344 }
2345
2346 pub fn mk_fn_sig<I, T>(
2351 self,
2352 inputs: I,
2353 output: I::Item,
2354 fn_sig_kind: FnSigKind<'tcx>,
2355 ) -> T::Output
2356 where
2357 I: IntoIterator<Item = T>,
2358 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2359 {
2360 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2361 inputs_and_output: self.mk_type_list(xs),
2362 fn_sig_kind,
2363 })
2364 }
2365
2366 pub fn mk_fn_sig_rust_abi<I, T>(
2368 self,
2369 inputs: I,
2370 output: I::Item,
2371 safety: hir::Safety,
2372 ) -> T::Output
2373 where
2374 I: IntoIterator<Item = T>,
2375 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2376 {
2377 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2378 }
2379
2380 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2382 where
2383 I: IntoIterator<Item = T>,
2384 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2385 {
2386 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2387 }
2388
2389 pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2391 where
2392 I: IntoIterator<Item = T>,
2393 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2394 {
2395 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2396 }
2397
2398 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2399 where
2400 I: Iterator<Item = T>,
2401 T: CollectAndApply<
2402 PolyExistentialPredicate<'tcx>,
2403 &'tcx List<PolyExistentialPredicate<'tcx>>,
2404 >,
2405 {
2406 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2407 }
2408
2409 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2410 where
2411 I: Iterator<Item = T>,
2412 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2413 {
2414 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2415 }
2416
2417 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2418 where
2419 I: Iterator<Item = T>,
2420 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2421 {
2422 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2423 }
2424
2425 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2426 where
2427 I: Iterator<Item = T>,
2428 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2429 {
2430 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2431 }
2432
2433 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2434 where
2435 I: Iterator<Item = T>,
2436 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2437 {
2438 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2439 }
2440
2441 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2442 where
2443 I: Iterator<Item = T>,
2444 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2445 {
2446 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2447 }
2448
2449 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2450 where
2451 I: Iterator<Item = T>,
2452 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2453 {
2454 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2455 }
2456
2457 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2458 where
2459 I: Iterator<Item = T>,
2460 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2461 {
2462 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2463 }
2464
2465 pub fn mk_args_trait(
2466 self,
2467 self_ty: Ty<'tcx>,
2468 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2469 ) -> GenericArgsRef<'tcx> {
2470 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2471 }
2472
2473 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2474 where
2475 I: Iterator<Item = T>,
2476 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2477 {
2478 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2479 }
2480
2481 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2482 where
2483 I: Iterator<Item = T>,
2484 T: CollectAndApply<
2485 ty::ArgOutlivesPredicate<'tcx>,
2486 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2487 >,
2488 {
2489 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2490 }
2491
2492 #[track_caller]
2495 pub fn emit_node_span_lint(
2496 self,
2497 lint: &'static Lint,
2498 hir_id: HirId,
2499 span: impl Into<MultiSpan>,
2500 decorator: impl for<'a> Diagnostic<'a, ()>,
2501 ) {
2502 let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2503 emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2504 }
2505
2506 pub fn crate_level_attribute_injection_span(self) -> Span {
2508 let node = self.hir_node(hir::CRATE_HIR_ID);
2509 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2510 m.spans.inject_use_span.shrink_to_lo()
2511 }
2512
2513 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2514 self,
2515 diag: &mut Diag<'_, E>,
2516 features: impl IntoIterator<Item = (String, Symbol)>,
2517 ) {
2518 if !self.sess.is_nightly_build() {
2519 return;
2520 }
2521
2522 let span = self.crate_level_attribute_injection_span();
2523 for (desc, feature) in features {
2524 let msg =
2526 ::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}");
2527 diag.span_suggestion_verbose(
2528 span,
2529 msg,
2530 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2531 Applicability::MaybeIncorrect,
2532 );
2533 }
2534 }
2535
2536 #[track_caller]
2539 pub fn emit_node_lint(
2540 self,
2541 lint: &'static Lint,
2542 id: HirId,
2543 decorator: impl for<'a> Diagnostic<'a, ()>,
2544 ) {
2545 let level_spec = self.lint_level_spec_at_node(lint, id);
2546 emit_lint_base(self.sess, lint, level_spec, None, decorator);
2547 }
2548
2549 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2550 let map = self.in_scope_traits_map(id.owner)?;
2551 let candidates = map.get(&id.local_id)?;
2552 Some(candidates)
2553 }
2554
2555 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2556 {
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:2556",
"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(2556u32),
::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");
2557 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2558 }
2559
2560 pub fn is_late_bound(self, id: HirId) -> bool {
2561 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2562 }
2563
2564 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2565 self.mk_bound_variable_kinds(
2566 &self
2567 .late_bound_vars_map(id.owner)
2568 .get(&id.local_id)
2569 .cloned()
2570 .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))),
2571 )
2572 }
2573
2574 pub fn map_opaque_lifetime_to_parent_lifetime(
2582 self,
2583 mut opaque_lifetime_param_def_id: LocalDefId,
2584 ) -> ty::Region<'tcx> {
2585 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!(
2586 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2587 "{opaque_lifetime_param_def_id:?} is a {}",
2588 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2589 );
2590
2591 loop {
2592 let parent = self.local_parent(opaque_lifetime_param_def_id);
2593 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2594
2595 let Some((lifetime, _)) = lifetime_mapping
2596 .iter()
2597 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2598 else {
2599 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2600 };
2601
2602 match *lifetime {
2603 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2604 let new_parent = self.local_parent(ebv);
2605
2606 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2609 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);
2610 opaque_lifetime_param_def_id = ebv;
2611 continue;
2612 }
2613
2614 let generics = self.generics_of(new_parent);
2615 return ty::Region::new_early_param(
2616 self,
2617 ty::EarlyParamRegion {
2618 index: generics
2619 .param_def_id_to_index(self, ebv.to_def_id())
2620 .expect("early-bound var should be present in fn generics"),
2621 name: self.item_name(ebv.to_def_id()),
2622 },
2623 );
2624 }
2625 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2626 let new_parent = self.local_parent(lbv);
2627 return ty::Region::new_late_param(
2628 self,
2629 new_parent.to_def_id(),
2630 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2631 );
2632 }
2633 resolve_bound_vars::ResolvedArg::Error(guar) => {
2634 return ty::Region::new_error(self, guar);
2635 }
2636 _ => {
2637 return ty::Region::new_error_with_message(
2638 self,
2639 self.def_span(opaque_lifetime_param_def_id),
2640 "cannot resolve lifetime",
2641 );
2642 }
2643 }
2644 }
2645 }
2646
2647 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2652 self.is_const_fn(def_id)
2653 && match self.lookup_const_stability(def_id) {
2654 None => true, Some(stability) if stability.is_const_stable() => true,
2656 _ => false,
2657 }
2658 }
2659
2660 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2662 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2663 && #[allow(non_exhaustive_omitted_patterns)] match self.impl_trait_header(def_id).constness
{
hir::Constness::Const { always: false } => true,
_ => false,
}matches!(
2664 self.impl_trait_header(def_id).constness,
2665 hir::Constness::Const { always: false }
2666 )
2667 }
2668
2669 pub fn is_sdylib_interface_build(self) -> bool {
2670 self.sess.opts.unstable_opts.build_sdylib_interface
2671 }
2672
2673 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2674 let def_id = def_id.into_query_key();
2675 match self.def_kind(def_id) {
2676 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2677 _ => None,
2678 }
2679 }
2680
2681 pub fn next_trait_solver_globally(self) -> bool {
2682 self.sess.opts.unstable_opts.next_solver.globally
2683 }
2684
2685 pub fn next_trait_solver_in_coherence(self) -> bool {
2686 self.sess.opts.unstable_opts.next_solver.coherence
2687 }
2688
2689 pub fn disable_trait_solver_fast_paths(self) -> bool {
2690 self.sess.opts.unstable_opts.disable_fast_paths
2691 }
2692
2693 #[allow(rustc::bad_opt_access)]
2694 pub fn use_typing_mode_post_typeck_until_borrowck(self) -> bool {
2695 self.next_trait_solver_globally()
2696 || self.sess.opts.unstable_opts.typing_mode_post_typeck_until_borrowck
2697 }
2698
2699 pub fn assumptions_on_binders(self) -> bool {
2700 self.sess.opts.unstable_opts.assumptions_on_binders
2701 }
2702
2703 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2704 self.opt_rpitit_info(def_id).is_some()
2705 }
2706
2707 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2717 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2718 }
2719
2720 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2722 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2723 }
2724
2725 pub fn resolver_for_lowering(
2726 self,
2727 ) -> (&'tcx Steal<ty::ResolverAstLowering<'tcx>>, &'tcx Steal<ast::Crate>) {
2728 let (resolver, krate, _) = self.resolver_for_lowering_raw(());
2729 (resolver, krate)
2730 }
2731
2732 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2733 make_metadata(self)
2734 }
2735
2736 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2737 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2738 self.coroutine_kind(def_id)
2739 && let ty::Coroutine(_, args) =
2740 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2741 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2742 {
2743 true
2744 } else {
2745 false
2746 }
2747 }
2748
2749 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2751 {
{
'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)
2752 }
2753
2754 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2755 let def_id = def_id.into_query_key();
2756 self.trivial_const(def_id).is_some()
2757 }
2758
2759 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2762 if self.is_lang_item(def_id, LangItem::Start) {
2763 return true;
2764 }
2765 if let Some((entry_def_id, _)) = self.entry_fn(())
2766 && entry_def_id == def_id
2767 {
2768 return true;
2769 }
2770 false
2771 }
2772}
2773
2774pub fn provide(providers: &mut Providers) {
2775 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);
2776 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);
2777 providers.has_panic_handler = |tcx, LocalCrate| {
2778 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2780 };
2781 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2782}