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::fingerprint::Fingerprint;
22use rustc_data_structures::fx::FxHashMap;
23use rustc_data_structures::intern::Interned;
24use rustc_data_structures::jobserver::Proxy;
25use rustc_data_structures::profiling::SelfProfilerRef;
26use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
27use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
28use rustc_data_structures::steal::Steal;
29use rustc_data_structures::sync::{
30 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
31};
32use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
33use rustc_hir::def::DefKind;
34use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
35use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState};
36use rustc_hir::intravisit::VisitorExt;
37use rustc_hir::lang_items::LangItem;
38use rustc_hir::limit::Limit;
39use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, MaybeOwner, Node, TraitCandidate, find_attr};
40use rustc_index::IndexVec;
41use rustc_macros::Diagnostic;
42use rustc_session::Session;
43use rustc_session::config::CrateType;
44use rustc_session::cstore::{CrateStoreDyn, Untracked};
45use rustc_session::lint::Lint;
46use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
47use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
48use rustc_type_ir::TyKind::*;
49pub use rustc_type_ir::lift::Lift;
50use rustc_type_ir::{
51 CollectAndApply, FnSigKind, TypeFlags, WithCachedTypeInfo, elaborate, search_graph,
52};
53use tracing::{debug, instrument};
54
55use crate::arena::Arena;
56use crate::dep_graph::dep_node::make_metadata;
57use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
58use crate::ich::StableHashingContext;
59use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
60use crate::lint::emit_lint_base;
61use crate::metadata::ModChild;
62use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
63use crate::middle::resolve_bound_vars;
64use crate::mir::interpret::{self, Allocation, ConstAllocation};
65use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
66use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
67use crate::thir::Thir;
68use crate::traits;
69use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
70use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
71use crate::ty::{
72 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
73 GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, Pattern,
74 PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity,
75 Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, ValTree, ValTreeKind,
76 Visibility,
77};
78
79impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
80 fn is_local(self) -> bool {
81 self.is_local()
82 }
83
84 fn as_local(self) -> Option<LocalDefId> {
85 self.as_local()
86 }
87}
88
89impl<'tcx> rustc_type_ir::inherent::FSigKind<TyCtxt<'tcx>> for FnSigKind {
90 fn fn_sig_kind(self) -> Self {
91 self
92 }
93
94 fn new(abi: ExternAbi, safety: hir::Safety, c_variadic: bool) -> Self {
95 FnSigKind::default().set_abi(abi).set_safe(safety.is_safe()).set_c_variadic(c_variadic)
96 }
97
98 fn abi(self) -> ExternAbi {
99 self.abi()
100 }
101
102 fn safety(self) -> hir::Safety {
103 if self.is_safe() { hir::Safety::Safe } else { hir::Safety::Unsafe }
104 }
105
106 fn c_variadic(self) -> bool {
107 self.c_variadic()
108 }
109}
110
111impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
112 fn abi(self) -> Self {
113 self
114 }
115
116 fn rust() -> Self {
117 ExternAbi::Rust
118 }
119
120 fn is_rust(self) -> bool {
121 #[allow(non_exhaustive_omitted_patterns)] match self {
ExternAbi::Rust => true,
_ => false,
}matches!(self, ExternAbi::Rust)
122 }
123
124 fn pack_abi(self) -> u8 {
125 self.as_packed()
126 }
127
128 fn unpack_abi(abi_index: u8) -> Self {
129 Self::from_packed(abi_index)
130 }
131}
132
133impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
134 fn safe() -> Self {
135 hir::Safety::Safe
136 }
137
138 fn unsafe_mode() -> Self {
139 hir::Safety::Unsafe
140 }
141
142 fn is_safe(self) -> bool {
143 self.is_safe()
144 }
145
146 fn prefix_str(self) -> &'static str {
147 self.prefix_str()
148 }
149}
150
151impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
152 fn generic_const_exprs(self) -> bool {
153 self.generic_const_exprs()
154 }
155
156 fn coroutine_clone(self) -> bool {
157 self.coroutine_clone()
158 }
159
160 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
161 !self.staged_api() && self.enabled(symbol)
165 }
166}
167
168impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
169 fn dummy() -> Self {
170 DUMMY_SP
171 }
172}
173
174type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
175
176pub struct CtxtInterners<'tcx> {
177 arena: &'tcx WorkerLocal<Arena<'tcx>>,
179
180 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
183 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
184 args: InternedSet<'tcx, GenericArgs<'tcx>>,
185 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
186 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
187 region: InternedSet<'tcx, RegionKind<'tcx>>,
188 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
189 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
190 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
191 projs: InternedSet<'tcx, List<ProjectionKind>>,
192 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
193 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
194 pat: InternedSet<'tcx, PatternKind<'tcx>>,
195 const_allocation: InternedSet<'tcx, Allocation>,
196 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
197 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
198 adt_def: InternedSet<'tcx, AdtDefData>,
199 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
200 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
201 fields: InternedSet<'tcx, List<FieldIdx>>,
202 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
203 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
204 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
205 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
206 outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
207}
208
209impl<'tcx> CtxtInterners<'tcx> {
210 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
211 const N: usize = 2048;
214 CtxtInterners {
215 arena,
216 type_: InternedSet::with_capacity(N * 16),
220 const_lists: InternedSet::with_capacity(N * 4),
221 args: InternedSet::with_capacity(N * 4),
222 type_lists: InternedSet::with_capacity(N * 4),
223 region: InternedSet::with_capacity(N * 4),
224 poly_existential_predicates: InternedSet::with_capacity(N / 4),
225 canonical_var_kinds: InternedSet::with_capacity(N / 2),
226 predicate: InternedSet::with_capacity(N),
227 clauses: InternedSet::with_capacity(N),
228 projs: InternedSet::with_capacity(N * 4),
229 place_elems: InternedSet::with_capacity(N * 2),
230 const_: InternedSet::with_capacity(N * 2),
231 pat: InternedSet::with_capacity(N),
232 const_allocation: InternedSet::with_capacity(N),
233 bound_variable_kinds: InternedSet::with_capacity(N * 2),
234 layout: InternedSet::with_capacity(N),
235 adt_def: InternedSet::with_capacity(N),
236 external_constraints: InternedSet::with_capacity(N),
237 predefined_opaques_in_body: InternedSet::with_capacity(N),
238 fields: InternedSet::with_capacity(N * 4),
239 local_def_ids: InternedSet::with_capacity(N),
240 captures: InternedSet::with_capacity(N),
241 valtree: InternedSet::with_capacity(N),
242 patterns: InternedSet::with_capacity(N),
243 outlives: InternedSet::with_capacity(N),
244 }
245 }
246
247 #[allow(rustc::usage_of_ty_tykind)]
249 #[inline(never)]
250 fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
251 Ty(Interned::new_unchecked(
252 self.type_
253 .intern(kind, |kind| {
254 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
255 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
256
257 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
258 internee: kind,
259 stable_hash,
260 flags: flags.flags,
261 outer_exclusive_binder: flags.outer_exclusive_binder,
262 }))
263 })
264 .0,
265 ))
266 }
267
268 #[allow(rustc::usage_of_ty_tykind)]
270 #[inline(never)]
271 fn intern_const(
272 &self,
273 kind: ty::ConstKind<'tcx>,
274 sess: &Session,
275 untracked: &Untracked,
276 ) -> Const<'tcx> {
277 Const(Interned::new_unchecked(
278 self.const_
279 .intern(kind, |kind: ty::ConstKind<'_>| {
280 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
281 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
282
283 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
284 internee: kind,
285 stable_hash,
286 flags: flags.flags,
287 outer_exclusive_binder: flags.outer_exclusive_binder,
288 }))
289 })
290 .0,
291 ))
292 }
293
294 fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
295 &self,
296 flags: &ty::FlagComputation<TyCtxt<'tcx>>,
297 sess: &'a Session,
298 untracked: &'a Untracked,
299 val: &T,
300 ) -> Fingerprint {
301 if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() {
304 Fingerprint::ZERO
305 } else {
306 let mut hasher = StableHasher::new();
307 let mut hcx = StableHashingContext::new(sess, untracked);
308 val.hash_stable(&mut hcx, &mut hasher);
309 hasher.finish()
310 }
311 }
312
313 #[inline(never)]
315 fn intern_predicate(
316 &self,
317 kind: Binder<'tcx, PredicateKind<'tcx>>,
318 sess: &Session,
319 untracked: &Untracked,
320 ) -> Predicate<'tcx> {
321 Predicate(Interned::new_unchecked(
322 self.predicate
323 .intern(kind, |kind| {
324 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
325
326 let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
327
328 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
329 internee: kind,
330 stable_hash,
331 flags: flags.flags,
332 outer_exclusive_binder: flags.outer_exclusive_binder,
333 }))
334 })
335 .0,
336 ))
337 }
338
339 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
340 if clauses.is_empty() {
341 ListWithCachedTypeInfo::empty()
342 } else {
343 self.clauses
344 .intern_ref(clauses, || {
345 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
346
347 InternedInSet(ListWithCachedTypeInfo::from_arena(
348 &*self.arena,
349 flags.into(),
350 clauses,
351 ))
352 })
353 .0
354 }
355 }
356}
357
358const NUM_PREINTERNED_TY_VARS: u32 = 100;
363const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
364const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
365const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
366const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
367
368const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
377
378const NUM_PREINTERNED_RE_VARS: u32 = 500;
380const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
381const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
382
383pub struct CommonTypes<'tcx> {
384 pub unit: Ty<'tcx>,
385 pub bool: Ty<'tcx>,
386 pub char: Ty<'tcx>,
387 pub isize: Ty<'tcx>,
388 pub i8: Ty<'tcx>,
389 pub i16: Ty<'tcx>,
390 pub i32: Ty<'tcx>,
391 pub i64: Ty<'tcx>,
392 pub i128: Ty<'tcx>,
393 pub usize: Ty<'tcx>,
394 pub u8: Ty<'tcx>,
395 pub u16: Ty<'tcx>,
396 pub u32: Ty<'tcx>,
397 pub u64: Ty<'tcx>,
398 pub u128: Ty<'tcx>,
399 pub f16: Ty<'tcx>,
400 pub f32: Ty<'tcx>,
401 pub f64: Ty<'tcx>,
402 pub f128: Ty<'tcx>,
403 pub str_: Ty<'tcx>,
404 pub never: Ty<'tcx>,
405 pub self_param: Ty<'tcx>,
406
407 pub trait_object_dummy_self: Ty<'tcx>,
412
413 pub ty_vars: Vec<Ty<'tcx>>,
415
416 pub fresh_tys: Vec<Ty<'tcx>>,
418
419 pub fresh_int_tys: Vec<Ty<'tcx>>,
421
422 pub fresh_float_tys: Vec<Ty<'tcx>>,
424
425 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
429
430 pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
434}
435
436pub struct CommonLifetimes<'tcx> {
437 pub re_static: Region<'tcx>,
439
440 pub re_erased: Region<'tcx>,
442
443 pub re_vars: Vec<Region<'tcx>>,
445
446 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
450
451 pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
455}
456
457pub struct CommonConsts<'tcx> {
458 pub unit: Const<'tcx>,
459 pub true_: Const<'tcx>,
460 pub false_: Const<'tcx>,
461 pub(crate) valtree_zst: ValTree<'tcx>,
463}
464
465impl<'tcx> CommonTypes<'tcx> {
466 fn new(
467 interners: &CtxtInterners<'tcx>,
468 sess: &Session,
469 untracked: &Untracked,
470 ) -> CommonTypes<'tcx> {
471 let mk = |ty| interners.intern_ty(ty, sess, untracked);
472
473 let ty_vars =
474 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
475 let fresh_tys: Vec<_> =
476 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
477 let fresh_int_tys: Vec<_> =
478 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
479 let fresh_float_tys: Vec<_> =
480 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
481
482 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
483 .map(|i| {
484 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
485 .map(|v| {
486 mk(ty::Bound(
487 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
488 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
489 ))
490 })
491 .collect()
492 })
493 .collect();
494
495 let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
496 .map(|v| {
497 mk(ty::Bound(
498 ty::BoundVarIndexKind::Canonical,
499 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
500 ))
501 })
502 .collect();
503
504 CommonTypes {
505 unit: mk(Tuple(List::empty())),
506 bool: mk(Bool),
507 char: mk(Char),
508 never: mk(Never),
509 isize: mk(Int(ty::IntTy::Isize)),
510 i8: mk(Int(ty::IntTy::I8)),
511 i16: mk(Int(ty::IntTy::I16)),
512 i32: mk(Int(ty::IntTy::I32)),
513 i64: mk(Int(ty::IntTy::I64)),
514 i128: mk(Int(ty::IntTy::I128)),
515 usize: mk(Uint(ty::UintTy::Usize)),
516 u8: mk(Uint(ty::UintTy::U8)),
517 u16: mk(Uint(ty::UintTy::U16)),
518 u32: mk(Uint(ty::UintTy::U32)),
519 u64: mk(Uint(ty::UintTy::U64)),
520 u128: mk(Uint(ty::UintTy::U128)),
521 f16: mk(Float(ty::FloatTy::F16)),
522 f32: mk(Float(ty::FloatTy::F32)),
523 f64: mk(Float(ty::FloatTy::F64)),
524 f128: mk(Float(ty::FloatTy::F128)),
525 str_: mk(Str),
526 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
527
528 trait_object_dummy_self: fresh_tys[0],
529
530 ty_vars,
531 fresh_tys,
532 fresh_int_tys,
533 fresh_float_tys,
534 anon_bound_tys,
535 anon_canonical_bound_tys,
536 }
537 }
538}
539
540impl<'tcx> CommonLifetimes<'tcx> {
541 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
542 let mk = |r| {
543 Region(Interned::new_unchecked(
544 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
545 ))
546 };
547
548 let re_vars =
549 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
550
551 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
552 .map(|i| {
553 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
554 .map(|v| {
555 mk(ty::ReBound(
556 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
557 ty::BoundRegion {
558 var: ty::BoundVar::from(v),
559 kind: ty::BoundRegionKind::Anon,
560 },
561 ))
562 })
563 .collect()
564 })
565 .collect();
566
567 let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
568 .map(|v| {
569 mk(ty::ReBound(
570 ty::BoundVarIndexKind::Canonical,
571 ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
572 ))
573 })
574 .collect();
575
576 CommonLifetimes {
577 re_static: mk(ty::ReStatic),
578 re_erased: mk(ty::ReErased),
579 re_vars,
580 anon_re_bounds,
581 anon_re_canonical_bounds,
582 }
583 }
584}
585
586impl<'tcx> CommonConsts<'tcx> {
587 fn new(
588 interners: &CtxtInterners<'tcx>,
589 types: &CommonTypes<'tcx>,
590 sess: &Session,
591 untracked: &Untracked,
592 ) -> CommonConsts<'tcx> {
593 let mk_const = |c| {
594 interners.intern_const(
595 c, sess, untracked,
597 )
598 };
599
600 let mk_valtree = |v| {
601 ty::ValTree(Interned::new_unchecked(
602 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
603 ))
604 };
605
606 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
607 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
608 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
609
610 CommonConsts {
611 unit: mk_const(ty::ConstKind::Value(ty::Value {
612 ty: types.unit,
613 valtree: valtree_zst,
614 })),
615 true_: mk_const(ty::ConstKind::Value(ty::Value {
616 ty: types.bool,
617 valtree: valtree_true,
618 })),
619 false_: mk_const(ty::ConstKind::Value(ty::Value {
620 ty: types.bool,
621 valtree: valtree_false,
622 })),
623 valtree_zst,
624 }
625 }
626}
627
628#[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)]
631pub struct FreeRegionInfo {
632 pub scope: LocalDefId,
634 pub region_def_id: DefId,
636 pub is_impl_item: bool,
638}
639
640#[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)]
642pub struct TyCtxtFeed<'tcx, KEY: Copy> {
643 pub tcx: TyCtxt<'tcx>,
644 key: KEY,
646}
647
648impl<KEY: Copy, Hcx> !HashStable<Hcx> for TyCtxtFeed<'_, KEY> {}
651
652#[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)]
657pub struct Feed<'tcx, KEY: Copy> {
658 _tcx: PhantomData<TyCtxt<'tcx>>,
659 key: KEY,
661}
662
663impl<KEY: Copy, Hcx> !HashStable<Hcx> for Feed<'_, KEY> {}
666
667impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
668 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
669 self.key.fmt(f)
670 }
671}
672
673impl<'tcx> TyCtxt<'tcx> {
678 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
681 self.dep_graph.assert_ignored();
682 TyCtxtFeed { tcx: self, key: () }
683 }
684
685 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
688 let key = self.untracked().source_span.push(span);
689 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);
690 TyCtxtFeed { tcx: self, key }
691 }
692
693 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
697 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);
698 TyCtxtFeed { tcx: self, key }.type_of(value)
699 }
700
701 pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) {
703 self.dep_graph.assert_ignored();
704 TyCtxtFeed { tcx: self, key }.delayed_owner(owner);
705 }
706
707 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
715 if truecfg!(debug_assertions) {
716 match self.def_kind(self.local_parent(key)) {
717 DefKind::Impl { of_trait: true } => {}
718 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:?}"),
719 }
720 }
721 TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id())
722 }
723}
724
725impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
726 #[inline(always)]
727 pub fn key(&self) -> KEY {
728 self.key
729 }
730
731 #[inline(always)]
732 pub fn downgrade(self) -> Feed<'tcx, KEY> {
733 Feed { _tcx: PhantomData, key: self.key }
734 }
735}
736
737impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
738 #[inline(always)]
739 pub fn key(&self) -> KEY {
740 self.key
741 }
742
743 #[inline(always)]
744 pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
745 TyCtxtFeed { tcx, key: self.key }
746 }
747}
748
749impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
750 #[inline(always)]
751 pub fn def_id(&self) -> LocalDefId {
752 self.key
753 }
754
755 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
757 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
758 }
759
760 pub fn feed_hir(&self) {
762 self.local_def_id_to_hir_id(HirId::make_owner(self.def_id()));
763
764 let node = hir::OwnerNode::Synthetic;
765 let bodies = Default::default();
766 let attrs = hir::AttributeMap::EMPTY;
767
768 let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } =
769 self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque);
770 let node = node.into();
771 self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes {
772 opt_hash_including_bodies,
773 nodes: IndexVec::from_elem_n(
774 hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node },
775 1,
776 ),
777 bodies,
778 })));
779 self.feed_owner_id().hir_attr_map(attrs);
780 }
781}
782
783#[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)]
801#[rustc_diagnostic_item = "TyCtxt"]
802#[rustc_pass_by_value]
803pub struct TyCtxt<'tcx> {
804 gcx: &'tcx GlobalCtxt<'tcx>,
805}
806
807unsafe impl DynSend for TyCtxt<'_> {}
811unsafe impl DynSync for TyCtxt<'_> {}
812fn _assert_tcx_fields() {
813 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
814 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
815}
816
817impl<'tcx> Deref for TyCtxt<'tcx> {
818 type Target = &'tcx GlobalCtxt<'tcx>;
819 #[inline(always)]
820 fn deref(&self) -> &Self::Target {
821 &self.gcx
822 }
823}
824
825pub struct GlobalCtxt<'tcx> {
827 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
828 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
829
830 interners: CtxtInterners<'tcx>,
831
832 pub sess: &'tcx Session,
833 crate_types: Vec<CrateType>,
834 stable_crate_id: StableCrateId,
840
841 pub dep_graph: DepGraph,
842
843 pub prof: SelfProfilerRef,
844
845 pub types: CommonTypes<'tcx>,
847
848 pub lifetimes: CommonLifetimes<'tcx>,
850
851 pub consts: CommonConsts<'tcx>,
853
854 pub(crate) hooks: crate::hooks::Providers,
857
858 untracked: Untracked,
859
860 pub query_system: QuerySystem<'tcx>,
861 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
862
863 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
865
866 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
869
870 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
874
875 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
877 pub new_solver_canonical_param_env_cache:
878 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
879
880 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
881
882 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
884 pub clauses_cache:
886 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
887
888 pub data_layout: TargetDataLayout,
890
891 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
893
894 current_gcx: CurrentGcx,
895
896 pub jobserver_proxy: Arc<Proxy>,
898}
899
900impl<'tcx> GlobalCtxt<'tcx> {
901 pub fn enter<F, R>(&'tcx self, f: F) -> R
904 where
905 F: FnOnce(TyCtxt<'tcx>) -> R,
906 {
907 let icx = tls::ImplicitCtxt::new(self);
908
909 let _on_drop = defer(move || {
911 *self.current_gcx.value.write() = None;
912 });
913
914 {
916 let mut guard = self.current_gcx.value.write();
917 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
918 *guard = Some(self as *const _ as *const ());
919 }
920
921 tls::enter_context(&icx, || f(icx.tcx))
922 }
923}
924
925#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
932pub struct CurrentGcx {
933 value: Arc<RwLock<Option<*const ()>>>,
936}
937
938unsafe impl DynSend for CurrentGcx {}
939unsafe impl DynSync for CurrentGcx {}
940
941impl CurrentGcx {
942 pub fn new() -> Self {
943 Self { value: Arc::new(RwLock::new(None)) }
944 }
945
946 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
947 let read_guard = self.value.read();
948 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
949 f(unsafe { &*gcx })
953 }
954}
955
956impl<'tcx> TyCtxt<'tcx> {
957 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
958 let root = self.typeck_root_def_id_local(def_id);
961 self.hir_node_by_def_id(root).body_id().is_some()
962 }
963
964 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
969 let def_kind = self.def_kind(def_id);
970 if def_kind.has_codegen_attrs() {
971 self.codegen_fn_attrs(def_id)
972 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
DefKind::InlineConst | DefKind::GlobalAsm => true,
_ => false,
}matches!(
973 def_kind,
974 DefKind::AnonConst
975 | DefKind::AssocConst { .. }
976 | DefKind::Const { .. }
977 | DefKind::InlineConst
978 | DefKind::GlobalAsm
979 ) {
980 CodegenFnAttrs::EMPTY
981 } else {
982 crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind))bug!(
983 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
984 def_id,
985 def_kind
986 )
987 }
988 }
989
990 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
991 self.arena.alloc(Steal::new(thir))
992 }
993
994 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
995 self.arena.alloc(Steal::new(mir))
996 }
997
998 pub fn alloc_steal_promoted(
999 self,
1000 promoted: IndexVec<Promoted, Body<'tcx>>,
1001 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
1002 self.arena.alloc(Steal::new(promoted))
1003 }
1004
1005 pub fn mk_adt_def(
1006 self,
1007 did: DefId,
1008 kind: AdtKind,
1009 variants: IndexVec<VariantIdx, ty::VariantDef>,
1010 repr: ReprOptions,
1011 ) -> ty::AdtDef<'tcx> {
1012 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
1013 }
1014
1015 pub fn allocate_bytes_dedup<'a>(
1018 self,
1019 bytes: impl Into<Cow<'a, [u8]>>,
1020 salt: usize,
1021 ) -> interpret::AllocId {
1022 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
1024 let alloc = self.mk_const_alloc(alloc);
1025 self.reserve_and_set_memory_dedup(alloc, salt)
1026 }
1027
1028 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
1030 if self.sess.opts.unstable_opts.experimental_default_bounds {
1031 &[
1032 LangItem::DefaultTrait1,
1033 LangItem::DefaultTrait2,
1034 LangItem::DefaultTrait3,
1035 LangItem::DefaultTrait4,
1036 ]
1037 } else {
1038 &[]
1039 }
1040 }
1041
1042 pub fn is_default_trait(self, def_id: DefId) -> bool {
1043 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
1044 }
1045
1046 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
1047 #[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))
1048 }
1049
1050 pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
1054 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);
1055 let end =
1056 {
{
'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))
1057 .unwrap_or(Bound::Unbounded);
1058 (start, end)
1059 }
1060
1061 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
1062 value.lift_to_interner(self)
1063 }
1064
1065 pub fn create_global_ctxt<T>(
1072 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
1073 s: &'tcx Session,
1074 crate_types: Vec<CrateType>,
1075 stable_crate_id: StableCrateId,
1076 arena: &'tcx WorkerLocal<Arena<'tcx>>,
1077 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
1078 untracked: Untracked,
1079 dep_graph: DepGraph,
1080 dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
1081 query_system: QuerySystem<'tcx>,
1082 hooks: crate::hooks::Providers,
1083 current_gcx: CurrentGcx,
1084 jobserver_proxy: Arc<Proxy>,
1085 f: impl FnOnce(TyCtxt<'tcx>) -> T,
1086 ) -> T {
1087 let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
1088 s.dcx().emit_fatal(err);
1089 });
1090 let interners = CtxtInterners::new(arena);
1091 let common_types = CommonTypes::new(&interners, s, &untracked);
1092 let common_lifetimes = CommonLifetimes::new(&interners);
1093 let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked);
1094
1095 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
1096 sess: s,
1097 crate_types,
1098 stable_crate_id,
1099 arena,
1100 hir_arena,
1101 interners,
1102 dep_graph,
1103 hooks,
1104 prof: s.prof.clone(),
1105 types: common_types,
1106 lifetimes: common_lifetimes,
1107 consts: common_consts,
1108 untracked,
1109 query_system,
1110 dep_kind_vtables,
1111 ty_rcache: Default::default(),
1112 selection_cache: Default::default(),
1113 evaluation_cache: Default::default(),
1114 new_solver_evaluation_cache: Default::default(),
1115 new_solver_canonical_param_env_cache: Default::default(),
1116 canonical_param_env_cache: Default::default(),
1117 highest_var_in_clauses_cache: Default::default(),
1118 clauses_cache: Default::default(),
1119 data_layout,
1120 alloc_map: interpret::AllocMap::new(),
1121 current_gcx,
1122 jobserver_proxy,
1123 });
1124
1125 gcx.enter(f)
1127 }
1128
1129 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
1131 self.get_lang_items(())
1132 }
1133
1134 #[track_caller]
1136 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
1137 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
1138 self.type_of(ordering_enum).no_bound_vars().unwrap()
1139 }
1140
1141 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1144 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1145 }
1146
1147 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1149 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
1150 }
1151
1152 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1154 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1155 }
1156
1157 pub fn is_coroutine(self, def_id: DefId) -> bool {
1158 self.coroutine_kind(def_id).is_some()
1159 }
1160
1161 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1162 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1163 }
1164
1165 pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1166 if !self.is_type_const(def_id) {
1167 return None;
1168 }
1169 Some(self.def_span(def_id))
1170 }
1171
1172 pub fn is_type_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1174 let def_id = def_id.into_query_key();
1175 match self.def_kind(def_id) {
1176 DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1177 is_type_const
1178 }
1179 _ => false,
1180 }
1181 }
1182
1183 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1186 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1187 }
1188
1189 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1191 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1192 self.coroutine_kind(def_id),
1193 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1194 )
1195 }
1196
1197 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1200 #[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)
1201 }
1202
1203 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1206 #[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(_)))
1207 }
1208
1209 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1211 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1212 self.coroutine_kind(def_id),
1213 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1214 )
1215 }
1216
1217 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1219 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1220 self.coroutine_kind(def_id),
1221 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1222 )
1223 }
1224
1225 pub fn features(self) -> &'tcx rustc_feature::Features {
1226 self.features_query(())
1227 }
1228
1229 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1230 let id = id.into_query_key();
1231 if let Some(id) = id.as_local() {
1233 self.definitions_untracked().def_key(id)
1234 } else {
1235 self.cstore_untracked().def_key(id)
1236 }
1237 }
1238
1239 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1245 if let Some(id) = id.as_local() {
1247 self.definitions_untracked().def_path(id)
1248 } else {
1249 self.cstore_untracked().def_path(id)
1250 }
1251 }
1252
1253 #[inline]
1254 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1255 if let Some(def_id) = def_id.as_local() {
1257 self.definitions_untracked().def_path_hash(def_id)
1258 } else {
1259 self.cstore_untracked().def_path_hash(def_id)
1260 }
1261 }
1262
1263 #[inline]
1264 pub fn crate_types(self) -> &'tcx [CrateType] {
1265 &self.crate_types
1266 }
1267
1268 pub fn needs_metadata(self) -> bool {
1269 self.crate_types().iter().any(|ty| match *ty {
1270 CrateType::Executable
1271 | CrateType::StaticLib
1272 | CrateType::Cdylib
1273 | CrateType::Sdylib => false,
1274 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1275 })
1276 }
1277
1278 pub fn needs_crate_hash(self) -> bool {
1279 truecfg!(debug_assertions)
1291 || self.sess.opts.incremental.is_some()
1292 || self.needs_metadata()
1293 || self.sess.instrument_coverage()
1294 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1295 }
1296
1297 #[inline]
1298 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1299 if crate_num == LOCAL_CRATE {
1300 self.stable_crate_id
1301 } else {
1302 self.cstore_untracked().stable_crate_id(crate_num)
1303 }
1304 }
1305
1306 #[inline]
1309 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1310 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1311 LOCAL_CRATE
1312 } else {
1313 *self
1314 .untracked()
1315 .stable_crate_ids
1316 .read()
1317 .get(&stable_crate_id)
1318 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1319 }
1320 }
1321
1322 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1326 {
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:1326",
"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(1326u32),
::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);
1327
1328 let stable_crate_id = hash.stable_crate_id();
1329
1330 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1333 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1334 } else {
1335 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1336 }
1337 }
1338
1339 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1340 let (crate_name, stable_crate_id) = if def_id.is_local() {
1345 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1346 } else {
1347 let cstore = &*self.cstore_untracked();
1348 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1349 };
1350
1351 ::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!(
1352 "{}[{:04x}]{}",
1353 crate_name,
1354 stable_crate_id.as_u64() >> (8 * 6),
1357 self.def_path(def_id).to_string_no_crate_verbose()
1358 )
1359 }
1360
1361 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1362 self.sess.dcx()
1363 }
1364
1365 pub fn is_target_feature_call_safe(
1368 self,
1369 callee_features: &[TargetFeature],
1370 body_features: &[TargetFeature],
1371 ) -> bool {
1372 self.sess.target.options.is_like_wasm
1377 || callee_features
1378 .iter()
1379 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1380 }
1381
1382 pub fn adjust_target_feature_sig(
1385 self,
1386 fun_def: DefId,
1387 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1388 caller: DefId,
1389 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1390 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1391 let caller_features = &self.body_codegen_attrs(caller).target_features;
1392 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1393 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1394 fn_sig_kind: fun_sig.fn_sig_kind().set_safe(true),
1395 ..sig
1396 }));
1397 }
1398 None
1399 }
1400
1401 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1404 match self.env_var_os(key.as_ref()) {
1405 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1406 None => Err(VarError::NotPresent),
1407 }
1408 }
1409}
1410
1411impl<'tcx> TyCtxtAt<'tcx> {
1412 pub fn create_def(
1414 self,
1415 parent: LocalDefId,
1416 name: Option<Symbol>,
1417 def_kind: DefKind,
1418 override_def_path_data: Option<DefPathData>,
1419 disambiguator: &mut PerParentDisambiguatorState,
1420 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1421 let feed =
1422 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1423
1424 feed.def_span(self.span);
1425 feed
1426 }
1427}
1428
1429impl<'tcx> TyCtxt<'tcx> {
1430 pub fn create_def(
1432 self,
1433 parent: LocalDefId,
1434 name: Option<Symbol>,
1435 def_kind: DefKind,
1436 override_def_path_data: Option<DefPathData>,
1437 disambiguator: &mut PerParentDisambiguatorState,
1438 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1439 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1440 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1450
1451 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1456
1457 let feed = TyCtxtFeed { tcx: self, key: def_id };
1458 feed.def_kind(def_kind);
1459 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1464 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1465 feed.visibility(ty::Visibility::Restricted(parent_mod));
1466 }
1467
1468 feed
1469 }
1470
1471 pub fn create_crate_num(
1472 self,
1473 stable_crate_id: StableCrateId,
1474 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1475 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
1476 return Err(existing);
1477 }
1478
1479 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
1480 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
1481 Ok(TyCtxtFeed { key: num, tcx: self })
1482 }
1483
1484 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1485 self.ensure_ok().analysis(());
1487
1488 let definitions = &self.untracked.definitions;
1489 gen {
1490 let mut i = 0;
1491
1492 while i < { definitions.read().num_definitions() } {
1495 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1496 yield LocalDefId { local_def_index };
1497 i += 1;
1498 }
1499
1500 definitions.freeze();
1502 }
1503 }
1504
1505 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1506 self.ensure_ok().analysis(());
1508
1509 self.untracked.definitions.freeze().def_path_table()
1512 }
1513
1514 pub fn def_path_hash_to_def_index_map(
1515 self,
1516 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1517 self.ensure_ok().hir_crate_items(());
1520 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1523 }
1524
1525 #[inline]
1528 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1529 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1530 }
1531
1532 pub fn untracked(self) -> &'tcx Untracked {
1534 &self.untracked
1535 }
1536 #[inline]
1539 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1540 self.untracked.definitions.read()
1541 }
1542
1543 #[inline]
1546 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1547 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1548 }
1549
1550 #[inline(always)]
1551 pub fn with_stable_hashing_context<R>(
1552 self,
1553 f: impl FnOnce(StableHashingContext<'_>) -> R,
1554 ) -> R {
1555 f(StableHashingContext::new(self.sess, &self.untracked))
1556 }
1557
1558 #[inline]
1559 pub fn local_crate_exports_generics(self) -> bool {
1560 if self.is_compiler_builtins(LOCAL_CRATE) {
1564 return false;
1565 }
1566 self.crate_types().iter().any(|crate_type| {
1567 match crate_type {
1568 CrateType::Executable
1569 | CrateType::StaticLib
1570 | CrateType::ProcMacro
1571 | CrateType::Cdylib
1572 | CrateType::Sdylib => false,
1573
1574 CrateType::Dylib => true,
1579
1580 CrateType::Rlib => true,
1581 }
1582 })
1583 }
1584
1585 pub fn is_suitable_region(
1587 self,
1588 generic_param_scope: LocalDefId,
1589 mut region: Region<'tcx>,
1590 ) -> Option<FreeRegionInfo> {
1591 let (suitable_region_binding_scope, region_def_id) = loop {
1592 let def_id =
1593 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1594 let scope = self.local_parent(def_id);
1595 if self.def_kind(scope) == DefKind::OpaqueTy {
1596 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1599 continue;
1600 }
1601 break (scope, def_id.into());
1602 };
1603
1604 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1605 Node::Item(..) | Node::TraitItem(..) => false,
1606 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1607 hir::ImplItemImplKind::Trait { .. } => true,
1614 _ => false,
1615 },
1616 _ => false,
1617 };
1618
1619 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1620 }
1621
1622 pub fn return_type_impl_or_dyn_traits(
1624 self,
1625 scope_def_id: LocalDefId,
1626 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1627 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1628 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1629 self.hir_fn_decl_by_hir_id(hir_id)
1630 else {
1631 return ::alloc::vec::Vec::new()vec![];
1632 };
1633
1634 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1635 v.visit_ty_unambig(hir_output);
1636 v.0
1637 }
1638
1639 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1643 self,
1644 scope_def_id: LocalDefId,
1645 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1646 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1647 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1648 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1650 && let hir::TyKind::Path(hir::QPath::Resolved(
1651 None,
1652 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1653 && let Some(local_id) = def_id.as_local()
1654 && 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()
1656 {
1657 v.visit_ty_unambig(alias_ty);
1658 if !v.0.is_empty() {
1659 return Some((
1660 v.0,
1661 alias_generics.span,
1662 alias_generics.span_for_lifetime_suggestion(),
1663 ));
1664 }
1665 }
1666 None
1667 }
1668
1669 pub fn has_strict_asm_symbol_naming(self) -> bool {
1672 self.sess.target.llvm_target.starts_with("nvptx")
1673 }
1674
1675 pub fn caller_location_ty(self) -> Ty<'tcx> {
1677 Ty::new_imm_ref(
1678 self,
1679 self.lifetimes.re_static,
1680 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1681 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1682 .skip_norm_wip(),
1683 )
1684 }
1685
1686 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1688 let kind = self.def_kind(def_id);
1689 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1690 }
1691
1692 pub fn type_length_limit(self) -> Limit {
1693 self.limits(()).type_length_limit
1694 }
1695
1696 pub fn recursion_limit(self) -> Limit {
1697 self.limits(()).recursion_limit
1698 }
1699
1700 pub fn move_size_limit(self) -> Limit {
1701 self.limits(()).move_size_limit
1702 }
1703
1704 pub fn pattern_complexity_limit(self) -> Limit {
1705 self.limits(()).pattern_complexity_limit
1706 }
1707
1708 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1710 iter::once(LOCAL_CRATE)
1711 .chain(self.crates(()).iter().copied())
1712 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1713 }
1714
1715 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1717 let visible_crates =
1718 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1719
1720 iter::once(LOCAL_CRATE)
1721 .chain(visible_crates)
1722 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1723 }
1724
1725 #[inline]
1726 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1727 self.visibility(def_id).expect_local()
1728 }
1729
1730 x;#[instrument(skip(self), level = "trace", ret)]
1732 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1733 self.hir_expect_opaque_ty(def_id).origin
1734 }
1735
1736 pub fn finish(self) {
1737 self.alloc_self_profile_query_strings();
1740
1741 self.save_dep_graph();
1742 self.verify_query_key_hashes();
1743
1744 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1745 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
1746 }
1747 }
1748
1749 pub fn report_unused_features(self) {
1750 #[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)]
1751 #[diag("feature `{$feature}` is declared but not used")]
1752 struct UnusedFeature {
1753 feature: Symbol,
1754 }
1755
1756 let used_features = self.sess.used_features.lock();
1758 let unused_features = self
1759 .features()
1760 .enabled_features_iter_stable_order()
1761 .filter(|(f, _)| {
1762 !used_features.contains_key(f)
1763 && f.as_str() != "restricted_std"
1770 && *f != sym::doc_cfg
1774 })
1775 .collect::<Vec<_>>();
1776
1777 for (feature, span) in unused_features {
1778 self.emit_node_span_lint(
1779 rustc_session::lint::builtin::UNUSED_FEATURES,
1780 CRATE_HIR_ID,
1781 span,
1782 UnusedFeature { feature },
1783 );
1784 }
1785 }
1786}
1787
1788macro_rules! nop_lift {
1789 ($set:ident; $ty:ty => $lifted:ty) => {
1790 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1791 type Lifted = $lifted;
1792 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1793 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1798 _x: Interned<'tcx, Inner>,
1799 ) -> InternedSet<'tcx, Inner> {
1800 unreachable!()
1801 }
1802 fn _type_eq<T>(_x: &T, _y: &T) {}
1803 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1804 let interner = _intern_set_ty_from_interned_ty(x.0);
1808 _type_eq(&interner, &tcx.interners.$set);
1810 }
1811
1812 tcx.interners
1813 .$set
1814 .contains_pointer_to(&InternedInSet(&*self.0.0))
1815 .then(|| unsafe { mem::transmute(self) })
1818 }
1819 }
1820 };
1821}
1822
1823macro_rules! nop_list_lift {
1824 ($set:ident; $ty:ty => $lifted:ty) => {
1825 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
1826 type Lifted = &'tcx List<$lifted>;
1827 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1828 if false {
1830 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
1831 }
1832
1833 if self.is_empty() {
1834 return Some(List::empty());
1835 }
1836 tcx.interners
1837 .$set
1838 .contains_pointer_to(&InternedInSet(self))
1839 .then(|| unsafe { mem::transmute(self) })
1840 }
1841 }
1842 };
1843}
1844
1845impl<'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> }
1846impl<'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> }
1847impl<'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> }
1848impl<'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> }
1849impl<'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> }
1850impl<'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> }
1851impl<'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> }
1852impl<'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> }
1853impl<'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> }
1854
1855impl<'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> }
1856impl<'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! {
1857 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1858}
1859impl<'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> }
1860
1861impl<'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> }
1863
1864macro_rules! sty_debug_print {
1865 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1866 #[allow(non_snake_case)]
1869 mod inner {
1870 use crate::ty::{self, TyCtxt};
1871 use crate::ty::context::InternedInSet;
1872
1873 #[derive(Copy, Clone)]
1874 struct DebugStat {
1875 total: usize,
1876 lt_infer: usize,
1877 ty_infer: usize,
1878 ct_infer: usize,
1879 all_infer: usize,
1880 }
1881
1882 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1883 let mut total = DebugStat {
1884 total: 0,
1885 lt_infer: 0,
1886 ty_infer: 0,
1887 ct_infer: 0,
1888 all_infer: 0,
1889 };
1890 $(let mut $variant = total;)*
1891
1892 for shard in tcx.interners.type_.lock_shards() {
1893 #[allow(rustc::potential_query_instability)]
1895 let types = shard.iter();
1896 for &(InternedInSet(t), ()) in types {
1897 let variant = match t.internee {
1898 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1899 ty::Float(..) | ty::Str | ty::Never => continue,
1900 ty::Error(_) => continue,
1901 $(ty::$variant(..) => &mut $variant,)*
1902 };
1903 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1904 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1905 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1906
1907 variant.total += 1;
1908 total.total += 1;
1909 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1910 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1911 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1912 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1913 }
1914 }
1915 writeln!(fmt, "Ty interner total ty lt ct all")?;
1916 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1917 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1918 stringify!($variant),
1919 uses = $variant.total,
1920 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1921 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1922 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1923 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1924 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1925 )*
1926 writeln!(fmt, " total {uses:6} \
1927 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1928 uses = total.total,
1929 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1930 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1931 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1932 all = total.all_infer as f64 * 100.0 / total.total as f64)
1933 }
1934 }
1935
1936 inner::go($fmt, $ctxt)
1937 }}
1938}
1939
1940impl<'tcx> TyCtxt<'tcx> {
1941 pub fn debug_stats(self) -> impl fmt::Debug {
1942 fmt::from_fn(move |fmt| {
1943 {
#[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!(
1944 fmt,
1945 self,
1946 Adt,
1947 Array,
1948 Slice,
1949 RawPtr,
1950 Ref,
1951 FnDef,
1952 FnPtr,
1953 UnsafeBinder,
1954 Placeholder,
1955 Coroutine,
1956 CoroutineWitness,
1957 Dynamic,
1958 Closure,
1959 CoroutineClosure,
1960 Tuple,
1961 Bound,
1962 Param,
1963 Infer,
1964 Alias,
1965 Pat,
1966 Foreign
1967 )?;
1968
1969 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1970 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1971 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())?;
1972 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1973
1974 Ok(())
1975 })
1976 }
1977}
1978
1979struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1984
1985impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1986 fn clone(&self) -> Self {
1987 *self
1988 }
1989}
1990
1991impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1992
1993impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1994 fn into_pointer(&self) -> *const () {
1995 self.0 as *const _ as *const ()
1996 }
1997}
1998
1999#[allow(rustc::usage_of_ty_tykind)]
2000impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2001 fn borrow(&self) -> &T {
2002 &self.0.internee
2003 }
2004}
2005
2006impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2007 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
2008 self.0.internee == other.0.internee
2011 }
2012}
2013
2014impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
2015
2016impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
2017 fn hash<H: Hasher>(&self, s: &mut H) {
2018 self.0.internee.hash(s)
2020 }
2021}
2022
2023impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
2024 fn borrow(&self) -> &[T] {
2025 &self.0[..]
2026 }
2027}
2028
2029impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
2030 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
2031 self.0[..] == other.0[..]
2034 }
2035}
2036
2037impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
2038
2039impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
2040 fn hash<H: Hasher>(&self, s: &mut H) {
2041 self.0[..].hash(s)
2043 }
2044}
2045
2046impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2047 fn borrow(&self) -> &[T] {
2048 &self.0[..]
2049 }
2050}
2051
2052impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2053 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
2054 self.0[..] == other.0[..]
2057 }
2058}
2059
2060impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
2061
2062impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
2063 fn hash<H: Hasher>(&self, s: &mut H) {
2064 self.0[..].hash(s)
2066 }
2067}
2068
2069macro_rules! direct_interners {
2070 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
2071 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
2072 fn borrow<'a>(&'a self) -> &'a $ty {
2073 &self.0
2074 }
2075 }
2076
2077 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
2078 fn eq(&self, other: &Self) -> bool {
2079 self.0 == other.0
2082 }
2083 }
2084
2085 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
2086
2087 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
2088 fn hash<H: Hasher>(&self, s: &mut H) {
2089 self.0.hash(s)
2092 }
2093 }
2094
2095 impl<'tcx> TyCtxt<'tcx> {
2096 $vis fn $method(self, v: $ty) -> $ret_ty {
2097 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
2098 InternedInSet(self.interners.arena.alloc(v))
2099 }).0))
2100 }
2101 })+
2102 }
2103}
2104
2105impl<'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! {
2109 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2110 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
2111 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
2112 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
2113 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
2114 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2115 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
2116 ExternalConstraints -> ExternalConstraints<'tcx>,
2117}
2118
2119macro_rules! slice_interners {
2120 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
2121 impl<'tcx> TyCtxt<'tcx> {
2122 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
2123 if v.is_empty() {
2124 List::empty()
2125 } else {
2126 self.interners.$field.intern_ref(v, || {
2127 InternedInSet(List::from_arena(&*self.arena, (), v))
2128 }).0
2129 }
2130 })+
2131 }
2132 );
2133}
2134
2135impl<'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!(
2139 const_lists: pub mk_const_list(Const<'tcx>),
2140 args: pub mk_args(GenericArg<'tcx>),
2141 type_lists: pub mk_type_list(Ty<'tcx>),
2142 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2143 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
2144 projs: pub mk_projs(ProjectionKind),
2145 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
2146 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
2147 fields: pub mk_fields(FieldIdx),
2148 local_def_ids: intern_local_def_ids(LocalDefId),
2149 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
2150 patterns: pub mk_patterns(Pattern<'tcx>),
2151 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
2152 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
2153);
2154
2155impl<'tcx> TyCtxt<'tcx> {
2156 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2160 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2161 Ty::new_fn_ptr(
2162 self,
2163 sig.map_bound(|sig| ty::FnSig { fn_sig_kind: sig.fn_sig_kind.set_safe(false), ..sig }),
2164 )
2165 }
2166
2167 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2171 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2172 sig.map_bound(|sig| ty::FnSig { fn_sig_kind: sig.fn_sig_kind.set_safe(false), ..sig })
2173 }
2174
2175 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2178 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2179 self.associated_items(trait_did)
2180 .filter_by_name_unhygienic(assoc_name.name)
2181 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2182 })
2183 }
2184
2185 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2187 let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2188 return false;
2189 };
2190 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2191
2192 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2193 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2194 return false;
2195 };
2196 trait_predicate.trait_ref.def_id == future_trait
2197 && trait_predicate.polarity == PredicatePolarity::Positive
2198 })
2199 }
2200
2201 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2209 sig.map_bound(|s| {
2210 let params = match s.inputs()[0].kind() {
2211 ty::Tuple(params) => *params,
2212 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2213 };
2214 self.mk_fn_sig(
2215 params,
2216 s.output(),
2217 s.fn_sig_kind.set_safe(safety.is_safe()).set_abi(ExternAbi::Rust),
2218 )
2219 })
2220 }
2221
2222 #[inline]
2223 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2224 self.interners.intern_predicate(
2225 binder,
2226 self.sess,
2227 &self.untracked,
2229 )
2230 }
2231
2232 #[inline]
2233 pub fn reuse_or_mk_predicate(
2234 self,
2235 pred: Predicate<'tcx>,
2236 binder: Binder<'tcx, PredicateKind<'tcx>>,
2237 ) -> Predicate<'tcx> {
2238 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2239 }
2240
2241 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2242 self.check_args_compatible_inner(def_id, args, false)
2243 }
2244
2245 fn check_args_compatible_inner(
2246 self,
2247 def_id: DefId,
2248 args: &'tcx [ty::GenericArg<'tcx>],
2249 nested: bool,
2250 ) -> bool {
2251 let generics = self.generics_of(def_id);
2252
2253 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)
2257 && #[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 });
2258 let is_inherent_assoc_type_const =
2259 #[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 })
2260 && #[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 });
2261 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2262 if generics.own_params.len() + 1 != args.len() {
2263 return false;
2264 }
2265
2266 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2267 return false;
2268 }
2269
2270 &args[1..]
2271 } else {
2272 if generics.count() != args.len() {
2273 return false;
2274 }
2275
2276 let (parent_args, own_args) = args.split_at(generics.parent_count);
2277
2278 if let Some(parent) = generics.parent
2279 && !self.check_args_compatible_inner(parent, parent_args, true)
2280 {
2281 return false;
2282 }
2283
2284 own_args
2285 };
2286
2287 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2288 match (¶m.kind, arg.kind()) {
2289 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2290 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2291 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2292 _ => return false,
2293 }
2294 }
2295
2296 true
2297 }
2298
2299 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2302 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2303 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)
2304 && #[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 });
2305 let is_inherent_assoc_type_const =
2306 #[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 })
2307 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(
2308 self.def_kind(self.parent(def_id)),
2309 DefKind::Impl { of_trait: false }
2310 );
2311 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2312 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!(
2313 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2314 self.def_path_str(def_id),
2315 args,
2316 self.mk_args_from_iter(
2318 [self.types.self_param.into()].into_iter().chain(
2319 self.generics_of(def_id)
2320 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2321 .iter()
2322 .copied()
2323 )
2324 )
2325 );
2326 } else {
2327 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!(
2328 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2329 self.def_path_str(def_id),
2330 args,
2331 ty::GenericArgs::identity_for_item(self, def_id)
2332 );
2333 }
2334 }
2335 }
2336
2337 #[inline(always)]
2338 pub(crate) fn check_and_mk_args(
2339 self,
2340 def_id: DefId,
2341 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2342 ) -> GenericArgsRef<'tcx> {
2343 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2344 self.debug_assert_args_compatible(def_id, args);
2345 args
2346 }
2347
2348 #[inline]
2349 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2350 self.interners.intern_const(
2351 kind,
2352 self.sess,
2353 &self.untracked,
2355 )
2356 }
2357
2358 #[allow(rustc::usage_of_ty_tykind)]
2360 #[inline]
2361 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2362 self.interners.intern_ty(
2363 st,
2364 self.sess,
2365 &self.untracked,
2367 )
2368 }
2369
2370 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2371 match param.kind {
2372 GenericParamDefKind::Lifetime => {
2373 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2374 }
2375 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2376 GenericParamDefKind::Const { .. } => {
2377 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2378 .into()
2379 }
2380 }
2381 }
2382
2383 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2384 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2385 }
2386
2387 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2388 self.mk_place_elem(place, PlaceElem::Deref)
2389 }
2390
2391 pub fn mk_place_downcast(
2392 self,
2393 place: Place<'tcx>,
2394 adt_def: AdtDef<'tcx>,
2395 variant_index: VariantIdx,
2396 ) -> Place<'tcx> {
2397 self.mk_place_elem(
2398 place,
2399 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2400 )
2401 }
2402
2403 pub fn mk_place_downcast_unnamed(
2404 self,
2405 place: Place<'tcx>,
2406 variant_index: VariantIdx,
2407 ) -> Place<'tcx> {
2408 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2409 }
2410
2411 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2412 self.mk_place_elem(place, PlaceElem::Index(index))
2413 }
2414
2415 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2419 Place {
2420 local: place.local,
2421 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2422 }
2423 }
2424
2425 pub fn mk_poly_existential_predicates(
2426 self,
2427 eps: &[PolyExistentialPredicate<'tcx>],
2428 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2429 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2430 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!(
2431 eps.array_windows()
2432 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2433 != Ordering::Greater)
2434 );
2435 self.intern_poly_existential_predicates(eps)
2436 }
2437
2438 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2439 self.interners.intern_clauses(clauses)
2443 }
2444
2445 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2446 self.intern_local_def_ids(def_ids)
2450 }
2451
2452 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2453 where
2454 I: Iterator<Item = T>,
2455 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2456 {
2457 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2458 }
2459
2460 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2461 where
2462 I: Iterator<Item = T>,
2463 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2464 {
2465 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2466 }
2467
2468 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2469 where
2470 I: Iterator<Item = T>,
2471 T: CollectAndApply<
2472 &'tcx ty::CapturedPlace<'tcx>,
2473 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2474 >,
2475 {
2476 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2477 }
2478
2479 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2480 where
2481 I: Iterator<Item = T>,
2482 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2483 {
2484 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2485 }
2486
2487 pub fn mk_fn_sig<I, T>(self, inputs: I, output: I::Item, fn_sig_kind: FnSigKind) -> T::Output
2492 where
2493 I: IntoIterator<Item = T>,
2494 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2495 {
2496 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2497 inputs_and_output: self.mk_type_list(xs),
2498 fn_sig_kind,
2499 })
2500 }
2501
2502 pub fn mk_fn_sig_rust_abi<I, T>(
2504 self,
2505 inputs: I,
2506 output: I::Item,
2507 safety: hir::Safety,
2508 ) -> T::Output
2509 where
2510 I: IntoIterator<Item = T>,
2511 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2512 {
2513 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safe(safety.is_safe()))
2514 }
2515
2516 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2518 where
2519 I: IntoIterator<Item = T>,
2520 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2521 {
2522 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safe(true))
2523 }
2524
2525 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2526 where
2527 I: Iterator<Item = T>,
2528 T: CollectAndApply<
2529 PolyExistentialPredicate<'tcx>,
2530 &'tcx List<PolyExistentialPredicate<'tcx>>,
2531 >,
2532 {
2533 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2534 }
2535
2536 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2537 where
2538 I: Iterator<Item = T>,
2539 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2540 {
2541 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2542 }
2543
2544 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2545 where
2546 I: Iterator<Item = T>,
2547 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2548 {
2549 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2550 }
2551
2552 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2553 where
2554 I: Iterator<Item = T>,
2555 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2556 {
2557 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2558 }
2559
2560 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2561 where
2562 I: Iterator<Item = T>,
2563 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2564 {
2565 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2566 }
2567
2568 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2569 where
2570 I: Iterator<Item = T>,
2571 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2572 {
2573 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2574 }
2575
2576 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2577 where
2578 I: Iterator<Item = T>,
2579 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2580 {
2581 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2582 }
2583
2584 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2585 where
2586 I: Iterator<Item = T>,
2587 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2588 {
2589 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2590 }
2591
2592 pub fn mk_args_trait(
2593 self,
2594 self_ty: Ty<'tcx>,
2595 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2596 ) -> GenericArgsRef<'tcx> {
2597 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2598 }
2599
2600 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2601 where
2602 I: Iterator<Item = T>,
2603 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2604 {
2605 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2606 }
2607
2608 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2609 where
2610 I: Iterator<Item = T>,
2611 T: CollectAndApply<
2612 ty::ArgOutlivesPredicate<'tcx>,
2613 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2614 >,
2615 {
2616 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2617 }
2618
2619 #[track_caller]
2622 pub fn emit_node_span_lint(
2623 self,
2624 lint: &'static Lint,
2625 hir_id: HirId,
2626 span: impl Into<MultiSpan>,
2627 decorator: impl for<'a> Diagnostic<'a, ()>,
2628 ) {
2629 let level = self.lint_level_at_node(lint, hir_id);
2630 emit_lint_base(self.sess, lint, level, Some(span.into()), decorator)
2631 }
2632
2633 pub fn crate_level_attribute_injection_span(self) -> Span {
2635 let node = self.hir_node(hir::CRATE_HIR_ID);
2636 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2637 m.spans.inject_use_span.shrink_to_lo()
2638 }
2639
2640 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2641 self,
2642 diag: &mut Diag<'_, E>,
2643 features: impl IntoIterator<Item = (String, Symbol)>,
2644 ) {
2645 if !self.sess.is_nightly_build() {
2646 return;
2647 }
2648
2649 let span = self.crate_level_attribute_injection_span();
2650 for (desc, feature) in features {
2651 let msg =
2653 ::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}");
2654 diag.span_suggestion_verbose(
2655 span,
2656 msg,
2657 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2658 Applicability::MaybeIncorrect,
2659 );
2660 }
2661 }
2662
2663 #[track_caller]
2666 pub fn emit_node_lint(
2667 self,
2668 lint: &'static Lint,
2669 id: HirId,
2670 decorator: impl for<'a> Diagnostic<'a, ()>,
2671 ) {
2672 let level = self.lint_level_at_node(lint, id);
2673 emit_lint_base(self.sess, lint, level, None, decorator);
2674 }
2675
2676 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2677 let map = self.in_scope_traits_map(id.owner)?;
2678 let candidates = map.get(&id.local_id)?;
2679 Some(candidates)
2680 }
2681
2682 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2683 {
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:2683",
"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(2683u32),
::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");
2684 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2685 }
2686
2687 pub fn is_late_bound(self, id: HirId) -> bool {
2688 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2689 }
2690
2691 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2692 self.mk_bound_variable_kinds(
2693 &self
2694 .late_bound_vars_map(id.owner)
2695 .get(&id.local_id)
2696 .cloned()
2697 .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))),
2698 )
2699 }
2700
2701 pub fn map_opaque_lifetime_to_parent_lifetime(
2709 self,
2710 mut opaque_lifetime_param_def_id: LocalDefId,
2711 ) -> ty::Region<'tcx> {
2712 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!(
2713 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2714 "{opaque_lifetime_param_def_id:?} is a {}",
2715 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2716 );
2717
2718 loop {
2719 let parent = self.local_parent(opaque_lifetime_param_def_id);
2720 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2721
2722 let Some((lifetime, _)) = lifetime_mapping
2723 .iter()
2724 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2725 else {
2726 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2727 };
2728
2729 match *lifetime {
2730 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2731 let new_parent = self.local_parent(ebv);
2732
2733 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2736 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);
2737 opaque_lifetime_param_def_id = ebv;
2738 continue;
2739 }
2740
2741 let generics = self.generics_of(new_parent);
2742 return ty::Region::new_early_param(
2743 self,
2744 ty::EarlyParamRegion {
2745 index: generics
2746 .param_def_id_to_index(self, ebv.to_def_id())
2747 .expect("early-bound var should be present in fn generics"),
2748 name: self.item_name(ebv.to_def_id()),
2749 },
2750 );
2751 }
2752 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2753 let new_parent = self.local_parent(lbv);
2754 return ty::Region::new_late_param(
2755 self,
2756 new_parent.to_def_id(),
2757 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2758 );
2759 }
2760 resolve_bound_vars::ResolvedArg::Error(guar) => {
2761 return ty::Region::new_error(self, guar);
2762 }
2763 _ => {
2764 return ty::Region::new_error_with_message(
2765 self,
2766 self.def_span(opaque_lifetime_param_def_id),
2767 "cannot resolve lifetime",
2768 );
2769 }
2770 }
2771 }
2772 }
2773
2774 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2779 self.is_const_fn(def_id)
2780 && match self.lookup_const_stability(def_id) {
2781 None => true, Some(stability) if stability.is_const_stable() => true,
2783 _ => false,
2784 }
2785 }
2786
2787 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2789 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2790 && self.impl_trait_header(def_id).constness == hir::Constness::Const
2791 }
2792
2793 pub fn is_sdylib_interface_build(self) -> bool {
2794 self.sess.opts.unstable_opts.build_sdylib_interface
2795 }
2796
2797 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2798 let def_id = def_id.into_query_key();
2799 match self.def_kind(def_id) {
2800 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2801 _ => None,
2802 }
2803 }
2804
2805 pub fn next_trait_solver_globally(self) -> bool {
2806 self.sess.opts.unstable_opts.next_solver.globally
2807 }
2808
2809 pub fn next_trait_solver_in_coherence(self) -> bool {
2810 self.sess.opts.unstable_opts.next_solver.coherence
2811 }
2812
2813 #[allow(rustc::bad_opt_access)]
2814 pub fn use_typing_mode_borrowck(self) -> bool {
2815 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
2816 }
2817
2818 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2819 self.opt_rpitit_info(def_id).is_some()
2820 }
2821
2822 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2832 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2833 }
2834
2835 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2837 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2838 }
2839
2840 pub fn resolver_for_lowering(
2841 self,
2842 ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc<ast::Crate>)> {
2843 self.resolver_for_lowering_raw(()).0
2844 }
2845
2846 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2847 make_metadata(self)
2848 }
2849
2850 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2851 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2852 self.coroutine_kind(def_id)
2853 && let ty::Coroutine(_, args) =
2854 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2855 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2856 {
2857 true
2858 } else {
2859 false
2860 }
2861 }
2862
2863 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2865 {
{
'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 { .. })
2866 }
2867
2868 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2869 let def_id = def_id.into_query_key();
2870 self.trivial_const(def_id).is_some()
2871 }
2872
2873 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2876 if self.is_lang_item(def_id, LangItem::Start) {
2877 return true;
2878 }
2879 if let Some((entry_def_id, _)) = self.entry_fn(())
2880 && entry_def_id == def_id
2881 {
2882 return true;
2883 }
2884 false
2885 }
2886}
2887
2888pub fn provide(providers: &mut Providers) {
2889 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);
2890 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);
2891 providers.has_panic_handler = |tcx, LocalCrate| {
2892 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2894 };
2895 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2896}