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) -> Ty {
64 Ty::from_rigid_kind(RigidTy::Coroutine(def, args))
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, Hash, 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, Hash, 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, Hash, Serialize)]
155pub struct TyConstId(usize);
156
157#[derive(Clone, Debug, Eq, PartialEq, Hash, 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, Hash, Serialize)]
216pub struct MirConstId(usize);
217
218type Ident = Opaque;
219
220#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
221pub struct Region {
222 pub kind: RegionKind,
223}
224
225#[derive(Clone, Debug, Eq, PartialEq, Hash, 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, Hash, 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, Hash, 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, Hash, Serialize)]
253pub struct Placeholder<T> {
254 pub universe: UniverseIndex,
255 pub bound: T,
256}
257
258#[derive(Clone, Copy, PartialEq, Eq, Hash, 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),
564 CoroutineClosure(CoroutineClosureDef, GenericArgs),
565 Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
566 Never,
567 Tuple(Vec<Ty>),
568 CoroutineWitness(CoroutineWitnessDef, GenericArgs),
569}
570
571impl RigidTy {
572 pub fn discriminant_ty(&self) -> Ty {
574 with(|cx| cx.rigid_ty_discriminant_ty(self))
575 }
576}
577
578impl From<RigidTy> for TyKind {
579 fn from(value: RigidTy) -> Self {
580 TyKind::RigidTy(value)
581 }
582}
583
584#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
585pub enum IntTy {
586 Isize,
587 I8,
588 I16,
589 I32,
590 I64,
591 I128,
592}
593
594impl IntTy {
595 pub fn num_bytes(self) -> usize {
596 match self {
597 IntTy::Isize => MachineInfo::target_pointer_width().bytes(),
598 IntTy::I8 => 1,
599 IntTy::I16 => 2,
600 IntTy::I32 => 4,
601 IntTy::I64 => 8,
602 IntTy::I128 => 16,
603 }
604 }
605}
606
607#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
608pub enum UintTy {
609 Usize,
610 U8,
611 U16,
612 U32,
613 U64,
614 U128,
615}
616
617impl UintTy {
618 pub fn num_bytes(self) -> usize {
619 match self {
620 UintTy::Usize => MachineInfo::target_pointer_width().bytes(),
621 UintTy::U8 => 1,
622 UintTy::U16 => 2,
623 UintTy::U32 => 4,
624 UintTy::U64 => 8,
625 UintTy::U128 => 16,
626 }
627 }
628}
629
630#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
631pub enum FloatTy {
632 F16,
633 F32,
634 F64,
635 F128,
636}
637
638#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
639pub enum Movability {
640 Static,
641 Movable,
642}
643
644crate_def! {
645 #[derive(Serialize)]
646 pub ForeignModuleDef;
647}
648
649impl ForeignModuleDef {
650 pub fn module(&self) -> ForeignModule {
651 with(|cx| cx.foreign_module(*self))
652 }
653}
654
655pub struct ForeignModule {
656 pub def_id: ForeignModuleDef,
657 pub abi: Abi,
658}
659
660impl ForeignModule {
661 pub fn items(&self) -> Vec<ForeignDef> {
662 with(|cx| cx.foreign_items(self.def_id))
663 }
664}
665
666crate_def_with_ty! {
667 #[derive(Serialize)]
669 pub ForeignDef;
670}
671
672impl ForeignDef {
673 pub fn kind(&self) -> ForeignItemKind {
674 with(|cx| cx.foreign_item_kind(*self))
675 }
676}
677
678#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
679pub enum ForeignItemKind {
680 Fn(FnDef),
681 Static(StaticDef),
682 Type(Ty),
683}
684
685crate_def_with_ty! {
686 #[derive(Serialize)]
688 pub FnDef;
689}
690
691impl FnDef {
692 pub fn body(&self) -> Option<Body> {
694 with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
695 }
696
697 pub fn has_body(&self) -> bool {
699 with(|ctx| ctx.has_body(self.0))
700 }
701
702 pub fn as_intrinsic(&self) -> Option<IntrinsicDef> {
704 with(|cx| cx.intrinsic(self.def_id()))
705 }
706
707 #[inline]
709 pub fn is_intrinsic(&self) -> bool {
710 self.as_intrinsic().is_some()
711 }
712
713 pub fn fn_sig(&self) -> PolyFnSig {
715 let kind = self.ty().kind();
716 kind.fn_sig().unwrap()
717 }
718}
719
720crate_def_with_ty! {
721 #[derive(Serialize)]
722 pub IntrinsicDef;
723}
724
725impl IntrinsicDef {
726 pub fn fn_name(&self) -> Symbol {
729 with(|cx| cx.intrinsic_name(*self))
730 }
731
732 pub fn must_be_overridden(&self) -> bool {
735 with(|cx| !cx.has_body(self.0))
736 }
737}
738
739impl From<IntrinsicDef> for FnDef {
740 fn from(def: IntrinsicDef) -> Self {
741 FnDef(def.0)
742 }
743}
744
745crate_def! {
746 #[derive(Serialize)]
747 pub ClosureDef;
748}
749
750impl ClosureDef {
751 pub fn body(&self) -> Option<Body> {
754 with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
755 }
756}
757
758crate_def! {
759 #[derive(Serialize)]
760 pub CoroutineDef;
761}
762
763impl CoroutineDef {
764 pub fn body(&self) -> Option<Body> {
767 with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
768 }
769
770 pub fn discriminant_for_variant(&self, args: &GenericArgs, idx: VariantIdx) -> Discr {
771 with(|cx| cx.coroutine_discr_for_variant(*self, args, idx))
772 }
773}
774
775crate_def! {
776 #[derive(Serialize)]
777 pub CoroutineClosureDef;
778}
779
780crate_def! {
781 #[derive(Serialize)]
782 pub ParamDef;
783}
784
785crate_def! {
786 #[derive(Serialize)]
787 pub BrNamedDef;
788}
789
790crate_def! {
791 #[derive(Serialize)]
792 pub AdtDef;
793}
794
795#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
796pub enum AdtKind {
797 Enum,
798 Union,
799 Struct,
800}
801
802impl AdtDef {
803 pub fn kind(&self) -> AdtKind {
804 with(|cx| cx.adt_kind(*self))
805 }
806
807 pub fn ty(&self) -> Ty {
809 with(|cx| cx.def_ty(self.0))
810 }
811
812 pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
816 with(|cx| cx.def_ty_with_args(self.0, args))
817 }
818
819 pub fn is_box(&self) -> bool {
820 with(|cx| cx.adt_is_box(*self))
821 }
822
823 pub fn is_simd(&self) -> bool {
824 with(|cx| cx.adt_is_simd(*self))
825 }
826
827 pub fn num_variants(&self) -> usize {
829 with(|cx| cx.adt_variants_len(*self))
830 }
831
832 pub fn variants(&self) -> Vec<VariantDef> {
834 self.variants_iter().collect()
835 }
836
837 pub fn variants_iter(&self) -> impl Iterator<Item = VariantDef> {
839 (0..self.num_variants())
840 .map(|idx| VariantDef { idx: VariantIdx::to_val(idx), adt_def: *self })
841 }
842
843 pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
844 (idx.to_index() < self.num_variants()).then_some(VariantDef { idx, adt_def: *self })
845 }
846
847 pub fn repr(&self) -> ReprOptions {
848 with(|cx| cx.adt_repr(*self))
849 }
850
851 pub fn discriminant_for_variant(&self, idx: VariantIdx) -> Discr {
852 with(|cx| cx.adt_discr_for_variant(*self, idx))
853 }
854}
855
856pub struct Discr {
857 pub val: u128,
858 pub ty: Ty,
859}
860
861#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
863pub struct VariantDef {
864 pub idx: VariantIdx,
869 pub adt_def: AdtDef,
876}
877
878impl VariantDef {
879 pub fn name(&self) -> Symbol {
880 with(|cx| cx.variant_name(*self))
881 }
882
883 pub fn fields(&self) -> Vec<FieldDef> {
887 with(|cx| cx.variant_fields(*self))
888 }
889}
890
891#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
892pub struct FieldDef {
893 pub def: DefId,
898
899 pub name: Symbol,
901}
902
903impl FieldDef {
904 pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
908 with(|cx| cx.def_ty_with_args(self.def, args))
909 }
910
911 pub fn ty(&self) -> Ty {
913 with(|cx| cx.def_ty(self.def))
914 }
915}
916
917impl Display for AdtKind {
918 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
919 f.write_str(match self {
920 AdtKind::Enum => "enum",
921 AdtKind::Union => "union",
922 AdtKind::Struct => "struct",
923 })
924 }
925}
926
927impl AdtKind {
928 pub fn is_enum(&self) -> bool {
929 matches!(self, AdtKind::Enum)
930 }
931
932 pub fn is_struct(&self) -> bool {
933 matches!(self, AdtKind::Struct)
934 }
935
936 pub fn is_union(&self) -> bool {
937 matches!(self, AdtKind::Union)
938 }
939}
940
941crate_def! {
942 #[derive(Serialize)]
943 pub AliasDef;
944}
945
946crate_def! {
947 #[derive(Serialize)]
949 pub TraitDef;
950}
951
952impl_crate_def_items! {
953 TraitDef;
954}
955
956impl TraitDef {
957 pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
958 with(|cx| cx.trait_decl(trait_def))
959 }
960}
961
962crate_def! {
963 #[derive(Serialize)]
964 pub GenericDef;
965}
966
967crate_def_with_ty! {
968 #[derive(Serialize)]
969 pub ConstDef;
970}
971
972crate_def! {
973 #[derive(Serialize)]
975 pub ImplDef;
976}
977
978impl_crate_def_items! {
979 ImplDef;
980}
981
982impl ImplDef {
983 pub fn trait_impl(&self) -> ImplTrait {
985 with(|cx| cx.trait_impl(self))
986 }
987}
988
989crate_def! {
990 #[derive(Serialize)]
991 pub RegionDef;
992}
993
994crate_def! {
995 #[derive(Serialize)]
996 pub CoroutineWitnessDef;
997}
998
999#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1001pub struct GenericArgs(pub Vec<GenericArgKind>);
1002
1003impl std::ops::Index<ParamTy> for GenericArgs {
1004 type Output = Ty;
1005
1006 fn index(&self, index: ParamTy) -> &Self::Output {
1007 self.0[index.index as usize].expect_ty()
1008 }
1009}
1010
1011impl std::ops::Index<ParamConst> for GenericArgs {
1012 type Output = TyConst;
1013
1014 fn index(&self, index: ParamConst) -> &Self::Output {
1015 self.0[index.index as usize].expect_const()
1016 }
1017}
1018
1019#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1020pub enum GenericArgKind {
1021 Lifetime(Region),
1022 Type(Ty),
1023 Const(TyConst),
1024}
1025
1026impl GenericArgKind {
1027 #[track_caller]
1030 pub fn expect_ty(&self) -> &Ty {
1031 match self {
1032 GenericArgKind::Type(ty) => ty,
1033 _ => panic!("{self:?}"),
1034 }
1035 }
1036
1037 #[track_caller]
1040 pub fn expect_const(&self) -> &TyConst {
1041 match self {
1042 GenericArgKind::Const(c) => c,
1043 _ => panic!("{self:?}"),
1044 }
1045 }
1046
1047 pub fn ty(&self) -> Option<&Ty> {
1049 match self {
1050 GenericArgKind::Type(ty) => Some(ty),
1051 _ => None,
1052 }
1053 }
1054}
1055
1056#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1057pub enum TermKind {
1058 Type(Ty),
1059 Const(TyConst),
1060}
1061
1062#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1063pub enum AliasKind {
1064 Projection,
1065 Inherent,
1066 Opaque,
1067 Free,
1068}
1069
1070#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1071pub struct AliasTy {
1072 pub def_id: AliasDef,
1073 pub args: GenericArgs,
1074}
1075
1076#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1077pub struct AliasTerm {
1078 pub def_id: AliasDef,
1079 pub args: GenericArgs,
1080}
1081
1082pub type PolyFnSig = Binder<FnSig>;
1083
1084impl PolyFnSig {
1085 pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> {
1090 with(|cx| cx.fn_ptr_abi(self))
1091 }
1092}
1093
1094#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1095pub struct FnSig {
1096 pub inputs_and_output: Vec<Ty>,
1097 pub c_variadic: bool,
1098 pub safety: Safety,
1099 pub abi: Abi,
1100}
1101
1102impl FnSig {
1103 pub fn output(&self) -> Ty {
1104 self.inputs_and_output[self.inputs_and_output.len() - 1]
1105 }
1106
1107 pub fn inputs(&self) -> &[Ty] {
1108 &self.inputs_and_output[..self.inputs_and_output.len() - 1]
1109 }
1110}
1111
1112#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1113pub enum Abi {
1114 Rust,
1115 C { unwind: bool },
1116 Cdecl { unwind: bool },
1117 Stdcall { unwind: bool },
1118 Fastcall { unwind: bool },
1119 Vectorcall { unwind: bool },
1120 Thiscall { unwind: bool },
1121 Aapcs { unwind: bool },
1122 Win64 { unwind: bool },
1123 SysV64 { unwind: bool },
1124 PtxKernel,
1125 Msp430Interrupt,
1126 X86Interrupt,
1127 GpuKernel,
1128 EfiApi,
1129 AvrInterrupt,
1130 AvrNonBlockingInterrupt,
1131 CCmseNonSecureCall,
1132 CCmseNonSecureEntry,
1133 System { unwind: bool },
1134 RustCall,
1135 Unadjusted,
1136 RustCold,
1137 RiscvInterruptM,
1138 RiscvInterruptS,
1139 RustInvalid,
1140 Custom,
1141}
1142
1143#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1145pub struct Binder<T> {
1146 pub value: T,
1147 pub bound_vars: Vec<BoundVariableKind>,
1148}
1149
1150impl<T> Binder<T> {
1151 pub fn bind_with_vars(value: T, bound_vars: Vec<BoundVariableKind>) -> Self {
1153 Binder { value, bound_vars }
1154 }
1155
1156 pub fn dummy(value: T) -> Self {
1158 Binder { value, bound_vars: vec![] }
1159 }
1160
1161 pub fn skip_binder(self) -> T {
1162 self.value
1163 }
1164
1165 pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
1166 where
1167 F: FnOnce(&T) -> U,
1168 {
1169 let Binder { value, bound_vars } = self;
1170 let new_value = f(value);
1171 Binder { value: new_value, bound_vars: bound_vars.clone() }
1172 }
1173
1174 pub fn map_bound<F, U>(self, f: F) -> Binder<U>
1175 where
1176 F: FnOnce(T) -> U,
1177 {
1178 let Binder { value, bound_vars } = self;
1179 let new_value = f(value);
1180 Binder { value: new_value, bound_vars }
1181 }
1182}
1183
1184#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1185pub struct EarlyBinder<T> {
1186 pub value: T,
1187}
1188
1189#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1190pub enum BoundVariableKind {
1191 Ty(BoundTyKind),
1192 Region(BoundRegionKind),
1193 Const,
1194}
1195
1196#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1197pub enum BoundTyKind {
1198 Anon,
1199 Param(ParamDef, String),
1200}
1201
1202#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1203pub enum BoundRegionKind {
1204 BrAnon,
1205 BrNamed(BrNamedDef, String),
1206 BrEnv,
1207}
1208
1209#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1210pub enum DynKind {
1211 Dyn,
1212}
1213
1214#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1215pub enum ExistentialPredicate {
1216 Trait(ExistentialTraitRef),
1217 Projection(ExistentialProjection),
1218 AutoTrait(TraitDef),
1219}
1220
1221#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1225pub struct ExistentialTraitRef {
1226 pub def_id: TraitDef,
1227 pub generic_args: GenericArgs,
1228}
1229
1230impl Binder<ExistentialTraitRef> {
1231 pub fn with_self_ty(&self, self_ty: Ty) -> Binder<TraitRef> {
1232 self.map_bound_ref(|trait_ref| trait_ref.with_self_ty(self_ty))
1233 }
1234}
1235
1236impl ExistentialTraitRef {
1237 pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
1238 TraitRef::new(self.def_id, self_ty, &self.generic_args)
1239 }
1240}
1241
1242#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1243pub struct ExistentialProjection {
1244 pub def_id: TraitDef,
1245 pub generic_args: GenericArgs,
1246 pub term: TermKind,
1247}
1248
1249#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1250pub struct ParamTy {
1251 pub index: u32,
1252 pub name: String,
1253}
1254
1255#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1256pub struct BoundTy {
1257 pub var: usize,
1258 pub kind: BoundTyKind,
1259}
1260
1261pub type Bytes = Vec<Option<u8>>;
1262
1263pub type Size = usize;
1265
1266#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1267pub struct Prov(pub AllocId);
1268
1269pub type Align = u64;
1270pub type Promoted = u32;
1271pub type InitMaskMaterialized = Vec<u64>;
1272
1273#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1275pub struct ProvenanceMap {
1276 pub ptrs: Vec<(Size, Prov)>,
1279}
1280
1281#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1282pub struct Allocation {
1283 pub bytes: Bytes,
1284 pub provenance: ProvenanceMap,
1285 pub align: Align,
1286 pub mutability: Mutability,
1287}
1288
1289impl Allocation {
1290 pub fn raw_bytes(&self) -> Result<Vec<u8>, Error> {
1292 self.bytes
1293 .iter()
1294 .copied()
1295 .collect::<Option<Vec<_>>>()
1296 .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))
1297 }
1298
1299 pub fn read_partial_uint(&self, range: Range<usize>) -> Result<u128, Error> {
1301 if range.end - range.start > 16 {
1302 return Err(error!("Allocation is bigger than largest integer"));
1303 }
1304 if range.end > self.bytes.len() {
1305 return Err(error!(
1306 "Range is out of bounds. Allocation length is `{}`, but requested range `{:?}`",
1307 self.bytes.len(),
1308 range
1309 ));
1310 }
1311 let raw = self.bytes[range]
1312 .iter()
1313 .copied()
1314 .collect::<Option<Vec<_>>>()
1315 .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))?;
1316 read_target_uint(&raw)
1317 }
1318
1319 pub fn read_uint(&self) -> Result<u128, Error> {
1321 if self.bytes.len() > 16 {
1322 return Err(error!("Allocation is bigger than largest integer"));
1323 }
1324 let raw = self.raw_bytes()?;
1325 read_target_uint(&raw)
1326 }
1327
1328 pub fn read_int(&self) -> Result<i128, Error> {
1330 if self.bytes.len() > 16 {
1331 return Err(error!("Allocation is bigger than largest integer"));
1332 }
1333 let raw = self.raw_bytes()?;
1334 read_target_int(&raw)
1335 }
1336
1337 pub fn read_bool(&self) -> Result<bool, Error> {
1339 match self.read_int()? {
1340 0 => Ok(false),
1341 1 => Ok(true),
1342 val => Err(error!("Unexpected value for bool: `{val}`")),
1343 }
1344 }
1345
1346 pub fn is_null(&self) -> Result<bool, Error> {
1348 let len = self.bytes.len();
1349 let ptr_len = MachineInfo::target_pointer_width().bytes();
1350 if len != ptr_len {
1351 return Err(error!("Expected width of pointer (`{ptr_len}`), but found: `{len}`"));
1352 }
1353 Ok(self.read_uint()? == 0 && self.provenance.ptrs.is_empty())
1354 }
1355}
1356
1357#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1358pub enum ConstantKind {
1359 Ty(TyConst),
1360 Allocated(Allocation),
1361 Unevaluated(UnevaluatedConst),
1362 Param(ParamConst),
1363 ZeroSized,
1366}
1367
1368#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1369pub struct ParamConst {
1370 pub index: u32,
1371 pub name: String,
1372}
1373
1374#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1375pub struct UnevaluatedConst {
1376 pub def: ConstDef,
1377 pub args: GenericArgs,
1378 pub promoted: Option<Promoted>,
1379}
1380
1381#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
1382pub enum TraitSpecializationKind {
1383 None,
1384 Marker,
1385 AlwaysApplicable,
1386}
1387
1388#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1389pub struct TraitDecl {
1390 pub def_id: TraitDef,
1391 pub safety: Safety,
1392 pub paren_sugar: bool,
1393 pub has_auto_impl: bool,
1394 pub is_marker: bool,
1395 pub is_coinductive: bool,
1396 pub skip_array_during_method_dispatch: bool,
1397 pub skip_boxed_slice_during_method_dispatch: bool,
1398 pub specialization_kind: TraitSpecializationKind,
1399 pub must_implement_one_of: Option<Vec<Ident>>,
1400 pub implement_via_object: bool,
1401 pub deny_explicit_impl: bool,
1402}
1403
1404impl TraitDecl {
1405 pub fn generics_of(&self) -> Generics {
1406 with(|cx| cx.generics_of(self.def_id.0))
1407 }
1408
1409 pub fn predicates_of(&self) -> GenericPredicates {
1410 with(|cx| cx.predicates_of(self.def_id.0))
1411 }
1412
1413 pub fn explicit_predicates_of(&self) -> GenericPredicates {
1414 with(|cx| cx.explicit_predicates_of(self.def_id.0))
1415 }
1416}
1417
1418pub type ImplTrait = EarlyBinder<TraitRef>;
1419
1420#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1422pub struct TraitRef {
1423 pub def_id: TraitDef,
1424 args: GenericArgs,
1427}
1428
1429impl TraitRef {
1430 pub fn new(def_id: TraitDef, self_ty: Ty, gen_args: &GenericArgs) -> TraitRef {
1431 let mut args = vec![GenericArgKind::Type(self_ty)];
1432 args.extend_from_slice(&gen_args.0);
1433 TraitRef { def_id, args: GenericArgs(args) }
1434 }
1435
1436 pub fn try_new(def_id: TraitDef, args: GenericArgs) -> Result<TraitRef, ()> {
1437 match &args.0[..] {
1438 [GenericArgKind::Type(_), ..] => Ok(TraitRef { def_id, args }),
1439 _ => Err(()),
1440 }
1441 }
1442
1443 pub fn args(&self) -> &GenericArgs {
1444 &self.args
1445 }
1446
1447 pub fn self_ty(&self) -> Ty {
1448 let GenericArgKind::Type(self_ty) = self.args.0[0] else {
1449 panic!("Self must be a type, but found: {:?}", self.args.0[0])
1450 };
1451 self_ty
1452 }
1453}
1454
1455#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1456pub struct Generics {
1457 pub parent: Option<GenericDef>,
1458 pub parent_count: usize,
1459 pub params: Vec<GenericParamDef>,
1460 pub param_def_id_to_index: Vec<(GenericDef, u32)>,
1461 pub has_self: bool,
1462 pub has_late_bound_regions: Option<Span>,
1463}
1464
1465#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1466pub enum GenericParamDefKind {
1467 Lifetime,
1468 Type { has_default: bool, synthetic: bool },
1469 Const { has_default: bool },
1470}
1471
1472#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1473pub struct GenericParamDef {
1474 pub name: super::Symbol,
1475 pub def_id: GenericDef,
1476 pub index: u32,
1477 pub pure_wrt_drop: bool,
1478 pub kind: GenericParamDefKind,
1479}
1480
1481pub struct GenericPredicates {
1482 pub parent: Option<TraitDef>,
1483 pub predicates: Vec<(PredicateKind, Span)>,
1484}
1485
1486#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1487pub enum PredicateKind {
1488 Clause(ClauseKind),
1489 DynCompatible(TraitDef),
1490 SubType(SubtypePredicate),
1491 Coerce(CoercePredicate),
1492 ConstEquate(TyConst, TyConst),
1493 Ambiguous,
1494 AliasRelate(TermKind, TermKind, AliasRelationDirection),
1495}
1496
1497#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1498pub enum ClauseKind {
1499 Trait(TraitPredicate),
1500 RegionOutlives(RegionOutlivesPredicate),
1501 TypeOutlives(TypeOutlivesPredicate),
1502 Projection(ProjectionPredicate),
1503 ConstArgHasType(TyConst, Ty),
1504 WellFormed(TermKind),
1505 ConstEvaluatable(TyConst),
1506}
1507
1508#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1509pub enum ClosureKind {
1510 Fn,
1511 FnMut,
1512 FnOnce,
1513}
1514
1515#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1516pub struct SubtypePredicate {
1517 pub a: Ty,
1518 pub b: Ty,
1519}
1520
1521#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1522pub struct CoercePredicate {
1523 pub a: Ty,
1524 pub b: Ty,
1525}
1526
1527#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1528pub enum AliasRelationDirection {
1529 Equate,
1530 Subtype,
1531}
1532
1533#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1534pub struct TraitPredicate {
1535 pub trait_ref: TraitRef,
1536 pub polarity: PredicatePolarity,
1537}
1538
1539#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1540pub struct OutlivesPredicate<A, B>(pub A, pub B);
1541
1542pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
1543pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
1544
1545#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1546pub struct ProjectionPredicate {
1547 pub projection_term: AliasTerm,
1548 pub term: TermKind,
1549}
1550
1551#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1552pub enum ImplPolarity {
1553 Positive,
1554 Negative,
1555 Reservation,
1556}
1557
1558#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1559pub enum PredicatePolarity {
1560 Positive,
1561 Negative,
1562}
1563
1564macro_rules! index_impl {
1565 ($name:ident) => {
1566 impl crate::IndexedVal for $name {
1567 fn to_val(index: usize) -> Self {
1568 $name(index)
1569 }
1570 fn to_index(&self) -> usize {
1571 self.0
1572 }
1573 }
1574 };
1575}
1576
1577index_impl!(TyConstId);
1578index_impl!(MirConstId);
1579index_impl!(Ty);
1580index_impl!(Span);
1581
1582#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
1596pub struct VariantIdx(usize);
1597
1598index_impl!(VariantIdx);
1599
1600crate_def! {
1601 #[derive(Serialize)]
1603 pub OpaqueDef;
1604}
1605
1606crate_def! {
1607 #[derive(Serialize)]
1608 pub AssocDef;
1609}
1610
1611#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1612pub struct AssocItem {
1613 pub def_id: AssocDef,
1614 pub kind: AssocKind,
1615 pub container: AssocItemContainer,
1616
1617 pub trait_item_def_id: Option<AssocDef>,
1620}
1621
1622#[derive(Clone, PartialEq, Debug, Eq, Serialize)]
1623pub enum AssocTypeData {
1624 Normal(Symbol),
1625 Rpitit(ImplTraitInTraitData),
1629}
1630
1631#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1632pub enum AssocKind {
1633 Const { name: Symbol },
1634 Fn { name: Symbol, has_self: bool },
1635 Type { data: AssocTypeData },
1636}
1637
1638#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1639pub enum AssocItemContainer {
1640 Trait,
1641 Impl,
1642}
1643
1644#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1645pub enum ImplTraitInTraitData {
1646 Trait { fn_def_id: FnDef, opaque_def_id: OpaqueDef },
1647 Impl { fn_def_id: FnDef },
1648}
1649
1650impl AssocItem {
1651 pub fn is_impl_trait_in_trait(&self) -> bool {
1652 matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) })
1653 }
1654}