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(_, _)))
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),
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 ExistentialPredicate {
1211 Trait(ExistentialTraitRef),
1212 Projection(ExistentialProjection),
1213 AutoTrait(TraitDef),
1214}
1215
1216#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1220pub struct ExistentialTraitRef {
1221 pub def_id: TraitDef,
1222 pub generic_args: GenericArgs,
1223}
1224
1225impl Binder<ExistentialTraitRef> {
1226 pub fn with_self_ty(&self, self_ty: Ty) -> Binder<TraitRef> {
1227 self.map_bound_ref(|trait_ref| trait_ref.with_self_ty(self_ty))
1228 }
1229}
1230
1231impl ExistentialTraitRef {
1232 pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
1233 TraitRef::new(self.def_id, self_ty, &self.generic_args)
1234 }
1235}
1236
1237#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1238pub struct ExistentialProjection {
1239 pub def_id: TraitDef,
1240 pub generic_args: GenericArgs,
1241 pub term: TermKind,
1242}
1243
1244#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1245pub struct ParamTy {
1246 pub index: u32,
1247 pub name: String,
1248}
1249
1250#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1251pub struct BoundTy {
1252 pub var: usize,
1253 pub kind: BoundTyKind,
1254}
1255
1256pub type Bytes = Vec<Option<u8>>;
1257
1258pub type Size = usize;
1260
1261#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1262pub struct Prov(pub AllocId);
1263
1264pub type Align = u64;
1265pub type Promoted = u32;
1266pub type InitMaskMaterialized = Vec<u64>;
1267
1268#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1270pub struct ProvenanceMap {
1271 pub ptrs: Vec<(Size, Prov)>,
1274}
1275
1276#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1277pub struct Allocation {
1278 pub bytes: Bytes,
1279 pub provenance: ProvenanceMap,
1280 pub align: Align,
1281 pub mutability: Mutability,
1282}
1283
1284impl Allocation {
1285 pub fn raw_bytes(&self) -> Result<Vec<u8>, Error> {
1287 self.bytes
1288 .iter()
1289 .copied()
1290 .collect::<Option<Vec<_>>>()
1291 .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))
1292 }
1293
1294 pub fn read_partial_uint(&self, range: Range<usize>) -> Result<u128, Error> {
1296 if range.end - range.start > 16 {
1297 return Err(error!("Allocation is bigger than largest integer"));
1298 }
1299 if range.end > self.bytes.len() {
1300 return Err(error!(
1301 "Range is out of bounds. Allocation length is `{}`, but requested range `{:?}`",
1302 self.bytes.len(),
1303 range
1304 ));
1305 }
1306 let raw = self.bytes[range]
1307 .iter()
1308 .copied()
1309 .collect::<Option<Vec<_>>>()
1310 .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))?;
1311 read_target_uint(&raw)
1312 }
1313
1314 pub fn read_uint(&self) -> Result<u128, Error> {
1316 if self.bytes.len() > 16 {
1317 return Err(error!("Allocation is bigger than largest integer"));
1318 }
1319 let raw = self.raw_bytes()?;
1320 read_target_uint(&raw)
1321 }
1322
1323 pub fn read_int(&self) -> Result<i128, Error> {
1325 if self.bytes.len() > 16 {
1326 return Err(error!("Allocation is bigger than largest integer"));
1327 }
1328 let raw = self.raw_bytes()?;
1329 read_target_int(&raw)
1330 }
1331
1332 pub fn read_bool(&self) -> Result<bool, Error> {
1334 match self.read_int()? {
1335 0 => Ok(false),
1336 1 => Ok(true),
1337 val => Err(error!("Unexpected value for bool: `{val}`")),
1338 }
1339 }
1340
1341 pub fn is_null(&self) -> Result<bool, Error> {
1343 let len = self.bytes.len();
1344 let ptr_len = MachineInfo::target_pointer_width().bytes();
1345 if len != ptr_len {
1346 return Err(error!("Expected width of pointer (`{ptr_len}`), but found: `{len}`"));
1347 }
1348 Ok(self.read_uint()? == 0 && self.provenance.ptrs.is_empty())
1349 }
1350}
1351
1352#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1353pub enum ConstantKind {
1354 Ty(TyConst),
1355 Allocated(Allocation),
1356 Unevaluated(UnevaluatedConst),
1357 Param(ParamConst),
1358 ZeroSized,
1361}
1362
1363#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1364pub struct ParamConst {
1365 pub index: u32,
1366 pub name: String,
1367}
1368
1369#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1370pub struct UnevaluatedConst {
1371 pub def: ConstDef,
1372 pub args: GenericArgs,
1373 pub promoted: Option<Promoted>,
1374}
1375
1376#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
1377pub enum TraitSpecializationKind {
1378 None,
1379 Marker,
1380 AlwaysApplicable,
1381}
1382
1383#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1384pub struct TraitDecl {
1385 pub def_id: TraitDef,
1386 pub safety: Safety,
1387 pub paren_sugar: bool,
1388 pub has_auto_impl: bool,
1389 pub is_marker: bool,
1390 pub is_coinductive: bool,
1391 pub skip_array_during_method_dispatch: bool,
1392 pub skip_boxed_slice_during_method_dispatch: bool,
1393 pub specialization_kind: TraitSpecializationKind,
1394 pub must_implement_one_of: Option<Vec<Ident>>,
1395 pub implement_via_object: bool,
1396 pub deny_explicit_impl: bool,
1397}
1398
1399impl TraitDecl {
1400 pub fn generics_of(&self) -> Generics {
1401 with(|cx| cx.generics_of(self.def_id.0))
1402 }
1403
1404 pub fn predicates_of(&self) -> GenericPredicates {
1405 with(|cx| cx.predicates_of(self.def_id.0))
1406 }
1407
1408 pub fn explicit_predicates_of(&self) -> GenericPredicates {
1409 with(|cx| cx.explicit_predicates_of(self.def_id.0))
1410 }
1411}
1412
1413pub type ImplTrait = EarlyBinder<TraitRef>;
1414
1415#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1417pub struct TraitRef {
1418 pub def_id: TraitDef,
1419 args: GenericArgs,
1422}
1423
1424impl TraitRef {
1425 pub fn new(def_id: TraitDef, self_ty: Ty, gen_args: &GenericArgs) -> TraitRef {
1426 let mut args = vec![GenericArgKind::Type(self_ty)];
1427 args.extend_from_slice(&gen_args.0);
1428 TraitRef { def_id, args: GenericArgs(args) }
1429 }
1430
1431 pub fn try_new(def_id: TraitDef, args: GenericArgs) -> Result<TraitRef, ()> {
1432 match &args.0[..] {
1433 [GenericArgKind::Type(_), ..] => Ok(TraitRef { def_id, args }),
1434 _ => Err(()),
1435 }
1436 }
1437
1438 pub fn args(&self) -> &GenericArgs {
1439 &self.args
1440 }
1441
1442 pub fn self_ty(&self) -> Ty {
1443 let GenericArgKind::Type(self_ty) = self.args.0[0] else {
1444 panic!("Self must be a type, but found: {:?}", self.args.0[0])
1445 };
1446 self_ty
1447 }
1448}
1449
1450#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1451pub struct Generics {
1452 pub parent: Option<GenericDef>,
1453 pub parent_count: usize,
1454 pub params: Vec<GenericParamDef>,
1455 pub param_def_id_to_index: Vec<(GenericDef, u32)>,
1456 pub has_self: bool,
1457 pub has_late_bound_regions: Option<Span>,
1458}
1459
1460#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1461pub enum GenericParamDefKind {
1462 Lifetime,
1463 Type { has_default: bool, synthetic: bool },
1464 Const { has_default: bool },
1465}
1466
1467#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1468pub struct GenericParamDef {
1469 pub name: super::Symbol,
1470 pub def_id: GenericDef,
1471 pub index: u32,
1472 pub pure_wrt_drop: bool,
1473 pub kind: GenericParamDefKind,
1474}
1475
1476pub struct GenericPredicates {
1477 pub parent: Option<TraitDef>,
1478 pub predicates: Vec<(PredicateKind, Span)>,
1479}
1480
1481#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1482pub enum PredicateKind {
1483 Clause(ClauseKind),
1484 DynCompatible(TraitDef),
1485 SubType(SubtypePredicate),
1486 Coerce(CoercePredicate),
1487 ConstEquate(TyConst, TyConst),
1488 Ambiguous,
1489 AliasRelate(TermKind, TermKind, AliasRelationDirection),
1490}
1491
1492#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1493pub enum ClauseKind {
1494 Trait(TraitPredicate),
1495 RegionOutlives(RegionOutlivesPredicate),
1496 TypeOutlives(TypeOutlivesPredicate),
1497 Projection(ProjectionPredicate),
1498 ConstArgHasType(TyConst, Ty),
1499 WellFormed(TermKind),
1500 ConstEvaluatable(TyConst),
1501}
1502
1503#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1504pub enum ClosureKind {
1505 Fn,
1506 FnMut,
1507 FnOnce,
1508}
1509
1510#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1511pub struct SubtypePredicate {
1512 pub a: Ty,
1513 pub b: Ty,
1514}
1515
1516#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1517pub struct CoercePredicate {
1518 pub a: Ty,
1519 pub b: Ty,
1520}
1521
1522#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1523pub enum AliasRelationDirection {
1524 Equate,
1525 Subtype,
1526}
1527
1528#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1529pub struct TraitPredicate {
1530 pub trait_ref: TraitRef,
1531 pub polarity: PredicatePolarity,
1532}
1533
1534#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1535pub struct OutlivesPredicate<A, B>(pub A, pub B);
1536
1537pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
1538pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
1539
1540#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1541pub struct ProjectionPredicate {
1542 pub projection_term: AliasTerm,
1543 pub term: TermKind,
1544}
1545
1546#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1547pub enum ImplPolarity {
1548 Positive,
1549 Negative,
1550 Reservation,
1551}
1552
1553#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1554pub enum PredicatePolarity {
1555 Positive,
1556 Negative,
1557}
1558
1559macro_rules! index_impl {
1560 ($name:ident) => {
1561 impl crate::IndexedVal for $name {
1562 fn to_val(index: usize) -> Self {
1563 $name(index)
1564 }
1565 fn to_index(&self) -> usize {
1566 self.0
1567 }
1568 }
1569 };
1570}
1571
1572index_impl!(TyConstId);
1573index_impl!(MirConstId);
1574index_impl!(Ty);
1575index_impl!(Span);
1576
1577#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
1591pub struct VariantIdx(usize);
1592
1593index_impl!(VariantIdx);
1594
1595crate_def! {
1596 #[derive(Serialize)]
1598 pub OpaqueDef;
1599}
1600
1601crate_def! {
1602 #[derive(Serialize)]
1603 pub AssocDef;
1604}
1605
1606#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1607pub struct AssocItem {
1608 pub def_id: AssocDef,
1609 pub kind: AssocKind,
1610 pub container: AssocContainer,
1611}
1612
1613#[derive(Clone, PartialEq, Debug, Eq, Serialize)]
1614pub enum AssocTypeData {
1615 Normal(Symbol),
1616 Rpitit(ImplTraitInTraitData),
1620}
1621
1622#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1623pub enum AssocKind {
1624 Const { name: Symbol },
1625 Fn { name: Symbol, has_self: bool },
1626 Type { data: AssocTypeData },
1627}
1628
1629#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1630pub enum AssocContainer {
1631 InherentImpl,
1632 TraitImpl(AssocDef),
1634 Trait,
1635}
1636
1637#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1638pub enum ImplTraitInTraitData {
1639 Trait { fn_def_id: FnDef, opaque_def_id: OpaqueDef },
1640 Impl { fn_def_id: FnDef },
1641}
1642
1643impl AssocItem {
1644 pub fn is_impl_trait_in_trait(&self) -> bool {
1645 matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) })
1646 }
1647}