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