1#![allow(rustc::usage_of_ty_tykind)]
4
5mod impl_interner;
6pub mod tls;
7
8use std::borrow::{Borrow, Cow};
9use std::cmp::Ordering;
10use std::env::VarError;
11use std::ffi::OsStr;
12use std::hash::{Hash, Hasher};
13use std::marker::PointeeSized;
14use std::ops::Deref;
15use std::sync::{Arc, OnceLock};
16use std::{fmt, iter, mem};
17
18use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx};
19use rustc_ast as ast;
20use rustc_data_structures::defer;
21use rustc_data_structures::fx::FxHashMap;
22use rustc_data_structures::intern::Interned;
23use rustc_data_structures::jobserver::Proxy;
24use rustc_data_structures::profiling::SelfProfilerRef;
25use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
26use rustc_data_structures::stable_hash::StableHash;
27use rustc_data_structures::steal::Steal;
28use rustc_data_structures::sync::{
29 self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal,
30};
31use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, MultiSpan};
32use rustc_hir::def::DefKind;
33use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
34use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorState};
35use rustc_hir::intravisit::VisitorExt;
36use rustc_hir::lang_items::LangItem;
37use rustc_hir::limit::Limit;
38use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, MaybeOwner, Node, TraitCandidate, find_attr};
39use rustc_index::IndexVec;
40use rustc_macros::Diagnostic;
41use rustc_session::Session;
42use rustc_session::config::CrateType;
43use rustc_session::cstore::{CrateStoreDyn, Untracked};
44use rustc_session::lint::Lint;
45use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
46use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
47use rustc_type_ir::TyKind::*;
48pub use rustc_type_ir::lift::Lift;
49use rustc_type_ir::{CollectAndApply, WithCachedTypeInfo, elaborate, search_graph};
50use tracing::{debug, instrument};
51
52use crate::arena::Arena;
53use crate::dep_graph::dep_node::make_metadata;
54use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex};
55use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo};
56use crate::ich::StableHashState;
57use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind};
58use crate::lint::emit_lint_base;
59use crate::metadata::ModChild;
60use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
61use crate::middle::resolve_bound_vars;
62use crate::mir::interpret::{self, Allocation, ConstAllocation};
63use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
64use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt};
65use crate::thir::Thir;
66use crate::traits;
67use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
68use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
69use crate::ty::{
70 self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, FnSigKind, GenericArg,
71 GenericArgs, GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst,
72 Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
73 PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
74 ValTree, ValTreeKind, Visibility,
75};
76
77impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
78 fn is_local(self) -> bool {
79 self.is_local()
80 }
81
82 fn as_local(self) -> Option<LocalDefId> {
83 self.as_local()
84 }
85}
86
87impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
88 fn safe() -> Self {
89 hir::Safety::Safe
90 }
91
92 fn unsafe_mode() -> Self {
93 hir::Safety::Unsafe
94 }
95
96 fn is_safe(self) -> bool {
97 self.is_safe()
98 }
99
100 fn prefix_str(self) -> &'static str {
101 self.prefix_str()
102 }
103}
104
105impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_feature::Features {
106 fn generic_const_exprs(self) -> bool {
107 self.generic_const_exprs()
108 }
109
110 fn generic_const_args(self) -> bool {
111 self.generic_const_args()
112 }
113
114 fn coroutine_clone(self) -> bool {
115 self.coroutine_clone()
116 }
117
118 fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool {
119 !self.staged_api() && self.enabled(symbol)
123 }
124}
125
126impl<'tcx> rustc_type_ir::inherent::Span<TyCtxt<'tcx>> for Span {
127 fn dummy() -> Self {
128 DUMMY_SP
129 }
130}
131
132type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
133
134pub struct CtxtInterners<'tcx> {
135 arena: &'tcx WorkerLocal<Arena<'tcx>>,
137
138 type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>,
141 const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
142 args: InternedSet<'tcx, GenericArgs<'tcx>>,
143 type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
144 canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
145 region: InternedSet<'tcx, RegionKind<'tcx>>,
146 poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
147 predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
148 clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
149 projs: InternedSet<'tcx, List<ProjectionKind>>,
150 place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
151 const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
152 pat: InternedSet<'tcx, PatternKind<'tcx>>,
153 const_allocation: InternedSet<'tcx, Allocation>,
154 bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>>,
155 layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
156 adt_def: InternedSet<'tcx, AdtDefData>,
157 external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
158 predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
159 fields: InternedSet<'tcx, List<FieldIdx>>,
160 local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
161 captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
162 valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
163 patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
164 outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
165}
166
167impl<'tcx> CtxtInterners<'tcx> {
168 fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
169 const N: usize = 2048;
172 CtxtInterners {
173 arena,
174 type_: InternedSet::with_capacity(N * 16),
179 const_lists: InternedSet::with_capacity(N * 4),
180 args: InternedSet::with_capacity(N * 4),
181 type_lists: InternedSet::with_capacity(N * 4),
182 region: InternedSet::with_capacity(N * 4),
183 poly_existential_predicates: InternedSet::with_capacity(N / 4),
184 canonical_var_kinds: InternedSet::with_capacity(N / 2),
185 predicate: InternedSet::with_capacity(N),
186 clauses: InternedSet::with_capacity(N),
187 projs: InternedSet::with_capacity(N * 4),
188 place_elems: InternedSet::with_capacity(N * 2),
189 const_: InternedSet::with_capacity(N * 2),
190 pat: InternedSet::with_capacity(N),
191 const_allocation: InternedSet::with_capacity(N),
192 bound_variable_kinds: InternedSet::with_capacity(N * 2),
193 layout: InternedSet::with_capacity(N),
194 adt_def: InternedSet::with_capacity(N),
195 external_constraints: InternedSet::with_capacity(N),
196 predefined_opaques_in_body: InternedSet::with_capacity(N),
197 fields: InternedSet::with_capacity(N * 4),
198 local_def_ids: InternedSet::with_capacity(N),
199 captures: InternedSet::with_capacity(N),
200 valtree: InternedSet::with_capacity(N),
201 patterns: InternedSet::with_capacity(N),
202 outlives: InternedSet::with_capacity(N),
203 }
204 }
205
206 #[allow(rustc::usage_of_ty_tykind)]
208 #[inline(never)]
209 fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
210 Ty(Interned::new_unchecked(
211 self.type_
212 .intern(kind, |kind| {
213 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_kind(&kind);
214 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
215 internee: kind,
216 flags: flags.flags,
217 outer_exclusive_binder: flags.outer_exclusive_binder,
218 }))
219 })
220 .0,
221 ))
222 }
223
224 #[allow(rustc::usage_of_ty_tykind)]
226 #[inline(never)]
227 fn intern_const(&self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
228 Const(Interned::new_unchecked(
229 self.const_
230 .intern(kind, |kind: ty::ConstKind<'_>| {
231 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_const_kind(&kind);
232 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
233 internee: kind,
234 flags: flags.flags,
235 outer_exclusive_binder: flags.outer_exclusive_binder,
236 }))
237 })
238 .0,
239 ))
240 }
241
242 #[inline(never)]
244 fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
245 Predicate(Interned::new_unchecked(
246 self.predicate
247 .intern(kind, |kind| {
248 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_predicate(kind);
249 InternedInSet(self.arena.alloc(WithCachedTypeInfo {
250 internee: kind,
251 flags: flags.flags,
252 outer_exclusive_binder: flags.outer_exclusive_binder,
253 }))
254 })
255 .0,
256 ))
257 }
258
259 fn intern_clauses(&self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
260 if clauses.is_empty() {
261 ListWithCachedTypeInfo::empty()
262 } else {
263 self.clauses
264 .intern_ref(clauses, || {
265 let flags = ty::FlagComputation::<TyCtxt<'tcx>>::for_clauses(clauses);
266
267 InternedInSet(ListWithCachedTypeInfo::from_arena(
268 &*self.arena,
269 flags.into(),
270 clauses,
271 ))
272 })
273 .0
274 }
275 }
276}
277
278const NUM_PREINTERNED_TY_VARS: u32 = 100;
283const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
284const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
285const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
286const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
287
288const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
298
299const NUM_PREINTERNED_RE_VARS: u32 = 500;
301const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3;
302const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20;
303
304pub struct CommonTypes<'tcx> {
305 pub unit: Ty<'tcx>,
306 pub bool: Ty<'tcx>,
307 pub char: Ty<'tcx>,
308 pub isize: Ty<'tcx>,
309 pub i8: Ty<'tcx>,
310 pub i16: Ty<'tcx>,
311 pub i32: Ty<'tcx>,
312 pub i64: Ty<'tcx>,
313 pub i128: Ty<'tcx>,
314 pub usize: Ty<'tcx>,
315 pub u8: Ty<'tcx>,
316 pub u16: Ty<'tcx>,
317 pub u32: Ty<'tcx>,
318 pub u64: Ty<'tcx>,
319 pub u128: Ty<'tcx>,
320 pub f16: Ty<'tcx>,
321 pub f32: Ty<'tcx>,
322 pub f64: Ty<'tcx>,
323 pub f128: Ty<'tcx>,
324 pub str_: Ty<'tcx>,
325 pub never: Ty<'tcx>,
326 pub self_param: Ty<'tcx>,
327
328 pub trait_object_dummy_self: Ty<'tcx>,
333
334 pub ty_vars: Vec<Ty<'tcx>>,
336
337 pub fresh_tys: Vec<Ty<'tcx>>,
339
340 pub fresh_int_tys: Vec<Ty<'tcx>>,
342
343 pub fresh_float_tys: Vec<Ty<'tcx>>,
345
346 pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
350
351 pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
355}
356
357pub struct CommonLifetimes<'tcx> {
358 pub re_static: Region<'tcx>,
360
361 pub re_erased: Region<'tcx>,
363
364 pub re_vars: Vec<Region<'tcx>>,
366
367 pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
371
372 pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
376}
377
378pub struct CommonConsts<'tcx> {
379 pub unit: Const<'tcx>,
380 pub true_: Const<'tcx>,
381 pub false_: Const<'tcx>,
382 pub(crate) valtree_zst: ValTree<'tcx>,
384}
385
386impl<'tcx> CommonTypes<'tcx> {
387 fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
388 let mk = |ty| interners.intern_ty(ty);
389
390 let ty_vars =
391 (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect();
392 let fresh_tys: Vec<_> =
393 (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect();
394 let fresh_int_tys: Vec<_> =
395 (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect();
396 let fresh_float_tys: Vec<_> =
397 (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
398
399 let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
400 .map(|i| {
401 (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
402 .map(|v| {
403 mk(ty::Bound(
404 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
405 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
406 ))
407 })
408 .collect()
409 })
410 .collect();
411
412 let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
413 .map(|v| {
414 mk(ty::Bound(
415 ty::BoundVarIndexKind::Canonical,
416 ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
417 ))
418 })
419 .collect();
420
421 CommonTypes {
422 unit: mk(Tuple(List::empty())),
423 bool: mk(Bool),
424 char: mk(Char),
425 never: mk(Never),
426 isize: mk(Int(ty::IntTy::Isize)),
427 i8: mk(Int(ty::IntTy::I8)),
428 i16: mk(Int(ty::IntTy::I16)),
429 i32: mk(Int(ty::IntTy::I32)),
430 i64: mk(Int(ty::IntTy::I64)),
431 i128: mk(Int(ty::IntTy::I128)),
432 usize: mk(Uint(ty::UintTy::Usize)),
433 u8: mk(Uint(ty::UintTy::U8)),
434 u16: mk(Uint(ty::UintTy::U16)),
435 u32: mk(Uint(ty::UintTy::U32)),
436 u64: mk(Uint(ty::UintTy::U64)),
437 u128: mk(Uint(ty::UintTy::U128)),
438 f16: mk(Float(ty::FloatTy::F16)),
439 f32: mk(Float(ty::FloatTy::F32)),
440 f64: mk(Float(ty::FloatTy::F64)),
441 f128: mk(Float(ty::FloatTy::F128)),
442 str_: mk(Str),
443 self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
444
445 trait_object_dummy_self: fresh_tys[0],
446
447 ty_vars,
448 fresh_tys,
449 fresh_int_tys,
450 fresh_float_tys,
451 anon_bound_tys,
452 anon_canonical_bound_tys,
453 }
454 }
455}
456
457impl<'tcx> CommonLifetimes<'tcx> {
458 fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
459 let mk = |r| {
460 Region(Interned::new_unchecked(
461 interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
462 ))
463 };
464
465 let re_vars =
466 (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect();
467
468 let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I)
469 .map(|i| {
470 (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
471 .map(|v| {
472 mk(ty::ReBound(
473 ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
474 ty::BoundRegion {
475 var: ty::BoundVar::from(v),
476 kind: ty::BoundRegionKind::Anon,
477 },
478 ))
479 })
480 .collect()
481 })
482 .collect();
483
484 let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
485 .map(|v| {
486 mk(ty::ReBound(
487 ty::BoundVarIndexKind::Canonical,
488 ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
489 ))
490 })
491 .collect();
492
493 CommonLifetimes {
494 re_static: mk(ty::ReStatic),
495 re_erased: mk(ty::ReErased),
496 re_vars,
497 anon_re_bounds,
498 anon_re_canonical_bounds,
499 }
500 }
501}
502
503impl<'tcx> CommonConsts<'tcx> {
504 fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
505 let mk_const = |c| interners.intern_const(c);
506
507 let mk_valtree = |v| {
508 ty::ValTree(Interned::new_unchecked(
509 interners.valtree.intern(v, |v| InternedInSet(interners.arena.alloc(v))).0,
510 ))
511 };
512
513 let valtree_zst = mk_valtree(ty::ValTreeKind::Branch(List::empty()));
514 let valtree_true = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::TRUE));
515 let valtree_false = mk_valtree(ty::ValTreeKind::Leaf(ty::ScalarInt::FALSE));
516
517 CommonConsts {
518 unit: mk_const(ty::ConstKind::Value(ty::Value {
519 ty: types.unit,
520 valtree: valtree_zst,
521 })),
522 true_: mk_const(ty::ConstKind::Value(ty::Value {
523 ty: types.bool,
524 valtree: valtree_true,
525 })),
526 false_: mk_const(ty::ConstKind::Value(ty::Value {
527 ty: types.bool,
528 valtree: valtree_false,
529 })),
530 valtree_zst,
531 }
532 }
533}
534
535#[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)]
538pub struct FreeRegionInfo {
539 pub scope: LocalDefId,
541 pub region_def_id: DefId,
543 pub is_impl_item: bool,
545}
546
547#[derive(#[automatically_derived]
impl<'tcx, K: ::core::marker::Copy + Copy> ::core::marker::Copy for
TyCtxtFeed<'tcx, K> {
}Copy, #[automatically_derived]
impl<'tcx, K: ::core::clone::Clone + Copy> ::core::clone::Clone for
TyCtxtFeed<'tcx, K> {
#[inline]
fn clone(&self) -> TyCtxtFeed<'tcx, K> {
TyCtxtFeed {
tcx: ::core::clone::Clone::clone(&self.tcx),
key: ::core::clone::Clone::clone(&self.key),
}
}
}Clone)]
549pub struct TyCtxtFeed<'tcx, K: Copy> {
550 pub tcx: TyCtxt<'tcx>,
551 key: K,
553}
554
555impl<K: Copy> !StableHash for TyCtxtFeed<'_, K> {}
557
558impl<'tcx> TyCtxt<'tcx> {
563 pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
566 self.dep_graph.assert_ignored();
567 TyCtxtFeed { tcx: self, key: () }
568 }
569
570 pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
573 let key = self.untracked().source_span.push(span);
574 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);
575 TyCtxtFeed { tcx: self, key }
576 }
577
578 pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
582 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);
583 TyCtxtFeed { tcx: self, key }.type_of(value)
584 }
585
586 pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) {
588 self.dep_graph.assert_ignored();
589 TyCtxtFeed { tcx: self, key }.hir_delayed_owner(owner);
590 }
591
592 pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
600 if truecfg!(debug_assertions) {
601 match self.def_kind(self.local_parent(key)) {
602 DefKind::Impl { of_trait: true } => {}
603 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:?}"),
604 }
605 }
606 TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id())
607 }
608}
609
610impl<'tcx, K: Copy> TyCtxtFeed<'tcx, K> {
611 #[inline(always)]
612 pub fn key(&self) -> K {
613 self.key
614 }
615}
616
617impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
618 #[inline(always)]
619 pub fn def_id(&self) -> LocalDefId {
620 self.key
621 }
622
623 pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
625 TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
626 }
627
628 pub fn feed_hir(&self) {
630 self.hir_owner(ProjectedMaybeOwner::Owner(ProjectedOwnerInfo::new(
631 self.tcx.arena.alloc(hir::OwnerNodes::synthetic()),
632 self.tcx.arena.alloc(Default::default()),
633 self.tcx.arena.alloc(Default::default()),
634 self.tcx.arena.alloc(Steal::new(Default::default())),
635 )));
636
637 self.feed_owner_id().hir_attr_map(hir::AttributeMap::EMPTY);
638 }
639}
640
641#[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)]
659#[rustc_diagnostic_item = "TyCtxt"]
660#[rustc_pass_by_value]
661pub struct TyCtxt<'tcx> {
662 gcx: &'tcx GlobalCtxt<'tcx>,
663}
664
665unsafe impl DynSend for TyCtxt<'_> {}
669unsafe impl DynSync for TyCtxt<'_> {}
670fn _assert_tcx_fields() {
671 sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
672 sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
673}
674
675impl<'tcx> Deref for TyCtxt<'tcx> {
676 type Target = &'tcx GlobalCtxt<'tcx>;
677 #[inline(always)]
678 fn deref(&self) -> &Self::Target {
679 &self.gcx
680 }
681}
682
683pub struct GlobalCtxt<'tcx> {
685 pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
686 pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
687
688 interners: CtxtInterners<'tcx>,
689
690 pub sess: &'tcx Session,
691 crate_types: Vec<CrateType>,
692 stable_crate_id: StableCrateId,
698
699 pub dep_graph: DepGraph,
700
701 pub prof: SelfProfilerRef,
702
703 pub types: CommonTypes<'tcx>,
705
706 pub lifetimes: CommonLifetimes<'tcx>,
708
709 pub consts: CommonConsts<'tcx>,
711
712 pub(crate) hooks: crate::hooks::Providers,
715
716 untracked: Untracked,
717
718 pub query_system: QuerySystem<'tcx>,
719 pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
720
721 pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
723
724 pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
727
728 pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
732
733 pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
735 pub new_solver_canonical_param_env_cache:
736 Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
737
738 pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
739
740 pub highest_var_in_clauses_cache: Lock<FxHashMap<ty::Clauses<'tcx>, usize>>,
742 pub clauses_cache:
744 Lock<FxHashMap<(ty::Clauses<'tcx>, &'tcx [ty::GenericArg<'tcx>]), ty::Clauses<'tcx>>>,
745
746 pub data_layout: TargetDataLayout,
748
749 pub(crate) alloc_map: interpret::AllocMap<'tcx>,
751
752 current_gcx: CurrentGcx,
753
754 pub jobserver_proxy: Arc<Proxy>,
756}
757
758impl<'tcx> GlobalCtxt<'tcx> {
759 pub fn enter<F, R>(&'tcx self, f: F) -> R
762 where
763 F: FnOnce(TyCtxt<'tcx>) -> R,
764 {
765 let icx = tls::ImplicitCtxt::new(self);
766
767 let _on_drop = defer(move || {
769 *self.current_gcx.value.write() = None;
770 });
771
772 {
774 let mut guard = self.current_gcx.value.write();
775 if !guard.is_none() {
{
::core::panicking::panic_fmt(format_args!("no `GlobalCtxt` is currently set"));
}
};assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
776 *guard = Some(self as *const _ as *const ());
777 }
778
779 tls::enter_context(&icx, || f(icx.tcx))
780 }
781}
782
783#[derive(#[automatically_derived]
impl ::core::clone::Clone for CurrentGcx {
#[inline]
fn clone(&self) -> CurrentGcx {
CurrentGcx { value: ::core::clone::Clone::clone(&self.value) }
}
}Clone)]
790pub struct CurrentGcx {
791 value: Arc<RwLock<Option<*const ()>>>,
794}
795
796unsafe impl DynSend for CurrentGcx {}
797unsafe impl DynSync for CurrentGcx {}
798
799impl CurrentGcx {
800 pub fn new() -> Self {
801 Self { value: Arc::new(RwLock::new(None)) }
802 }
803
804 pub fn access<R>(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R {
805 let read_guard = self.value.read();
806 let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _;
807 f(unsafe { &*gcx })
811 }
812}
813
814impl<'tcx> TyCtxt<'tcx> {
815 pub fn has_typeck_results(self, def_id: LocalDefId) -> bool {
816 let root = self.typeck_root_def_id_local(def_id);
819 self.hir_node_by_def_id(root).body_id().is_some()
820 }
821
822 pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
827 let def_kind = self.def_kind(def_id);
828 if def_kind.has_codegen_attrs() {
829 self.codegen_fn_attrs(def_id)
830 } else if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst | DefKind::AssocConst { .. } | DefKind::Const { .. } |
DefKind::InlineConst | DefKind::GlobalAsm => true,
_ => false,
}matches!(
831 def_kind,
832 DefKind::AnonConst
833 | DefKind::AssocConst { .. }
834 | DefKind::Const { .. }
835 | DefKind::InlineConst
836 | DefKind::GlobalAsm
837 ) {
838 CodegenFnAttrs::EMPTY
839 } else {
840 crate::util::bug::bug_fmt(format_args!("body_codegen_fn_attrs called on unexpected definition: {0:?} {1:?}",
def_id, def_kind))bug!(
841 "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
842 def_id,
843 def_kind
844 )
845 }
846 }
847
848 pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
849 self.arena.alloc(Steal::new(thir))
850 }
851
852 pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
853 self.arena.alloc(Steal::new(mir))
854 }
855
856 pub fn alloc_steal_promoted(
857 self,
858 promoted: IndexVec<Promoted, Body<'tcx>>,
859 ) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
860 self.arena.alloc(Steal::new(promoted))
861 }
862
863 pub fn mk_adt_def(
864 self,
865 did: DefId,
866 kind: AdtKind,
867 variants: IndexVec<VariantIdx, ty::VariantDef>,
868 repr: ReprOptions,
869 ) -> ty::AdtDef<'tcx> {
870 self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
871 }
872
873 pub fn allocate_bytes_dedup<'a>(
876 self,
877 bytes: impl Into<Cow<'a, [u8]>>,
878 salt: usize,
879 ) -> interpret::AllocId {
880 let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
882 let alloc = self.mk_const_alloc(alloc);
883 self.reserve_and_set_memory_dedup(alloc, salt)
884 }
885
886 pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
888 if self.sess.opts.unstable_opts.experimental_default_bounds {
889 &[
890 LangItem::DefaultTrait1,
891 LangItem::DefaultTrait2,
892 LangItem::DefaultTrait3,
893 LangItem::DefaultTrait4,
894 ]
895 } else {
896 &[]
897 }
898 }
899
900 pub fn is_default_trait(self, def_id: DefId) -> bool {
901 self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
902 }
903
904 pub fn is_sizedness_trait(self, def_id: DefId) -> bool {
905 #[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))
906 }
907
908 pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> T::Lifted {
909 value.lift_to_interner(self)
910 }
911
912 pub fn create_global_ctxt<T>(
919 gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
920 sess: &'tcx Session,
921 crate_types: Vec<CrateType>,
922 stable_crate_id: StableCrateId,
923 arena: &'tcx WorkerLocal<Arena<'tcx>>,
924 hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
925 untracked: Untracked,
926 dep_graph: DepGraph,
927 dep_kind_vtables: &'tcx [DepKindVTable<'tcx>],
928 query_system: QuerySystem<'tcx>,
929 hooks: crate::hooks::Providers,
930 current_gcx: CurrentGcx,
931 jobserver_proxy: Arc<Proxy>,
932 f: impl FnOnce(TyCtxt<'tcx>) -> T,
933 ) -> T {
934 let data_layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
935 sess.dcx().emit_fatal(err);
936 });
937 let interners = CtxtInterners::new(arena);
938 let common_types = CommonTypes::new(&interners);
939 let common_lifetimes = CommonLifetimes::new(&interners);
940 let common_consts = CommonConsts::new(&interners, &common_types);
941
942 let gcx = gcx_cell.get_or_init(|| GlobalCtxt {
943 sess,
944 crate_types,
945 stable_crate_id,
946 arena,
947 hir_arena,
948 interners,
949 dep_graph,
950 hooks,
951 prof: sess.prof.clone(),
952 types: common_types,
953 lifetimes: common_lifetimes,
954 consts: common_consts,
955 untracked,
956 query_system,
957 dep_kind_vtables,
958 ty_rcache: Default::default(),
959 selection_cache: Default::default(),
960 evaluation_cache: Default::default(),
961 new_solver_evaluation_cache: Default::default(),
962 new_solver_canonical_param_env_cache: Default::default(),
963 canonical_param_env_cache: Default::default(),
964 highest_var_in_clauses_cache: Default::default(),
965 clauses_cache: Default::default(),
966 data_layout,
967 alloc_map: interpret::AllocMap::new(),
968 current_gcx,
969 jobserver_proxy,
970 });
971
972 gcx.enter(f)
974 }
975
976 pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
978 self.get_lang_items(())
979 }
980
981 #[track_caller]
983 pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
984 let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
985 self.type_of(ordering_enum).no_bound_vars().unwrap()
986 }
987
988 pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
991 self.all_diagnostic_items(()).name_to_id.get(&name).copied()
992 }
993
994 pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
996 self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
997 }
998
999 pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1001 self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
1002 }
1003
1004 pub fn is_coroutine(self, def_id: DefId) -> bool {
1005 self.coroutine_kind(def_id).is_some()
1006 }
1007
1008 pub fn is_async_drop_in_place_coroutine(self, def_id: DefId) -> bool {
1009 self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
1010 }
1011
1012 pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
1013 if !self.is_type_const(def_id) {
1014 return None;
1015 }
1016 Some(self.def_span(def_id))
1017 }
1018
1019 pub fn is_type_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
1021 let def_id = def_id.into_query_key();
1022 match self.def_kind(def_id) {
1023 DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => {
1024 is_type_const
1025 }
1026 _ => false,
1027 }
1028 }
1029
1030 pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability {
1033 self.coroutine_kind(def_id).expect("expected a coroutine").movability()
1034 }
1035
1036 pub fn coroutine_is_async(self, def_id: DefId) -> bool {
1038 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) =>
true,
_ => false,
}matches!(
1039 self.coroutine_kind(def_id),
1040 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _))
1041 )
1042 }
1043
1044 pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
1047 #[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)
1048 }
1049
1050 pub fn is_general_coroutine(self, def_id: DefId) -> bool {
1053 #[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(_)))
1054 }
1055
1056 pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
1058 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) =>
true,
_ => false,
}matches!(
1059 self.coroutine_kind(def_id),
1060 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
1061 )
1062 }
1063
1064 pub fn coroutine_is_async_gen(self, def_id: DefId) -> bool {
1066 #[allow(non_exhaustive_omitted_patterns)] match self.coroutine_kind(def_id) {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
=> true,
_ => false,
}matches!(
1067 self.coroutine_kind(def_id),
1068 Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _))
1069 )
1070 }
1071
1072 pub fn features(self) -> &'tcx rustc_feature::Features {
1073 self.features_query(())
1074 }
1075
1076 pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey {
1077 let id = id.into_query_key();
1078 if let Some(id) = id.as_local() {
1080 self.definitions_untracked().def_key(id)
1081 } else {
1082 self.cstore_untracked().def_key(id)
1083 }
1084 }
1085
1086 pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
1092 if let Some(id) = id.as_local() {
1094 self.definitions_untracked().def_path(id)
1095 } else {
1096 self.cstore_untracked().def_path(id)
1097 }
1098 }
1099
1100 #[inline]
1101 pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
1102 if let Some(def_id) = def_id.as_local() {
1104 self.definitions_untracked().def_path_hash(def_id)
1105 } else {
1106 self.cstore_untracked().def_path_hash(def_id)
1107 }
1108 }
1109
1110 #[inline]
1111 pub fn crate_types(self) -> &'tcx [CrateType] {
1112 &self.crate_types
1113 }
1114
1115 pub fn needs_metadata(self) -> bool {
1116 self.crate_types().iter().any(|ty| match *ty {
1117 CrateType::Executable
1118 | CrateType::StaticLib
1119 | CrateType::Cdylib
1120 | CrateType::Sdylib => false,
1121 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1122 })
1123 }
1124
1125 pub fn needs_hir_hash(self) -> bool {
1126 truecfg!(debug_assertions)
1138 || self.sess.opts.incremental.is_some()
1139 || self.needs_metadata()
1140 || self.sess.instrument_coverage()
1141 || self.sess.opts.unstable_opts.metrics_dir.is_some()
1142 }
1143
1144 #[inline]
1145 pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId {
1146 if crate_num == LOCAL_CRATE {
1147 self.stable_crate_id
1148 } else {
1149 self.cstore_untracked().stable_crate_id(crate_num)
1150 }
1151 }
1152
1153 #[inline]
1156 pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum {
1157 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1158 LOCAL_CRATE
1159 } else {
1160 *self
1161 .untracked()
1162 .stable_crate_ids
1163 .read()
1164 .get(&stable_crate_id)
1165 .unwrap_or_else(|| crate::util::bug::bug_fmt(format_args!("uninterned StableCrateId: {0:?}",
stable_crate_id))bug!("uninterned StableCrateId: {stable_crate_id:?}"))
1166 }
1167 }
1168
1169 pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
1173 {
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:1173",
"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(1173u32),
::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);
1174
1175 let stable_crate_id = hash.stable_crate_id();
1176
1177 if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1180 Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
1181 } else {
1182 self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1183 }
1184 }
1185
1186 pub fn def_path_debug_str(self, def_id: DefId) -> String {
1187 let (crate_name, stable_crate_id) = if def_id.is_local() {
1192 (self.crate_name(LOCAL_CRATE), self.stable_crate_id(LOCAL_CRATE))
1193 } else {
1194 let cstore = &*self.cstore_untracked();
1195 (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
1196 };
1197
1198 ::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!(
1199 "{}[{:04x}]{}",
1200 crate_name,
1201 stable_crate_id.as_u64() >> (8 * 6),
1204 self.def_path(def_id).to_string_no_crate_verbose()
1205 )
1206 }
1207
1208 pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
1209 self.sess.dcx()
1210 }
1211
1212 pub fn is_target_feature_call_safe(
1215 self,
1216 callee_features: &[TargetFeature],
1217 body_features: &[TargetFeature],
1218 ) -> bool {
1219 self.sess.target.options.is_like_wasm
1224 || callee_features
1225 .iter()
1226 .all(|feature| body_features.iter().any(|f| f.name == feature.name))
1227 }
1228
1229 pub fn adjust_target_feature_sig(
1232 self,
1233 fun_def: DefId,
1234 fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
1235 caller: DefId,
1236 ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
1237 let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
1238 let caller_features = &self.body_codegen_attrs(caller).target_features;
1239 if self.is_target_feature_call_safe(&fun_features, &caller_features) {
1240 return Some(fun_sig.map_bound(|sig| ty::FnSig {
1241 fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
1242 ..sig
1243 }));
1244 }
1245 None
1246 }
1247
1248 pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
1251 match self.env_var_os(key.as_ref()) {
1252 Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
1253 None => Err(VarError::NotPresent),
1254 }
1255 }
1256}
1257
1258impl<'tcx> TyCtxtAt<'tcx> {
1259 pub fn create_def(
1261 self,
1262 parent: LocalDefId,
1263 name: Option<Symbol>,
1264 def_kind: DefKind,
1265 override_def_path_data: Option<DefPathData>,
1266 disambiguator: &mut PerParentDisambiguatorState,
1267 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1268 let feed =
1269 self.tcx.create_def(parent, name, def_kind, override_def_path_data, disambiguator);
1270
1271 feed.def_span(self.span);
1272 feed
1273 }
1274}
1275
1276impl<'tcx> TyCtxt<'tcx> {
1277 pub fn create_def(
1279 self,
1280 parent: LocalDefId,
1281 name: Option<Symbol>,
1282 def_kind: DefKind,
1283 override_def_path_data: Option<DefPathData>,
1284 disambiguator: &mut PerParentDisambiguatorState,
1285 ) -> TyCtxtFeed<'tcx, LocalDefId> {
1286 let data = override_def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
1287 let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
1297
1298 self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
1303
1304 let feed = TyCtxtFeed { tcx: self, key: def_id };
1305 feed.def_kind(def_kind);
1306 if #[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::Closure | DefKind::OpaqueTy => true,
_ => false,
}matches!(def_kind, DefKind::Closure | DefKind::OpaqueTy) {
1311 let parent_mod = self.parent_module_from_def_id(def_id).to_def_id();
1312 feed.visibility(ty::Visibility::Restricted(parent_mod));
1313 }
1314
1315 feed
1316 }
1317
1318 pub fn create_crate_num(
1319 self,
1320 stable_crate_id: StableCrateId,
1321 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1322 let mut lock = self.untracked().stable_crate_ids.write();
1323 if let Some(&existing) = lock.get(&stable_crate_id) {
1324 return Err(existing);
1325 }
1326 let num = CrateNum::new(lock.len());
1327 lock.insert(stable_crate_id, num);
1328 Ok(TyCtxtFeed { key: num, tcx: self })
1329 }
1330
1331 pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> {
1332 self.ensure_ok().analysis(());
1334
1335 let definitions = &self.untracked.definitions;
1336 gen {
1337 let mut i = 0;
1338
1339 while i < { definitions.read().num_definitions() } {
1342 let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
1343 yield LocalDefId { local_def_index };
1344 i += 1;
1345 }
1346
1347 definitions.freeze();
1349 }
1350 }
1351
1352 pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1353 self.ensure_ok().analysis(());
1355
1356 self.untracked.definitions.freeze().def_path_table()
1359 }
1360
1361 pub fn def_path_hash_to_def_index_map(
1362 self,
1363 ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
1364 self.ensure_ok().hir_crate_items(());
1367 self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
1370 }
1371
1372 #[inline]
1375 pub fn cstore_untracked(self) -> FreezeReadGuard<'tcx, CrateStoreDyn> {
1376 FreezeReadGuard::map(self.untracked.cstore.read(), |c| &**c)
1377 }
1378
1379 pub fn untracked(self) -> &'tcx Untracked {
1381 &self.untracked
1382 }
1383 #[inline]
1386 pub fn definitions_untracked(self) -> FreezeReadGuard<'tcx, Definitions> {
1387 self.untracked.definitions.read()
1388 }
1389
1390 #[inline]
1393 pub fn source_span_untracked(self, def_id: LocalDefId) -> Span {
1394 self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP)
1395 }
1396
1397 #[inline(always)]
1398 pub fn with_stable_hashing_context<R>(self, f: impl FnOnce(StableHashState<'_>) -> R) -> R {
1399 f(StableHashState::new(self.sess, &self.untracked))
1400 }
1401
1402 #[inline]
1403 pub fn local_crate_exports_generics(self) -> bool {
1404 if self.is_compiler_builtins(LOCAL_CRATE) {
1408 return false;
1409 }
1410 self.crate_types().iter().any(|crate_type| {
1411 match crate_type {
1412 CrateType::Executable
1413 | CrateType::StaticLib
1414 | CrateType::ProcMacro
1415 | CrateType::Cdylib
1416 | CrateType::Sdylib => false,
1417
1418 CrateType::Dylib => true,
1423
1424 CrateType::Rlib => true,
1425 }
1426 })
1427 }
1428
1429 pub fn is_suitable_region(
1431 self,
1432 generic_param_scope: LocalDefId,
1433 mut region: Region<'tcx>,
1434 ) -> Option<FreeRegionInfo> {
1435 let (suitable_region_binding_scope, region_def_id) = loop {
1436 let def_id =
1437 region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?;
1438 let scope = self.local_parent(def_id);
1439 if self.def_kind(scope) == DefKind::OpaqueTy {
1440 region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
1443 continue;
1444 }
1445 break (scope, def_id.into());
1446 };
1447
1448 let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
1449 Node::Item(..) | Node::TraitItem(..) => false,
1450 Node::ImplItem(impl_item) => match impl_item.impl_kind {
1451 hir::ImplItemImplKind::Trait { .. } => true,
1458 _ => false,
1459 },
1460 _ => false,
1461 };
1462
1463 Some(FreeRegionInfo { scope: suitable_region_binding_scope, region_def_id, is_impl_item })
1464 }
1465
1466 pub fn return_type_impl_or_dyn_traits(
1468 self,
1469 scope_def_id: LocalDefId,
1470 ) -> Vec<&'tcx hir::Ty<'tcx>> {
1471 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1472 let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
1473 self.hir_fn_decl_by_hir_id(hir_id)
1474 else {
1475 return ::alloc::vec::Vec::new()vec![];
1476 };
1477
1478 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1479 v.visit_ty_unambig(hir_output);
1480 v.0
1481 }
1482
1483 pub fn return_type_impl_or_dyn_traits_with_type_alias(
1487 self,
1488 scope_def_id: LocalDefId,
1489 ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
1490 let hir_id = self.local_def_id_to_hir_id(scope_def_id);
1491 let mut v = TraitObjectVisitor(::alloc::vec::Vec::new()vec![]);
1492 if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id)
1494 && let hir::TyKind::Path(hir::QPath::Resolved(
1495 None,
1496 hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
1497 && let Some(local_id) = def_id.as_local()
1498 && 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()
1500 {
1501 v.visit_ty_unambig(alias_ty);
1502 if !v.0.is_empty() {
1503 return Some((
1504 v.0,
1505 alias_generics.span,
1506 alias_generics.span_for_lifetime_suggestion(),
1507 ));
1508 }
1509 }
1510 None
1511 }
1512
1513 pub fn has_strict_asm_symbol_naming(self) -> bool {
1516 self.sess.target.llvm_target.starts_with("nvptx")
1517 }
1518
1519 pub fn caller_location_ty(self) -> Ty<'tcx> {
1521 Ty::new_imm_ref(
1522 self,
1523 self.lifetimes.re_static,
1524 self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
1525 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()]))
1526 .skip_norm_wip(),
1527 )
1528 }
1529
1530 pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
1532 let kind = self.def_kind(def_id);
1533 (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id))
1534 }
1535
1536 pub fn type_length_limit(self) -> Limit {
1537 self.limits(()).type_length_limit
1538 }
1539
1540 pub fn recursion_limit(self) -> Limit {
1541 self.limits(()).recursion_limit
1542 }
1543
1544 pub fn move_size_limit(self) -> Limit {
1545 self.limits(()).move_size_limit
1546 }
1547
1548 pub fn pattern_complexity_limit(self) -> Limit {
1549 self.limits(()).pattern_complexity_limit
1550 }
1551
1552 pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
1554 iter::once(LOCAL_CRATE)
1555 .chain(self.crates(()).iter().copied())
1556 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1557 }
1558
1559 pub fn visible_traits(self) -> impl Iterator<Item = DefId> {
1561 let visible_crates =
1562 self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
1563
1564 iter::once(LOCAL_CRATE)
1565 .chain(visible_crates)
1566 .flat_map(move |cnum| self.traits(cnum).iter().copied())
1567 }
1568
1569 #[inline]
1570 pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
1571 self.visibility(def_id).expect_local()
1572 }
1573
1574 x;#[instrument(skip(self), level = "trace", ret)]
1576 pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
1577 self.hir_expect_opaque_ty(def_id).origin
1578 }
1579
1580 pub fn finish(self) {
1581 self.alloc_self_profile_query_strings();
1584
1585 self.save_dep_graph();
1586 self.verify_query_key_hashes();
1587
1588 if let Err((path, error)) = self.dep_graph.finish_encoding() {
1589 self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
1590 }
1591 }
1592
1593 pub fn report_unused_features(self) {
1594 #[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)]
1595 #[diag("feature `{$feature}` is declared but not used")]
1596 struct UnusedFeature {
1597 feature: Symbol,
1598 }
1599
1600 let used_features = self.sess.used_features.lock();
1602 let unused_features = self
1603 .features()
1604 .enabled_features_iter_stable_order()
1605 .filter(|(f, _)| {
1606 !used_features.contains_key(f)
1607 && f.as_str() != "restricted_std"
1614 && *f != sym::doc_cfg
1618 })
1619 .collect::<Vec<_>>();
1620
1621 for (feature, span) in unused_features {
1622 self.emit_node_span_lint(
1623 rustc_session::lint::builtin::UNUSED_FEATURES,
1624 CRATE_HIR_ID,
1625 span,
1626 UnusedFeature { feature },
1627 );
1628 }
1629 }
1630}
1631
1632macro_rules! nop_lift {
1633 ($set:ident; $ty:ty => $lifted:ty) => {
1634 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
1635 type Lifted = $lifted;
1636 #[track_caller]
1637 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1638 fn _intern_set_ty_from_interned_ty<'tcx, Inner>(
1643 _x: Interned<'tcx, Inner>,
1644 ) -> InternedSet<'tcx, Inner> {
1645 unreachable!()
1646 }
1647 fn _type_eq<T>(_x: &T, _y: &T) {}
1648 fn _test<'tcx>(x: $lifted, tcx: TyCtxt<'tcx>) {
1649 let interner = _intern_set_ty_from_interned_ty(x.0);
1653 _type_eq(&interner, &tcx.interners.$set);
1655 }
1656
1657 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)));
1658 unsafe { mem::transmute(self) }
1661 }
1662 }
1663 };
1664}
1665
1666macro_rules! nop_list_lift {
1667 ($set:ident; $ty:ty => $lifted:ty) => {
1668 impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
1669 type Lifted = &'tcx List<$lifted>;
1670 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
1671 if false {
1673 let _x: &InternedSet<'tcx, List<$lifted>> = &tcx.interners.$set;
1674 }
1675
1676 if self.is_empty() {
1677 return List::empty();
1678 }
1679 assert!(tcx.interners.$set.contains_pointer_to(&InternedInSet(self)));
1680 unsafe { mem::transmute(self) }
1683 }
1684 }
1685 };
1686}
1687
1688impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Ty<'a> {
type Lifted = Ty<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Ty<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.type_);
}
if !tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.type_.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { type_; Ty<'a> => Ty<'tcx> }
1689impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Region<'a> {
type Lifted = Region<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Region<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.region);
}
if !tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.region.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { region; Region<'a> => Region<'tcx> }
1690impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Const<'a> {
type Lifted = Const<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Const<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_);
}
if !tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.const_.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { const_; Const<'a> => Const<'tcx> }
1691impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Pattern<'a> {
type Lifted = Pattern<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Pattern<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.pat);
}
if !tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.pat.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { pat; Pattern<'a> => Pattern<'tcx> }
1692impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ConstAllocation<'a> {
type Lifted = ConstAllocation<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ConstAllocation<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.const_allocation);
}
if !tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.const_allocation.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx> }
1693impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Predicate<'a> {
type Lifted = Predicate<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Predicate<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { predicate; Predicate<'a> => Predicate<'tcx> }
1694impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Clause<'a> {
type Lifted = Clause<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Clause<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.predicate);
}
if !tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.predicate.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { predicate; Clause<'a> => Clause<'tcx> }
1695impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Layout<'a> {
type Lifted = Layout<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: Layout<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.layout);
}
if !tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.layout.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { layout; Layout<'a> => Layout<'tcx> }
1696impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for ValTree<'a> {
type Lifted = ValTree<'tcx>;
#[track_caller]
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
fn _intern_set_ty_from_interned_ty<'tcx,
Inner>(_x: Interned<'tcx, Inner>) -> InternedSet<'tcx, Inner> {
::core::panicking::panic("internal error: entered unreachable code")
}
fn _type_eq<T>(_x: &T, _y: &T) {}
fn _test<'tcx>(x: ValTree<'tcx>, tcx: TyCtxt<'tcx>) {
let interner = _intern_set_ty_from_interned_ty(x.0);
_type_eq(&interner, &tcx.interners.valtree);
}
if !tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))
{
::core::panicking::panic("assertion failed: tcx.interners.valtree.contains_pointer_to(&InternedInSet(&*self.0.0))")
};
unsafe { mem::transmute(self) }
}
}nop_lift! { valtree; ValTree<'a> => ValTree<'tcx> }
1697
1698impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<Ty<'a>> {
type Lifted = &'tcx List<Ty<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<Ty<'tcx>>> =
&tcx.interners.type_lists;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self))
{
::core::panicking::panic("assertion failed: tcx.interners.type_lists.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { type_lists; Ty<'a> => Ty<'tcx> }
1699impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<PolyExistentialPredicate<'a>> {
type Lifted = &'tcx List<PolyExistentialPredicate<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>> =
&tcx.interners.poly_existential_predicates;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self))
{
::core::panicking::panic("assertion failed: tcx.interners.poly_existential_predicates.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! {
1700 poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>
1701}
1702impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<ty::BoundVariableKind<'a>> {
type Lifted = &'tcx List<ty::BoundVariableKind<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<ty::BoundVariableKind<'tcx>>> =
&tcx.interners.bound_variable_kinds;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self))
{
::core::panicking::panic("assertion failed: tcx.interners.bound_variable_kinds.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { bound_variable_kinds; ty::BoundVariableKind<'a> => ty::BoundVariableKind<'tcx> }
1703
1704impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<GenericArg<'a>> {
type Lifted = &'tcx List<GenericArg<'tcx>>;
fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Self::Lifted {
if false {
let _x: &InternedSet<'tcx, List<GenericArg<'tcx>>> =
&tcx.interners.args;
}
if self.is_empty() { return List::empty(); }
if !tcx.interners.args.contains_pointer_to(&InternedInSet(self)) {
::core::panicking::panic("assertion failed: tcx.interners.args.contains_pointer_to(&InternedInSet(self))")
};
unsafe { mem::transmute(self) }
}
}nop_list_lift! { args; GenericArg<'a> => GenericArg<'tcx> }
1706
1707macro_rules! sty_debug_print {
1708 ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
1709 #[allow(non_snake_case)]
1712 mod inner {
1713 use crate::ty::{self, TyCtxt};
1714 use crate::ty::context::InternedInSet;
1715
1716 #[derive(Copy, Clone)]
1717 struct DebugStat {
1718 total: usize,
1719 lt_infer: usize,
1720 ty_infer: usize,
1721 ct_infer: usize,
1722 all_infer: usize,
1723 }
1724
1725 pub(crate) fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result {
1726 let mut total = DebugStat {
1727 total: 0,
1728 lt_infer: 0,
1729 ty_infer: 0,
1730 ct_infer: 0,
1731 all_infer: 0,
1732 };
1733 $(let mut $variant = total;)*
1734
1735 for shard in tcx.interners.type_.lock_shards() {
1736 #[allow(rustc::potential_query_instability)]
1738 let types = shard.iter();
1739 for &(InternedInSet(t), ()) in types {
1740 let variant = match t.internee {
1741 ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1742 ty::Float(..) | ty::Str | ty::Never => continue,
1743 ty::Error(_) => continue,
1744 $(ty::$variant(..) => &mut $variant,)*
1745 };
1746 let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1747 let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1748 let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1749
1750 variant.total += 1;
1751 total.total += 1;
1752 if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1753 if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1754 if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1755 if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1756 }
1757 }
1758 writeln!(fmt, "Ty interner total ty lt ct all")?;
1759 $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \
1760 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1761 stringify!($variant),
1762 uses = $variant.total,
1763 usespc = $variant.total as f64 * 100.0 / total.total as f64,
1764 ty = $variant.ty_infer as f64 * 100.0 / total.total as f64,
1765 lt = $variant.lt_infer as f64 * 100.0 / total.total as f64,
1766 ct = $variant.ct_infer as f64 * 100.0 / total.total as f64,
1767 all = $variant.all_infer as f64 * 100.0 / total.total as f64)?;
1768 )*
1769 writeln!(fmt, " total {uses:6} \
1770 {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
1771 uses = total.total,
1772 ty = total.ty_infer as f64 * 100.0 / total.total as f64,
1773 lt = total.lt_infer as f64 * 100.0 / total.total as f64,
1774 ct = total.ct_infer as f64 * 100.0 / total.total as f64,
1775 all = total.all_infer as f64 * 100.0 / total.total as f64)
1776 }
1777 }
1778
1779 inner::go($fmt, $ctxt)
1780 }}
1781}
1782
1783impl<'tcx> TyCtxt<'tcx> {
1784 pub fn debug_stats(self) -> impl fmt::Debug {
1785 fmt::from_fn(move |fmt| {
1786 {
#[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!(
1787 fmt,
1788 self,
1789 Adt,
1790 Array,
1791 Slice,
1792 RawPtr,
1793 Ref,
1794 FnDef,
1795 FnPtr,
1796 UnsafeBinder,
1797 Placeholder,
1798 Coroutine,
1799 CoroutineWitness,
1800 Dynamic,
1801 Closure,
1802 CoroutineClosure,
1803 Tuple,
1804 Bound,
1805 Param,
1806 Infer,
1807 Alias,
1808 Pat,
1809 Foreign
1810 )?;
1811
1812 fmt.write_fmt(format_args!("GenericArgs interner: #{0}\n",
self.interners.args.len()))writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
1813 fmt.write_fmt(format_args!("Region interner: #{0}\n",
self.interners.region.len()))writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
1814 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())?;
1815 fmt.write_fmt(format_args!("Layout interner: #{0}\n",
self.interners.layout.len()))writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
1816
1817 Ok(())
1818 })
1819 }
1820}
1821
1822struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T);
1827
1828impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> {
1829 fn clone(&self) -> Self {
1830 *self
1831 }
1832}
1833
1834impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {}
1835
1836impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> {
1837 fn into_pointer(&self) -> *const () {
1838 self.0 as *const _ as *const ()
1839 }
1840}
1841
1842#[allow(rustc::usage_of_ty_tykind)]
1843impl<'tcx, T> Borrow<T> for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1844 fn borrow(&self) -> &T {
1845 &self.0.internee
1846 }
1847}
1848
1849impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1850 fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo<T>>) -> bool {
1851 self.0.internee == other.0.internee
1854 }
1855}
1856
1857impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo<T>> {}
1858
1859impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo<T>> {
1860 fn hash<H: Hasher>(&self, s: &mut H) {
1861 self.0.internee.hash(s)
1863 }
1864}
1865
1866impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
1867 fn borrow(&self) -> &[T] {
1868 &self.0[..]
1869 }
1870}
1871
1872impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
1873 fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
1874 self.0[..] == other.0[..]
1877 }
1878}
1879
1880impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
1881
1882impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
1883 fn hash<H: Hasher>(&self, s: &mut H) {
1884 self.0[..].hash(s)
1886 }
1887}
1888
1889impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1890 fn borrow(&self) -> &[T] {
1891 &self.0[..]
1892 }
1893}
1894
1895impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1896 fn eq(&self, other: &InternedInSet<'tcx, ListWithCachedTypeInfo<T>>) -> bool {
1897 self.0[..] == other.0[..]
1900 }
1901}
1902
1903impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {}
1904
1905impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, ListWithCachedTypeInfo<T>> {
1906 fn hash<H: Hasher>(&self, s: &mut H) {
1907 self.0[..].hash(s)
1909 }
1910}
1911
1912macro_rules! direct_interners {
1913 ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
1914 $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
1915 fn borrow<'a>(&'a self) -> &'a $ty {
1916 &self.0
1917 }
1918 }
1919
1920 impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
1921 fn eq(&self, other: &Self) -> bool {
1922 self.0 == other.0
1925 }
1926 }
1927
1928 impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
1929
1930 impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
1931 fn hash<H: Hasher>(&self, s: &mut H) {
1932 self.0.hash(s)
1935 }
1936 }
1937
1938 impl<'tcx> TyCtxt<'tcx> {
1939 $vis fn $method(self, v: $ty) -> $ret_ty {
1940 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
1941 InternedInSet(self.interners.arena.alloc(v))
1942 }).0))
1943 }
1944 })+
1945 }
1946}
1947
1948impl<'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! {
1952 region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
1953 valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
1954 pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
1955 const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
1956 layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
1957 adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
1958 external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
1959 ExternalConstraints -> ExternalConstraints<'tcx>,
1960}
1961
1962macro_rules! slice_interners {
1963 ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
1964 impl<'tcx> TyCtxt<'tcx> {
1965 $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
1966 if v.is_empty() {
1967 List::empty()
1968 } else {
1969 self.interners.$field.intern_ref(v, || {
1970 InternedInSet(List::from_arena(&*self.arena, (), v))
1971 }).0
1972 }
1973 })+
1974 }
1975 );
1976}
1977
1978impl<'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!(
1982 const_lists: pub mk_const_list(Const<'tcx>),
1983 args: pub mk_args(GenericArg<'tcx>),
1984 type_lists: pub mk_type_list(Ty<'tcx>),
1985 canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
1986 poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
1987 projs: pub mk_projs(ProjectionKind),
1988 place_elems: pub mk_place_elems(PlaceElem<'tcx>),
1989 bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind<'tcx>),
1990 fields: pub mk_fields(FieldIdx),
1991 local_def_ids: intern_local_def_ids(LocalDefId),
1992 captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
1993 patterns: pub mk_patterns(Pattern<'tcx>),
1994 outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
1995 predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
1996);
1997
1998impl<'tcx> TyCtxt<'tcx> {
1999 pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
2003 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2004 Ty::new_fn_ptr(
2005 self,
2006 sig.map_bound(|sig| ty::FnSig {
2007 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2008 ..sig
2009 }),
2010 )
2011 }
2012
2013 pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
2017 if !sig.safety().is_safe() {
::core::panicking::panic("assertion failed: sig.safety().is_safe()")
};assert!(sig.safety().is_safe());
2018 sig.map_bound(|sig| ty::FnSig {
2019 fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
2020 ..sig
2021 })
2022 }
2023
2024 pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2027 elaborate::supertrait_def_ids(self, trait_def_id).any(|trait_did| {
2028 self.associated_items(trait_did)
2029 .filter_by_name_unhygienic(assoc_name.name)
2030 .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did))
2031 })
2032 }
2033
2034 pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
2036 let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *ty.kind() else {
2037 return false;
2038 };
2039 let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
2040
2041 self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
2042 let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
2043 return false;
2044 };
2045 trait_predicate.trait_ref.def_id == future_trait
2046 && trait_predicate.polarity == PredicatePolarity::Positive
2047 })
2048 }
2049
2050 pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> PolyFnSig<'tcx> {
2058 sig.map_bound(|s| {
2059 let params = match s.inputs()[0].kind() {
2060 ty::Tuple(params) => *params,
2061 _ => crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!(),
2062 };
2063 self.mk_fn_sig(
2064 params,
2065 s.output(),
2066 s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
2067 )
2068 })
2069 }
2070
2071 #[inline]
2072 pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
2073 self.interners.intern_predicate(binder)
2074 }
2075
2076 #[inline]
2077 pub fn reuse_or_mk_predicate(
2078 self,
2079 pred: Predicate<'tcx>,
2080 binder: Binder<'tcx, PredicateKind<'tcx>>,
2081 ) -> Predicate<'tcx> {
2082 if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
2083 }
2084
2085 pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
2086 self.check_args_compatible_inner(def_id, args, false)
2087 }
2088
2089 fn check_args_compatible_inner(
2090 self,
2091 def_id: DefId,
2092 args: &'tcx [ty::GenericArg<'tcx>],
2093 nested: bool,
2094 ) -> bool {
2095 let generics = self.generics_of(def_id);
2096
2097 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)
2101 && #[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 });
2102 let is_inherent_assoc_type_const =
2103 #[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 })
2104 && #[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 });
2105 let own_args = if !nested && (is_inherent_assoc_ty || is_inherent_assoc_type_const) {
2106 if generics.own_params.len() + 1 != args.len() {
2107 return false;
2108 }
2109
2110 if !#[allow(non_exhaustive_omitted_patterns)] match args[0].kind() {
ty::GenericArgKind::Type(_) => true,
_ => false,
}matches!(args[0].kind(), ty::GenericArgKind::Type(_)) {
2111 return false;
2112 }
2113
2114 &args[1..]
2115 } else {
2116 if generics.count() != args.len() {
2117 return false;
2118 }
2119
2120 let (parent_args, own_args) = args.split_at(generics.parent_count);
2121
2122 if let Some(parent) = generics.parent
2123 && !self.check_args_compatible_inner(parent, parent_args, true)
2124 {
2125 return false;
2126 }
2127
2128 own_args
2129 };
2130
2131 for (param, arg) in std::iter::zip(&generics.own_params, own_args) {
2132 match (¶m.kind, arg.kind()) {
2133 (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
2134 | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
2135 | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
2136 _ => return false,
2137 }
2138 }
2139
2140 true
2141 }
2142
2143 pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
2146 if truecfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
2147 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)
2148 && #[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 });
2149 let is_inherent_assoc_type_const =
2150 #[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 })
2151 && #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(self.parent(def_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(
2152 self.def_kind(self.parent(def_id)),
2153 DefKind::Impl { of_trait: false }
2154 );
2155 if is_inherent_assoc_ty || is_inherent_assoc_type_const {
2156 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!(
2157 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2158 self.def_path_str(def_id),
2159 args,
2160 self.mk_args_from_iter(
2162 [self.types.self_param.into()].into_iter().chain(
2163 self.generics_of(def_id)
2164 .own_args(ty::GenericArgs::identity_for_item(self, def_id))
2165 .iter()
2166 .copied()
2167 )
2168 )
2169 );
2170 } else {
2171 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!(
2172 "args not compatible with generics for {}: args={:#?}, generics={:#?}",
2173 self.def_path_str(def_id),
2174 args,
2175 ty::GenericArgs::identity_for_item(self, def_id)
2176 );
2177 }
2178 }
2179 }
2180
2181 #[inline(always)]
2182 pub(crate) fn check_and_mk_args(
2183 self,
2184 def_id: DefId,
2185 args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
2186 ) -> GenericArgsRef<'tcx> {
2187 let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
2188 self.debug_assert_args_compatible(def_id, args);
2189 args
2190 }
2191
2192 #[inline]
2193 pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
2194 self.interners.intern_const(kind)
2195 }
2196
2197 #[allow(rustc::usage_of_ty_tykind)]
2199 #[inline]
2200 pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
2201 self.interners.intern_ty(st)
2202 }
2203
2204 pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
2205 match param.kind {
2206 GenericParamDefKind::Lifetime => {
2207 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
2208 }
2209 GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
2210 GenericParamDefKind::Const { .. } => {
2211 ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
2212 .into()
2213 }
2214 }
2215 }
2216
2217 pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
2218 self.mk_place_elem(place, PlaceElem::Field(f, ty))
2219 }
2220
2221 pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
2222 self.mk_place_elem(place, PlaceElem::Deref)
2223 }
2224
2225 pub fn mk_place_downcast(
2226 self,
2227 place: Place<'tcx>,
2228 adt_def: AdtDef<'tcx>,
2229 variant_index: VariantIdx,
2230 ) -> Place<'tcx> {
2231 self.mk_place_elem(
2232 place,
2233 PlaceElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index),
2234 )
2235 }
2236
2237 pub fn mk_place_downcast_unnamed(
2238 self,
2239 place: Place<'tcx>,
2240 variant_index: VariantIdx,
2241 ) -> Place<'tcx> {
2242 self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
2243 }
2244
2245 pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2246 self.mk_place_elem(place, PlaceElem::Index(index))
2247 }
2248
2249 pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2253 Place {
2254 local: place.local,
2255 projection: self.mk_place_elems_from_iter(place.projection.iter().chain([elem])),
2256 }
2257 }
2258
2259 pub fn mk_poly_existential_predicates(
2260 self,
2261 eps: &[PolyExistentialPredicate<'tcx>],
2262 ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
2263 if !!eps.is_empty() {
::core::panicking::panic("assertion failed: !eps.is_empty()")
};assert!(!eps.is_empty());
2264 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!(
2265 eps.array_windows()
2266 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
2267 != Ordering::Greater)
2268 );
2269 self.intern_poly_existential_predicates(eps)
2270 }
2271
2272 pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> Clauses<'tcx> {
2273 self.interners.intern_clauses(clauses)
2277 }
2278
2279 pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> {
2280 self.intern_local_def_ids(def_ids)
2284 }
2285
2286 pub fn mk_patterns_from_iter<I, T>(self, iter: I) -> T::Output
2287 where
2288 I: Iterator<Item = T>,
2289 T: CollectAndApply<ty::Pattern<'tcx>, &'tcx List<ty::Pattern<'tcx>>>,
2290 {
2291 T::collect_and_apply(iter, |xs| self.mk_patterns(xs))
2292 }
2293
2294 pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2295 where
2296 I: Iterator<Item = T>,
2297 T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2298 {
2299 T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2300 }
2301
2302 pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
2303 where
2304 I: Iterator<Item = T>,
2305 T: CollectAndApply<
2306 &'tcx ty::CapturedPlace<'tcx>,
2307 &'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
2308 >,
2309 {
2310 T::collect_and_apply(iter, |xs| self.intern_captures(xs))
2311 }
2312
2313 pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
2314 where
2315 I: Iterator<Item = T>,
2316 T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
2317 {
2318 T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
2319 }
2320
2321 pub fn mk_fn_sig<I, T>(
2326 self,
2327 inputs: I,
2328 output: I::Item,
2329 fn_sig_kind: FnSigKind<'tcx>,
2330 ) -> T::Output
2331 where
2332 I: IntoIterator<Item = T>,
2333 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2334 {
2335 T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
2336 inputs_and_output: self.mk_type_list(xs),
2337 fn_sig_kind,
2338 })
2339 }
2340
2341 pub fn mk_fn_sig_rust_abi<I, T>(
2343 self,
2344 inputs: I,
2345 output: I::Item,
2346 safety: hir::Safety,
2347 ) -> T::Output
2348 where
2349 I: IntoIterator<Item = T>,
2350 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2351 {
2352 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
2353 }
2354
2355 pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2357 where
2358 I: IntoIterator<Item = T>,
2359 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2360 {
2361 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
2362 }
2363
2364 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
2365 where
2366 I: Iterator<Item = T>,
2367 T: CollectAndApply<
2368 PolyExistentialPredicate<'tcx>,
2369 &'tcx List<PolyExistentialPredicate<'tcx>>,
2370 >,
2371 {
2372 T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
2373 }
2374
2375 pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
2376 where
2377 I: Iterator<Item = T>,
2378 T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
2379 {
2380 T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
2381 }
2382
2383 pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
2384 where
2385 I: Iterator<Item = T>,
2386 T: CollectAndApply<Clause<'tcx>, Clauses<'tcx>>,
2387 {
2388 T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
2389 }
2390
2391 pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
2392 where
2393 I: Iterator<Item = T>,
2394 T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
2395 {
2396 T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
2397 }
2398
2399 pub fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
2400 where
2401 I: Iterator<Item = T>,
2402 T: CollectAndApply<GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
2403 {
2404 T::collect_and_apply(iter, |xs| self.mk_args(xs))
2405 }
2406
2407 pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
2408 where
2409 I: Iterator<Item = T>,
2410 T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
2411 {
2412 T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
2413 }
2414
2415 pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
2416 where
2417 I: Iterator<Item = T>,
2418 T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
2419 {
2420 T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
2421 }
2422
2423 pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
2424 where
2425 I: Iterator<Item = T>,
2426 T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
2427 {
2428 T::collect_and_apply(iter, |xs| self.mk_fields(xs))
2429 }
2430
2431 pub fn mk_args_trait(
2432 self,
2433 self_ty: Ty<'tcx>,
2434 rest: impl IntoIterator<Item = GenericArg<'tcx>>,
2435 ) -> GenericArgsRef<'tcx> {
2436 self.mk_args_from_iter(iter::once(self_ty.into()).chain(rest))
2437 }
2438
2439 pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
2440 where
2441 I: Iterator<Item = T>,
2442 T: CollectAndApply<ty::BoundVariableKind<'tcx>, &'tcx List<ty::BoundVariableKind<'tcx>>>,
2443 {
2444 T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
2445 }
2446
2447 pub fn mk_outlives_from_iter<I, T>(self, iter: I) -> T::Output
2448 where
2449 I: Iterator<Item = T>,
2450 T: CollectAndApply<
2451 ty::ArgOutlivesPredicate<'tcx>,
2452 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>,
2453 >,
2454 {
2455 T::collect_and_apply(iter, |xs| self.mk_outlives(xs))
2456 }
2457
2458 #[track_caller]
2461 pub fn emit_node_span_lint(
2462 self,
2463 lint: &'static Lint,
2464 hir_id: HirId,
2465 span: impl Into<MultiSpan>,
2466 decorator: impl for<'a> Diagnostic<'a, ()>,
2467 ) {
2468 let level_spec = self.lint_level_spec_at_node(lint, hir_id);
2469 emit_lint_base(self.sess, lint, level_spec, Some(span.into()), decorator)
2470 }
2471
2472 pub fn crate_level_attribute_injection_span(self) -> Span {
2474 let node = self.hir_node(hir::CRATE_HIR_ID);
2475 let hir::Node::Crate(m) = node else { crate::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
2476 m.spans.inject_use_span.shrink_to_lo()
2477 }
2478
2479 pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>(
2480 self,
2481 diag: &mut Diag<'_, E>,
2482 features: impl IntoIterator<Item = (String, Symbol)>,
2483 ) {
2484 if !self.sess.is_nightly_build() {
2485 return;
2486 }
2487
2488 let span = self.crate_level_attribute_injection_span();
2489 for (desc, feature) in features {
2490 let msg =
2492 ::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}");
2493 diag.span_suggestion_verbose(
2494 span,
2495 msg,
2496 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#![feature({0})]\n", feature))
})format!("#![feature({feature})]\n"),
2497 Applicability::MaybeIncorrect,
2498 );
2499 }
2500 }
2501
2502 #[track_caller]
2505 pub fn emit_node_lint(
2506 self,
2507 lint: &'static Lint,
2508 id: HirId,
2509 decorator: impl for<'a> Diagnostic<'a, ()>,
2510 ) {
2511 let level_spec = self.lint_level_spec_at_node(lint, id);
2512 emit_lint_base(self.sess, lint, level_spec, None, decorator);
2513 }
2514
2515 pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate<'tcx>]> {
2516 let map = self.in_scope_traits_map(id.owner)?;
2517 let candidates = map.get(&id.local_id)?;
2518 Some(candidates)
2519 }
2520
2521 pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
2522 {
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:2522",
"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(2522u32),
::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");
2523 self.named_variable_map(id.owner).get(&id.local_id).cloned()
2524 }
2525
2526 pub fn is_late_bound(self, id: HirId) -> bool {
2527 self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id))
2528 }
2529
2530 pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind<'tcx>> {
2531 self.mk_bound_variable_kinds(
2532 &self
2533 .late_bound_vars_map(id.owner)
2534 .get(&id.local_id)
2535 .cloned()
2536 .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))),
2537 )
2538 }
2539
2540 pub fn map_opaque_lifetime_to_parent_lifetime(
2548 self,
2549 mut opaque_lifetime_param_def_id: LocalDefId,
2550 ) -> ty::Region<'tcx> {
2551 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!(
2552 matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
2553 "{opaque_lifetime_param_def_id:?} is a {}",
2554 self.def_descr(opaque_lifetime_param_def_id.to_def_id())
2555 );
2556
2557 loop {
2558 let parent = self.local_parent(opaque_lifetime_param_def_id);
2559 let lifetime_mapping = self.opaque_captured_lifetimes(parent);
2560
2561 let Some((lifetime, _)) = lifetime_mapping
2562 .iter()
2563 .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
2564 else {
2565 crate::util::bug::bug_fmt(format_args!("duplicated lifetime param should be present"));bug!("duplicated lifetime param should be present");
2566 };
2567
2568 match *lifetime {
2569 resolve_bound_vars::ResolvedArg::EarlyBound(ebv) => {
2570 let new_parent = self.local_parent(ebv);
2571
2572 if #[allow(non_exhaustive_omitted_patterns)] match self.def_kind(new_parent) {
DefKind::OpaqueTy => true,
_ => false,
}matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
2575 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);
2576 opaque_lifetime_param_def_id = ebv;
2577 continue;
2578 }
2579
2580 let generics = self.generics_of(new_parent);
2581 return ty::Region::new_early_param(
2582 self,
2583 ty::EarlyParamRegion {
2584 index: generics
2585 .param_def_id_to_index(self, ebv.to_def_id())
2586 .expect("early-bound var should be present in fn generics"),
2587 name: self.item_name(ebv.to_def_id()),
2588 },
2589 );
2590 }
2591 resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv) => {
2592 let new_parent = self.local_parent(lbv);
2593 return ty::Region::new_late_param(
2594 self,
2595 new_parent.to_def_id(),
2596 ty::LateParamRegionKind::Named(lbv.to_def_id()),
2597 );
2598 }
2599 resolve_bound_vars::ResolvedArg::Error(guar) => {
2600 return ty::Region::new_error(self, guar);
2601 }
2602 _ => {
2603 return ty::Region::new_error_with_message(
2604 self,
2605 self.def_span(opaque_lifetime_param_def_id),
2606 "cannot resolve lifetime",
2607 );
2608 }
2609 }
2610 }
2611 }
2612
2613 pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
2618 self.is_const_fn(def_id)
2619 && match self.lookup_const_stability(def_id) {
2620 None => true, Some(stability) if stability.is_const_stable() => true,
2622 _ => false,
2623 }
2624 }
2625
2626 pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
2628 self.def_kind(def_id) == DefKind::Impl { of_trait: true }
2629 && self.impl_trait_header(def_id).constness == hir::Constness::Const
2630 }
2631
2632 pub fn is_sdylib_interface_build(self) -> bool {
2633 self.sess.opts.unstable_opts.build_sdylib_interface
2634 }
2635
2636 pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> {
2637 let def_id = def_id.into_query_key();
2638 match self.def_kind(def_id) {
2639 DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id),
2640 _ => None,
2641 }
2642 }
2643
2644 pub fn next_trait_solver_globally(self) -> bool {
2645 self.sess.opts.unstable_opts.next_solver.globally
2646 }
2647
2648 pub fn next_trait_solver_in_coherence(self) -> bool {
2649 self.sess.opts.unstable_opts.next_solver.coherence
2650 }
2651
2652 pub fn disable_trait_solver_fast_paths(self) -> bool {
2653 self.sess.opts.unstable_opts.disable_fast_paths
2654 }
2655
2656 #[allow(rustc::bad_opt_access)]
2657 pub fn use_typing_mode_borrowck(self) -> bool {
2658 self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck
2659 }
2660
2661 pub fn assumptions_on_binders(self) -> bool {
2662 self.sess.opts.unstable_opts.assumptions_on_binders
2663 }
2664
2665 pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
2666 self.opt_rpitit_info(def_id).is_some()
2667 }
2668
2669 pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
2679 self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
2680 }
2681
2682 pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
2684 self.resolutions(()).extern_crate_map.get(&def_id).copied()
2685 }
2686
2687 pub fn resolver_for_lowering(
2688 self,
2689 ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc<ast::Crate>)> {
2690 self.resolver_for_lowering_raw(()).0
2691 }
2692
2693 pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode {
2694 make_metadata(self)
2695 }
2696
2697 pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
2698 if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
2699 self.coroutine_kind(def_id)
2700 && let ty::Coroutine(_, args) =
2701 self.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
2702 && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
2703 {
2704 true
2705 } else {
2706 false
2707 }
2708 }
2709
2710 pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
2712 {
{
'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)
2713 }
2714
2715 pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
2716 let def_id = def_id.into_query_key();
2717 self.trivial_const(def_id).is_some()
2718 }
2719
2720 pub fn is_entrypoint(self, def_id: DefId) -> bool {
2723 if self.is_lang_item(def_id, LangItem::Start) {
2724 return true;
2725 }
2726 if let Some((entry_def_id, _)) = self.entry_fn(())
2727 && entry_def_id == def_id
2728 {
2729 return true;
2730 }
2731 false
2732 }
2733}
2734
2735pub fn provide(providers: &mut Providers) {
2736 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);
2737 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);
2738 providers.has_panic_handler = |tcx, LocalCrate| {
2739 tcx.lang_items().panic_impl().is_some_and(|did| did.is_local())
2741 };
2742 providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP);
2743}