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::{PhantomData, PointeeSized};
14use std::ops::{Bound, Deref};
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::fx::FxHashMap;
22use rustc_data_structures::intern::Interned;
23use rustc_data_structures::jobserver::Proxy;
24use rustc_data_structures::profiling::SelfProfilerRef;
25use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
26use rustc_data_structures::stable_hasher::HashStable;
27use rustc_data_structures::steal::Steal;
28use rustc_data_structures::sync::{
29 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
30};
31use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
32use rustc_hir::def::DefKind;
33use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
34use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState};
35use rustc_hir::intravisit::VisitorExt;
36use rustc_hir::lang_items::LangItem;
37use rustc_hir::limit::Limit;
38use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, MaybeOwner, Node, TraitCandidate, find_attr};
39use rustc_index::IndexVec;
40use rustc_macros::Diagnostic;
41use rustc_session::Session;
42use rustc_session::config::CrateType;
43use rustc_session::cstore::{CrateStoreDyn, Untracked};
44use rustc_session::lint::Lint;
45use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
46use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
47use rustc_type_ir::TyKind::*;
48pub use rustc_type_ir::lift::Lift;
49use rustc_type_ir::{CollectAndApply, FnSigKind, WithCachedTypeInfo, elaborate, search_graph};
50use tracing::{debug, instrument};
51
52use crate::arena::Arena;
53use crate::dep_graph::dep_node::make_metadata;
54use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
55use crate::ich::StableHashingContext;
56use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
57use crate::lint::emit_lint_base;
58use crate::metadata::ModChild;
59use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
60use crate::middle::resolve_bound_vars;
61use crate::mir::interpret::{self, Allocation, ConstAllocation};
62use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
63use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
64use crate::thir::Thir;
65use crate::traits;
66use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
67use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
68use crate::ty::{
69 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
70 GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, Pattern,
71 PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity,
72 Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, ValTree, ValTreeKind,
73 Visibility,
74};
75
76impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
77 fn is_local(self) -> bool {
78 self.is_local()
79 }
80
81 fn as_local(self) -> Option<LocalDefId> {
82 self.as_local()
83 }
84}
85
86impl<'tcx> rustc_type_ir::inherent::FSigKind<TyCtxt<'tcx>> for FnSigKind {
87 fn fn_sig_kind(self) -> Self {
88 self
89 }
90
91 fn new(abi: ExternAbi, safety: hir::Safety, c_variadic: bool) -> Self {
92 FnSigKind::default().set_abi(abi).set_safe(safety.is_safe()).set_c_variadic(c_variadic)
93 }
94
95 fn abi(self) -> ExternAbi {
96 self.abi()
97 }
98
99 fn safety(self) -> hir::Safety {
100 if self.is_safe() { hir::Safety::Safe } else { hir::Safety::Unsafe }
101 }
102
103 fn c_variadic(self) -> bool {
104 self.c_variadic()
105 }
106}
107
108impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
109 fn abi(self) -> Self {
110 self
111 }
112
113 fn rust() -> Self {
114 ExternAbi::Rust
115 }
116
117 fn is_rust(self) -> bool {
118 #[allow(non_exhaustive_omitted_patterns)] match self {
ExternAbi::Rust => true,
_ => false,
}matches!(self, ExternAbi::Rust)
119 }
120
121 fn pack_abi(self) -> u8 {
122 self.as_packed()
123 }
124
125 fn unpack_abi(abi_index: u8) -> Self {
126 Self::from_packed(abi_index)
127 }
128}
129
130impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
131 fn safe() -> Self {
132 hir::Safety::Safe
133 }
134
135 fn unsafe_mode() -> Self {
136 hir::Safety::Unsafe
137 }
138
139 fn is_safe(self) -> bool {
140 self.is_safe()
141 }
142
143 fn prefix_str(self) -> &'static str {
144 self.prefix_str()
145 }
146}
147
148impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
149 fn generic_const_exprs(self) -> bool {
150 self.generic_const_exprs()
151 }
152
153 fn coroutine_clone(self) -> bool {
154 self.coroutine_clone()
155 }
156
157 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
158 !self.staged_api() && self.enabled(symbol)
162 }
163}
164
165impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
166 fn dummy() -> Self {
167 DUMMY_SP
168 }
169}
170
171type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
172
173pub struct CtxtInterners<'tcx> {
174 arena: &'tcx WorkerLocal<Arena<'tcx>>,
176
177 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
180 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
181 args: InternedSet<'tcx, GenericArgs<'tcx>>,
182 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
183 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
184 region: InternedSet<'tcx, RegionKind<'tcx>>,
185 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
186 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
187 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
188 projs: InternedSet<'tcx, List<ProjectionKind>>,
189 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
190 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
191 pat: InternedSet<'tcx, PatternKind<'tcx>>,
192 const_allocation: InternedSet<'tcx, Allocation>,
193 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
194 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
195 adt_def: InternedSet<'tcx, AdtDefData>,
196 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
197 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
198 fields: InternedSet<'tcx, List<FieldIdx>>,
199 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
200 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
201 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
202 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
203 outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
204}
205
206impl<'tcx> CtxtInterners<'tcx> {
207 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
208 const N: usize = 2048;
211 CtxtInterners {
212 arena,
213 type_: InternedSet::with_capacity(N * 16),
217 const_lists: InternedSet::with_capacity(N * 4),
218 args: InternedSet::with_capacity(N * 4),
219 type_lists: InternedSet::with_capacity(N * 4),
220 region: InternedSet::with_capacity(N * 4),
221 poly_existential_predicates: InternedSet::with_capacity(N / 4),
222 canonical_var_kinds: InternedSet::with_capacity(N / 2),
223 predicate: InternedSet::with_capacity(N),
224 clauses: InternedSet::with_capacity(N),
225 projs: InternedSet::with_capacity(N * 4),
226 place_elems: InternedSet::with_capacity(N * 2),
227 const_: InternedSet::with_capacity(N * 2),
228 pat: InternedSet::with_capacity(N),
229 const_allocation: InternedSet::with_capacity(N),
230 bound_variable_kinds: InternedSet::with_capacity(N * 2),
231 layout: InternedSet::with_capacity(N),
232 adt_def: InternedSet::with_capacity(N),
233 external_constraints: InternedSet::with_capacity(N),
234 predefined_opaques_in_body: InternedSet::with_capacity(N),
235 fields: InternedSet::with_capacity(N * 4),
236 local_def_ids: InternedSet::with_capacity(N),
237 captures: InternedSet::with_capacity(N),
238 valtree: InternedSet::with_capacity(N),
239 patterns: InternedSet::with_capacity(N),
240 outlives: InternedSet::with_capacity(N),
241 }
242 }
243
244 #[allow(rustc::usage_of_ty_tykind)]
246 #[inline(never)]
247 fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
248 Ty(Interned::new_unchecked(
249 self.type_
250 .intern(kind, |kind| {
251 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
252 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
253 internee: kind,
254 flags: flags.flags,
255 outer_exclusive_binder: flags.outer_exclusive_binder,
256 }))
257 })
258 .0,
259 ))
260 }
261
262 #[allow(rustc::usage_of_ty_tykind)]
264 #[inline(never)]
265 fn intern_const(&self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
266 Const(Interned::new_unchecked(
267 self.const_
268 .intern(kind, |kind: ty::ConstKind<'_>| {
269 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
270 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
271 internee: kind,
272 flags: flags.flags,
273 outer_exclusive_binder: flags.outer_exclusive_binder,
274 }))
275 })
276 .0,
277 ))
278 }
279
280 #[inline(never)]
282 fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
283 Predicate(Interned::new_unchecked(
284 self.predicate
285 .intern(kind, |kind| {
286 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
287 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
288 internee: kind,
289 flags: flags.flags,
290 outer_exclusive_binder: flags.outer_exclusive_binder,
291 }))
292 })
293 .0,
294 ))
295 }
296
297 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
298 if clauses.is_empty() {
299 ListWithCachedTypeInfo::empty()
300 } else {
301 self.clauses
302 .intern_ref(clauses, || {
303 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
304
305 InternedInSet(ListWithCachedTypeInfo::from_arena(
306 &*self.arena,
307 flags.into(),
308 clauses,
309 ))
310 })
311 .0
312 }
313 }
314}
315
316const NUM_PREINTERNED_TY_VARS: u32 = 100;
321const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
322const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
323const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
324const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
325
326const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
335
336const NUM_PREINTERNED_RE_VARS: u32 = 500;
338const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
339const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
340
341pub struct CommonTypes<'tcx> {
342 pub unit: Ty<'tcx>,
343 pub bool: Ty<'tcx>,
344 pub char: Ty<'tcx>,
345 pub isize: Ty<'tcx>,
346 pub i8: Ty<'tcx>,
347 pub i16: Ty<'tcx>,
348 pub i32: Ty<'tcx>,
349 pub i64: Ty<'tcx>,
350 pub i128: Ty<'tcx>,
351 pub usize: Ty<'tcx>,
352 pub u8: Ty<'tcx>,
353 pub u16: Ty<'tcx>,
354 pub u32: Ty<'tcx>,
355 pub u64: Ty<'tcx>,
356 pub u128: Ty<'tcx>,
357 pub f16: Ty<'tcx>,
358 pub f32: Ty<'tcx>,
359 pub f64: Ty<'tcx>,
360 pub f128: Ty<'tcx>,
361 pub str_: Ty<'tcx>,
362 pub never: Ty<'tcx>,
363 pub self_param: Ty<'tcx>,
364
365 pub trait_object_dummy_self: Ty<'tcx>,
370
371 pub ty_vars: Vec<Ty<'tcx>>,
373
374 pub fresh_tys: Vec<Ty<'tcx>>,
376
377 pub fresh_int_tys: Vec<Ty<'tcx>>,
379
380 pub fresh_float_tys: Vec<Ty<'tcx>>,
382
383 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
387
388 pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
392}
393
394pub struct CommonLifetimes<'tcx> {
395 pub re_static: Region<'tcx>,
397
398 pub re_erased: Region<'tcx>,
400
401 pub re_vars: Vec<Region<'tcx>>,
403
404 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
408
409 pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
413}
414
415pub struct CommonConsts<'tcx> {
416 pub unit: Const<'tcx>,
417 pub true_: Const<'tcx>,
418 pub false_: Const<'tcx>,
419 pub(crate) valtree_zst: ValTree<'tcx>,
421}
422
423impl<'tcx> CommonTypes<'tcx> {
424 fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
425 let mk = |ty| interners.intern_ty(ty);
426
427 let ty_vars =
428 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
429 let fresh_tys: Vec<_> =
430 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
431 let fresh_int_tys: Vec<_> =
432 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
433 let fresh_float_tys: Vec<_> =
434 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
435
436 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
437 .map(|i| {
438 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
439 .map(|v| {
440 mk(ty::Bound(
441 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
442 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
443 ))
444 })
445 .collect()
446 })
447 .collect();
448
449 let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
450 .map(|v| {
451 mk(ty::Bound(
452 ty::BoundVarIndexKind::Canonical,
453 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
454 ))
455 })
456 .collect();
457
458 CommonTypes {
459 unit: mk(Tuple(List::empty())),
460 bool: mk(Bool),
461 char: mk(Char),
462 never: mk(Never),
463 isize: mk(Int(ty::IntTy::Isize)),
464 i8: mk(Int(ty::IntTy::I8)),
465 i16: mk(Int(ty::IntTy::I16)),
466 i32: mk(Int(ty::IntTy::I32)),
467 i64: mk(Int(ty::IntTy::I64)),
468 i128: mk(Int(ty::IntTy::I128)),
469 usize: mk(Uint(ty::UintTy::Usize)),
470 u8: mk(Uint(ty::UintTy::U8)),
471 u16: mk(Uint(ty::UintTy::U16)),
472 u32: mk(Uint(ty::UintTy::U32)),
473 u64: mk(Uint(ty::UintTy::U64)),
474 u128: mk(Uint(ty::UintTy::U128)),
475 f16: mk(Float(ty::FloatTy::F16)),
476 f32: mk(Float(ty::FloatTy::F32)),
477 f64: mk(Float(ty::FloatTy::F64)),
478 f128: mk(Float(ty::FloatTy::F128)),
479 str_: mk(Str),
480 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
481
482 trait_object_dummy_self: fresh_tys[0],
483
484 ty_vars,
485 fresh_tys,
486 fresh_int_tys,
487 fresh_float_tys,
488 anon_bound_tys,
489 anon_canonical_bound_tys,
490 }
491 }
492}
493
494impl<'tcx> CommonLifetimes<'tcx> {
495 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
496 let mk = |r| {
497 Region(Interned::new_unchecked(
498 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
499 ))
500 };
501
502 let re_vars =
503 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
504
505 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
506 .map(|i| {
507 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
508 .map(|v| {
509 mk(ty::ReBound(
510 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
511 ty::BoundRegion {
512 var: ty::BoundVar::from(v),
513 kind: ty::BoundRegionKind::Anon,
514 },
515 ))
516 })
517 .collect()
518 })
519 .collect();
520
521 let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
522 .map(|v| {
523 mk(ty::ReBound(
524 ty::BoundVarIndexKind::Canonical,
525 ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
526 ))
527 })
528 .collect();
529
530 CommonLifetimes {
531 re_static: mk(ty::ReStatic),
532 re_erased: mk(ty::ReErased),
533 re_vars,
534 anon_re_bounds,
535 anon_re_canonical_bounds,
536 }
537 }
538}
539
540impl<'tcx> CommonConsts<'tcx> {
541 fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
542 let mk_const = |c| interners.intern_const(c);
543
544 let mk_valtree = |v| {
545 ty::ValTree(Interned::new_unchecked(
546 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
547 ))
548 };
549
550 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
551 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
552 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
553
554 CommonConsts {
555 unit: mk_const(ty::ConstKind::Value(ty::Value {
556 ty: types.unit,
557 valtree: valtree_zst,
558 })),
559 true_: mk_const(ty::ConstKind::Value(ty::Value {
560 ty: types.bool,
561 valtree: valtree_true,
562 })),
563 false_: mk_const(ty::ConstKind::Value(ty::Value {
564 ty: types.bool,
565 valtree: valtree_false,
566 })),
567 valtree_zst,
568 }
569 }
570}
571
572#[derive(#[automatically_derived]
impl ::core::fmt::Debug for FreeRegionInfo {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"FreeRegionInfo", "scope", &self.scope, "region_def_id",
&self.region_def_id, "is_impl_item", &&self.is_impl_item)
}
}Debug)]
575pub struct FreeRegionInfo {
576 pub scope: LocalDefId,
578 pub region_def_id: DefId,
580 pub is_impl_item: bool,
582}
583
584#[derive(#[automatically_derived]
impl<'tcx, KEY: ::core::marker::Copy + Copy> ::core::marker::Copy for
TyCtxtFeed<'tcx, KEY> {
}Copy, #[automatically_derived]
impl<'tcx, KEY: ::core::clone::Clone + Copy> ::core::clone::Clone for
TyCtxtFeed<'tcx, KEY> {
#[inline]
fn clone(&self) -> TyCtxtFeed<'tcx, KEY> {
TyCtxtFeed {
tcx: ::core::clone::Clone::clone(&self.tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
586pub struct TyCtxtFeed<'tcx, KEY: Copy> {
587 pub tcx: TyCtxt<'tcx>,
588 key: KEY,
590}
591
592impl<KEY: Copy, Hcx> !HashStable<Hcx> for TyCtxtFeed<'_, KEY> {}
595
596#[derive(#[automatically_derived]
impl<'tcx, KEY: ::core::marker::Copy + Copy> ::core::marker::Copy for
Feed<'tcx, KEY> {
}Copy, #[automatically_derived]
impl<'tcx, KEY: ::core::clone::Clone + Copy> ::core::clone::Clone for
Feed<'tcx, KEY> {
#[inline]
fn clone(&self) -> Feed<'tcx, KEY> {
Feed {
_tcx: ::core::clone::Clone::clone(&self._tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
601pub struct Feed<'tcx, KEY: Copy> {
602 _tcx: PhantomData<TyCtxt<'tcx>>,
603 key: KEY,
605}
606
607impl<KEY: Copy, Hcx> !HashStable<Hcx> for Feed<'_, KEY> {}
610
611impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
612 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
613 self.key.fmt(f)
614 }
615}
616
617impl<'tcx> TyCtxt<'tcx> {
622 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
625 self.dep_graph.assert_ignored();
626 TyCtxtFeed { tcx: self, key: () }
627 }
628
629 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
632 let key = self.untracked().source_span.push(span);
633 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);
634 TyCtxtFeed { tcx: self, key }
635 }
636
637 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
641 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);
642 TyCtxtFeed { tcx: self, key }.type_of(value)
643 }
644
645 pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) {
647 self.dep_graph.assert_ignored();
648 TyCtxtFeed { tcx: self, key }.delayed_owner(owner);
649 }
650
651 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
659 if truecfg!(debug_assertions) {
660 match self.def_kind(self.local_parent(key)) {
661 DefKind::Impl { of_trait: true } => {}
662 other => crate::util::bug::bug_fmt(format_args!("{0:?} is not an assoc item of a trait impl: {1:?}",
key, other))bug!("{key:?} is not an assoc item of a trait impl: {other:?}"),
663 }
664 }
665 TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id())
666 }
667}
668
669impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
670 #[inline(always)]
671 pub fn key(&self) -> KEY {
672 self.key
673 }
674
675 #[inline(always)]
676 pub fn downgrade(self) -> Feed<'tcx, KEY> {
677 Feed { _tcx: PhantomData, key: self.key }
678 }
679}
680
681impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
682 #[inline(always)]
683 pub fn key(&self) -> KEY {
684 self.key
685 }
686
687 #[inline(always)]
688 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
689 TyCtxtFeed { tcx, key: self.key }
690 }
691}
692
693impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
694 #[inline(always)]
695 pub fn def_id(&self) -> LocalDefId {
696 self.key
697 }
698
699 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
701 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
702 }
703
704 pub fn feed_hir(&self) {
706 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
707
708 let node = hir::OwnerNode::Synthetic;
709 let bodies = Default::default();
710 let attrs = hir::AttributeMap::EMPTY;
711
712 let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
713 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque);
714 let node = node.into();
715 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
716 opt_hash_including_bodies,
717 nodes: IndexVec::from_elem_n(
718 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
719 1,
720 ),
721 bodies,
722 })));
723 self.feed_owner_id().hir_attr_map(attrs);
724 }
725}
726
727#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for TyCtxt<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for TyCtxt<'tcx> {
#[inline]
fn clone(&self) -> TyCtxt<'tcx> {
let _: ::core::clone::AssertParamIsClone<&'tcx GlobalCtxt<'tcx>>;
*self
}
}Clone)]
745#[rustc_diagnostic_item = "TyCtxt"]
746#[rustc_pass_by_value]
747pub struct TyCtxt<'tcx> {
748 gcx: &'tcx GlobalCtxt<'tcx>,
749}
750
751unsafe impl DynSend for TyCtxt<'_> {}
755unsafe impl DynSync for TyCtxt<'_> {}
756fn _assert_tcx_fields() {
757 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
758 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
759}
760
761impl<'tcx> Deref for TyCtxt<'tcx> {
762 type Target = &'tcx GlobalCtxt<'tcx>;
763 #[inline(always)]
764 fn deref(&self) -> &Self::Target {
765 &self.gcx
766 }
767}
768
769pub struct GlobalCtxt<'tcx> {
771 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
772 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
773
774 interners: CtxtInterners<'tcx>,
775
776 pub sess: &'tcx Session,
777 crate_types: Vec<CrateType>,
778 stable_crate_id: StableCrateId,
784
785 pub dep_graph: DepGraph,
786
787 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 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
806
807 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
809
810 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
813
814 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
818
819 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
821 pub new_solver_canonical_param_env_cache:
822 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
823
824 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
825
826 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
828 pub clauses_cache:
830 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
831
832 pub data_layout: TargetDataLayout,
834
835 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
837
838 current_gcx: CurrentGcx,
839
840 pub jobserver_proxy: Arc<Proxy>,
842}
843
844impl<'tcx> GlobalCtxt<'tcx> {
845 pub fn enter<F, R>(&'tcx self, f: F) -> R
848 where
849 F: FnOnce(TyCtxt<'tcx>) -> R,
850 {
851 let icx = tls::ImplicitCtxt::new(self);
852
853 let _on_drop = defer(move || {
855 *self.current_gcx.value.write() = None;
856 });
857
858 {
860 let mut guard = self.current_gcx.value.write();
861 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
862 *guard = Some(self as *const _ as *const ());
863 }
864
865 tls::enter_context(&icx, || f(icx.tcx))
866 }
867}
868
869#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
876pub struct CurrentGcx {
877 value: Arc<RwLock<Option<*const ()>>>,
880}
881
882unsafe impl DynSend for CurrentGcx {}
883unsafe impl DynSync for CurrentGcx {}
884
885impl CurrentGcx {
886 pub fn new() -> Self {
887 Self { value: Arc::new(RwLock::new(None)) }
888 }
889
890 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
891 let read_guard = self.value.read();
892 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
893 f(unsafe { &*gcx })
897 }
898}
899
900impl<'tcx> TyCtxt<'tcx> {
901 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
902 let root = self.typeck_root_def_id_local(def_id);
905 self.hir_node_by_def_id(root).body_id().is_some()
906 }
907
908 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
913 let def_kind = self.def_kind(def_id);
914 if def_kind.has_codegen_attrs() {
915 self.codegen_fn_attrs(def_id)
916 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
DefKind::InlineConst | DefKind::GlobalAsm => true,
_ => false,
}matches!(
917 def_kind,
918 DefKind::AnonConst
919 | DefKind::AssocConst { .. }
920 | DefKind::Const { .. }
921 | DefKind::InlineConst
922 | DefKind::GlobalAsm
923 ) {
924 CodegenFnAttrs::EMPTY
925 } else {
926 crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind))bug!(
927 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
928 def_id,
929 def_kind
930 )
931 }
932 }
933
934 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
935 self.arena.alloc(Steal::new(thir))
936 }
937
938 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
939 self.arena.alloc(Steal::new(mir))
940 }
941
942 pub fn alloc_steal_promoted(
943 self,
944 promoted: IndexVec<Promoted, Body<'tcx>>,
945 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
946 self.arena.alloc(Steal::new(promoted))
947 }
948
949 pub fn mk_adt_def(
950 self,
951 did: DefId,
952 kind: AdtKind,
953 variants: IndexVec<VariantIdx, ty::VariantDef>,
954 repr: ReprOptions,
955 ) -> ty::AdtDef<'tcx> {
956 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
957 }
958
959 pub fn allocate_bytes_dedup<'a>(
962 self,
963 bytes: impl Into<Cow<'a, [u8]>>,
964 salt: usize,
965 ) -> interpret::AllocId {
966 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
968 let alloc = self.mk_const_alloc(alloc);
969 self.reserve_and_set_memory_dedup(alloc, salt)
970 }
971
972 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
974 if self.sess.opts.unstable_opts.experimental_default_bounds {
975 &[
976 LangItem::DefaultTrait1,
977 LangItem::DefaultTrait2,
978 LangItem::DefaultTrait3,
979 LangItem::DefaultTrait4,
980 ]
981 } else {
982 &[]
983 }
984 }
985
986 pub fn is_default_trait(self, def_id: DefId) -> bool {
987 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
988 }
989
990 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
991 #[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))
992 }
993
994 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
998 let start = {
{
'done:
{
for i in ::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcLayoutScalarValidRangeStart(n,
_)) => {
break 'done Some(Bound::Included(**n));
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}find_attr!(self, def_id, RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded);
999 let end =
1000 {
{
'done:
{
for i in ::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcLayoutScalarValidRangeEnd(n,
_)) => {
break 'done Some(Bound::Included(**n));
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}find_attr!(self, def_id, RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n))
1001 .unwrap_or(Bound::Unbounded);
1002 (start, end)
1003 }
1004
1005 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1006 value.lift_to_interner(self)
1007 }
1008
1009 pub fn create_global_ctxt<T>(
1016 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1017 s: &'tcx Session,
1018 crate_types: Vec<CrateType>,
1019 stable_crate_id: StableCrateId,
1020 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1021 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1022 untracked: Untracked,
1023 dep_graph: DepGraph,
1024 dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
1025 query_system: QuerySystem<'tcx>,
1026 hooks: crate::hooks::Providers,
1027 current_gcx: CurrentGcx,
1028 jobserver_proxy: Arc<Proxy>,
1029 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1030 ) -> T {
1031 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1032 s.dcx().emit_fatal(err);
1033 });
1034 let interners = CtxtInterners::new(arena);
1035 let common_types = CommonTypes::new(&interners);
1036 let common_lifetimes = CommonLifetimes::new(&interners);
1037 let common_consts = CommonConsts::new(&interners, &common_types);
1038
1039 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1040 sess: s,
1041 crate_types,
1042 stable_crate_id,
1043 arena,
1044 hir_arena,
1045 interners,
1046 dep_graph,
1047 hooks,
1048 prof: s.prof.clone(),
1049 types: common_types,
1050 lifetimes: common_lifetimes,
1051 consts: common_consts,
1052 untracked,
1053 query_system,
1054 dep_kind_vtables,
1055 ty_rcache: Default::default(),
1056 selection_cache: Default::default(),
1057 evaluation_cache: Default::default(),
1058 new_solver_evaluation_cache: Default::default(),
1059 new_solver_canonical_param_env_cache: Default::default(),
1060 canonical_param_env_cache: Default::default(),
1061 highest_var_in_clauses_cache: Default::default(),
1062 clauses_cache: Default::default(),
1063 data_layout,
1064 alloc_map: interpret::AllocMap::new(),
1065 current_gcx,
1066 jobserver_proxy,
1067 });
1068
1069 gcx.enter(f)
1071 }
1072
1073 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1075 self.get_lang_items(())
1076 }
1077
1078 #[track_caller]
1080 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1081 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1082 self.type_of(ordering_enum).no_bound_vars().unwrap()
1083 }
1084
1085 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1088 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1089 }
1090
1091 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1093 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1094 }
1095
1096 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1098 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1099 }
1100
1101 pub fn is_coroutine(self, def_id: DefId) -> bool {
1102 self.coroutine_kind(def_id).is_some()
1103 }
1104
1105 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1106 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1107 }
1108
1109 pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1110 if !self.is_type_const(def_id) {
1111 return None;
1112 }
1113 Some(self.def_span(def_id))
1114 }
1115
1116 pub fn is_type_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1118 let def_id = def_id.into_query_key();
1119 match self.def_kind(def_id) {
1120 DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1121 is_type_const
1122 }
1123 _ => false,
1124 }
1125 }
1126
1127 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1130 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1131 }
1132
1133 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1135 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1136 self.coroutine_kind(def_id),
1137 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1138 )
1139 }
1140
1141 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1144 #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id.into()) {
DefKind::SyntheticCoroutineBody => true,
_ => false,
}matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
1145 }
1146
1147 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1150 #[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(_)))
1151 }
1152
1153 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1155 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1156 self.coroutine_kind(def_id),
1157 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1158 )
1159 }
1160
1161 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1163 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1164 self.coroutine_kind(def_id),
1165 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1166 )
1167 }
1168
1169 pub fn features(self) -> &'tcx rustc_feature::Features {
1170 self.features_query(())
1171 }
1172
1173 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1174 let id = id.into_query_key();
1175 if let Some(id) = id.as_local() {
1177 self.definitions_untracked().def_key(id)
1178 } else {
1179 self.cstore_untracked().def_key(id)
1180 }
1181 }
1182
1183 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1189 if let Some(id) = id.as_local() {
1191 self.definitions_untracked().def_path(id)
1192 } else {
1193 self.cstore_untracked().def_path(id)
1194 }
1195 }
1196
1197 #[inline]
1198 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1199 if let Some(def_id) = def_id.as_local() {
1201 self.definitions_untracked().def_path_hash(def_id)
1202 } else {
1203 self.cstore_untracked().def_path_hash(def_id)
1204 }
1205 }
1206
1207 #[inline]
1208 pub fn crate_types(self) -> &'tcx [CrateType] {
1209 &self.crate_types
1210 }
1211
1212 pub fn needs_metadata(self) -> bool {
1213 self.crate_types().iter().any(|ty| match *ty {
1214 CrateType::Executable
1215 | CrateType::StaticLib
1216 | CrateType::Cdylib
1217 | CrateType::Sdylib => false,
1218 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1219 })
1220 }
1221
1222 pub fn needs_crate_hash(self) -> bool {
1223 truecfg!(debug_assertions)
1235 || self.sess.opts.incremental.is_some()
1236 || self.needs_metadata()
1237 || self.sess.instrument_coverage()
1238 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1239 }
1240
1241 #[inline]
1242 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1243 if crate_num == LOCAL_CRATE {
1244 self.stable_crate_id
1245 } else {
1246 self.cstore_untracked().stable_crate_id(crate_num)
1247 }
1248 }
1249
1250 #[inline]
1253 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1254 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1255 LOCAL_CRATE
1256 } else {
1257 *self
1258 .untracked()
1259 .stable_crate_ids
1260 .read()
1261 .get(&stable_crate_id)
1262 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1263 }
1264 }
1265
1266 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1270 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/context.rs:1270",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(1270u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("def_path_hash_to_def_id({0:?})",
hash) as &dyn Value))])
});
} else { ; }
};debug!("def_path_hash_to_def_id({:?})", hash);
1271
1272 let stable_crate_id = hash.stable_crate_id();
1273
1274 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1277 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1278 } else {
1279 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1280 }
1281 }
1282
1283 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1284 let (crate_name, stable_crate_id) = if def_id.is_local() {
1289 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1290 } else {
1291 let cstore = &*self.cstore_untracked();
1292 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1293 };
1294
1295 ::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!(
1296 "{}[{:04x}]{}",
1297 crate_name,
1298 stable_crate_id.as_u64() >> (8 * 6),
1301 self.def_path(def_id).to_string_no_crate_verbose()
1302 )
1303 }
1304
1305 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1306 self.sess.dcx()
1307 }
1308
1309 pub fn is_target_feature_call_safe(
1312 self,
1313 callee_features: &[TargetFeature],
1314 body_features: &[TargetFeature],
1315 ) -> bool {
1316 self.sess.target.options.is_like_wasm
1321 || callee_features
1322 .iter()
1323 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1324 }
1325
1326 pub fn adjust_target_feature_sig(
1329 self,
1330 fun_def: DefId,
1331 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1332 caller: DefId,
1333 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1334 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1335 let caller_features = &self.body_codegen_attrs(caller).target_features;
1336 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1337 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1338 fn_sig_kind: fun_sig.fn_sig_kind().set_safe(true),
1339 ..sig
1340 }));
1341 }
1342 None
1343 }
1344
1345 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1348 match self.env_var_os(key.as_ref()) {
1349 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1350 None => Err(VarError::NotPresent),
1351 }
1352 }
1353}
1354
1355impl<'tcx> TyCtxtAt<'tcx> {
1356 pub fn create_def(
1358 self,
1359 parent: LocalDefId,
1360 name: Option<Symbol>,
1361 def_kind: DefKind,
1362 override_def_path_data: Option<DefPathData>,
1363 disambiguator: &mut PerParentDisambiguatorState,
1364 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1365 let feed =
1366 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1367
1368 feed.def_span(self.span);
1369 feed
1370 }
1371}
1372
1373impl<'tcx> TyCtxt<'tcx> {
1374 pub fn create_def(
1376 self,
1377 parent: LocalDefId,
1378 name: Option<Symbol>,
1379 def_kind: DefKind,
1380 override_def_path_data: Option<DefPathData>,
1381 disambiguator: &mut PerParentDisambiguatorState,
1382 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1383 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1384 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1394
1395 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1400
1401 let feed = TyCtxtFeed { tcx: self, key: def_id };
1402 feed.def_kind(def_kind);
1403 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1408 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1409 feed.visibility(ty::Visibility::Restricted(parent_mod));
1410 }
1411
1412 feed
1413 }
1414
1415 pub fn create_crate_num(
1416 self,
1417 stable_crate_id: StableCrateId,
1418 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1419 let mut lock = self.untracked().stable_crate_ids.write();
1420 if let Some(&existing) = lock.get(&stable_crate_id) {
1421 return Err(existing);
1422 }
1423 let num = CrateNum::new(lock.len());
1424 lock.insert(stable_crate_id, num);
1425 Ok(TyCtxtFeed { key: num, tcx: self })
1426 }
1427
1428 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1429 self.ensure_ok().analysis(());
1431
1432 let definitions = &self.untracked.definitions;
1433 gen {
1434 let mut i = 0;
1435
1436 while i < { definitions.read().num_definitions() } {
1439 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1440 yield LocalDefId { local_def_index };
1441 i += 1;
1442 }
1443
1444 definitions.freeze();
1446 }
1447 }
1448
1449 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1450 self.ensure_ok().analysis(());
1452
1453 self.untracked.definitions.freeze().def_path_table()
1456 }
1457
1458 pub fn def_path_hash_to_def_index_map(
1459 self,
1460 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1461 self.ensure_ok().hir_crate_items(());
1464 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1467 }
1468
1469 #[inline]
1472 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1473 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1474 }
1475
1476 pub fn untracked(self) -> &'tcx Untracked {
1478 &self.untracked
1479 }
1480 #[inline]
1483 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1484 self.untracked.definitions.read()
1485 }
1486
1487 #[inline]
1490 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1491 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1492 }
1493
1494 #[inline(always)]
1495 pub fn with_stable_hashing_context<R>(
1496 self,
1497 f: impl FnOnce(StableHashingContext<'_>) -> R,
1498 ) -> R {
1499 f(StableHashingContext::new(self.sess, &self.untracked))
1500 }
1501
1502 #[inline]
1503 pub fn local_crate_exports_generics(self) -> bool {
1504 if self.is_compiler_builtins(LOCAL_CRATE) {
1508 return false;
1509 }
1510 self.crate_types().iter().any(|crate_type| {
1511 match crate_type {
1512 CrateType::Executable
1513 | CrateType::StaticLib
1514 | CrateType::ProcMacro
1515 | CrateType::Cdylib
1516 | CrateType::Sdylib => false,
1517
1518 CrateType::Dylib => true,
1523
1524 CrateType::Rlib => true,
1525 }
1526 })
1527 }
1528
1529 pub fn is_suitable_region(
1531 self,
1532 generic_param_scope: LocalDefId,
1533 mut region: Region<'tcx>,
1534 ) -> Option<FreeRegionInfo> {
1535 let (suitable_region_binding_scope, region_def_id) = loop {
1536 let def_id =
1537 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1538 let scope = self.local_parent(def_id);
1539 if self.def_kind(scope) == DefKind::OpaqueTy {
1540 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1543 continue;
1544 }
1545 break (scope, def_id.into());
1546 };
1547
1548 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1549 Node::Item(..) | Node::TraitItem(..) => false,
1550 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1551 hir::ImplItemImplKind::Trait { .. } => true,
1558 _ => false,
1559 },
1560 _ => false,
1561 };
1562
1563 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1564 }
1565
1566 pub fn return_type_impl_or_dyn_traits(
1568 self,
1569 scope_def_id: LocalDefId,
1570 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1571 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1572 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1573 self.hir_fn_decl_by_hir_id(hir_id)
1574 else {
1575 return ::alloc::vec::Vec::new()vec![];
1576 };
1577
1578 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1579 v.visit_ty_unambig(hir_output);
1580 v.0
1581 }
1582
1583 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1587 self,
1588 scope_def_id: LocalDefId,
1589 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1590 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1591 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1592 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1594 && let hir::TyKind::Path(hir::QPath::Resolved(
1595 None,
1596 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1597 && let Some(local_id) = def_id.as_local()
1598 && 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()
1600 {
1601 v.visit_ty_unambig(alias_ty);
1602 if !v.0.is_empty() {
1603 return Some((
1604 v.0,
1605 alias_generics.span,
1606 alias_generics.span_for_lifetime_suggestion(),
1607 ));
1608 }
1609 }
1610 None
1611 }
1612
1613 pub fn has_strict_asm_symbol_naming(self) -> bool {
1616 self.sess.target.llvm_target.starts_with("nvptx")
1617 }
1618
1619 pub fn caller_location_ty(self) -> Ty<'tcx> {
1621 Ty::new_imm_ref(
1622 self,
1623 self.lifetimes.re_static,
1624 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1625 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1626 .skip_norm_wip(),
1627 )
1628 }
1629
1630 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1632 let kind = self.def_kind(def_id);
1633 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1634 }
1635
1636 pub fn type_length_limit(self) -> Limit {
1637 self.limits(()).type_length_limit
1638 }
1639
1640 pub fn recursion_limit(self) -> Limit {
1641 self.limits(()).recursion_limit
1642 }
1643
1644 pub fn move_size_limit(self) -> Limit {
1645 self.limits(()).move_size_limit
1646 }
1647
1648 pub fn pattern_complexity_limit(self) -> Limit {
1649 self.limits(()).pattern_complexity_limit
1650 }
1651
1652 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1654 iter::once(LOCAL_CRATE)
1655 .chain(self.crates(()).iter().copied())
1656 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1657 }
1658
1659 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1661 let visible_crates =
1662 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1663
1664 iter::once(LOCAL_CRATE)
1665 .chain(visible_crates)
1666 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1667 }
1668
1669 #[inline]
1670 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1671 self.visibility(def_id).expect_local()
1672 }
1673
1674 x;#[instrument(skip(self), level = "trace", ret)]
1676 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1677 self.hir_expect_opaque_ty(def_id).origin
1678 }
1679
1680 pub fn finish(self) {
1681 self.alloc_self_profile_query_strings();
1684
1685 self.save_dep_graph();
1686 self.verify_query_key_hashes();
1687
1688 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1689 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
1690 }
1691 }
1692
1693 pub fn report_unused_features(self) {
1694 #[derive(const _: () =
{
impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for UnusedFeature
where G: rustc_errors::EmissionGuarantee {
#[track_caller]
fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
match self {
UnusedFeature { feature: __binding_0 } => {
let mut diag =
rustc_errors::Diag::new(dcx, level,
rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("feature `{$feature}` is declared but not used")));
;
diag.arg("feature", __binding_0);
diag
}
}
}
}
};Diagnostic)]
1695 #[diag("feature `{$feature}` is declared but not used")]
1696 struct UnusedFeature {
1697 feature: Symbol,
1698 }
1699
1700 let used_features = self.sess.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 rustc_session::lint::builtin::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 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1737 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1742 _x: Interned<'tcx, Inner>,
1743 ) -> InternedSet<'tcx, Inner> {
1744 unreachable!()
1745 }
1746 fn _type_eq<T>(_x: &T, _y: &T) {}
1747 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1748 let interner = _intern_set_ty_from_interned_ty(x.0);
1752 _type_eq(&interner, &tcx.interners.$set);
1754 }
1755
1756 tcx.interners
1757 .$set
1758 .contains_pointer_to(&InternedInSet(&*self.0.0))
1759 .then(|| unsafe { mem::transmute(self) })
1762 }
1763 }
1764 };
1765}
1766
1767macro_rules! nop_list_lift {
1768 ($set:ident; $ty:ty => $lifted:ty) => {
1769 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
1770 type Lifted = &'tcx List<$lifted>;
1771 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1772 if false {
1774 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
1775 }
1776
1777 if self.is_empty() {
1778 return Some(List::empty());
1779 }
1780 tcx.interners
1781 .$set
1782 .contains_pointer_to(&InternedInSet(self))
1783 .then(|| unsafe { mem::transmute(self) })
1784 }
1785 }
1786 };
1787}
1788
1789impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Ty<'a> {
type Lifted = Ty<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Ty<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.type_);
}
tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { type_; Ty<'a> => Ty<'tcx> }
1790impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Region<'a> {
type Lifted = Region<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Region<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.region);
}
tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { region; Region<'a> => Region<'tcx> }
1791impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Const<'a> {
type Lifted = Const<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Const<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_);
}
tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { const_; Const<'a> => Const<'tcx> }
1792impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Pattern<'a> {
type Lifted = Pattern<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Pattern<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.pat);
}
tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
1793impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ConstAllocation<'a> {
type Lifted = ConstAllocation<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ConstAllocation<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_allocation);
}
tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
1794impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Predicate<'a> {
type Lifted = Predicate<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Predicate<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
1795impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Clause<'a> {
type Lifted = Clause<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Clause<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
1796impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Layout<'a> {
type Lifted = Layout<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Layout<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.layout);
}
tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { layout; Layout<'a> => Layout<'tcx> }
1797impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ValTree<'a> {
type Lifted = ValTree<'tcx>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ValTree<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.valtree);
}
tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0)).then(||
unsafe { mem::transmute(self) })
}
}nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
1798
1799impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Ty<'a>> {
type Lifted = &'tcx List<Ty<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<Ty<'tcx>>> =
&tcx.interners.type_lists;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
1800impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<PolyExistentialPredicate<'a>> {
type Lifted = &'tcx List<PolyExistentialPredicate<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>> =
&tcx.interners.poly_existential_predicates;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! {
1801 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1802}
1803impl<'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>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>> =
&tcx.interners.bound_variable_kinds;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind<'a> => ty::BoundVariableKind<'tcx> }
1804
1805impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<GenericArg<'a>> {
type Lifted = &'tcx List<GenericArg<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if false {
let _x: &InternedSet<'tcx, List<GenericArg<'tcx>>> =
&tcx.interners.args;
}
if self.is_empty() { return Some(List::empty()); }
tcx.interners.args.contains_pointer_to(&InternedInSet(self)).then(||
unsafe { mem::transmute(self) })
}
}nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
1807
1808macro_rules! sty_debug_print {
1809 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1810 #[allow(non_snake_case)]
1813 mod inner {
1814 use crate::ty::{self, TyCtxt};
1815 use crate::ty::context::InternedInSet;
1816
1817 #[derive(Copy, Clone)]
1818 struct DebugStat {
1819 total: usize,
1820 lt_infer: usize,
1821 ty_infer: usize,
1822 ct_infer: usize,
1823 all_infer: usize,
1824 }
1825
1826 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1827 let mut total = DebugStat {
1828 total: 0,
1829 lt_infer: 0,
1830 ty_infer: 0,
1831 ct_infer: 0,
1832 all_infer: 0,
1833 };
1834 $(let mut $variant = total;)*
1835
1836 for shard in tcx.interners.type_.lock_shards() {
1837 #[allow(rustc::potential_query_instability)]
1839 let types = shard.iter();
1840 for &(InternedInSet(t), ()) in types {
1841 let variant = match t.internee {
1842 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1843 ty::Float(..) | ty::Str | ty::Never => continue,
1844 ty::Error(_) => continue,
1845 $(ty::$variant(..) => &mut $variant,)*
1846 };
1847 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1848 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1849 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1850
1851 variant.total += 1;
1852 total.total += 1;
1853 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1854 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1855 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1856 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1857 }
1858 }
1859 writeln!(fmt, "Ty interner total ty lt ct all")?;
1860 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1861 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1862 stringify!($variant),
1863 uses = $variant.total,
1864 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1865 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1866 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1867 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1868 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1869 )*
1870 writeln!(fmt, " total {uses:6} \
1871 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1872 uses = total.total,
1873 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1874 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1875 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1876 all = total.all_infer as f64 * 100.0 / total.total as f64)
1877 }
1878 }
1879
1880 inner::go($fmt, $ctxt)
1881 }}
1882}
1883
1884impl<'tcx> TyCtxt<'tcx> {
1885 pub fn debug_stats(self) -> impl fmt::Debug {
1886 fmt::from_fn(move |fmt| {
1887 {
#[allow(non_snake_case)]
mod inner {
use crate::ty::{self, TyCtxt};
use crate::ty::context::InternedInSet;
struct DebugStat {
total: usize,
lt_infer: usize,
ty_infer: usize,
ct_infer: usize,
all_infer: usize,
}
#[automatically_derived]
impl ::core::marker::Copy for DebugStat { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DebugStat { }
#[automatically_derived]
impl ::core::clone::Clone for DebugStat {
#[inline]
fn clone(&self) -> DebugStat {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}
pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>)
-> std::fmt::Result {
let mut total =
DebugStat {
total: 0,
lt_infer: 0,
ty_infer: 0,
ct_infer: 0,
all_infer: 0,
};
let mut Adt = total;
let mut Array = total;
let mut Slice = total;
let mut RawPtr = total;
let mut Ref = total;
let mut FnDef = total;
let mut FnPtr = total;
let mut UnsafeBinder = total;
let mut Placeholder = total;
let mut Coroutine = total;
let mut CoroutineWitness = total;
let mut Dynamic = total;
let mut Closure = total;
let mut CoroutineClosure = total;
let mut Tuple = total;
let mut Bound = total;
let mut Param = total;
let mut Infer = total;
let mut Alias = total;
let mut Pat = total;
let mut Foreign = total;
for shard in tcx.interners.type_.lock_shards() {
#[allow(rustc :: potential_query_instability)]
let types = shard.iter();
for &(InternedInSet(t), ()) in types {
let variant =
match t.internee {
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
ty::Float(..) | ty::Str | ty::Never => continue,
ty::Error(_) => continue,
ty::Adt(..) => &mut Adt,
ty::Array(..) => &mut Array,
ty::Slice(..) => &mut Slice,
ty::RawPtr(..) => &mut RawPtr,
ty::Ref(..) => &mut Ref,
ty::FnDef(..) => &mut FnDef,
ty::FnPtr(..) => &mut FnPtr,
ty::UnsafeBinder(..) => &mut UnsafeBinder,
ty::Placeholder(..) => &mut Placeholder,
ty::Coroutine(..) => &mut Coroutine,
ty::CoroutineWitness(..) => &mut CoroutineWitness,
ty::Dynamic(..) => &mut Dynamic,
ty::Closure(..) => &mut Closure,
ty::CoroutineClosure(..) => &mut CoroutineClosure,
ty::Tuple(..) => &mut Tuple,
ty::Bound(..) => &mut Bound,
ty::Param(..) => &mut Param,
ty::Infer(..) => &mut Infer,
ty::Alias(..) => &mut Alias,
ty::Pat(..) => &mut Pat,
ty::Foreign(..) => &mut Foreign,
};
let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
variant.total += 1;
total.total += 1;
if lt { total.lt_infer += 1; variant.lt_infer += 1 }
if ty { total.ty_infer += 1; variant.ty_infer += 1 }
if ct { total.ct_infer += 1; variant.ct_infer += 1 }
if lt && ty && ct {
total.all_infer += 1;
variant.all_infer += 1
}
}
}
fmt.write_fmt(format_args!("Ty interner total ty lt ct all\n"))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Adt", Adt.total,
Adt.total as f64 * 100.0 / total.total as f64,
Adt.ty_infer as f64 * 100.0 / total.total as f64,
Adt.lt_infer as f64 * 100.0 / total.total as f64,
Adt.ct_infer as f64 * 100.0 / total.total as f64,
Adt.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Array", Array.total,
Array.total as f64 * 100.0 / total.total as f64,
Array.ty_infer as f64 * 100.0 / total.total as f64,
Array.lt_infer as f64 * 100.0 / total.total as f64,
Array.ct_infer as f64 * 100.0 / total.total as f64,
Array.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Slice", Slice.total,
Slice.total as f64 * 100.0 / total.total as f64,
Slice.ty_infer as f64 * 100.0 / total.total as f64,
Slice.lt_infer as f64 * 100.0 / total.total as f64,
Slice.ct_infer as f64 * 100.0 / total.total as f64,
Slice.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"RawPtr", RawPtr.total,
RawPtr.total as f64 * 100.0 / total.total as f64,
RawPtr.ty_infer as f64 * 100.0 / total.total as f64,
RawPtr.lt_infer as f64 * 100.0 / total.total as f64,
RawPtr.ct_infer as f64 * 100.0 / total.total as f64,
RawPtr.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Ref", Ref.total,
Ref.total as f64 * 100.0 / total.total as f64,
Ref.ty_infer as f64 * 100.0 / total.total as f64,
Ref.lt_infer as f64 * 100.0 / total.total as f64,
Ref.ct_infer as f64 * 100.0 / total.total as f64,
Ref.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"FnDef", FnDef.total,
FnDef.total as f64 * 100.0 / total.total as f64,
FnDef.ty_infer as f64 * 100.0 / total.total as f64,
FnDef.lt_infer as f64 * 100.0 / total.total as f64,
FnDef.ct_infer as f64 * 100.0 / total.total as f64,
FnDef.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"FnPtr", FnPtr.total,
FnPtr.total as f64 * 100.0 / total.total as f64,
FnPtr.ty_infer as f64 * 100.0 / total.total as f64,
FnPtr.lt_infer as f64 * 100.0 / total.total as f64,
FnPtr.ct_infer as f64 * 100.0 / total.total as f64,
FnPtr.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"UnsafeBinder", UnsafeBinder.total,
UnsafeBinder.total as f64 * 100.0 / total.total as f64,
UnsafeBinder.ty_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.lt_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.ct_infer as f64 * 100.0 / total.total as f64,
UnsafeBinder.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Placeholder", Placeholder.total,
Placeholder.total as f64 * 100.0 / total.total as f64,
Placeholder.ty_infer as f64 * 100.0 / total.total as f64,
Placeholder.lt_infer as f64 * 100.0 / total.total as f64,
Placeholder.ct_infer as f64 * 100.0 / total.total as f64,
Placeholder.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Coroutine", Coroutine.total,
Coroutine.total as f64 * 100.0 / total.total as f64,
Coroutine.ty_infer as f64 * 100.0 / total.total as f64,
Coroutine.lt_infer as f64 * 100.0 / total.total as f64,
Coroutine.ct_infer as f64 * 100.0 / total.total as f64,
Coroutine.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"CoroutineWitness", CoroutineWitness.total,
CoroutineWitness.total as f64 * 100.0 / total.total as f64,
CoroutineWitness.ty_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.lt_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.ct_infer as f64 * 100.0 /
total.total as f64,
CoroutineWitness.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Dynamic", Dynamic.total,
Dynamic.total as f64 * 100.0 / total.total as f64,
Dynamic.ty_infer as f64 * 100.0 / total.total as f64,
Dynamic.lt_infer as f64 * 100.0 / total.total as f64,
Dynamic.ct_infer as f64 * 100.0 / total.total as f64,
Dynamic.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Closure", Closure.total,
Closure.total as f64 * 100.0 / total.total as f64,
Closure.ty_infer as f64 * 100.0 / total.total as f64,
Closure.lt_infer as f64 * 100.0 / total.total as f64,
Closure.ct_infer as f64 * 100.0 / total.total as f64,
Closure.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"CoroutineClosure", CoroutineClosure.total,
CoroutineClosure.total as f64 * 100.0 / total.total as f64,
CoroutineClosure.ty_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.lt_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.ct_infer as f64 * 100.0 /
total.total as f64,
CoroutineClosure.all_infer as f64 * 100.0 /
total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Tuple", Tuple.total,
Tuple.total as f64 * 100.0 / total.total as f64,
Tuple.ty_infer as f64 * 100.0 / total.total as f64,
Tuple.lt_infer as f64 * 100.0 / total.total as f64,
Tuple.ct_infer as f64 * 100.0 / total.total as f64,
Tuple.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Bound", Bound.total,
Bound.total as f64 * 100.0 / total.total as f64,
Bound.ty_infer as f64 * 100.0 / total.total as f64,
Bound.lt_infer as f64 * 100.0 / total.total as f64,
Bound.ct_infer as f64 * 100.0 / total.total as f64,
Bound.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Param", Param.total,
Param.total as f64 * 100.0 / total.total as f64,
Param.ty_infer as f64 * 100.0 / total.total as f64,
Param.lt_infer as f64 * 100.0 / total.total as f64,
Param.ct_infer as f64 * 100.0 / total.total as f64,
Param.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Infer", Infer.total,
Infer.total as f64 * 100.0 / total.total as f64,
Infer.ty_infer as f64 * 100.0 / total.total as f64,
Infer.lt_infer as f64 * 100.0 / total.total as f64,
Infer.ct_infer as f64 * 100.0 / total.total as f64,
Infer.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Alias", Alias.total,
Alias.total as f64 * 100.0 / total.total as f64,
Alias.ty_infer as f64 * 100.0 / total.total as f64,
Alias.lt_infer as f64 * 100.0 / total.total as f64,
Alias.ct_infer as f64 * 100.0 / total.total as f64,
Alias.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Pat", Pat.total,
Pat.total as f64 * 100.0 / total.total as f64,
Pat.ty_infer as f64 * 100.0 / total.total as f64,
Pat.lt_infer as f64 * 100.0 / total.total as f64,
Pat.ct_infer as f64 * 100.0 / total.total as f64,
Pat.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" {0:18}: {1:6} {2:4.1}%, {3:4.1}% {4:5.1}% {5:4.1}% {6:4.1}%\n",
"Foreign", Foreign.total,
Foreign.total as f64 * 100.0 / total.total as f64,
Foreign.ty_infer as f64 * 100.0 / total.total as f64,
Foreign.lt_infer as f64 * 100.0 / total.total as f64,
Foreign.ct_infer as f64 * 100.0 / total.total as f64,
Foreign.all_infer as f64 * 100.0 / total.total as f64))?;
fmt.write_fmt(format_args!(" total {0:6} {1:4.1}% {2:5.1}% {3:4.1}% {4:4.1}%\n",
total.total,
total.ty_infer as f64 * 100.0 / total.total as f64,
total.lt_infer as f64 * 100.0 / total.total as f64,
total.ct_infer as f64 * 100.0 / total.total as f64,
total.all_infer as f64 * 100.0 / total.total as f64))
}
}
inner::go(fmt, self)
}sty_debug_print!(
1888 fmt,
1889 self,
1890 Adt,
1891 Array,
1892 Slice,
1893 RawPtr,
1894 Ref,
1895 FnDef,
1896 FnPtr,
1897 UnsafeBinder,
1898 Placeholder,
1899 Coroutine,
1900 CoroutineWitness,
1901 Dynamic,
1902 Closure,
1903 CoroutineClosure,
1904 Tuple,
1905 Bound,
1906 Param,
1907 Infer,
1908 Alias,
1909 Pat,
1910 Foreign
1911 )?;
1912
1913 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1914 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1915 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())?;
1916 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1917
1918 Ok(())
1919 })
1920 }
1921}
1922
1923struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1928
1929impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1930 fn clone(&self) -> Self {
1931 *self
1932 }
1933}
1934
1935impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1936
1937impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1938 fn into_pointer(&self) -> *const () {
1939 self.0 as *const _ as *const ()
1940 }
1941}
1942
1943#[allow(rustc::usage_of_ty_tykind)]
1944impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1945 fn borrow(&self) -> &T {
1946 &self.0.internee
1947 }
1948}
1949
1950impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1951 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1952 self.0.internee == other.0.internee
1955 }
1956}
1957
1958impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1959
1960impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1961 fn hash<H: Hasher>(&self, s: &mut H) {
1962 self.0.internee.hash(s)
1964 }
1965}
1966
1967impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1968 fn borrow(&self) -> &[T] {
1969 &self.0[..]
1970 }
1971}
1972
1973impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1974 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1975 self.0[..] == other.0[..]
1978 }
1979}
1980
1981impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1982
1983impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1984 fn hash<H: Hasher>(&self, s: &mut H) {
1985 self.0[..].hash(s)
1987 }
1988}
1989
1990impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1991 fn borrow(&self) -> &[T] {
1992 &self.0[..]
1993 }
1994}
1995
1996impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1997 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1998 self.0[..] == other.0[..]
2001 }
2002}
2003
2004impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2005
2006impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2007 fn hash<H: Hasher>(&self, s: &mut H) {
2008 self.0[..].hash(s)
2010 }
2011}
2012
2013macro_rules! direct_interners {
2014 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2015 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2016 fn borrow<'a>(&'a self) -> &'a $ty {
2017 &self.0
2018 }
2019 }
2020
2021 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2022 fn eq(&self, other: &Self) -> bool {
2023 self.0 == other.0
2026 }
2027 }
2028
2029 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2030
2031 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2032 fn hash<H: Hasher>(&self, s: &mut H) {
2033 self.0.hash(s)
2036 }
2037 }
2038
2039 impl<'tcx> TyCtxt<'tcx> {
2040 $vis fn $method(self, v: $ty) -> $ret_ty {
2041 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2042 InternedInSet(self.interners.arena.alloc(v))
2043 }).0))
2044 }
2045 })+
2046 }
2047}
2048
2049impl<'tcx> Borrow<ExternalConstraintsData<TyCtxt<'tcx>>> for
InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a ExternalConstraintsData<TyCtxt<'tcx>> {
&self.0
}
}
impl<'tcx> PartialEq for
InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>> {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl<'tcx> Eq for InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>
{}
impl<'tcx> Hash for InternedInSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>
{
fn hash<H: Hasher>(&self, s: &mut H) { self.0.hash(s) }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn mk_external_constraints(self,
v: ExternalConstraintsData<TyCtxt<'tcx>>)
-> ExternalConstraints<'tcx> {
ExternalConstraints(Interned::new_unchecked(self.interners.external_constraints.intern(v,
|v| { InternedInSet(self.interners.arena.alloc(v)) }).0))
}
}direct_interners! {
2053 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2054 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2055 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2056 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2057 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2058 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2059 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2060 ExternalConstraints -> ExternalConstraints<'tcx>,
2061}
2062
2063macro_rules! slice_interners {
2064 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2065 impl<'tcx> TyCtxt<'tcx> {
2066 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2067 if v.is_empty() {
2068 List::empty()
2069 } else {
2070 self.interners.$field.intern_ref(v, || {
2071 InternedInSet(List::from_arena(&*self.arena, (), v))
2072 }).0
2073 }
2074 })+
2075 }
2076 );
2077}
2078
2079impl<'tcx> TyCtxt<'tcx> {
pub fn mk_const_list(self, v: &[Const<'tcx>]) -> &'tcx List<Const<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.const_lists.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_args(self, v: &[GenericArg<'tcx>])
-> &'tcx List<GenericArg<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.args.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.type_lists.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_canonical_var_kinds(self, v: &[CanonicalVarKind<'tcx>])
-> &'tcx List<CanonicalVarKind<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.canonical_var_kinds.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_poly_existential_predicates(self,
v: &[PolyExistentialPredicate<'tcx>])
-> &'tcx List<PolyExistentialPredicate<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.poly_existential_predicates.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_projs(self, v: &[ProjectionKind])
-> &'tcx List<ProjectionKind> {
if v.is_empty() {
List::empty()
} else {
self.interners.projs.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_place_elems(self, v: &[PlaceElem<'tcx>])
-> &'tcx List<PlaceElem<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.place_elems.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_bound_variable_kinds(self, v: &[ty::BoundVariableKind<'tcx>])
-> &'tcx List<ty::BoundVariableKind<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.bound_variable_kinds.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_fields(self, v: &[FieldIdx]) -> &'tcx List<FieldIdx> {
if v.is_empty() {
List::empty()
} else {
self.interners.fields.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_local_def_ids(self, v: &[LocalDefId])
-> &'tcx List<LocalDefId> {
if v.is_empty() {
List::empty()
} else {
self.interners.local_def_ids.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
fn intern_captures(self, v: &[&'tcx ty::CapturedPlace<'tcx>])
-> &'tcx List<&'tcx ty::CapturedPlace<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.captures.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_patterns(self, v: &[Pattern<'tcx>])
-> &'tcx List<Pattern<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.patterns.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_outlives(self, v: &[ty::ArgOutlivesPredicate<'tcx>])
-> &'tcx List<ty::ArgOutlivesPredicate<'tcx>> {
if v.is_empty() {
List::empty()
} else {
self.interners.outlives.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
pub fn mk_predefined_opaques_in_body(self,
v: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)])
-> &'tcx List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
if v.is_empty() {
List::empty()
} else {
self.interners.predefined_opaques_in_body.intern_ref(v,
||
{ InternedInSet(List::from_arena(&*self.arena, (), v)) }).0
}
}
}slice_interners!(
2083 const_lists: pub mk_const_list(Const<'tcx>),
2084 args: pub mk_args(GenericArg<'tcx>),
2085 type_lists: pub mk_type_list(Ty<'tcx>),
2086 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2087 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2088 projs: pub mk_projs(ProjectionKind),
2089 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2090 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2091 fields: pub mk_fields(FieldIdx),
2092 local_def_ids: intern_local_def_ids(LocalDefId),
2093 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2094 patterns: pub mk_patterns(Pattern<'tcx>),
2095 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2096 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2097);
2098
2099impl<'tcx> TyCtxt<'tcx> {
2100 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2104 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2105 Ty::new_fn_ptr(
2106 self,
2107 sig.map_bound(|sig| ty::FnSig { fn_sig_kind: sig.fn_sig_kind.set_safe(false), ..sig }),
2108 )
2109 }
2110
2111 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2115 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2116 sig.map_bound(|sig| ty::FnSig { fn_sig_kind: sig.fn_sig_kind.set_safe(false), ..sig })
2117 }
2118
2119 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2122 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2123 self.associated_items(trait_did)
2124 .filter_by_name_unhygienic(assoc_name.name)
2125 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2126 })
2127 }
2128
2129 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2131 let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2132 return false;
2133 };
2134 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2135
2136 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2137 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2138 return false;
2139 };
2140 trait_predicate.trait_ref.def_id == future_trait
2141 && trait_predicate.polarity == PredicatePolarity::Positive
2142 })
2143 }
2144
2145 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2153 sig.map_bound(|s| {
2154 let params = match s.inputs()[0].kind() {
2155 ty::Tuple(params) => *params,
2156 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2157 };
2158 self.mk_fn_sig(
2159 params,
2160 s.output(),
2161 s.fn_sig_kind.set_safe(safety.is_safe()).set_abi(ExternAbi::Rust),
2162 )
2163 })
2164 }
2165
2166 #[inline]
2167 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2168 self.interners.intern_predicate(binder)
2169 }
2170
2171 #[inline]
2172 pub fn reuse_or_mk_predicate(
2173 self,
2174 pred: Predicate<'tcx>,
2175 binder: Binder<'tcx, PredicateKind<'tcx>>,
2176 ) -> Predicate<'tcx> {
2177 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2178 }
2179
2180 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2181 self.check_args_compatible_inner(def_id, args, false)
2182 }
2183
2184 fn check_args_compatible_inner(
2185 self,
2186 def_id: DefId,
2187 args: &'tcx [ty::GenericArg<'tcx>],
2188 nested: bool,
2189 ) -> bool {
2190 let generics = self.generics_of(def_id);
2191
2192 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)
2196 && #[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 });
2197 let is_inherent_assoc_type_const =
2198 #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocConst { is_type_const: true } => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocConst { is_type_const: true })
2199 && #[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 });
2200 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2201 if generics.own_params.len() + 1 != args.len() {
2202 return false;
2203 }
2204
2205 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2206 return false;
2207 }
2208
2209 &args[1..]
2210 } else {
2211 if generics.count() != args.len() {
2212 return false;
2213 }
2214
2215 let (parent_args, own_args) = args.split_at(generics.parent_count);
2216
2217 if let Some(parent) = generics.parent
2218 && !self.check_args_compatible_inner(parent, parent_args, true)
2219 {
2220 return false;
2221 }
2222
2223 own_args
2224 };
2225
2226 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2227 match (¶m.kind, arg.kind()) {
2228 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2229 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2230 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2231 _ => return false,
2232 }
2233 }
2234
2235 true
2236 }
2237
2238 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2241 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2242 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)
2243 && #[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 });
2244 let is_inherent_assoc_type_const =
2245 #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(def_id) {
DefKind::AssocConst { is_type_const: true } => true,
_ => false,
}matches!(self.def_kind(def_id), DefKind::AssocConst { is_type_const: true })
2246 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(
2247 self.def_kind(self.parent(def_id)),
2248 DefKind::Impl { of_trait: false }
2249 );
2250 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2251 crate::util::bug::bug_fmt(format_args!("args not compatible with generics for {0}: args={1:#?}, generics={2:#?}",
self.def_path_str(def_id), args,
self.mk_args_from_iter([self.types.self_param.into()].into_iter().chain(self.generics_of(def_id).own_args(ty::GenericArgs::identity_for_item(self,
def_id)).iter().copied()))));bug!(
2252 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2253 self.def_path_str(def_id),
2254 args,
2255 self.mk_args_from_iter(
2257 [self.types.self_param.into()].into_iter().chain(
2258 self.generics_of(def_id)
2259 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2260 .iter()
2261 .copied()
2262 )
2263 )
2264 );
2265 } else {
2266 crate::util::bug::bug_fmt(format_args!("args not compatible with generics for {0}: args={1:#?}, generics={2:#?}",
self.def_path_str(def_id), args,
ty::GenericArgs::identity_for_item(self, def_id)));bug!(
2267 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2268 self.def_path_str(def_id),
2269 args,
2270 ty::GenericArgs::identity_for_item(self, def_id)
2271 );
2272 }
2273 }
2274 }
2275
2276 #[inline(always)]
2277 pub(crate) fn check_and_mk_args(
2278 self,
2279 def_id: DefId,
2280 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2281 ) -> GenericArgsRef<'tcx> {
2282 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2283 self.debug_assert_args_compatible(def_id, args);
2284 args
2285 }
2286
2287 #[inline]
2288 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2289 self.interners.intern_const(kind)
2290 }
2291
2292 #[allow(rustc::usage_of_ty_tykind)]
2294 #[inline]
2295 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2296 self.interners.intern_ty(st)
2297 }
2298
2299 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2300 match param.kind {
2301 GenericParamDefKind::Lifetime => {
2302 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2303 }
2304 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2305 GenericParamDefKind::Const { .. } => {
2306 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2307 .into()
2308 }
2309 }
2310 }
2311
2312 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2313 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2314 }
2315
2316 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2317 self.mk_place_elem(place, PlaceElem::Deref)
2318 }
2319
2320 pub fn mk_place_downcast(
2321 self,
2322 place: Place<'tcx>,
2323 adt_def: AdtDef<'tcx>,
2324 variant_index: VariantIdx,
2325 ) -> Place<'tcx> {
2326 self.mk_place_elem(
2327 place,
2328 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2329 )
2330 }
2331
2332 pub fn mk_place_downcast_unnamed(
2333 self,
2334 place: Place<'tcx>,
2335 variant_index: VariantIdx,
2336 ) -> Place<'tcx> {
2337 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2338 }
2339
2340 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2341 self.mk_place_elem(place, PlaceElem::Index(index))
2342 }
2343
2344 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2348 Place {
2349 local: place.local,
2350 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2351 }
2352 }
2353
2354 pub fn mk_poly_existential_predicates(
2355 self,
2356 eps: &[PolyExistentialPredicate<'tcx>],
2357 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2358 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2359 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!(
2360 eps.array_windows()
2361 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2362 != Ordering::Greater)
2363 );
2364 self.intern_poly_existential_predicates(eps)
2365 }
2366
2367 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2368 self.interners.intern_clauses(clauses)
2372 }
2373
2374 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2375 self.intern_local_def_ids(def_ids)
2379 }
2380
2381 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2382 where
2383 I: Iterator<Item = T>,
2384 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2385 {
2386 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2387 }
2388
2389 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2390 where
2391 I: Iterator<Item = T>,
2392 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2393 {
2394 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2395 }
2396
2397 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2398 where
2399 I: Iterator<Item = T>,
2400 T: CollectAndApply<
2401 &'tcx ty::CapturedPlace<'tcx>,
2402 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2403 >,
2404 {
2405 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2406 }
2407
2408 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2409 where
2410 I: Iterator<Item = T>,
2411 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2412 {
2413 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2414 }
2415
2416 pub fn mk_fn_sig<I, T>(self, inputs: I, output: I::Item, fn_sig_kind: FnSigKind) -> T::Output
2421 where
2422 I: IntoIterator<Item = T>,
2423 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2424 {
2425 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2426 inputs_and_output: self.mk_type_list(xs),
2427 fn_sig_kind,
2428 })
2429 }
2430
2431 pub fn mk_fn_sig_rust_abi<I, T>(
2433 self,
2434 inputs: I,
2435 output: I::Item,
2436 safety: hir::Safety,
2437 ) -> T::Output
2438 where
2439 I: IntoIterator<Item = T>,
2440 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2441 {
2442 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safe(safety.is_safe()))
2443 }
2444
2445 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2447 where
2448 I: IntoIterator<Item = T>,
2449 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2450 {
2451 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safe(true))
2452 }
2453
2454 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2455 where
2456 I: Iterator<Item = T>,
2457 T: CollectAndApply<
2458 PolyExistentialPredicate<'tcx>,
2459 &'tcx List<PolyExistentialPredicate<'tcx>>,
2460 >,
2461 {
2462 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2463 }
2464
2465 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2466 where
2467 I: Iterator<Item = T>,
2468 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2469 {
2470 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2471 }
2472
2473 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2474 where
2475 I: Iterator<Item = T>,
2476 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2477 {
2478 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2479 }
2480
2481 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2482 where
2483 I: Iterator<Item = T>,
2484 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2485 {
2486 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2487 }
2488
2489 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2490 where
2491 I: Iterator<Item = T>,
2492 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2493 {
2494 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2495 }
2496
2497 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2498 where
2499 I: Iterator<Item = T>,
2500 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2501 {
2502 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2503 }
2504
2505 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2506 where
2507 I: Iterator<Item = T>,
2508 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2509 {
2510 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2511 }
2512
2513 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2514 where
2515 I: Iterator<Item = T>,
2516 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2517 {
2518 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2519 }
2520
2521 pub fn mk_args_trait(
2522 self,
2523 self_ty: Ty<'tcx>,
2524 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2525 ) -> GenericArgsRef<'tcx> {
2526 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2527 }
2528
2529 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2530 where
2531 I: Iterator<Item = T>,
2532 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2533 {
2534 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2535 }
2536
2537 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2538 where
2539 I: Iterator<Item = T>,
2540 T: CollectAndApply<
2541 ty::ArgOutlivesPredicate<'tcx>,
2542 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2543 >,
2544 {
2545 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2546 }
2547
2548 #[track_caller]
2551 pub fn emit_node_span_lint(
2552 self,
2553 lint: &'static Lint,
2554 hir_id: HirId,
2555 span: impl Into<MultiSpan>,
2556 decorator: impl for<'a> Diagnostic<'a, ()>,
2557 ) {
2558 let level = self.lint_level_at_node(lint, hir_id);
2559 emit_lint_base(self.sess, lint, level, Some(span.into()), decorator)
2560 }
2561
2562 pub fn crate_level_attribute_injection_span(self) -> Span {
2564 let node = self.hir_node(hir::CRATE_HIR_ID);
2565 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2566 m.spans.inject_use_span.shrink_to_lo()
2567 }
2568
2569 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2570 self,
2571 diag: &mut Diag<'_, E>,
2572 features: impl IntoIterator<Item = (String, Symbol)>,
2573 ) {
2574 if !self.sess.is_nightly_build() {
2575 return;
2576 }
2577
2578 let span = self.crate_level_attribute_injection_span();
2579 for (desc, feature) in features {
2580 let msg =
2582 ::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}");
2583 diag.span_suggestion_verbose(
2584 span,
2585 msg,
2586 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2587 Applicability::MaybeIncorrect,
2588 );
2589 }
2590 }
2591
2592 #[track_caller]
2595 pub fn emit_node_lint(
2596 self,
2597 lint: &'static Lint,
2598 id: HirId,
2599 decorator: impl for<'a> Diagnostic<'a, ()>,
2600 ) {
2601 let level = self.lint_level_at_node(lint, id);
2602 emit_lint_base(self.sess, lint, level, None, decorator);
2603 }
2604
2605 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2606 let map = self.in_scope_traits_map(id.owner)?;
2607 let candidates = map.get(&id.local_id)?;
2608 Some(candidates)
2609 }
2610
2611 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2612 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/context.rs:2612",
"rustc_middle::ty::context", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/context.rs"),
::tracing_core::__macro_support::Option::Some(2612u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::context"),
::tracing_core::field::FieldSet::new(&["message", "id"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("named_region")
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&id) as
&dyn Value))])
});
} else { ; }
};debug!(?id, "named_region");
2613 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2614 }
2615
2616 pub fn is_late_bound(self, id: HirId) -> bool {
2617 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2618 }
2619
2620 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2621 self.mk_bound_variable_kinds(
2622 &self
2623 .late_bound_vars_map(id.owner)
2624 .get(&id.local_id)
2625 .cloned()
2626 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("No bound vars found for {0}",
self.hir_id_to_string(id)))bug!("No bound vars found for {}", self.hir_id_to_string(id))),
2627 )
2628 }
2629
2630 pub fn map_opaque_lifetime_to_parent_lifetime(
2638 self,
2639 mut opaque_lifetime_param_def_id: LocalDefId,
2640 ) -> ty::Region<'tcx> {
2641 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!(
2642 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2643 "{opaque_lifetime_param_def_id:?} is a {}",
2644 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2645 );
2646
2647 loop {
2648 let parent = self.local_parent(opaque_lifetime_param_def_id);
2649 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2650
2651 let Some((lifetime, _)) = lifetime_mapping
2652 .iter()
2653 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2654 else {
2655 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2656 };
2657
2658 match *lifetime {
2659 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2660 let new_parent = self.local_parent(ebv);
2661
2662 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2665 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);
2666 opaque_lifetime_param_def_id = ebv;
2667 continue;
2668 }
2669
2670 let generics = self.generics_of(new_parent);
2671 return ty::Region::new_early_param(
2672 self,
2673 ty::EarlyParamRegion {
2674 index: generics
2675 .param_def_id_to_index(self, ebv.to_def_id())
2676 .expect("early-bound var should be present in fn generics"),
2677 name: self.item_name(ebv.to_def_id()),
2678 },
2679 );
2680 }
2681 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2682 let new_parent = self.local_parent(lbv);
2683 return ty::Region::new_late_param(
2684 self,
2685 new_parent.to_def_id(),
2686 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2687 );
2688 }
2689 resolve_bound_vars::ResolvedArg::Error(guar) => {
2690 return ty::Region::new_error(self, guar);
2691 }
2692 _ => {
2693 return ty::Region::new_error_with_message(
2694 self,
2695 self.def_span(opaque_lifetime_param_def_id),
2696 "cannot resolve lifetime",
2697 );
2698 }
2699 }
2700 }
2701 }
2702
2703 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2708 self.is_const_fn(def_id)
2709 && match self.lookup_const_stability(def_id) {
2710 None => true, Some(stability) if stability.is_const_stable() => true,
2712 _ => false,
2713 }
2714 }
2715
2716 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2718 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2719 && self.impl_trait_header(def_id).constness == hir::Constness::Const
2720 }
2721
2722 pub fn is_sdylib_interface_build(self) -> bool {
2723 self.sess.opts.unstable_opts.build_sdylib_interface
2724 }
2725
2726 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2727 let def_id = def_id.into_query_key();
2728 match self.def_kind(def_id) {
2729 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2730 _ => None,
2731 }
2732 }
2733
2734 pub fn next_trait_solver_globally(self) -> bool {
2735 self.sess.opts.unstable_opts.next_solver.globally
2736 }
2737
2738 pub fn next_trait_solver_in_coherence(self) -> bool {
2739 self.sess.opts.unstable_opts.next_solver.coherence
2740 }
2741
2742 #[allow(rustc::bad_opt_access)]
2743 pub fn use_typing_mode_borrowck(self) -> bool {
2744 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
2745 }
2746
2747 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2748 self.opt_rpitit_info(def_id).is_some()
2749 }
2750
2751 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2761 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2762 }
2763
2764 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2766 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2767 }
2768
2769 pub fn resolver_for_lowering(
2770 self,
2771 ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc<ast::Crate>)> {
2772 self.resolver_for_lowering_raw(()).0
2773 }
2774
2775 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2776 make_metadata(self)
2777 }
2778
2779 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2780 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2781 self.coroutine_kind(def_id)
2782 && let ty::Coroutine(_, args) =
2783 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2784 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2785 {
2786 true
2787 } else {
2788 false
2789 }
2790 }
2791
2792 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2794 {
{
'done:
{
for i in
::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &self) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(DoNotRecommend { .. }) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(self, def_id, DoNotRecommend { .. })
2795 }
2796
2797 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2798 let def_id = def_id.into_query_key();
2799 self.trivial_const(def_id).is_some()
2800 }
2801
2802 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2805 if self.is_lang_item(def_id, LangItem::Start) {
2806 return true;
2807 }
2808 if let Some((entry_def_id, _)) = self.entry_fn(())
2809 && entry_def_id == def_id
2810 {
2811 return true;
2812 }
2813 false
2814 }
2815}
2816
2817pub fn provide(providers: &mut Providers) {
2818 providers.is_panic_runtime = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(PanicRuntime) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, PanicRuntime);
2819 providers.is_compiler_builtins = |tcx, LocalCrate| {
'done:
{
for i in tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(CompilerBuiltins) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()find_attr!(tcx, crate, CompilerBuiltins);
2820 providers.has_panic_handler = |tcx, LocalCrate| {
2821 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2823 };
2824 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2825}