1use std::fmt::{self, Debug, Display, Formatter};
2use std::ops::Range;
3
4use serde::Serialize;
5
6use super::mir::{Body, Mutability, Safety};
7use super::{DefId, Error, Symbol, with};
8use crate::abi::{FnAbi, Layout};
9use crate::crate_def::{CrateDef, CrateDefType};
10use crate::mir::alloc::{AllocId, read_target_int, read_target_uint};
11use crate::mir::mono::StaticDef;
12use crate::target::MachineInfo;
13use crate::{Filename, Opaque};
14
15#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
16pub struct Ty(usize);
17
18impl Debug for Ty {
19 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
20 f.debug_struct("Ty").field("id", &self.0).field("kind", &self.kind()).finish()
21 }
22}
23
24impl Ty {
26 pub fn from_rigid_kind(kind: RigidTy) -> Ty {
28 with(|cx| cx.new_rigid_ty(kind))
29 }
30
31 pub fn try_new_array(elem_ty: Ty, size: u64) -> Result<Ty, Error> {
33 Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, TyConst::try_from_target_usize(size)?)))
34 }
35
36 pub fn new_array_with_const_len(elem_ty: Ty, len: TyConst) -> Ty {
38 Ty::from_rigid_kind(RigidTy::Array(elem_ty, len))
39 }
40
41 pub fn new_ptr(pointee_ty: Ty, mutability: Mutability) -> Ty {
43 Ty::from_rigid_kind(RigidTy::RawPtr(pointee_ty, mutability))
44 }
45
46 pub fn new_ref(reg: Region, pointee_ty: Ty, mutability: Mutability) -> Ty {
48 Ty::from_rigid_kind(RigidTy::Ref(reg, pointee_ty, mutability))
49 }
50
51 pub fn new_tuple(tys: &[Ty]) -> Ty {
53 Ty::from_rigid_kind(RigidTy::Tuple(Vec::from(tys)))
54 }
55
56 pub fn new_closure(def: ClosureDef, args: GenericArgs) -> Ty {
58 Ty::from_rigid_kind(RigidTy::Closure(def, args))
59 }
60
61 pub fn new_coroutine(def: CoroutineDef, args: GenericArgs, mov: Movability) -> Ty {
63 Ty::from_rigid_kind(RigidTy::Coroutine(def, args, mov))
64 }
65
66 pub fn new_coroutine_closure(def: CoroutineClosureDef, args: GenericArgs) -> Ty {
68 Ty::from_rigid_kind(RigidTy::CoroutineClosure(def, args))
69 }
70
71 pub fn new_box(inner_ty: Ty) -> Ty {
73 with(|cx| cx.new_box_ty(inner_ty))
74 }
75
76 pub fn usize_ty() -> Ty {
78 Ty::from_rigid_kind(RigidTy::Uint(UintTy::Usize))
79 }
80
81 pub fn bool_ty() -> Ty {
83 Ty::from_rigid_kind(RigidTy::Bool)
84 }
85
86 pub fn signed_ty(inner: IntTy) -> Ty {
88 Ty::from_rigid_kind(RigidTy::Int(inner))
89 }
90
91 pub fn unsigned_ty(inner: UintTy) -> Ty {
93 Ty::from_rigid_kind(RigidTy::Uint(inner))
94 }
95
96 pub fn layout(self) -> Result<Layout, Error> {
98 with(|cx| cx.ty_layout(self))
99 }
100}
101
102impl Ty {
103 pub fn kind(&self) -> TyKind {
104 with(|context| context.ty_kind(*self))
105 }
106}
107
108#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
110pub enum Pattern {
111 Range { start: Option<TyConst>, end: Option<TyConst>, include_end: bool },
112}
113
114#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
116pub struct TyConst {
117 pub(crate) kind: TyConstKind,
118 pub id: TyConstId,
119}
120
121impl TyConst {
122 pub fn new(kind: TyConstKind, id: TyConstId) -> TyConst {
123 Self { kind, id }
124 }
125
126 pub fn kind(&self) -> &TyConstKind {
128 &self.kind
129 }
130
131 pub fn try_from_target_usize(val: u64) -> Result<Self, Error> {
133 with(|cx| cx.try_new_ty_const_uint(val.into(), UintTy::Usize))
134 }
135
136 pub fn eval_target_usize(&self) -> Result<u64, Error> {
138 with(|cx| cx.eval_target_usize_ty(self))
139 }
140}
141
142#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
143pub enum TyConstKind {
144 Param(ParamConst),
145 Bound(DebruijnIndex, BoundVar),
146 Unevaluated(ConstDef, GenericArgs),
147
148 Value(Ty, Allocation),
150 ZSTValue(Ty),
151}
152
153#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
154pub struct TyConstId(usize);
155
156#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
158pub struct MirConst {
159 pub(crate) kind: ConstantKind,
161 pub(crate) ty: Ty,
163 pub id: MirConstId,
165}
166
167impl MirConst {
168 pub fn new(kind: ConstantKind, ty: Ty, id: MirConstId) -> MirConst {
170 MirConst { kind, ty, id }
171 }
172
173 pub fn kind(&self) -> &ConstantKind {
175 &self.kind
176 }
177
178 pub fn ty(&self) -> Ty {
180 self.ty
181 }
182
183 pub fn eval_target_usize(&self) -> Result<u64, Error> {
185 with(|cx| cx.eval_target_usize(self))
186 }
187
188 pub fn try_new_zero_sized(ty: Ty) -> Result<MirConst, Error> {
191 with(|cx| cx.try_new_const_zst(ty))
192 }
193
194 pub fn from_str(value: &str) -> MirConst {
200 with(|cx| cx.new_const_str(value))
201 }
202
203 pub fn from_bool(value: bool) -> MirConst {
205 with(|cx| cx.new_const_bool(value))
206 }
207
208 pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
210 with(|cx| cx.try_new_const_uint(value, uint_ty))
211 }
212}
213
214#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
215pub struct MirConstId(usize);
216
217type Ident = Opaque;
218
219#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
220pub struct Region {
221 pub kind: RegionKind,
222}
223
224#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
225pub enum RegionKind {
226 ReEarlyParam(EarlyParamRegion),
227 ReBound(DebruijnIndex, BoundRegion),
228 ReStatic,
229 RePlaceholder(Placeholder<BoundRegion>),
230 ReErased,
231}
232
233pub(crate) type DebruijnIndex = u32;
234
235#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
236pub struct EarlyParamRegion {
237 pub index: u32,
238 pub name: Symbol,
239}
240
241pub(crate) type BoundVar = u32;
242
243#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
244pub struct BoundRegion {
245 pub var: BoundVar,
246 pub kind: BoundRegionKind,
247}
248
249pub(crate) type UniverseIndex = u32;
250
251#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
252pub struct Placeholder<T> {
253 pub universe: UniverseIndex,
254 pub bound: T,
255}
256
257#[derive(Clone, Copy, PartialEq, Eq, Serialize)]
258pub struct Span(usize);
259
260impl Debug for Span {
261 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
262 f.debug_struct("Span")
263 .field("id", &self.0)
264 .field("repr", &with(|cx| cx.span_to_string(*self)))
265 .finish()
266 }
267}
268
269impl Span {
270 pub fn get_filename(&self) -> Filename {
272 with(|c| c.get_filename(self))
273 }
274
275 pub fn get_lines(&self) -> LineInfo {
277 with(|c| c.get_lines(self))
278 }
279
280 pub fn diagnostic(&self) -> String {
285 with(|c| c.span_to_string(*self))
286 }
287}
288
289#[derive(Clone, Copy, Debug, Serialize)]
290pub struct LineInfo {
293 pub start_line: usize,
294 pub start_col: usize,
295 pub end_line: usize,
296 pub end_col: usize,
297}
298
299#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
300pub enum TyKind {
301 RigidTy(RigidTy),
302 Alias(AliasKind, AliasTy),
303 Param(ParamTy),
304 Bound(usize, BoundTy),
305}
306
307impl TyKind {
308 pub fn rigid(&self) -> Option<&RigidTy> {
309 if let TyKind::RigidTy(inner) = self { Some(inner) } else { None }
310 }
311
312 #[inline]
313 pub fn is_unit(&self) -> bool {
314 matches!(self, TyKind::RigidTy(RigidTy::Tuple(data)) if data.is_empty())
315 }
316
317 #[inline]
318 pub fn is_bool(&self) -> bool {
319 matches!(self, TyKind::RigidTy(RigidTy::Bool))
320 }
321
322 #[inline]
323 pub fn is_char(&self) -> bool {
324 matches!(self, TyKind::RigidTy(RigidTy::Char))
325 }
326
327 #[inline]
328 pub fn is_trait(&self) -> bool {
329 matches!(self, TyKind::RigidTy(RigidTy::Dynamic(_, _, DynKind::Dyn)))
330 }
331
332 #[inline]
333 pub fn is_enum(&self) -> bool {
334 matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Enum)
335 }
336
337 #[inline]
338 pub fn is_struct(&self) -> bool {
339 matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Struct)
340 }
341
342 #[inline]
343 pub fn is_union(&self) -> bool {
344 matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Union)
345 }
346
347 #[inline]
348 pub fn is_adt(&self) -> bool {
349 matches!(self, TyKind::RigidTy(RigidTy::Adt(..)))
350 }
351
352 #[inline]
353 pub fn is_ref(&self) -> bool {
354 matches!(self, TyKind::RigidTy(RigidTy::Ref(..)))
355 }
356
357 #[inline]
358 pub fn is_fn(&self) -> bool {
359 matches!(self, TyKind::RigidTy(RigidTy::FnDef(..)))
360 }
361
362 #[inline]
363 pub fn is_fn_ptr(&self) -> bool {
364 matches!(self, TyKind::RigidTy(RigidTy::FnPtr(..)))
365 }
366
367 #[inline]
368 pub fn is_primitive(&self) -> bool {
369 matches!(
370 self,
371 TyKind::RigidTy(
372 RigidTy::Bool
373 | RigidTy::Char
374 | RigidTy::Int(_)
375 | RigidTy::Uint(_)
376 | RigidTy::Float(_)
377 )
378 )
379 }
380
381 #[inline]
382 pub fn is_float(&self) -> bool {
383 matches!(self, TyKind::RigidTy(RigidTy::Float(_)))
384 }
385
386 #[inline]
387 pub fn is_integral(&self) -> bool {
388 matches!(self, TyKind::RigidTy(RigidTy::Int(_) | RigidTy::Uint(_)))
389 }
390
391 #[inline]
392 pub fn is_numeric(&self) -> bool {
393 self.is_integral() || self.is_float()
394 }
395
396 #[inline]
397 pub fn is_signed(&self) -> bool {
398 matches!(self, TyKind::RigidTy(RigidTy::Int(_)))
399 }
400
401 #[inline]
402 pub fn is_str(&self) -> bool {
403 *self == TyKind::RigidTy(RigidTy::Str)
404 }
405
406 #[inline]
407 pub fn is_cstr(&self) -> bool {
408 let TyKind::RigidTy(RigidTy::Adt(def, _)) = self else {
409 return false;
410 };
411 with(|cx| cx.adt_is_cstr(*def))
412 }
413
414 #[inline]
415 pub fn is_slice(&self) -> bool {
416 matches!(self, TyKind::RigidTy(RigidTy::Slice(_)))
417 }
418
419 #[inline]
420 pub fn is_array(&self) -> bool {
421 matches!(self, TyKind::RigidTy(RigidTy::Array(..)))
422 }
423
424 #[inline]
425 pub fn is_mutable_ptr(&self) -> bool {
426 matches!(
427 self,
428 TyKind::RigidTy(RigidTy::RawPtr(_, Mutability::Mut))
429 | TyKind::RigidTy(RigidTy::Ref(_, _, Mutability::Mut))
430 )
431 }
432
433 #[inline]
434 pub fn is_raw_ptr(&self) -> bool {
435 matches!(self, TyKind::RigidTy(RigidTy::RawPtr(..)))
436 }
437
438 #[inline]
440 pub fn is_any_ptr(&self) -> bool {
441 self.is_ref() || self.is_raw_ptr() || self.is_fn_ptr()
442 }
443
444 #[inline]
445 pub fn is_coroutine(&self) -> bool {
446 matches!(self, TyKind::RigidTy(RigidTy::Coroutine(..)))
447 }
448
449 #[inline]
450 pub fn is_closure(&self) -> bool {
451 matches!(self, TyKind::RigidTy(RigidTy::Closure(..)))
452 }
453
454 #[inline]
455 pub fn is_box(&self) -> bool {
456 match self {
457 TyKind::RigidTy(RigidTy::Adt(def, _)) => def.is_box(),
458 _ => false,
459 }
460 }
461
462 #[inline]
463 pub fn is_simd(&self) -> bool {
464 matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.is_simd())
465 }
466
467 pub fn trait_principal(&self) -> Option<Binder<ExistentialTraitRef>> {
468 if let TyKind::RigidTy(RigidTy::Dynamic(predicates, _, _)) = self {
469 if let Some(Binder { value: ExistentialPredicate::Trait(trait_ref), bound_vars }) =
470 predicates.first()
471 {
472 Some(Binder { value: trait_ref.clone(), bound_vars: bound_vars.clone() })
473 } else {
474 None
475 }
476 } else {
477 None
478 }
479 }
480
481 pub fn builtin_index(&self) -> Option<Ty> {
483 match self.rigid()? {
484 RigidTy::Array(ty, _) | RigidTy::Slice(ty) => Some(*ty),
485 _ => None,
486 }
487 }
488
489 pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut> {
494 match self.rigid()? {
495 RigidTy::Adt(def, args) if def.is_box() => {
496 Some(TypeAndMut { ty: *args.0.first()?.ty()?, mutability: Mutability::Not })
497 }
498 RigidTy::Ref(_, ty, mutability) => {
499 Some(TypeAndMut { ty: *ty, mutability: *mutability })
500 }
501 RigidTy::RawPtr(ty, mutability) if explicit => {
502 Some(TypeAndMut { ty: *ty, mutability: *mutability })
503 }
504 _ => None,
505 }
506 }
507
508 pub fn fn_sig(&self) -> Option<PolyFnSig> {
510 match self {
511 TyKind::RigidTy(RigidTy::FnDef(def, args)) => Some(with(|cx| cx.fn_sig(*def, args))),
512 TyKind::RigidTy(RigidTy::FnPtr(sig)) => Some(sig.clone()),
513 TyKind::RigidTy(RigidTy::Closure(_def, args)) => Some(with(|cx| cx.closure_sig(args))),
514 _ => None,
515 }
516 }
517
518 pub fn discriminant_ty(&self) -> Option<Ty> {
520 self.rigid().map(|ty| with(|cx| cx.rigid_ty_discriminant_ty(ty)))
521 }
522
523 pub fn fn_def(&self) -> Option<(FnDef, &GenericArgs)> {
525 if let TyKind::RigidTy(RigidTy::FnDef(def, args)) = self {
526 Some((*def, args))
527 } else {
528 None
529 }
530 }
531}
532
533pub struct TypeAndMut {
534 pub ty: Ty,
535 pub mutability: Mutability,
536}
537
538#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
539pub enum RigidTy {
540 Bool,
541 Char,
542 Int(IntTy),
543 Uint(UintTy),
544 Float(FloatTy),
545 Adt(AdtDef, GenericArgs),
546 Foreign(ForeignDef),
547 Str,
548 Array(Ty, TyConst),
549 Pat(Ty, Pattern),
550 Slice(Ty),
551 RawPtr(Ty, Mutability),
552 Ref(Region, Ty, Mutability),
553 FnDef(FnDef, GenericArgs),
554 FnPtr(PolyFnSig),
555 Closure(ClosureDef, GenericArgs),
556 Coroutine(CoroutineDef, GenericArgs, Movability),
558 CoroutineClosure(CoroutineClosureDef, GenericArgs),
559 Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
560 Never,
561 Tuple(Vec<Ty>),
562 CoroutineWitness(CoroutineWitnessDef, GenericArgs),
563}
564
565impl RigidTy {
566 pub fn discriminant_ty(&self) -> Ty {
568 with(|cx| cx.rigid_ty_discriminant_ty(self))
569 }
570}
571
572impl From<RigidTy> for TyKind {
573 fn from(value: RigidTy) -> Self {
574 TyKind::RigidTy(value)
575 }
576}
577
578#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
579pub enum IntTy {
580 Isize,
581 I8,
582 I16,
583 I32,
584 I64,
585 I128,
586}
587
588impl IntTy {
589 pub fn num_bytes(self) -> usize {
590 match self {
591 IntTy::Isize => crate::target::MachineInfo::target_pointer_width().bytes(),
592 IntTy::I8 => 1,
593 IntTy::I16 => 2,
594 IntTy::I32 => 4,
595 IntTy::I64 => 8,
596 IntTy::I128 => 16,
597 }
598 }
599}
600
601#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
602pub enum UintTy {
603 Usize,
604 U8,
605 U16,
606 U32,
607 U64,
608 U128,
609}
610
611impl UintTy {
612 pub fn num_bytes(self) -> usize {
613 match self {
614 UintTy::Usize => crate::target::MachineInfo::target_pointer_width().bytes(),
615 UintTy::U8 => 1,
616 UintTy::U16 => 2,
617 UintTy::U32 => 4,
618 UintTy::U64 => 8,
619 UintTy::U128 => 16,
620 }
621 }
622}
623
624#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
625pub enum FloatTy {
626 F16,
627 F32,
628 F64,
629 F128,
630}
631
632#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
633pub enum Movability {
634 Static,
635 Movable,
636}
637
638crate_def! {
639 #[derive(Serialize)]
640 pub ForeignModuleDef;
641}
642
643impl ForeignModuleDef {
644 pub fn module(&self) -> ForeignModule {
645 with(|cx| cx.foreign_module(*self))
646 }
647}
648
649pub struct ForeignModule {
650 pub def_id: ForeignModuleDef,
651 pub abi: Abi,
652}
653
654impl ForeignModule {
655 pub fn items(&self) -> Vec<ForeignDef> {
656 with(|cx| cx.foreign_items(self.def_id))
657 }
658}
659
660crate_def_with_ty! {
661 #[derive(Serialize)]
663 pub ForeignDef;
664}
665
666impl ForeignDef {
667 pub fn kind(&self) -> ForeignItemKind {
668 with(|cx| cx.foreign_item_kind(*self))
669 }
670}
671
672#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
673pub enum ForeignItemKind {
674 Fn(FnDef),
675 Static(StaticDef),
676 Type(Ty),
677}
678
679crate_def_with_ty! {
680 #[derive(Serialize)]
682 pub FnDef;
683}
684
685impl FnDef {
686 pub fn body(&self) -> Option<Body> {
688 with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
689 }
690
691 pub fn has_body(&self) -> bool {
693 with(|ctx| ctx.has_body(self.0))
694 }
695
696 pub fn as_intrinsic(&self) -> Option<IntrinsicDef> {
698 with(|cx| cx.intrinsic(self.def_id()))
699 }
700
701 #[inline]
703 pub fn is_intrinsic(&self) -> bool {
704 self.as_intrinsic().is_some()
705 }
706
707 pub fn fn_sig(&self) -> PolyFnSig {
709 let kind = self.ty().kind();
710 kind.fn_sig().unwrap()
711 }
712}
713
714crate_def_with_ty! {
715 #[derive(Serialize)]
716 pub IntrinsicDef;
717}
718
719impl IntrinsicDef {
720 pub fn fn_name(&self) -> Symbol {
723 with(|cx| cx.intrinsic_name(*self))
724 }
725
726 pub fn must_be_overridden(&self) -> bool {
729 with(|cx| !cx.has_body(self.0))
730 }
731}
732
733impl From<IntrinsicDef> for FnDef {
734 fn from(def: IntrinsicDef) -> Self {
735 FnDef(def.0)
736 }
737}
738
739crate_def! {
740 #[derive(Serialize)]
741 pub ClosureDef;
742}
743
744crate_def! {
745 #[derive(Serialize)]
746 pub CoroutineDef;
747}
748
749crate_def! {
750 #[derive(Serialize)]
751 pub CoroutineClosureDef;
752}
753
754crate_def! {
755 #[derive(Serialize)]
756 pub ParamDef;
757}
758
759crate_def! {
760 #[derive(Serialize)]
761 pub BrNamedDef;
762}
763
764crate_def! {
765 #[derive(Serialize)]
766 pub AdtDef;
767}
768
769#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
770pub enum AdtKind {
771 Enum,
772 Union,
773 Struct,
774}
775
776impl AdtDef {
777 pub fn kind(&self) -> AdtKind {
778 with(|cx| cx.adt_kind(*self))
779 }
780
781 pub fn ty(&self) -> Ty {
783 with(|cx| cx.def_ty(self.0))
784 }
785
786 pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
790 with(|cx| cx.def_ty_with_args(self.0, args))
791 }
792
793 pub fn is_box(&self) -> bool {
794 with(|cx| cx.adt_is_box(*self))
795 }
796
797 pub fn is_simd(&self) -> bool {
798 with(|cx| cx.adt_is_simd(*self))
799 }
800
801 pub fn num_variants(&self) -> usize {
803 with(|cx| cx.adt_variants_len(*self))
804 }
805
806 pub fn variants(&self) -> Vec<VariantDef> {
808 self.variants_iter().collect()
809 }
810
811 pub fn variants_iter(&self) -> impl Iterator<Item = VariantDef> + '_ {
813 (0..self.num_variants())
814 .map(|idx| VariantDef { idx: VariantIdx::to_val(idx), adt_def: *self })
815 }
816
817 pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
818 (idx.to_index() < self.num_variants()).then_some(VariantDef { idx, adt_def: *self })
819 }
820}
821
822#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
824pub struct VariantDef {
825 pub idx: VariantIdx,
830 pub adt_def: AdtDef,
837}
838
839impl VariantDef {
840 pub fn name(&self) -> Symbol {
841 with(|cx| cx.variant_name(*self))
842 }
843
844 pub fn fields(&self) -> Vec<FieldDef> {
848 with(|cx| cx.variant_fields(*self))
849 }
850}
851
852#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
853pub struct FieldDef {
854 pub def: DefId,
859
860 pub name: Symbol,
862}
863
864impl FieldDef {
865 pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
869 with(|cx| cx.def_ty_with_args(self.def, args))
870 }
871
872 pub fn ty(&self) -> Ty {
874 with(|cx| cx.def_ty(self.def))
875 }
876}
877
878impl Display for AdtKind {
879 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
880 f.write_str(match self {
881 AdtKind::Enum => "enum",
882 AdtKind::Union => "union",
883 AdtKind::Struct => "struct",
884 })
885 }
886}
887
888impl AdtKind {
889 pub fn is_enum(&self) -> bool {
890 matches!(self, AdtKind::Enum)
891 }
892
893 pub fn is_struct(&self) -> bool {
894 matches!(self, AdtKind::Struct)
895 }
896
897 pub fn is_union(&self) -> bool {
898 matches!(self, AdtKind::Union)
899 }
900}
901
902crate_def! {
903 #[derive(Serialize)]
904 pub AliasDef;
905}
906
907crate_def! {
908 #[derive(Serialize)]
910 pub TraitDef;
911}
912
913impl TraitDef {
914 pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
915 with(|cx| cx.trait_decl(trait_def))
916 }
917}
918
919crate_def! {
920 #[derive(Serialize)]
921 pub GenericDef;
922}
923
924crate_def_with_ty! {
925 #[derive(Serialize)]
926 pub ConstDef;
927}
928
929crate_def! {
930 #[derive(Serialize)]
932 pub ImplDef;
933}
934
935impl ImplDef {
936 pub fn trait_impl(&self) -> ImplTrait {
938 with(|cx| cx.trait_impl(self))
939 }
940}
941
942crate_def! {
943 #[derive(Serialize)]
944 pub RegionDef;
945}
946
947crate_def! {
948 #[derive(Serialize)]
949 pub CoroutineWitnessDef;
950}
951
952#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
954pub struct GenericArgs(pub Vec<GenericArgKind>);
955
956impl std::ops::Index<ParamTy> for GenericArgs {
957 type Output = Ty;
958
959 fn index(&self, index: ParamTy) -> &Self::Output {
960 self.0[index.index as usize].expect_ty()
961 }
962}
963
964impl std::ops::Index<ParamConst> for GenericArgs {
965 type Output = TyConst;
966
967 fn index(&self, index: ParamConst) -> &Self::Output {
968 self.0[index.index as usize].expect_const()
969 }
970}
971
972#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
973pub enum GenericArgKind {
974 Lifetime(Region),
975 Type(Ty),
976 Const(TyConst),
977}
978
979impl GenericArgKind {
980 #[track_caller]
983 pub fn expect_ty(&self) -> &Ty {
984 match self {
985 GenericArgKind::Type(ty) => ty,
986 _ => panic!("{self:?}"),
987 }
988 }
989
990 #[track_caller]
993 pub fn expect_const(&self) -> &TyConst {
994 match self {
995 GenericArgKind::Const(c) => c,
996 _ => panic!("{self:?}"),
997 }
998 }
999
1000 pub fn ty(&self) -> Option<&Ty> {
1002 match self {
1003 GenericArgKind::Type(ty) => Some(ty),
1004 _ => None,
1005 }
1006 }
1007}
1008
1009#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1010pub enum TermKind {
1011 Type(Ty),
1012 Const(TyConst),
1013}
1014
1015#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1016pub enum AliasKind {
1017 Projection,
1018 Inherent,
1019 Opaque,
1020 Weak,
1021}
1022
1023#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1024pub struct AliasTy {
1025 pub def_id: AliasDef,
1026 pub args: GenericArgs,
1027}
1028
1029#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1030pub struct AliasTerm {
1031 pub def_id: AliasDef,
1032 pub args: GenericArgs,
1033}
1034
1035pub type PolyFnSig = Binder<FnSig>;
1036
1037impl PolyFnSig {
1038 pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> {
1043 with(|cx| cx.fn_ptr_abi(self))
1044 }
1045}
1046
1047#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1048pub struct FnSig {
1049 pub inputs_and_output: Vec<Ty>,
1050 pub c_variadic: bool,
1051 pub safety: Safety,
1052 pub abi: Abi,
1053}
1054
1055impl FnSig {
1056 pub fn output(&self) -> Ty {
1057 self.inputs_and_output[self.inputs_and_output.len() - 1]
1058 }
1059
1060 pub fn inputs(&self) -> &[Ty] {
1061 &self.inputs_and_output[..self.inputs_and_output.len() - 1]
1062 }
1063}
1064
1065#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1066pub enum Abi {
1067 Rust,
1068 C { unwind: bool },
1069 Cdecl { unwind: bool },
1070 Stdcall { unwind: bool },
1071 Fastcall { unwind: bool },
1072 Vectorcall { unwind: bool },
1073 Thiscall { unwind: bool },
1074 Aapcs { unwind: bool },
1075 Win64 { unwind: bool },
1076 SysV64 { unwind: bool },
1077 PtxKernel,
1078 Msp430Interrupt,
1079 X86Interrupt,
1080 GpuKernel,
1081 EfiApi,
1082 AvrInterrupt,
1083 AvrNonBlockingInterrupt,
1084 CCmseNonSecureCall,
1085 CCmseNonSecureEntry,
1086 System { unwind: bool },
1087 RustIntrinsic,
1088 RustCall,
1089 Unadjusted,
1090 RustCold,
1091 RiscvInterruptM,
1092 RiscvInterruptS,
1093}
1094
1095#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1097pub struct Binder<T> {
1098 pub value: T,
1099 pub bound_vars: Vec<BoundVariableKind>,
1100}
1101
1102impl<T> Binder<T> {
1103 pub fn bind_with_vars(value: T, bound_vars: Vec<BoundVariableKind>) -> Self {
1105 Binder { value, bound_vars }
1106 }
1107
1108 pub fn dummy(value: T) -> Self {
1110 Binder { value, bound_vars: vec![] }
1111 }
1112
1113 pub fn skip_binder(self) -> T {
1114 self.value
1115 }
1116
1117 pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
1118 where
1119 F: FnOnce(&T) -> U,
1120 {
1121 let Binder { value, bound_vars } = self;
1122 let new_value = f(value);
1123 Binder { value: new_value, bound_vars: bound_vars.clone() }
1124 }
1125
1126 pub fn map_bound<F, U>(self, f: F) -> Binder<U>
1127 where
1128 F: FnOnce(T) -> U,
1129 {
1130 let Binder { value, bound_vars } = self;
1131 let new_value = f(value);
1132 Binder { value: new_value, bound_vars }
1133 }
1134}
1135
1136#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1137pub struct EarlyBinder<T> {
1138 pub value: T,
1139}
1140
1141#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1142pub enum BoundVariableKind {
1143 Ty(BoundTyKind),
1144 Region(BoundRegionKind),
1145 Const,
1146}
1147
1148#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1149pub enum BoundTyKind {
1150 Anon,
1151 Param(ParamDef, String),
1152}
1153
1154#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1155pub enum BoundRegionKind {
1156 BrAnon,
1157 BrNamed(BrNamedDef, String),
1158 BrEnv,
1159}
1160
1161#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1162pub enum DynKind {
1163 Dyn,
1164 DynStar,
1165}
1166
1167#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1168pub enum ExistentialPredicate {
1169 Trait(ExistentialTraitRef),
1170 Projection(ExistentialProjection),
1171 AutoTrait(TraitDef),
1172}
1173
1174#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1178pub struct ExistentialTraitRef {
1179 pub def_id: TraitDef,
1180 pub generic_args: GenericArgs,
1181}
1182
1183impl Binder<ExistentialTraitRef> {
1184 pub fn with_self_ty(&self, self_ty: Ty) -> Binder<TraitRef> {
1185 self.map_bound_ref(|trait_ref| trait_ref.with_self_ty(self_ty))
1186 }
1187}
1188
1189impl ExistentialTraitRef {
1190 pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
1191 TraitRef::new(self.def_id, self_ty, &self.generic_args)
1192 }
1193}
1194
1195#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1196pub struct ExistentialProjection {
1197 pub def_id: TraitDef,
1198 pub generic_args: GenericArgs,
1199 pub term: TermKind,
1200}
1201
1202#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1203pub struct ParamTy {
1204 pub index: u32,
1205 pub name: String,
1206}
1207
1208#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1209pub struct BoundTy {
1210 pub var: usize,
1211 pub kind: BoundTyKind,
1212}
1213
1214pub type Bytes = Vec<Option<u8>>;
1215
1216pub type Size = usize;
1218
1219#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1220pub struct Prov(pub AllocId);
1221
1222pub type Align = u64;
1223pub type Promoted = u32;
1224pub type InitMaskMaterialized = Vec<u64>;
1225
1226#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1228pub struct ProvenanceMap {
1229 pub ptrs: Vec<(Size, Prov)>,
1232}
1233
1234#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1235pub struct Allocation {
1236 pub bytes: Bytes,
1237 pub provenance: ProvenanceMap,
1238 pub align: Align,
1239 pub mutability: Mutability,
1240}
1241
1242impl Allocation {
1243 pub fn raw_bytes(&self) -> Result<Vec<u8>, Error> {
1245 self.bytes
1246 .iter()
1247 .copied()
1248 .collect::<Option<Vec<_>>>()
1249 .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))
1250 }
1251
1252 pub fn read_partial_uint(&self, range: Range<usize>) -> Result<u128, Error> {
1254 if range.end - range.start > 16 {
1255 return Err(error!("Allocation is bigger than largest integer"));
1256 }
1257 if range.end > self.bytes.len() {
1258 return Err(error!(
1259 "Range is out of bounds. Allocation length is `{}`, but requested range `{:?}`",
1260 self.bytes.len(),
1261 range
1262 ));
1263 }
1264 let raw = self.bytes[range]
1265 .iter()
1266 .copied()
1267 .collect::<Option<Vec<_>>>()
1268 .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))?;
1269 read_target_uint(&raw)
1270 }
1271
1272 pub fn read_uint(&self) -> Result<u128, Error> {
1274 if self.bytes.len() > 16 {
1275 return Err(error!("Allocation is bigger than largest integer"));
1276 }
1277 let raw = self.raw_bytes()?;
1278 read_target_uint(&raw)
1279 }
1280
1281 pub fn read_int(&self) -> Result<i128, Error> {
1283 if self.bytes.len() > 16 {
1284 return Err(error!("Allocation is bigger than largest integer"));
1285 }
1286 let raw = self.raw_bytes()?;
1287 read_target_int(&raw)
1288 }
1289
1290 pub fn read_bool(&self) -> Result<bool, Error> {
1292 match self.read_int()? {
1293 0 => Ok(false),
1294 1 => Ok(true),
1295 val => Err(error!("Unexpected value for bool: `{val}`")),
1296 }
1297 }
1298
1299 pub fn is_null(&self) -> Result<bool, Error> {
1301 let len = self.bytes.len();
1302 let ptr_len = MachineInfo::target_pointer_width().bytes();
1303 if len != ptr_len {
1304 return Err(error!("Expected width of pointer (`{ptr_len}`), but found: `{len}`"));
1305 }
1306 Ok(self.read_uint()? == 0 && self.provenance.ptrs.is_empty())
1307 }
1308}
1309
1310#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1311pub enum ConstantKind {
1312 Ty(TyConst),
1313 Allocated(Allocation),
1314 Unevaluated(UnevaluatedConst),
1315 Param(ParamConst),
1316 ZeroSized,
1319}
1320
1321#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1322pub struct ParamConst {
1323 pub index: u32,
1324 pub name: String,
1325}
1326
1327#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1328pub struct UnevaluatedConst {
1329 pub def: ConstDef,
1330 pub args: GenericArgs,
1331 pub promoted: Option<Promoted>,
1332}
1333
1334#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
1335pub enum TraitSpecializationKind {
1336 None,
1337 Marker,
1338 AlwaysApplicable,
1339}
1340
1341#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1342pub struct TraitDecl {
1343 pub def_id: TraitDef,
1344 pub safety: Safety,
1345 pub paren_sugar: bool,
1346 pub has_auto_impl: bool,
1347 pub is_marker: bool,
1348 pub is_coinductive: bool,
1349 pub skip_array_during_method_dispatch: bool,
1350 pub skip_boxed_slice_during_method_dispatch: bool,
1351 pub specialization_kind: TraitSpecializationKind,
1352 pub must_implement_one_of: Option<Vec<Ident>>,
1353 pub implement_via_object: bool,
1354 pub deny_explicit_impl: bool,
1355}
1356
1357impl TraitDecl {
1358 pub fn generics_of(&self) -> Generics {
1359 with(|cx| cx.generics_of(self.def_id.0))
1360 }
1361
1362 pub fn predicates_of(&self) -> GenericPredicates {
1363 with(|cx| cx.predicates_of(self.def_id.0))
1364 }
1365
1366 pub fn explicit_predicates_of(&self) -> GenericPredicates {
1367 with(|cx| cx.explicit_predicates_of(self.def_id.0))
1368 }
1369}
1370
1371pub type ImplTrait = EarlyBinder<TraitRef>;
1372
1373#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1375pub struct TraitRef {
1376 pub def_id: TraitDef,
1377 args: GenericArgs,
1380}
1381
1382impl TraitRef {
1383 pub fn new(def_id: TraitDef, self_ty: Ty, gen_args: &GenericArgs) -> TraitRef {
1384 let mut args = vec![GenericArgKind::Type(self_ty)];
1385 args.extend_from_slice(&gen_args.0);
1386 TraitRef { def_id, args: GenericArgs(args) }
1387 }
1388
1389 pub fn try_new(def_id: TraitDef, args: GenericArgs) -> Result<TraitRef, ()> {
1390 match &args.0[..] {
1391 [GenericArgKind::Type(_), ..] => Ok(TraitRef { def_id, args }),
1392 _ => Err(()),
1393 }
1394 }
1395
1396 pub fn args(&self) -> &GenericArgs {
1397 &self.args
1398 }
1399
1400 pub fn self_ty(&self) -> Ty {
1401 let GenericArgKind::Type(self_ty) = self.args.0[0] else {
1402 panic!("Self must be a type, but found: {:?}", self.args.0[0])
1403 };
1404 self_ty
1405 }
1406}
1407
1408#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1409pub struct Generics {
1410 pub parent: Option<GenericDef>,
1411 pub parent_count: usize,
1412 pub params: Vec<GenericParamDef>,
1413 pub param_def_id_to_index: Vec<(GenericDef, u32)>,
1414 pub has_self: bool,
1415 pub has_late_bound_regions: Option<Span>,
1416}
1417
1418#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1419pub enum GenericParamDefKind {
1420 Lifetime,
1421 Type { has_default: bool, synthetic: bool },
1422 Const { has_default: bool },
1423}
1424
1425#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1426pub struct GenericParamDef {
1427 pub name: super::Symbol,
1428 pub def_id: GenericDef,
1429 pub index: u32,
1430 pub pure_wrt_drop: bool,
1431 pub kind: GenericParamDefKind,
1432}
1433
1434pub struct GenericPredicates {
1435 pub parent: Option<TraitDef>,
1436 pub predicates: Vec<(PredicateKind, Span)>,
1437}
1438
1439#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1440pub enum PredicateKind {
1441 Clause(ClauseKind),
1442 DynCompatible(TraitDef),
1443 SubType(SubtypePredicate),
1444 Coerce(CoercePredicate),
1445 ConstEquate(TyConst, TyConst),
1446 Ambiguous,
1447 AliasRelate(TermKind, TermKind, AliasRelationDirection),
1448}
1449
1450#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1451pub enum ClauseKind {
1452 Trait(TraitPredicate),
1453 RegionOutlives(RegionOutlivesPredicate),
1454 TypeOutlives(TypeOutlivesPredicate),
1455 Projection(ProjectionPredicate),
1456 ConstArgHasType(TyConst, Ty),
1457 WellFormed(GenericArgKind),
1458 ConstEvaluatable(TyConst),
1459}
1460
1461#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1462pub enum ClosureKind {
1463 Fn,
1464 FnMut,
1465 FnOnce,
1466}
1467
1468#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1469pub struct SubtypePredicate {
1470 pub a: Ty,
1471 pub b: Ty,
1472}
1473
1474#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1475pub struct CoercePredicate {
1476 pub a: Ty,
1477 pub b: Ty,
1478}
1479
1480#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1481pub enum AliasRelationDirection {
1482 Equate,
1483 Subtype,
1484}
1485
1486#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1487pub struct TraitPredicate {
1488 pub trait_ref: TraitRef,
1489 pub polarity: PredicatePolarity,
1490}
1491
1492#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1493pub struct OutlivesPredicate<A, B>(pub A, pub B);
1494
1495pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
1496pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
1497
1498#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1499pub struct ProjectionPredicate {
1500 pub projection_term: AliasTerm,
1501 pub term: TermKind,
1502}
1503
1504#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1505pub enum ImplPolarity {
1506 Positive,
1507 Negative,
1508 Reservation,
1509}
1510
1511#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1512pub enum PredicatePolarity {
1513 Positive,
1514 Negative,
1515}
1516
1517pub trait IndexedVal {
1518 fn to_val(index: usize) -> Self;
1519
1520 fn to_index(&self) -> usize;
1521}
1522
1523macro_rules! index_impl {
1524 ($name:ident) => {
1525 impl IndexedVal for $name {
1526 fn to_val(index: usize) -> Self {
1527 $name(index)
1528 }
1529 fn to_index(&self) -> usize {
1530 self.0
1531 }
1532 }
1533 };
1534}
1535
1536index_impl!(TyConstId);
1537index_impl!(MirConstId);
1538index_impl!(Ty);
1539index_impl!(Span);
1540
1541#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
1555pub struct VariantIdx(usize);
1556
1557index_impl!(VariantIdx);