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::{debug_assert_matches, fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_attr_ir::find_attr;
21use rustc_attr_ir::lang_items::LangItem;
22use rustc_crate_store::{CrateStoreDyn, Untracked};
23use rustc_data_structures::defer;
24use rustc_data_structures::fx::FxHashMap;
25use rustc_data_structures::intern::Interned;
26use rustc_data_structures::profiling::SelfProfilerRef;
27use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
28use rustc_data_structures::stable_hash::StableHash;
29use rustc_data_structures::steal::Steal;
30use rustc_data_structures::sync::{
31 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
32};
33use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
34use rustc_hir::def::DefKind;
35use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
36use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState};
37use rustc_hir::intravisit::Visitor;
38use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate};
39use rustc_index::IndexVec;
40use rustc_lint_defs::Lint;
41use rustc_lint_defs::builtin::UNUSED_FEATURES;
42use rustc_macros::Diagnostic;
43use rustc_session::config::NextSolverConfig;
44use rustc_session::{IncrCompSession, Session};
45use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
46use rustc_span::{DUMMY_SP, Ident, Span, Symbol, bug, kw, sym};
47use rustc_structures::{CrateType, Limit};
48use rustc_type_ir::TyKind::*;
49pub use rustc_type_ir::lift::Lift;
50use rustc_type_ir::{
51 CollectAndApply, IncludeSizedImplicitBounds, PlaceholderType, WithCachedTypeInfo, elaborate,
52 search_graph,
53};
54use tracing::{debug, instrument};
55
56use crate::arena::Arena;
57use crate::dep_graph::dep_node::make_metadata;
58use crate::dep_graph::{DepGraph, DepNodeIndex};
59use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo};
60use crate::ich::StableHashState;
61use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
62use crate::lint::emit_lint_base;
63use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
64use crate::middle::resolve::{ModChild, ResolverAstLowering};
65use crate::middle::resolve_bound_vars;
66use crate::mir::interpret::{self, Allocation, ConstAllocation};
67use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
68use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
69use crate::thir::Thir;
70use crate::traits;
71use crate::traits::solve::{
72 CanonicalInput, CanonicalInputData, ExternalConstraints, ExternalConstraintsData,
73 PredefinedOpaques,
74};
75use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
76use crate::ty::{
77 self, AdtDef, AdtDefData, AdtKind, Binder, CanonicalizerState, Clause, ClausePolarity, Clauses,
78 Const, ConstKind, FnSigKind, GenericArg, GenericArgsUnsized, GenericParamDefKind, List,
79 ListWithCachedTypeInfo, ParamConst, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig,
80 Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind,
81 TyVid, ValTree, ValTreeKind, Visibility,
82};
83
84impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
85 fn is_local(self) -> bool {
86 self.is_local()
87 }
88
89 fn as_local(self) -> Option<LocalDefId> {
90 self.as_local()
91 }
92}
93
94impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
95 fn safe() -> Self {
96 hir::Safety::Safe
97 }
98
99 fn unsafe_mode() -> Self {
100 hir::Safety::Unsafe
101 }
102
103 fn is_safe(self) -> bool {
104 self.is_safe()
105 }
106
107 fn prefix_str(self) -> &'static str {
108 self.prefix_str()
109 }
110}
111
112impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
113 fn generic_const_exprs(self) -> bool {
114 self.generic_const_exprs()
115 }
116
117 fn gca_const_items(self) -> bool {
118 self.gca_const_items()
119 }
120
121 fn coroutine_clone(self) -> bool {
122 self.coroutine_clone()
123 }
124
125 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
126 !self.staged_api() && self.enabled(symbol)
130 }
131}
132
133impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
134 fn dummy() -> Self {
135 DUMMY_SP
136 }
137}
138
139type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
140
141pub struct CtxtInterners<'tcx> {
142 arena: &'tcx WorkerLocal<Arena<'tcx>>,
144
145 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
148 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
149 args: InternedSet<'tcx, GenericArgsUnsized<'tcx>>,
150 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
151 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
152 region: InternedSet<'tcx, RegionKind<'tcx>>,
153 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
154 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
155 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
156 projs: InternedSet<'tcx, List<ProjectionKind>>,
157 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
158 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
159 pat: InternedSet<'tcx, PatternKind<'tcx>>,
160 const_allocation: InternedSet<'tcx, Allocation>,
161 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
162 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
163 adt_def: InternedSet<'tcx, AdtDefData>,
164 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
165 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
166 fields: InternedSet<'tcx, List<FieldIdx>>,
167 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
168 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
169 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
170 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
171 outlives: InternedSet<'tcx, List<ty::ArgOutlivesClause<'tcx>>>,
172 canonical_inputs: InternedSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>>,
173}
174
175impl<'tcx> CtxtInterners<'tcx> {
176 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
177 const N: usize = 2048;
180 CtxtInterners {
181 arena,
182 type_: InternedSet::with_capacity(N * 16),
187 const_lists: InternedSet::with_capacity(N * 4),
188 args: InternedSet::with_capacity(N * 4),
189 type_lists: InternedSet::with_capacity(N * 4),
190 region: InternedSet::with_capacity(N * 4),
191 poly_existential_predicates: InternedSet::with_capacity(N / 4),
192 canonical_var_kinds: InternedSet::with_capacity(N / 2),
193 predicate: InternedSet::with_capacity(N),
194 clauses: InternedSet::with_capacity(N),
195 projs: InternedSet::with_capacity(N * 4),
196 place_elems: InternedSet::with_capacity(N * 2),
197 const_: InternedSet::with_capacity(N * 2),
198 pat: InternedSet::with_capacity(N),
199 const_allocation: InternedSet::with_capacity(N),
200 bound_variable_kinds: InternedSet::with_capacity(N * 2),
201 layout: InternedSet::with_capacity(N),
202 adt_def: InternedSet::with_capacity(N),
203 external_constraints: InternedSet::with_capacity(N),
204 predefined_opaques_in_body: InternedSet::with_capacity(N),
205 fields: InternedSet::with_capacity(N * 4),
206 local_def_ids: InternedSet::with_capacity(N),
207 captures: InternedSet::with_capacity(N),
208 valtree: InternedSet::with_capacity(N),
209 patterns: InternedSet::with_capacity(N),
210 outlives: InternedSet::with_capacity(N),
211 canonical_inputs: InternedSet::with_capacity(N),
212 }
213 }
214
215 #[allow(rustc::usage_of_ty_tykind)]
217 #[inline(never)]
218 fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
219 Ty(Interned::new_unchecked(
220 self.type_
221 .intern(kind, |kind| {
222 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
223 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
224 internee: kind,
225 flags: flags.flags,
226 outer_exclusive_binder: flags.outer_exclusive_binder,
227 }))
228 })
229 .0,
230 ))
231 }
232
233 #[allow(rustc::usage_of_ty_tykind)]
235 #[inline(never)]
236 fn intern_const(&self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
237 Const(Interned::new_unchecked(
238 self.const_
239 .intern(kind, |kind: ty::ConstKind<'_>| {
240 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
241 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
242 internee: kind,
243 flags: flags.flags,
244 outer_exclusive_binder: flags.outer_exclusive_binder,
245 }))
246 })
247 .0,
248 ))
249 }
250
251 #[inline(never)]
253 fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
254 Predicate(Interned::new_unchecked(
255 self.predicate
256 .intern(kind, |kind| {
257 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
258 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
259 internee: kind,
260 flags: flags.flags,
261 outer_exclusive_binder: flags.outer_exclusive_binder,
262 }))
263 })
264 .0,
265 ))
266 }
267
268 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
269 if clauses.is_empty() {
270 ListWithCachedTypeInfo::empty()
271 } else {
272 self.clauses
273 .intern_ref(clauses, || {
274 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
275
276 InternedInSet(ListWithCachedTypeInfo::from_arena(
277 &*self.arena,
278 flags.into(),
279 clauses,
280 ))
281 })
282 .0
283 }
284 }
285}
286
287const NUM_PREINTERNED_INFER_TY_VARS: u32 = 512;
294const NUM_PREINTERNED_INFER_FRESH_TYS: u32 = 20;
295const NUM_PREINTERNED_INFER_FRESH_INT_TYS: u32 = 3;
296const NUM_PREINTERNED_INFER_FRESH_FLOAT_TYS: u32 = 3;
297const NUM_PREINTERNED_BOUND_BOUND_ANONS_I: u32 = 3;
298const NUM_PREINTERNED_BOUND_BOUND_ANONS_V: u32 = 20;
299const NUM_PREINTERNED_BOUND_CANONICAL_ANONS: u32 = 128;
300const NUM_PREINTERNED_PLACEHOLDER_ROOT_ANONS: u32 = 128;
301
302const NUM_PREINTERNED_RE_VARS: u32 = 500;
303const NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_I: u32 = 3;
304const NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_V: u32 = 20;
305const NUM_PREINTERNED_RE_BOUND_CANONICAL_ANONS: u32 = 20;
306
307pub struct CommonTypes<'tcx> {
308 pub unit: Ty<'tcx>,
309 pub bool: Ty<'tcx>,
310 pub char: Ty<'tcx>,
311 pub isize: Ty<'tcx>,
312 pub i8: Ty<'tcx>,
313 pub i16: Ty<'tcx>,
314 pub i32: Ty<'tcx>,
315 pub i64: Ty<'tcx>,
316 pub i128: Ty<'tcx>,
317 pub usize: Ty<'tcx>,
318 pub u8: Ty<'tcx>,
319 pub u16: Ty<'tcx>,
320 pub u32: Ty<'tcx>,
321 pub u64: Ty<'tcx>,
322 pub u128: Ty<'tcx>,
323 pub f16: Ty<'tcx>,
324 pub f32: Ty<'tcx>,
325 pub f64: Ty<'tcx>,
326 pub f128: Ty<'tcx>,
327 pub str_: Ty<'tcx>,
328 pub never: Ty<'tcx>,
329 pub self_param: Ty<'tcx>,
330
331 pub trait_object_dummy_self: Ty<'tcx>,
358
359 pub infer_ty_vars: Vec<Ty<'tcx>>,
361
362 pub infer_fresh_tys: Vec<Ty<'tcx>>,
364
365 pub infer_fresh_int_tys: Vec<Ty<'tcx>>,
367
368 pub infer_fresh_float_tys: Vec<Ty<'tcx>>,
370
371 pub bound_bound_anons: Vec<Vec<Ty<'tcx>>>,
378
379 pub bound_canonical_anons: Vec<Ty<'tcx>>,
383
384 pub placeholder_root_anons: Vec<Ty<'tcx>>,
391}
392
393pub struct CommonLifetimes<'tcx> {
394 pub re_static: Region<'tcx>,
396
397 pub re_erased: Region<'tcx>,
399
400 pub re_vars: Vec<Region<'tcx>>,
402
403 pub re_bound_bound_anons: Vec<Vec<Region<'tcx>>>,
407
408 pub re_bound_canonical_anons: Vec<Region<'tcx>>,
412}
413
414pub struct CommonConsts<'tcx> {
415 pub unit: Const<'tcx>,
416 pub true_: Const<'tcx>,
417 pub false_: Const<'tcx>,
418 pub(crate) valtree_zst: ValTree<'tcx>,
420}
421
422impl<'tcx> CommonTypes<'tcx> {
423 fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
424 let mk = |ty| interners.intern_ty(ty);
425
426 let infer_ty_vars = (0..NUM_PREINTERNED_INFER_TY_VARS)
427 .map(|n| mk(Infer(ty::TyVar(TyVid::from(n)))))
428 .collect();
429 let infer_fresh_tys: Vec<_> =
430 (0..NUM_PREINTERNED_INFER_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
431 let infer_fresh_int_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_INT_TYS)
432 .map(|n| mk(Infer(ty::FreshIntTy(n))))
433 .collect();
434 let infer_fresh_float_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_FLOAT_TYS)
435 .map(|n| mk(Infer(ty::FreshFloatTy(n))))
436 .collect();
437
438 let bound_bound_anons = (0..NUM_PREINTERNED_BOUND_BOUND_ANONS_I)
439 .map(|i| {
440 (0..NUM_PREINTERNED_BOUND_BOUND_ANONS_V)
441 .map(|v| {
442 mk(ty::Bound(
443 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
444 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
445 ))
446 })
447 .collect()
448 })
449 .collect();
450
451 let bound_canonical_anons = (0..NUM_PREINTERNED_BOUND_CANONICAL_ANONS)
452 .map(|v| {
453 mk(ty::Bound(
454 ty::BoundVarIndexKind::Canonical,
455 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
456 ))
457 })
458 .collect();
459
460 let placeholder_root_anons = (0..NUM_PREINTERNED_PLACEHOLDER_ROOT_ANONS)
461 .map(|v| {
462 mk(ty::Placeholder(PlaceholderType::new_anon(
463 ty::UniverseIndex::ROOT,
464 ty::BoundVar::from(v),
465 )))
466 })
467 .collect();
468
469 CommonTypes {
470 unit: mk(Tuple(List::empty())),
471 bool: mk(Bool),
472 char: mk(Char),
473 never: mk(Never),
474 isize: mk(Int(ty::IntTy::Isize)),
475 i8: mk(Int(ty::IntTy::I8)),
476 i16: mk(Int(ty::IntTy::I16)),
477 i32: mk(Int(ty::IntTy::I32)),
478 i64: mk(Int(ty::IntTy::I64)),
479 i128: mk(Int(ty::IntTy::I128)),
480 usize: mk(Uint(ty::UintTy::Usize)),
481 u8: mk(Uint(ty::UintTy::U8)),
482 u16: mk(Uint(ty::UintTy::U16)),
483 u32: mk(Uint(ty::UintTy::U32)),
484 u64: mk(Uint(ty::UintTy::U64)),
485 u128: mk(Uint(ty::UintTy::U128)),
486 f16: mk(Float(ty::FloatTy::F16)),
487 f32: mk(Float(ty::FloatTy::F32)),
488 f64: mk(Float(ty::FloatTy::F64)),
489 f128: mk(Float(ty::FloatTy::F128)),
490 str_: mk(Str),
491 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
492
493 trait_object_dummy_self: infer_fresh_tys[0],
494
495 infer_ty_vars,
496 infer_fresh_tys,
497 infer_fresh_int_tys,
498 infer_fresh_float_tys,
499 bound_bound_anons,
500 bound_canonical_anons,
501 placeholder_root_anons,
502 }
503 }
504}
505
506impl<'tcx> CommonLifetimes<'tcx> {
507 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
508 let mk = |r| {
509 Region(Interned::new_unchecked(
510 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
511 ))
512 };
513
514 let re_vars =
515 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
516
517 let re_bound_bound_anons = (0..NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_I)
518 .map(|i| {
519 (0..NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_V)
520 .map(|v| {
521 mk(ty::ReBound(
522 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
523 ty::BoundRegion {
524 var: ty::BoundVar::from(v),
525 kind: ty::BoundRegionKind::Anon,
526 },
527 ))
528 })
529 .collect()
530 })
531 .collect();
532
533 let re_bound_canonical_anons = (0..NUM_PREINTERNED_RE_BOUND_CANONICAL_ANONS)
534 .map(|v| {
535 mk(ty::ReBound(
536 ty::BoundVarIndexKind::Canonical,
537 ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
538 ))
539 })
540 .collect();
541
542 CommonLifetimes {
543 re_static: mk(ty::ReStatic),
544 re_erased: mk(ty::ReErased),
545 re_vars,
546 re_bound_bound_anons,
547 re_bound_canonical_anons,
548 }
549 }
550}
551
552impl<'tcx> CommonConsts<'tcx> {
553 fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
554 let mk_const = |c| interners.intern_const(c);
555
556 let mk_valtree = |v| {
557 ty::ValTree(Interned::new_unchecked(
558 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
559 ))
560 };
561
562 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
563 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
564 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
565
566 CommonConsts {
567 unit: mk_const(ty::ConstKind::Value(ty::Value {
568 ty: types.unit,
569 valtree: valtree_zst,
570 })),
571 true_: mk_const(ty::ConstKind::Value(ty::Value {
572 ty: types.bool,
573 valtree: valtree_true,
574 })),
575 false_: mk_const(ty::ConstKind::Value(ty::Value {
576 ty: types.bool,
577 valtree: valtree_false,
578 })),
579 valtree_zst,
580 }
581 }
582}
583
584#[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 region_def_id is_impl_item", &self.scope,
&self.region_def_id, &&self.is_impl_item)
}
}Debug)]
587pub struct FreeRegionInfo {
588 pub scope: LocalDefId,
590 pub region_def_id: DefId,
592 pub is_impl_item: bool,
594}
595
596#[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) -> Self {
TyCtxtFeed {
tcx: ::core::clone::Clone::clone(&self.tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
598pub struct TyCtxtFeed<'tcx, K: Copy> {
599 pub tcx: TyCtxt<'tcx>,
600 key: K,
602}
603
604impl<K: Copy> !StableHash for TyCtxtFeed<'_, K> {}
606
607impl<'tcx> TyCtxt<'tcx> {
612 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
615 self.dep_graph.assert_ignored();
616 TyCtxtFeed { tcx: self, key: () }
617 }
618
619 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
622 let key = self.untracked().source_span.push(span);
623 {
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);
624 TyCtxtFeed { tcx: self, key }
625 }
626
627 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
631 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);
632 if true {
if !(self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline)
{
::core::panicking::panic("assertion failed: self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline")
};
};debug_assert!(self.anon_const_kind(key) != ty::AnonConstKind::NonTypeSystemInline);
633 TyCtxtFeed { tcx: self, key }.type_of(value)
634 }
635
636 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
644 if truecfg!(debug_assertions) {
645 match self.def_kind(self.local_parent(key)) {
646 DefKind::Impl { of_trait: true } => {}
647 other => ::rustc_span::macros::bug_impl(None,
format_args!("{0:?} is not an assoc item of a trait impl: {1:?}", key,
other), Location::caller())bug!("{key:?} is not an assoc item of a trait impl: {other:?}"),
648 }
649 }
650 TyCtxtFeed { tcx: self, key }.visibility(vis.to_mod_id())
651 }
652}
653
654impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> {
655 #[inline(always)]
656 pub fn key(&self) -> K {
657 self.key
658 }
659}
660
661impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
662 #[inline(always)]
663 pub fn def_id(&self) -> LocalDefId {
664 self.key
665 }
666
667 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
669 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
670 }
671
672 pub fn feed_hir(&self) {
674 self.hir_owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo::new(
675 self.tcx.arena.alloc(hir::OwnerNodes::synthetic()),
676 self.tcx.arena.alloc(Default::default()),
677 self.tcx.arena.alloc(Default::default()),
678 self.tcx.arena.alloc(Steal::new(Default::default())),
679 )));
680
681 self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
682 }
683}
684
685#[derive(#[automatically_derived]impl<'tcx> ::core::default::Default for
GlobalCaches<'tcx> {
#[inline]
fn default() -> Self {
GlobalCaches {
ty_rcache: ::core::default::Default::default(),
selection_cache: ::core::default::Default::default(),
evaluation_cache: ::core::default::Default::default(),
new_solver_evaluation_cache: ::core::default::Default::default(),
new_solver_canonical_param_env_cache: ::core::default::Default::default(),
canonicalizer_states: ::core::default::Default::default(),
canonical_param_env_cache: ::core::default::Default::default(),
highest_var_in_clauses_cache: ::core::default::Default::default(),
clauses_cache: ::core::default::Default::default(),
}
}
}Default)]
690pub struct GlobalCaches<'tcx> {
691 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
693
694 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
697
698 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
702
703 new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
705 new_solver_canonical_param_env_cache: Lock<ty::CanonicalParamEnvCache<TyCtxt<'tcx>>>,
706
707 pub canonicalizer_states: Lock<Vec<Box<CanonicalizerState<TyCtxt<'tcx>>>>>,
713
714 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
715
716 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
718
719 pub clauses_cache:
721 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
722}
723
724#[derive(#[automatically_derived]impl<'tcx> ::core::marker::Copy for TyCtxt<'tcx> { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl<'tcx>
::core::clone::TrivialClone for TyCtxt<'tcx> {
}
#[automatically_derived]impl<'tcx> ::core::clone::Clone for TyCtxt<'tcx> {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<&'tcx GlobalCtxt<'tcx>>;
*self
}
}Clone)]
742#[rustc_diagnostic_item = "TyCtxt"]
743#[rustc_pass_by_value]
744pub struct TyCtxt<'tcx> {
745 gcx: &'tcx GlobalCtxt<'tcx>,
746}
747
748unsafe impl DynSend for TyCtxt<'_> {}
752unsafe impl DynSync for TyCtxt<'_> {}
753fn _assert_tcx_fields() {
754 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
755 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
756}
757
758impl<'tcx> Deref for TyCtxt<'tcx> {
759 type Target = &'tcx GlobalCtxt<'tcx>;
760 #[inline(always)]
761 fn deref(&self) -> &Self::Target {
762 &self.gcx
763 }
764}
765
766pub struct GlobalCtxt<'tcx> {
768 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
769 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
770
771 interners: CtxtInterners<'tcx>,
772
773 pub sess: &'tcx Session,
774 crate_types: Vec<CrateType>,
775 stable_crate_id: StableCrateId,
781
782 pub incr_comp_session: Option<&'tcx IncrCompSession>,
783 pub dep_graph: DepGraph,
784
785 pub prof: SelfProfilerRef,
788
789 pub types: CommonTypes<'tcx>,
791
792 pub lifetimes: CommonLifetimes<'tcx>,
794
795 pub consts: CommonConsts<'tcx>,
797
798 pub(crate) hooks: crate::hooks::Providers,
801
802 untracked: Untracked,
803
804 pub query_system: QuerySystem<'tcx>,
805
806 pub caches: GlobalCaches<'tcx>,
807
808 pub data_layout: TargetDataLayout,
810
811 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
813
814 current_gcx: CurrentGcx,
815}
816
817impl<'tcx> GlobalCtxt<'tcx> {
818 pub fn enter<F, R>(&'tcx self, f: F) -> R
821 where
822 F: FnOnce(TyCtxt<'tcx>) -> R,
823 {
824 let icx = tls::ImplicitCtxt::new(self);
825
826 let _on_drop = defer(move || {
828 *self.current_gcx.value.write() = None;
829 });
830
831 {
833 let mut guard = self.current_gcx.value.write();
834 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
835 *guard = Some(self as *const _ as *const ());
836 }
837
838 tls::enter_context(&icx, || f(icx.tcx))
839 }
840}
841
842#[derive(#[automatically_derived]impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> Self {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
849pub struct CurrentGcx {
850 value: Arc<RwLock<Option<*const ()>>>,
853}
854
855unsafe impl DynSend for CurrentGcx {}
856unsafe impl DynSync for CurrentGcx {}
857
858impl CurrentGcx {
859 pub fn new() -> Self {
860 Self { value: Arc::new(RwLock::new(None)) }
861 }
862
863 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
864 let read_guard = self.value.read();
865 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
866 f(unsafe { &*gcx })
870 }
871}
872
873impl<'tcx> TyCtxt<'tcx> {
874 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
875 let root = self.typeck_root_def_id_local(def_id);
878 self.hir_node_by_def_id(root).body_id().is_some()
879 }
880
881 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
886 let def_kind = self.def_kind(def_id);
887 if def_kind.has_codegen_attrs() {
888 self.codegen_fn_attrs(def_id)
889 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst | DefKind::Const |
DefKind::GlobalAsm => true,
_ => false,
}matches!(
890 def_kind,
891 DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::GlobalAsm
892 ) {
893 CodegenFnAttrs::EMPTY
894 } else {
895 ::rustc_span::macros::bug_impl(None,
format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind), Location::caller())bug!(
896 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
897 def_id,
898 def_kind
899 )
900 }
901 }
902
903 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
904 self.arena.alloc(Steal::new(thir))
905 }
906
907 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
908 self.arena.alloc(Steal::new(mir))
909 }
910
911 pub fn alloc_steal_promoted(
912 self,
913 promoted: IndexVec<Promoted, Body<'tcx>>,
914 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
915 self.arena.alloc(Steal::new(promoted))
916 }
917
918 pub fn mk_adt_def(
919 self,
920 did: DefId,
921 kind: AdtKind,
922 variants: IndexVec<VariantIdx, ty::VariantDef>,
923 repr: ReprOptions,
924 ) -> ty::AdtDef<'tcx> {
925 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
926 }
927
928 pub fn allocate_bytes_dedup<'a>(
931 self,
932 bytes: impl Into<Cow<'a, [u8]>>,
933 salt: usize,
934 ) -> interpret::AllocId {
935 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
937 let alloc = self.mk_const_alloc(alloc);
938 self.reserve_and_set_memory_dedup(alloc, salt)
939 }
940
941 pub fn default_traits(self) -> &'static [LangItem] {
943 if self.sess.opts.unstable_opts.experimental_default_bounds {
944 &[
945 LangItem::DefaultTrait1,
946 LangItem::DefaultTrait2,
947 LangItem::DefaultTrait3,
948 LangItem::DefaultTrait4,
949 ]
950 } else {
951 &[]
952 }
953 }
954
955 pub fn is_default_trait(self, def_id: DefId) -> bool {
956 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
957 }
958
959 pub fn is_implicit_trait(
962 self,
963 def_id: DefId,
964 including_sized: IncludeSizedImplicitBounds,
965 ) -> bool {
966 self.is_default_trait(def_id)
967 || (#[allow(non_exhaustive_omitted_patterns)] match including_sized {
IncludeSizedImplicitBounds::Yes => true,
_ => false,
}matches!(including_sized, IncludeSizedImplicitBounds::Yes) && self.is_sizedness_trait(def_id))
969 }
970
971 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
972 #[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))
973 }
974
975 pub fn is_forget_trait(self, def_id: DefId) -> bool {
976 #[allow(non_exhaustive_omitted_patterns)] match self.as_lang_item(def_id) {
Some(LangItem::Forget) => true,
_ => false,
}matches!(self.as_lang_item(def_id), Some(LangItem::Forget))
977 }
978
979 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> T::Lifted {
980 value.lift_to_interner(self)
981 }
982
983 pub fn create_global_ctxt<T>(
990 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
991 sess: &'tcx Session,
992 crate_types: Vec<CrateType>,
993 stable_crate_id: StableCrateId,
994 arena: &'tcx WorkerLocal<Arena<'tcx>>,
995 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
996 untracked: Untracked,
997 incr_comp_session: Option<&'tcx IncrCompSession>,
998 dep_graph: DepGraph,
999 query_system: QuerySystem<'tcx>,
1000 hooks: crate::hooks::Providers,
1001 current_gcx: CurrentGcx,
1002 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1003 ) -> T {
1004 let data_layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
1005 sess.dcx().emit_fatal(err);
1006 });
1007 let interners = CtxtInterners::new(arena);
1008 let common_types = CommonTypes::new(&interners);
1009 let common_lifetimes = CommonLifetimes::new(&interners);
1010 let common_consts = CommonConsts::new(&interners, &common_types);
1011
1012 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1013 sess,
1014 crate_types,
1015 stable_crate_id,
1016 arena,
1017 hir_arena,
1018 interners,
1019 incr_comp_session,
1020 dep_graph,
1021 hooks,
1022 prof: sess.prof.clone(),
1023 types: common_types,
1024 lifetimes: common_lifetimes,
1025 consts: common_consts,
1026 untracked,
1027 query_system,
1028 caches: Default::default(),
1029 data_layout,
1030 alloc_map: interpret::AllocMap::new(),
1031 current_gcx,
1032 });
1033
1034 gcx.enter(f)
1036 }
1037
1038 pub fn lang_items(self) -> &'tcx rustc_attr_ir::lang_items::LanguageItems {
1040 self.get_lang_items(())
1041 }
1042
1043 #[track_caller]
1045 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1046 let ordering_enum = self.require_lang_item(LangItem::OrderingEnum, span);
1047 self.type_of(ordering_enum).no_bound_vars().unwrap()
1048 }
1049
1050 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1053 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1054 }
1055
1056 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1058 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1059 }
1060
1061 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1063 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1064 }
1065
1066 pub fn is_coroutine(self, def_id: DefId) -> bool {
1067 self.coroutine_kind(def_id).is_some()
1068 }
1069
1070 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1071 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1072 }
1073
1074 pub fn is_direct_const(self, def_id: DefId) -> bool {
1082 if true {
{
match self.def_kind(def_id) {
DefKind::Const | DefKind::AssocConst => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Const | DefKind::AssocConst",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::Const | DefKind::AssocConst);
1083 self.is_always_gca(def_id) || self.const_of_item(def_id).is_some()
1084 }
1085
1086 pub fn is_always_gca(self, def_id: DefId) -> bool {
1088 {
{
'done:
{
for i in ::rustc_attr_ir::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(AlwaysGca) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Tool(..) |
::rustc_attr_ir::Attribute::DeriveHelper(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(self, def_id, AlwaysGca)
1089 }
1090
1091 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1094 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1095 }
1096
1097 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1099 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1100 self.coroutine_kind(def_id),
1101 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1102 )
1103 }
1104
1105 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1108 let def_id = def_id.into();
1109 match self.def_kind(def_id) {
1110 DefKind::SyntheticCoroutineBody => true,
1111 DefKind::Const | DefKind::AssocConst => self.const_of_item(def_id).is_some(),
1112 _ => false,
1113 }
1114 }
1115
1116 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1119 #[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(_)))
1120 }
1121
1122 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1124 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1125 self.coroutine_kind(def_id),
1126 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1127 )
1128 }
1129
1130 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1132 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1133 self.coroutine_kind(def_id),
1134 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1135 )
1136 }
1137
1138 pub fn features(self) -> &'tcx rustc_feature::Features {
1139 self.features_query(())
1140 }
1141
1142 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1143 let id = id.into_query_key();
1144 if let Some(id) = id.as_local() {
1146 self.definitions_untracked().def_key(id)
1147 } else {
1148 self.cstore_untracked().def_key(id)
1149 }
1150 }
1151
1152 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1158 if let Some(id) = id.as_local() {
1160 self.definitions_untracked().def_path(id)
1161 } else {
1162 self.cstore_untracked().def_path(id)
1163 }
1164 }
1165
1166 #[inline]
1167 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1168 if let Some(def_id) = def_id.as_local() {
1170 self.definitions_untracked().def_path_hash(def_id)
1171 } else {
1172 self.cstore_untracked().def_path_hash(def_id)
1173 }
1174 }
1175
1176 pub fn prelocked_def_path_hasher(
1182 self,
1183 ) -> impl Fn(DefId) -> rustc_hir::definitions::DefPathHash {
1184 let definitions = self.definitions_untracked();
1185 let cstore = self.cstore_untracked();
1186 move |def_id| match def_id.as_local() {
1187 Some(def_id) => definitions.def_path_hash(def_id),
1188 None => cstore.def_path_hash(def_id),
1189 }
1190 }
1191
1192 #[inline]
1193 pub fn crate_types(self) -> &'tcx [CrateType] {
1194 &self.crate_types
1195 }
1196
1197 pub fn needs_metadata(self) -> bool {
1198 self.crate_types().iter().any(|ty| match *ty {
1199 CrateType::Executable
1200 | CrateType::StaticLib
1201 | CrateType::Cdylib
1202 | CrateType::Sdylib => false,
1203 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1204 }) && !self.sess.opts.actually_rustdoc
1205 }
1206
1207 pub fn needs_hir_hash(self) -> bool {
1208 truecfg!(debug_assertions)
1220 || self.sess.opts.incremental.is_some()
1221 || self.needs_metadata()
1222 || self.sess.instrument_coverage()
1223 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1224 }
1225
1226 pub fn needs_owner_info_hash(self) -> bool {
1241 self.needs_hir_hash()
1242 && (!self.sess.opts.unstable_opts.metadata_crate_hash
1243 || self.sess.opts.incremental.is_some()
1244 || truecfg!(debug_assertions))
1245 }
1246
1247 #[inline]
1248 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1249 if crate_num == LOCAL_CRATE {
1250 self.stable_crate_id
1251 } else {
1252 self.cstore_untracked().stable_crate_id(crate_num)
1253 }
1254 }
1255
1256 #[inline]
1259 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1260 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1261 LOCAL_CRATE
1262 } else {
1263 *self
1264 .untracked()
1265 .stable_crate_ids
1266 .read()
1267 .get(&stable_crate_id)
1268 .unwrap_or_else(|| ::rustc_span::macros::bug_impl(None,
format_args!("uninterned StableCrateId: {0:?}", stable_crate_id),
Location::caller())bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1269 }
1270 }
1271
1272 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1276 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs:1276",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1276u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("def_path_hash_to_def_id({0:?})",
hash) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("def_path_hash_to_def_id({:?})", hash);
1277
1278 let stable_crate_id = hash.stable_crate_id();
1279
1280 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1283 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1284 } else {
1285 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1286 }
1287 }
1288
1289 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1290 let (crate_name, stable_crate_id) = if def_id.is_local() {
1295 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1296 } else {
1297 let cstore = &*self.cstore_untracked();
1298 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1299 };
1300
1301 ::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!(
1302 "{}[{:04x}]{}",
1303 crate_name,
1304 stable_crate_id.as_u64() >> (8 * 6),
1307 self.def_path(def_id).to_string_no_crate_verbose()
1308 )
1309 }
1310
1311 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1312 self.sess.dcx()
1313 }
1314
1315 pub fn is_target_feature_call_safe(
1318 self,
1319 callee_features: &[TargetFeature],
1320 body_features: &[TargetFeature],
1321 ) -> bool {
1322 self.sess.target.options.is_like_wasm
1327 || callee_features
1328 .iter()
1329 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1330 }
1331
1332 pub fn adjust_target_feature_sig(
1335 self,
1336 fun_def: DefId,
1337 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1338 caller: DefId,
1339 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1340 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1341 let caller_features = &self.body_codegen_attrs(caller).target_features;
1342 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1343 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1344 fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1345 ..sig
1346 }));
1347 }
1348 None
1349 }
1350
1351 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1354 match self.env_var_os(key.as_ref()) {
1355 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1356 None => Err(VarError::NotPresent),
1357 }
1358 }
1359
1360 pub fn is_method(self, id: DefId) -> bool {
1361 self.opt_associated_item(id).is_some_and(|item| item.is_method())
1362 }
1363}
1364
1365impl<'tcx> TyCtxtAt<'tcx> {
1366 pub fn create_def(
1368 self,
1369 parent: LocalDefId,
1370 name: Option<Symbol>,
1371 def_kind: DefKind,
1372 override_def_path_data: Option<DefPathData>,
1373 disambiguator: &mut PerParentDisambiguatorState,
1374 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1375 let feed =
1376 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1377
1378 feed.def_span(self.span);
1379 feed
1380 }
1381}
1382
1383impl<'tcx> TyCtxt<'tcx> {
1384 pub fn create_def(
1386 self,
1387 parent: LocalDefId,
1388 name: Option<Symbol>,
1389 def_kind: DefKind,
1390 override_def_path_data: Option<DefPathData>,
1391 disambiguator: &mut PerParentDisambiguatorState,
1392 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1393 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1394 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1404
1405 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1410
1411 let feed = TyCtxtFeed { tcx: self, key: def_id };
1412 feed.def_kind(def_kind);
1413 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1418 let parent_mod = self.parent_module_from_def_id(def_id);
1419 feed.visibility(ty::Visibility::Restricted(parent_mod.to_mod_id()));
1420 }
1421
1422 feed
1423 }
1424
1425 pub fn create_crate_num(
1426 self,
1427 stable_crate_id: StableCrateId,
1428 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1429 let mut lock = self.untracked().stable_crate_ids.write();
1430 if let Some(&existing) = lock.get(&stable_crate_id) {
1431 return Err(existing);
1432 }
1433 let num = CrateNum::new(lock.len());
1434 lock.insert(stable_crate_id, num);
1435 Ok(TyCtxtFeed { key: num, tcx: self })
1436 }
1437
1438 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1439 self.ensure_ok().analysis(());
1441
1442 let definitions = &self.untracked.definitions;
1443 gen {
1444 let mut i = 0;
1445
1446 while i < { definitions.read().num_definitions() } {
1449 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1450 yield LocalDefId { local_def_index };
1451 i += 1;
1452 }
1453
1454 definitions.freeze();
1456 }
1457 }
1458
1459 pub fn definitions(self) -> &'tcx rustc_hir::definitions::Definitions {
1460 self.ensure_ok().analysis(());
1462
1463 self.untracked.definitions.freeze()
1466 }
1467
1468 pub fn def_path_hash_to_def_index_map(self) -> &'tcx rustc_hir::definitions::DefPathToIndexMap {
1469 self.ensure_ok().hir_crate_items(());
1472 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1475 }
1476
1477 #[inline]
1480 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1481 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1482 }
1483
1484 pub fn untracked(self) -> &'tcx Untracked {
1486 &self.untracked
1487 }
1488 #[inline]
1491 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1492 self.untracked.definitions.read()
1493 }
1494
1495 #[inline(always)]
1496 pub fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashState<'_>) -> R) -> R {
1497 f(StableHashState::new(self.sess, &self.untracked))
1498 }
1499
1500 #[inline]
1501 pub fn local_crate_exports_generics(self) -> bool {
1502 if self.is_compiler_builtins(LOCAL_CRATE) {
1506 return false;
1507 }
1508 self.crate_types().iter().any(|crate_type| {
1509 match crate_type {
1510 CrateType::Executable
1511 | CrateType::StaticLib
1512 | CrateType::ProcMacro
1513 | CrateType::Cdylib
1514 | CrateType::Sdylib => false,
1515
1516 CrateType::Dylib => true,
1521
1522 CrateType::Rlib => true,
1523 }
1524 })
1525 }
1526
1527 pub fn is_suitable_region(
1529 self,
1530 generic_param_scope: LocalDefId,
1531 mut region: Region<'tcx>,
1532 ) -> Option<FreeRegionInfo> {
1533 let (suitable_region_binding_scope, region_def_id) = loop {
1534 let def_id =
1535 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1536 let scope = self.local_parent(def_id);
1537 if self.def_kind(scope) == DefKind::OpaqueTy {
1538 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1541 continue;
1542 }
1543 break (scope, def_id.into());
1544 };
1545
1546 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1547 Node::Item(..) | Node::TraitItem(..) => false,
1548 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1549 hir::ImplItemImplKind::Trait { .. } => true,
1556 _ => false,
1557 },
1558 _ => false,
1559 };
1560
1561 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1562 }
1563
1564 pub fn return_type_impl_or_dyn_traits(
1566 self,
1567 scope_def_id: LocalDefId,
1568 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1569 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1570 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1571 self.hir_fn_decl_by_hir_id(hir_id)
1572 else {
1573 return ::alloc::vec::Vec::new()vec![];
1574 };
1575
1576 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1577 v.visit_ty_unambig(hir_output);
1578 v.0
1579 }
1580
1581 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1585 self,
1586 scope_def_id: LocalDefId,
1587 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1588 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1589 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1590 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1592 && let hir::TyKind::Path(hir::QPath::Resolved(
1593 None,
1594 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1595 && let Some(local_id) = def_id.as_local()
1596 && 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()
1598 {
1599 v.visit_ty_unambig(alias_ty);
1600 if !v.0.is_empty() {
1601 return Some((
1602 v.0,
1603 alias_generics.span,
1604 alias_generics.span_for_lifetime_suggestion(),
1605 ));
1606 }
1607 }
1608 None
1609 }
1610
1611 pub fn has_strict_asm_symbol_naming(self) -> bool {
1614 self.sess.target.llvm_target.starts_with("nvptx")
1615 }
1616
1617 pub fn caller_location_ty(self) -> Ty<'tcx> {
1619 Ty::new_imm_ref(
1620 self,
1621 self.lifetimes.re_static,
1622 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1623 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1624 .skip_norm_wip(),
1625 )
1626 }
1627
1628 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1630 let kind = self.def_kind(def_id);
1631 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1632 }
1633
1634 pub fn type_length_limit(self) -> Limit {
1635 self.limits(()).type_length_limit
1636 }
1637
1638 pub fn recursion_limit(self) -> Limit {
1639 self.limits(()).recursion_limit
1640 }
1641
1642 pub fn move_size_limit(self) -> Limit {
1643 self.limits(()).move_size_limit
1644 }
1645
1646 pub fn pattern_complexity_limit(self) -> Limit {
1647 self.limits(()).pattern_complexity_limit
1648 }
1649
1650 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1652 iter::once(LOCAL_CRATE)
1653 .chain(self.crates(()).iter().copied())
1654 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1655 }
1656
1657 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1659 let visible_crates =
1660 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1661
1662 iter::once(LOCAL_CRATE)
1663 .chain(visible_crates)
1664 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1665 }
1666
1667 #[inline]
1668 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1669 self.visibility(def_id).expect_local()
1670 }
1671
1672 {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("local_opaque_ty_origin",
"rustc_middle::ty::context", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1673u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("def_id")
}> =
::tracing::__macro_support::FieldName::new("def_id");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
hir::OpaqueTyOrigin<LocalDefId> = loop {};
return __tracing_attr_fake_return;
}
{ self.hir_expect_opaque_ty(def_id).origin }
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs:1673",
"rustc_middle::ty::context", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1673u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(skip(self), level = "trace", ret)]
1674 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1675 self.hir_expect_opaque_ty(def_id).origin
1676 }
1677
1678 pub fn finish(self) {
1679 self.alloc_self_profile_query_strings();
1682
1683 self.save_dep_graph();
1684 self.verify_query_key_hashes();
1685
1686 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1687 self.sess
1688 .dcx()
1689 .emit_fatal(crate::diagnostics::FailedWritingFile { path: &path, error });
1690 }
1691 }
1692
1693 pub fn report_unused_features(self) {
1694 #[derive(const _: () =
{
impl<'_sess> rustc_errors::Diagnostic<'_sess> for UnusedFeature {
#[track_caller]
fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
level: rustc_errors::Level) -> rustc_errors::Diag<'_sess> {
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)]
1695 #[diag("feature `{$feature}` is declared but not used")]
1696 struct UnusedFeature {
1697 feature: Symbol,
1698 }
1699
1700 let used_features = self.query_system.used_features.lock();
1702 let unused_features = self
1703 .features()
1704 .enabled_features_iter_stable_order()
1705 .filter(|(f, _)| {
1706 !used_features.contains_key(f)
1707 && f.as_str() != "restricted_std"
1714 && *f != sym::doc_cfg
1718 })
1719 .collect::<Vec<_>>();
1720
1721 for (feature, span) in unused_features {
1722 self.emit_node_span_lint(
1723 UNUSED_FEATURES,
1724 CRATE_HIR_ID,
1725 span,
1726 UnusedFeature { feature },
1727 );
1728 }
1729 }
1730}
1731
1732macro_rules! nop_lift {
1733 ($set:ident; $ty:ty => $lifted:ty) => {
1734 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1735 type Lifted = $lifted;
1736 #[track_caller]
1737 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1738 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1743 _x: Interned<'tcx, Inner>,
1744 ) -> InternedSet<'tcx, Inner> {
1745 unreachable!()
1746 }
1747 fn _type_eq<T>(_x: &T, _y: &T) {}
1748 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1749 let interner = _intern_set_ty_from_interned_ty(x.0);
1753 _type_eq(&interner, &tcx.interners.$set);
1755 }
1756
1757 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1758 unsafe { mem::transmute(self) }
1761 }
1762 }
1763 };
1764}
1765
1766macro_rules! nop_list_lift {
1767 ($set:ident; $ty:ty => $lifted:ty) => {
1768 nop_list_lift! { $set: List; $ty => $lifted }
1769 };
1770 ($set:ident: $list:ident; $ty:ty => $lifted:ty) => {
1772 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a $list<$ty> {
1773 type Lifted = &'tcx $list<$lifted>;
1774 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1775 if false {
1777 let _x: &InternedSet<'tcx, $list<$lifted>> = &tcx.interners.$set;
1778 }
1779
1780 if self.is_empty() {
1781 return $list::empty();
1782 }
1783 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1784 unsafe { mem::transmute(self) }
1787 }
1788 }
1789 };
1790}
1791
1792impl<'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::unreachable_default_msg()
}
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> }
1793impl<'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::unreachable_default_msg()
}
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> }
1794impl<'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::unreachable_default_msg()
}
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> }
1795impl<'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::unreachable_default_msg()
}
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> }
1796impl<'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::unreachable_default_msg()
}
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> }
1797impl<'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::unreachable_default_msg()
}
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> }
1798impl<'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::unreachable_default_msg()
}
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> }
1799
1800impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, RegionKind<'a>> {
1801 type Lifted = Interned<'tcx, RegionKind<'tcx>>;
1802
1803 #[track_caller]
1804 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1805 if !tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0)) {
::core::panicking::panic("assertion failed: tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0))")
};assert!(tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0)));
1806 unsafe { mem::transmute(self) }
1809 }
1810}
1811
1812impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Interned<'a, WithCachedTypeInfo<ConstKind<'a>>> {
1814 type Lifted = Interned<'tcx, WithCachedTypeInfo<ConstKind<'tcx>>>;
1815
1816 #[track_caller]
1817 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1818 if !tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0)) {
::core::panicking::panic("assertion failed: tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0))")
};assert!(tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0)));
1819 unsafe { mem::transmute(self) }
1822 }
1823}
1824
1825impl<'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> }
1826impl<'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> }
1827impl<'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! {
1828 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1829}
1830impl<'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> }
1831impl<'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> }
1832impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<ty::ArgOutlivesClause<'a>> {
type Lifted = &'tcx List<ty::ArgOutlivesClause<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<ty::ArgOutlivesClause<'tcx>>> =
&tcx.interners.outlives;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.outlives.contains_pointer_to(&InternedInSet(self)) {
::core::panicking::panic("assertion failed: tcx.interners.outlives.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { outlives; ty::ArgOutlivesClause<'a> => ty::ArgOutlivesClause<'tcx> }
1833
1834impl<'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> }
1836
1837macro_rules! sty_debug_print {
1838 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1839 #[allow(non_snake_case, reason = "we're using variant names as local variables")]
1840 mod inner {
1841 use crate::ty::{self, TyCtxt};
1842 use crate::ty::context::InternedInSet;
1843
1844 #[derive(Copy, Clone)]
1845 struct DebugStat {
1846 total: usize,
1847 lt_infer: usize,
1848 ty_infer: usize,
1849 ct_infer: usize,
1850 all_infer: usize,
1851 }
1852
1853 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1854 let mut total = DebugStat {
1855 total: 0,
1856 lt_infer: 0,
1857 ty_infer: 0,
1858 ct_infer: 0,
1859 all_infer: 0,
1860 };
1861 $(let mut $variant = total;)*
1862
1863 for shard in tcx.interners.type_.lock_shards() {
1864 #[allow(rustc::potential_query_instability)]
1866 let types = shard.iter();
1867 for &(InternedInSet(t), ()) in types {
1868 let variant = match t.internee {
1869 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1870 ty::Float(..) | ty::Str | ty::Never => continue,
1871 ty::Error(_) => continue,
1872 $(ty::$variant(..) => &mut $variant,)*
1873 };
1874 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1875 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1876 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1877
1878 variant.total += 1;
1879 total.total += 1;
1880 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1881 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1882 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1883 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1884 }
1885 }
1886 writeln!(fmt, "Ty interner total ty lt ct all")?;
1887 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1888 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1889 stringify!($variant),
1890 uses = $variant.total,
1891 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1892 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1893 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1894 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1895 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1896 )*
1897 writeln!(fmt, " total {uses:6} \
1898 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1899 uses = total.total,
1900 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1901 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1902 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1903 all = total.all_infer as f64 * 100.0 / total.total as f64)
1904 }
1905 }
1906
1907 inner::go($fmt, $ctxt)
1908 }}
1909}
1910
1911impl<'tcx> TyCtxt<'tcx> {
1912 pub fn debug_stats(self) -> impl fmt::Debug {
1913 fmt::from_fn(move |fmt| {
1914 {
#[allow(non_snake_case, reason =
"we're using variant names as local variables")]
mod inner {
use crate::ty::{self, TyCtxt};
use crate::ty::context::InternedInSet;
struct DebugStat {
total: usize,
lt_infer: usize,
ty_infer: usize,
ct_infer: usize,
all_infer: usize,
}
#[automatically_derived]
impl ::core::marker::Copy for DebugStat { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DebugStat { }
#[automatically_derived]
impl ::core::clone::Clone for DebugStat {
#[inline]
fn clone(&self) -> Self {
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!(
1915 fmt,
1916 self,
1917 Adt,
1918 Array,
1919 Slice,
1920 RawPtr,
1921 Ref,
1922 FnDef,
1923 FnPtr,
1924 UnsafeBinder,
1925 Placeholder,
1926 Coroutine,
1927 CoroutineWitness,
1928 Dynamic,
1929 Closure,
1930 CoroutineClosure,
1931 Tuple,
1932 Bound,
1933 Param,
1934 Infer,
1935 Alias,
1936 Pat,
1937 Foreign
1938 )?;
1939
1940 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1941 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1942 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())?;
1943 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1944
1945 Ok(())
1946 })
1947 }
1948}
1949
1950struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1955
1956impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1957 fn clone(&self) -> Self {
1958 *self
1959 }
1960}
1961
1962impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1963
1964impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1965 fn into_pointer(&self) -> *const () {
1966 self.0 as *const _ as *const ()
1967 }
1968}
1969
1970#[allow(rustc::usage_of_ty_tykind)]
1971impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1972 fn borrow(&self) -> &T {
1973 &self.0.internee
1974 }
1975}
1976
1977impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1978 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1979 self.0.internee == other.0.internee
1982 }
1983}
1984
1985impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1986
1987impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1988 fn hash<H: Hasher>(&self, s: &mut H) {
1989 self.0.internee.hash(s)
1991 }
1992}
1993
1994impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1995 fn borrow(&self) -> &[T] {
1996 &self.0[..]
1997 }
1998}
1999
2000impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2001 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2002 self.0[..] == other.0[..]
2005 }
2006}
2007
2008impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2009
2010impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2011 fn hash<H: Hasher>(&self, s: &mut H) {
2012 self.0[..].hash(s)
2014 }
2015}
2016
2017impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2018 fn borrow(&self) -> &[T] {
2019 &self.0[..]
2020 }
2021}
2022
2023impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2024 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2025 self.0[..] == other.0[..]
2028 }
2029}
2030
2031impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2032
2033impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2034 fn hash<H: Hasher>(&self, s: &mut H) {
2035 self.0[..].hash(s)
2037 }
2038}
2039
2040macro_rules! direct_interners {
2041 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2042 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2043 fn borrow<'a>(&'a self) -> &'a $ty {
2044 &self.0
2045 }
2046 }
2047
2048 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2049 fn eq(&self, other: &Self) -> bool {
2050 self.0 == other.0
2053 }
2054 }
2055
2056 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2057
2058 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2059 fn hash<H: Hasher>(&self, s: &mut H) {
2060 self.0.hash(s)
2063 }
2064 }
2065
2066 impl<'tcx> TyCtxt<'tcx> {
2067 $vis fn $method(self, v: $ty) -> $ret_ty {
2068 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2069 InternedInSet(self.interners.arena.alloc(v))
2070 }).0))
2071 }
2072 })+
2073 }
2074}
2075
2076impl<'tcx> Borrow<RegionKind<'tcx>> for InternedInSet<'tcx, RegionKind<'tcx>>
{
fn borrow<'a>(&'a self) -> &'a RegionKind<'tcx> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, RegionKind<'tcx>> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, RegionKind<'tcx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, RegionKind<'tcx>> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub(crate) fn intern_region(self, v: RegionKind<'tcx>) -> Region<'tcx> {
Region(Interned::new_unchecked(self.interners.region.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'tcx> Borrow<ValTreeKind<TyCtxt<'tcx>>> for
InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a ValTreeKind<TyCtxt<'tcx>> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {}
impl<'tcx> Hash for InternedInSet<'tcx, ValTreeKind<TyCtxt<'tcx>>> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub(crate) fn intern_valtree(self, v: ValTreeKind<TyCtxt<'tcx>>)
-> ValTree<'tcx> {
ValTree(Interned::new_unchecked(self.interners.valtree.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'tcx> Borrow<PatternKind<'tcx>> for
InternedInSet<'tcx, PatternKind<'tcx>> {
fn borrow<'a>(&'a self) -> &'a PatternKind<'tcx> { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, PatternKind<'tcx>> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, PatternKind<'tcx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, PatternKind<'tcx>> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_pat(self, v: PatternKind<'tcx>) -> Pattern<'tcx> {
Pattern(Interned::new_unchecked(self.interners.pat.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'tcx> Borrow<Allocation> for InternedInSet<'tcx, Allocation> {
fn borrow<'a>(&'a self) -> &'a Allocation { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, Allocation> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, Allocation> {}
impl<'tcx> Hash for InternedInSet<'tcx, Allocation> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_const_alloc(self, v: Allocation) -> ConstAllocation<'tcx> {
ConstAllocation(Interned::new_unchecked(self.interners.const_allocation.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'tcx> Borrow<LayoutData<FieldIdx, VariantIdx>> for
InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {
fn borrow<'a>(&'a self) -> &'a LayoutData<FieldIdx, VariantIdx> {
&self.0
}
}
impl<'tcx> PartialEq for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>>
{
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, LayoutData<FieldIdx, VariantIdx>> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_layout(self, v: LayoutData<FieldIdx, VariantIdx>)
-> Layout<'tcx> {
Layout(Interned::new_unchecked(self.interners.layout.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'tcx> Borrow<AdtDefData> for InternedInSet<'tcx, AdtDefData> {
fn borrow<'a>(&'a self) -> &'a AdtDefData { &self.0 }
}
impl<'tcx> PartialEq for InternedInSet<'tcx, AdtDefData> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, AdtDefData> {}
impl<'tcx> Hash for InternedInSet<'tcx, AdtDefData> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_adt_def_from_data(self, v: AdtDefData) -> AdtDef<'tcx> {
AdtDef(Interned::new_unchecked(self.interners.adt_def.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}
impl<'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))
}
}
impl<'tcx> Borrow<CanonicalInputData<TyCtxt<'tcx>>> for
InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a CanonicalInputData<TyCtxt<'tcx>> {
&self.0
}
}
impl<'tcx> PartialEq for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>>
{
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {}
impl<'tcx> Hash for InternedInSet<'tcx, CanonicalInputData<TyCtxt<'tcx>>> {
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
fn intern_canonical_input(self, v: CanonicalInputData<TyCtxt<'tcx>>)
-> CanonicalInput<'tcx> {
CanonicalInput(Interned::new_unchecked(self.interners.canonical_inputs.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}direct_interners! {
2080 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2081 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2082 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2083 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2084 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2085 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2086 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2087 ExternalConstraints -> ExternalConstraints<'tcx>,
2088 canonical_inputs: intern_canonical_input(CanonicalInputData<TyCtxt<'tcx>>): CanonicalInput -> CanonicalInput<'tcx>,
2089}
2090
2091macro_rules! slice_interners {
2092 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2093 impl<'tcx> TyCtxt<'tcx> {
2094 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2095 if v.is_empty() {
2096 List::empty()
2097 } else {
2098 self.interners.$field.intern_ref(v, || {
2099 InternedInSet(List::from_arena(&*self.arena, (), v))
2100 }).0
2101 }
2102 })+
2103 }
2104 );
2105}
2106
2107impl<'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_raw(self, v: &[GenericArg<'tcx>])
-> &'tcx List<GenericArg<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.args.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.type_lists.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_canonical_var_kinds(self, v: &[CanonicalVarKind<'tcx>])
-> &'tcx List<CanonicalVarKind<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.canonical_var_kinds.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_poly_existential_predicates(self,
v: &[PolyExistentialPredicate<'tcx>])
-> &'tcx List<PolyExistentialPredicate<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.poly_existential_predicates.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_projs(self, v: &[ProjectionKind])
-> &'tcx List<ProjectionKind> {
if v.is_empty() {
List::empty()
} else {
self.interners.projs.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_place_elems(self, v: &[PlaceElem<'tcx>])
-> &'tcx List<PlaceElem<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.place_elems.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_bound_variable_kinds(self, v: &[ty::BoundVariableKind<'tcx>])
-> &'tcx List<ty::BoundVariableKind<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.bound_variable_kinds.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_fields(self, v: &[FieldIdx]) -> &'tcx List<FieldIdx> {
if v.is_empty() {
List::empty()
} else {
self.interners.fields.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_local_def_ids(self, v: &[LocalDefId])
-> &'tcx List<LocalDefId> {
if v.is_empty() {
List::empty()
} else {
self.interners.local_def_ids.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_captures(self, v: &[&'tcx ty::CapturedPlace<'tcx>])
-> &'tcx List<&'tcx ty::CapturedPlace<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.captures.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_patterns(self, v: &[Pattern<'tcx>])
-> &'tcx List<Pattern<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.patterns.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_outlives(self, v: &[ty::ArgOutlivesClause<'tcx>])
-> &'tcx List<ty::ArgOutlivesClause<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.outlives.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_predefined_opaques_in_body(self,
v: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)])
-> &'tcx List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
if v.is_empty() {
List::empty()
} else {
self.interners.predefined_opaques_in_body.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
}slice_interners!(
2111 const_lists: pub mk_const_list(Const<'tcx>),
2112 args: pub mk_args_raw(GenericArg<'tcx>),
2113 type_lists: pub mk_type_list(Ty<'tcx>),
2114 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2115 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2116 projs: pub mk_projs(ProjectionKind),
2117 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2118 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2119 fields: pub mk_fields(FieldIdx),
2120 local_def_ids: intern_local_def_ids(LocalDefId),
2121 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2122 patterns: pub mk_patterns(Pattern<'tcx>),
2123 outlives: pub mk_outlives(ty::ArgOutlivesClause<'tcx>),
2124 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2125);
2126
2127impl<'tcx> TyCtxt<'tcx> {
2128 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2132 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2133 Ty::new_fn_ptr(
2134 self,
2135 sig.map_bound(|sig| ty::FnSig {
2136 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2137 ..sig
2138 }),
2139 )
2140 }
2141
2142 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2146 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2147 sig.map_bound(|sig| ty::FnSig {
2148 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2149 ..sig
2150 })
2151 }
2152
2153 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2156 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2157 self.associated_items(trait_did)
2158 .filter_by_name_unhygienic(assoc_name.name)
2159 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2160 })
2161 }
2162
2163 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2165 let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2166 return false;
2167 };
2168 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2169
2170 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2171 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2172 return false;
2173 };
2174 trait_predicate.trait_ref.def_id == future_trait
2175 && trait_predicate.polarity == ClausePolarity::Positive
2176 })
2177 }
2178
2179 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2187 sig.map_bound(|s| {
2188 let params = match s.inputs()[0].kind() {
2189 ty::Tuple(params) => *params,
2190 _ => ::rustc_span::macros::bug_impl(None, format_args!("impossible case reached"),
Location::caller())bug!(),
2191 };
2192 if !s.splatted().is_none() {
::core::panicking::panic("assertion failed: s.splatted().is_none()")
};assert!(s.splatted().is_none());
2194 self.mk_fn_sig(
2195 params,
2196 s.output(),
2197 s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2198 )
2199 })
2200 }
2201
2202 #[inline]
2203 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2204 self.interners.intern_predicate(binder)
2205 }
2206
2207 #[inline]
2208 pub fn reuse_or_mk_predicate(
2209 self,
2210 pred: Predicate<'tcx>,
2211 binder: Binder<'tcx, PredicateKind<'tcx>>,
2212 ) -> Predicate<'tcx> {
2213 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2214 }
2215
2216 pub fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgs<'tcx>) -> bool {
2222 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)
2223 && #[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 });
2224 self.check_args_compatible_inner(def_id, args.as_slice(), is_inherent_assoc_ty)
2225 }
2226
2227 pub fn check_alias_term_args_compatible(
2228 self,
2229 kind: ty::AliasTermKind<'tcx>,
2230 args: ty::GenericArgs<'tcx>,
2231 ) -> bool {
2232 let (def_id, is_self_args) = match kind {
2233 ty::AliasTermKind::ProjectionTy { def_id }
2234 | ty::AliasTermKind::OpaqueTy { def_id }
2235 | ty::AliasTermKind::FreeTy { def_id }
2236 | ty::AliasTermKind::AnonConst { def_id }
2237 | ty::AliasTermKind::ProjectionConst { def_id }
2238 | ty::AliasTermKind::FreeConst { def_id }
2239 | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2240 ty::AliasTermKind::InherentTy { def_id }
2241 | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2242 };
2243 self.check_args_compatible_inner(def_id, args.as_slice(), is_self_args)
2244 }
2245
2246 fn check_args_compatible_inner(
2247 self,
2248 def_id: DefId,
2249 args: &[ty::GenericArg<'tcx>],
2250 is_self_args: bool,
2251 ) -> bool {
2252 let generics = self.generics_of(def_id);
2253 let own_args = if is_self_args {
2254 if generics.own_params.len() + 1 != args.len() {
2255 return false;
2256 }
2257
2258 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2259 return false;
2260 }
2261
2262 &args[1..]
2263 } else {
2264 if generics.count() != args.len() {
2265 return false;
2266 }
2267
2268 let (parent_args, own_args) = args.split_at(generics.parent_count);
2269
2270 if let Some(parent) = generics.parent
2274 && !self.check_args_compatible_inner(parent, parent_args, false)
2275 {
2276 return false;
2277 }
2278
2279 own_args
2280 };
2281
2282 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2283 match (¶m.kind, arg.kind()) {
2284 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2285 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2286 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2287 _ => return false,
2288 }
2289 }
2290
2291 true
2292 }
2293
2294 pub fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgs<'tcx>) {
2301 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2302 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)
2303 && #[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 });
2304 self.emit_bug_args_compatible(def_id, args, is_inherent_assoc_ty);
2305 }
2306 }
2307
2308 pub fn debug_assert_alias_term_args_compatible(
2309 self,
2310 kind: ty::AliasTermKind<'tcx>,
2311 args: ty::GenericArgs<'tcx>,
2312 ) {
2313 if truecfg!(debug_assertions) {
2314 self.debug_assert_alias_term_kind_matches_def_kind(kind);
2315 if !self.check_alias_term_args_compatible(kind, args) {
2316 let (def_id, is_self_args) = match kind {
2317 ty::AliasTermKind::ProjectionTy { def_id }
2318 | ty::AliasTermKind::OpaqueTy { def_id }
2319 | ty::AliasTermKind::FreeTy { def_id }
2320 | ty::AliasTermKind::AnonConst { def_id }
2321 | ty::AliasTermKind::ProjectionConst { def_id }
2322 | ty::AliasTermKind::FreeConst { def_id }
2323 | ty::AliasTermKind::InherentConstImpl { def_id } => (def_id, false),
2324 ty::AliasTermKind::InherentTy { def_id }
2325 | ty::AliasTermKind::InherentConstSelf { def_id } => (def_id, true),
2326 };
2327 self.emit_bug_args_compatible(def_id, args, is_self_args);
2328 }
2329 }
2330 }
2331
2332 fn debug_assert_alias_term_kind_matches_def_kind(self, kind: ty::AliasTermKind<'tcx>) {
2333 match kind {
2334 ty::AliasTermKind::ProjectionTy { def_id } => {
2335 if true {
{
match self.def_kind(def_id) {
DefKind::AssocTy => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AssocTy", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy);
2336 if true {
{
match self.def_kind(self.parent(def_id)) {
DefKind::Trait | DefKind::Impl { of_trait: true } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Trait | DefKind::Impl { of_trait: true }",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(
2337 self.def_kind(self.parent(def_id)),
2338 DefKind::Trait | DefKind::Impl { of_trait: true }
2339 );
2340 }
2341 ty::AliasTermKind::InherentTy { def_id } => {
2342 if true {
{
match self.def_kind(def_id) {
DefKind::AssocTy => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AssocTy", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy);
2343 if true {
{
match self.def_kind(self.parent(def_id)) {
DefKind::Impl { of_trait: false } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Impl { of_trait: false }",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(
2344 self.def_kind(self.parent(def_id)),
2345 DefKind::Impl { of_trait: false }
2346 );
2347 }
2348 ty::AliasTermKind::OpaqueTy { def_id } => {
2349 if true {
{
match self.def_kind(def_id) {
DefKind::OpaqueTy => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::OpaqueTy", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::OpaqueTy);
2350 }
2351 ty::AliasTermKind::FreeTy { def_id } => {
2352 if true {
{
match self.def_kind(def_id) {
DefKind::TyAlias => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::TyAlias", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::TyAlias);
2353 }
2354 ty::AliasTermKind::AnonConst { def_id } => {
2355 if true {
{
match self.def_kind(def_id) {
DefKind::AnonConst => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AnonConst", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::AnonConst);
2356 }
2357 ty::AliasTermKind::ProjectionConst { def_id } => {
2358 if true {
{
match self.def_kind(def_id) {
DefKind::AssocConst => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AssocConst", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocConst);
2359 if true {
{
match self.def_kind(self.parent(def_id)) {
DefKind::Trait | DefKind::Impl { of_trait: true } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Trait | DefKind::Impl { of_trait: true }",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(
2360 self.def_kind(self.parent(def_id)),
2361 DefKind::Trait | DefKind::Impl { of_trait: true }
2362 );
2363 }
2364 ty::AliasTermKind::InherentConstSelf { def_id }
2365 | ty::AliasTermKind::InherentConstImpl { def_id } => {
2366 if true {
{
match self.def_kind(def_id) {
DefKind::AssocConst => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AssocConst", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocConst);
2367 if true {
{
match self.def_kind(self.parent(def_id)) {
DefKind::Impl { of_trait: false } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Impl { of_trait: false }",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(
2368 self.def_kind(self.parent(def_id)),
2369 DefKind::Impl { of_trait: false }
2370 );
2371 }
2372 ty::AliasTermKind::FreeConst { def_id } => {
2373 if true {
{
match self.def_kind(def_id) {
DefKind::Const => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Const", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(self.def_kind(def_id), DefKind::Const);
2374 }
2375 }
2376 }
2377
2378 fn emit_bug_args_compatible(
2379 self,
2380 def_id: DefId,
2381 args: ty::GenericArgs<'tcx>,
2382 is_self_args: bool,
2383 ) -> ! {
2384 if is_self_args {
2385 ::rustc_span::macros::bug_impl(None,
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).as_slice()).iter().copied()))), Location::caller());bug!(
2386 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2387 self.def_path_str(def_id),
2388 args,
2389 self.mk_args_from_iter(
2391 [self.types.self_param.into()].into_iter().chain(
2392 self.generics_of(def_id)
2393 .own_args(ty::GenericArgs::identity_for_item(self, def_id).as_slice())
2394 .iter()
2395 .copied()
2396 )
2397 )
2398 );
2399 } else {
2400 ::rustc_span::macros::bug_impl(None,
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)),
Location::caller());bug!(
2401 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2402 self.def_path_str(def_id),
2403 args,
2404 ty::GenericArgs::identity_for_item(self, def_id)
2405 );
2406 }
2407 }
2408
2409 #[inline(always)]
2410 pub(crate) fn check_and_mk_args(
2411 self,
2412 def_id: DefId,
2413 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2414 ) -> ty::GenericArgs<'tcx> {
2415 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2416 self.debug_assert_args_compatible(def_id, args);
2417 args
2418 }
2419
2420 #[inline]
2421 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2422 self.interners.intern_const(kind)
2423 }
2424
2425 #[allow(rustc::usage_of_ty_tykind)]
2427 #[inline]
2428 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2429 self.interners.intern_ty(st)
2430 }
2431
2432 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2433 match param.kind {
2434 GenericParamDefKind::Lifetime => {
2435 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2436 }
2437 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2438 GenericParamDefKind::Const { .. } => {
2439 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2440 .into()
2441 }
2442 }
2443 }
2444
2445 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2446 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2447 }
2448
2449 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2450 self.mk_place_elem(place, PlaceElem::Deref)
2451 }
2452
2453 pub fn mk_place_downcast(
2454 self,
2455 place: Place<'tcx>,
2456 adt_def: AdtDef<'tcx>,
2457 variant_index: VariantIdx,
2458 ) -> Place<'tcx> {
2459 self.mk_place_elem(
2460 place,
2461 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2462 )
2463 }
2464
2465 pub fn mk_place_downcast_unnamed(
2466 self,
2467 place: Place<'tcx>,
2468 variant_index: VariantIdx,
2469 ) -> Place<'tcx> {
2470 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2471 }
2472
2473 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2474 self.mk_place_elem(place, PlaceElem::Index(index))
2475 }
2476
2477 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2481 Place {
2482 local: place.local,
2483 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2484 }
2485 }
2486
2487 pub fn mk_poly_existential_predicates(
2488 self,
2489 eps: &[PolyExistentialPredicate<'tcx>],
2490 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2491 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2492 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!(
2493 eps.array_windows()
2494 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2495 != Ordering::Greater)
2496 );
2497 self.intern_poly_existential_predicates(eps)
2498 }
2499
2500 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2501 self.interners.intern_clauses(clauses)
2505 }
2506
2507 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2508 self.intern_local_def_ids(def_ids)
2512 }
2513
2514 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2515 where
2516 I: Iterator<Item = T>,
2517 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2518 {
2519 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2520 }
2521
2522 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2523 where
2524 I: Iterator<Item = T>,
2525 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2526 {
2527 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2528 }
2529
2530 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2531 where
2532 I: Iterator<Item = T>,
2533 T: CollectAndApply<
2534 &'tcx ty::CapturedPlace<'tcx>,
2535 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2536 >,
2537 {
2538 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2539 }
2540
2541 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2542 where
2543 I: Iterator<Item = T>,
2544 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2545 {
2546 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2547 }
2548
2549 pub fn mk_fn_sig<I, T>(
2554 self,
2555 inputs: I,
2556 output: I::Item,
2557 fn_sig_kind: FnSigKind<'tcx>,
2558 ) -> T::Output
2559 where
2560 I: IntoIterator<Item = T>,
2561 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2562 {
2563 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2564 inputs_and_output: self.mk_type_list(xs),
2565 fn_sig_kind,
2566 })
2567 }
2568
2569 pub fn mk_fn_sig_rust_abi<I, T>(
2571 self,
2572 inputs: I,
2573 output: I::Item,
2574 safety: hir::Safety,
2575 ) -> T::Output
2576 where
2577 I: IntoIterator<Item = T>,
2578 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2579 {
2580 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2581 }
2582
2583 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2585 where
2586 I: IntoIterator<Item = T>,
2587 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2588 {
2589 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2590 }
2591
2592 pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2594 where
2595 I: IntoIterator<Item = T>,
2596 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2597 {
2598 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2599 }
2600
2601 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2602 where
2603 I: Iterator<Item = T>,
2604 T: CollectAndApply<
2605 PolyExistentialPredicate<'tcx>,
2606 &'tcx List<PolyExistentialPredicate<'tcx>>,
2607 >,
2608 {
2609 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2610 }
2611
2612 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2613 where
2614 I: Iterator<Item = T>,
2615 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2616 {
2617 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2618 }
2619
2620 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2621 where
2622 I: Iterator<Item = T>,
2623 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2624 {
2625 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2626 }
2627
2628 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2629 where
2630 I: Iterator<Item = T>,
2631 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2632 {
2633 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2634 }
2635
2636 pub fn mk_args(self, args: &[GenericArg<'tcx>]) -> ty::GenericArgs<'tcx> {
2637 ty::GenericArgs::from_args(self.mk_args_raw(args))
2638 }
2639
2640 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2641 where
2642 I: Iterator<Item = T>,
2643 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgs<'tcx>>,
2644 {
2645 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2646 }
2647
2648 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2649 where
2650 I: Iterator<Item = T>,
2651 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2652 {
2653 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2654 }
2655
2656 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2657 where
2658 I: Iterator<Item = T>,
2659 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2660 {
2661 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2662 }
2663
2664 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2665 where
2666 I: Iterator<Item = T>,
2667 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2668 {
2669 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2670 }
2671
2672 pub fn mk_args_trait(
2673 self,
2674 self_ty: Ty<'tcx>,
2675 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2676 ) -> ty::GenericArgs<'tcx> {
2677 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2678 }
2679
2680 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2681 where
2682 I: Iterator<Item = T>,
2683 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2684 {
2685 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2686 }
2687
2688 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2689 where
2690 I: Iterator<Item = T>,
2691 T: CollectAndApply<
2692 ty::ArgOutlivesClause<'tcx>,
2693 &'tcx ty::List<ty::ArgOutlivesClause<'tcx>>,
2694 >,
2695 {
2696 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2697 }
2698
2699 #[track_caller]
2702 pub fn emit_node_span_lint(
2703 self,
2704 lint: &'static Lint,
2705 hir_id: HirId,
2706 span: impl Into<MultiSpan>,
2707 decorator: impl for<'a> Diagnostic<'a>,
2708 ) {
2709 let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2710 emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2711 }
2712
2713 pub fn crate_level_attribute_injection_span(self) -> Span {
2715 let node = self.hir_node(hir::CRATE_HIR_ID);
2716 let hir::Node::Crate(m) = node else { ::rustc_span::macros::bug_impl(None, format_args!("impossible case reached"),
Location::caller())bug!() };
2717 m.spans.inject_use_span.shrink_to_lo()
2718 }
2719
2720 pub fn disabled_nightly_features(
2721 self,
2722 diag: &mut Diag<'_>,
2723 features: impl IntoIterator<Item = (String, Symbol)>,
2724 ) {
2725 if !self.sess.is_nightly_build() {
2726 return;
2727 }
2728
2729 let span = self.crate_level_attribute_injection_span();
2730 for (desc, feature) in features {
2731 let msg =
2733 ::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}");
2734 diag.span_suggestion_verbose(
2735 span,
2736 msg,
2737 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2738 Applicability::MaybeIncorrect,
2739 );
2740 }
2741 }
2742
2743 #[track_caller]
2746 pub fn emit_node_lint(
2747 self,
2748 lint: &'static Lint,
2749 id: HirId,
2750 decorator: impl for<'a> Diagnostic<'a>,
2751 ) {
2752 let level_spec = self.lint_level_spec_at_node(lint, id);
2753 emit_lint_base(self.sess, lint, level_spec, None, decorator);
2754 }
2755
2756 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2757 let map = self.in_scope_traits_map(id.owner)?;
2758 let candidates = map.get(&id.local_id)?;
2759 Some(candidates)
2760 }
2761
2762 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2763 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs:2763",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(2763u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("id")
}> =
::tracing::__macro_support::FieldName::new("id");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("named_region")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&id)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?id, "named_region");
2764 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2765 }
2766
2767 pub fn is_late_bound(self, id: HirId) -> bool {
2768 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2769 }
2770
2771 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2772 self.mk_bound_variable_kinds(
2773 &self
2774 .late_bound_vars_map(id.owner)
2775 .get(&id.local_id)
2776 .cloned()
2777 .unwrap_or_else(|| ::rustc_span::macros::bug_impl(None,
format_args!("No bound vars found for {0}", self.hir_id_to_string(id)),
Location::caller())bug!("No bound vars found for {}", self.hir_id_to_string(id))),
2778 )
2779 }
2780
2781 pub fn map_opaque_lifetime_to_parent_lifetime(
2789 self,
2790 mut opaque_lifetime_param_def_id: LocalDefId,
2791 ) -> ty::Region<'tcx> {
2792 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!(
2793 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2794 "{opaque_lifetime_param_def_id:?} is a {}",
2795 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2796 );
2797
2798 loop {
2799 let parent = self.local_parent(opaque_lifetime_param_def_id);
2800 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2801
2802 let Some((lifetime, _)) = lifetime_mapping
2803 .iter()
2804 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2805 else {
2806 ::rustc_span::macros::bug_impl(None,
format_args!("duplicated lifetime param should be present"),
Location::caller());bug!("duplicated lifetime param should be present");
2807 };
2808
2809 match *lifetime {
2810 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2811 let new_parent = self.local_parent(ebv);
2812
2813 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2816 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);
2817 opaque_lifetime_param_def_id = ebv;
2818 continue;
2819 }
2820
2821 let generics = self.generics_of(new_parent);
2822 return ty::Region::new_early_param(
2823 self,
2824 ty::EarlyParamRegion {
2825 index: generics
2826 .param_def_id_to_index(self, ebv.to_def_id())
2827 .expect("early-bound var should be present in fn generics"),
2828 name: self.item_name(ebv.to_def_id()),
2829 },
2830 );
2831 }
2832 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2833 let new_parent = self.local_parent(lbv);
2834 return ty::Region::new_late_param(
2835 self,
2836 new_parent.to_def_id(),
2837 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2838 );
2839 }
2840 resolve_bound_vars::ResolvedArg::Error(guar) => {
2841 return ty::Region::new_error(self, guar);
2842 }
2843 _ => {
2844 return ty::Region::new_error_with_message(
2845 self,
2846 self.def_span(opaque_lifetime_param_def_id),
2847 "cannot resolve lifetime",
2848 );
2849 }
2850 }
2851 }
2852 }
2853
2854 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2859 self.is_const_fn(def_id)
2860 && match self.lookup_const_stability(def_id) {
2861 None => true, Some(stability) if stability.is_const_stable() => true,
2863 _ => false,
2864 }
2865 }
2866
2867 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2869 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2870 && #[allow(non_exhaustive_omitted_patterns)] match self.impl_trait_header(def_id).constness
{
hir::Constness::Const { always: false } => true,
_ => false,
}matches!(
2871 self.impl_trait_header(def_id).constness,
2872 hir::Constness::Const { always: false }
2873 )
2874 }
2875
2876 pub fn is_sdylib_interface_build(self) -> bool {
2877 self.sess.opts.unstable_opts.build_sdylib_interface
2878 }
2879
2880 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2881 let def_id = def_id.into_query_key();
2882 match self.def_kind(def_id) {
2883 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2884 _ => None,
2885 }
2886 }
2887
2888 pub fn next_trait_solver_globally(self) -> bool {
2889 self.sess.opts.unstable_opts.next_solver == NextSolverConfig::Globally
2890 && !self.sess.opts.unstable_opts.higher_ranked_assumptions
2891 && !self.features().generic_const_exprs()
2892 }
2893
2894 pub fn next_solver_overflow_fcw_limit(self) -> Option<usize> {
2895 self.sess.opts.unstable_opts.next_solver_overflow_fcw_limit
2896 }
2897
2898 pub fn disable_trait_solver_fast_paths(self) -> bool {
2899 self.sess.opts.unstable_opts.disable_fast_paths
2900 }
2901
2902 pub fn disable_param_env_normalization_hack(self) -> bool {
2903 self.sess.opts.unstable_opts.disable_param_env_normalization_hack
2904 }
2905
2906 pub fn renormalize_rigid_aliases(self) -> bool {
2907 self.sess.opts.unstable_opts.renormalize_rigid_aliases
2908 }
2909
2910 #[allow(rustc::bad_opt_access)]
2911 pub fn use_typing_mode_post_typeck_through_borrowck(self) -> bool {
2912 self.next_trait_solver_globally()
2913 }
2914
2915 pub fn assumptions_on_binders(self) -> bool {
2916 self.sess.opts.unstable_opts.assumptions_on_binders
2917 }
2918
2919 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2920 self.opt_rpitit_info(def_id).is_some()
2921 }
2922
2923 pub fn get_impl_future_output_ty(self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
2924 let (def_id, args) = match *ty.kind() {
2925 ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => (def_id, args),
2926 ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, args, .. })
2927 if self.is_impl_trait_in_trait(def_id) =>
2928 {
2929 (def_id, args)
2930 }
2931 _ => return None,
2932 };
2933
2934 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2935 let item_def_id = self.associated_item_def_ids(future_trait)[0];
2936
2937 self.explicit_item_self_bounds(def_id)
2938 .iter_instantiated_copied(self, args)
2939 .map(ty::Unnormalized::skip_norm_wip)
2940 .find_map(|(predicate, _)| {
2941 predicate
2942 .kind()
2943 .map_bound(|kind| match kind {
2944 ty::ClauseKind::Projection(projection_predicate)
2945 if projection_predicate.def_id() == item_def_id =>
2946 {
2947 projection_predicate.term.as_type()
2948 }
2949 _ => None,
2950 })
2951 .no_bound_vars()
2952 .flatten()
2953 })
2954 }
2955
2956 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2966 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2967 }
2968
2969 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2971 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2972 }
2973
2974 pub fn resolver_for_lowering(
2975 self,
2976 ) -> (&'tcx Steal<ResolverAstLowering<'tcx>>, &'tcx Steal<ast::Crate>) {
2977 let (resolver, krate, _) = self.resolver_for_lowering_raw(());
2978 (resolver, krate)
2979 }
2980
2981 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2982 make_metadata(self)
2983 }
2984
2985 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2986 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2987 self.coroutine_kind(def_id)
2988 && let ty::Coroutine(_, args) =
2989 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2990 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2991 {
2992 true
2993 } else {
2994 false
2995 }
2996 }
2997
2998 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
3000 {
{
'done:
{
for i in ::rustc_attr_ir::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(DoNotRecommend) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Tool(..) |
::rustc_attr_ir::Attribute::DeriveHelper(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(self, def_id, DoNotRecommend)
3001 }
3002
3003 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
3004 let def_id = def_id.into_query_key();
3005 self.trivial_const(def_id).is_some()
3006 }
3007
3008 pub fn is_entrypoint(self, def_id: DefId) -> bool {
3011 if self.is_lang_item(def_id, LangItem::Start) {
3012 return true;
3013 }
3014 if let Some((entry_def_id, _)) = self.entry_fn(())
3015 && entry_def_id == def_id
3016 {
3017 return true;
3018 }
3019 false
3020 }
3021}
3022
3023pub fn provide(providers: &mut Providers) {
3024 providers.is_panic_runtime = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(PanicRuntime) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Tool(..) |
::rustc_attr_ir::Attribute::DeriveHelper(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, PanicRuntime);
3025 providers.is_compiler_builtins = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(CompilerBuiltins) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Tool(..) |
::rustc_attr_ir::Attribute::DeriveHelper(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, CompilerBuiltins);
3026 providers.has_panic_handler = |tcx, LocalCrate| {
3027 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
3029 };
3030 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
3031}