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