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