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, ThreadLocalIndex};
15
16#[derive(Copy, Clone, Eq, PartialEq, Hash)]
17pub struct Ty(usize, ThreadLocalIndex);
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)]
155pub struct TyConstId(usize, ThreadLocalIndex);
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)]
216pub struct MirConstId(usize, ThreadLocalIndex);
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)]
259pub struct Span(usize, ThreadLocalIndex);
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 {
883 with(|cx| cx.variant_name(*self))
884 }
885
886 pub fn fields(&self) -> Vec<FieldDef> {
890 with(|cx| cx.variant_fields(*self))
891 }
892}
893
894#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
895pub struct FieldDef {
896 pub def: DefId,
901
902 pub name: Symbol,
904}
905
906impl FieldDef {
907 pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
911 with(|cx| cx.def_ty_with_args(self.def, args))
912 }
913
914 pub fn ty(&self) -> Ty {
916 with(|cx| cx.def_ty(self.def))
917 }
918}
919
920impl Display for AdtKind {
921 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
922 f.write_str(match self {
923 AdtKind::Enum => "enum",
924 AdtKind::Union => "union",
925 AdtKind::Struct => "struct",
926 })
927 }
928}
929
930impl AdtKind {
931 pub fn is_enum(&self) -> bool {
932 matches!(self, AdtKind::Enum)
933 }
934
935 pub fn is_struct(&self) -> bool {
936 matches!(self, AdtKind::Struct)
937 }
938
939 pub fn is_union(&self) -> bool {
940 matches!(self, AdtKind::Union)
941 }
942}
943
944crate_def! {
945 #[derive(Serialize)]
946 pub AliasDef;
947}
948
949crate_def! {
950 #[derive(Serialize)]
952 pub TraitDef;
953}
954
955impl_crate_def_items! {
956 TraitDef;
957}
958
959impl TraitDef {
960 pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
961 with(|cx| cx.trait_decl(trait_def))
962 }
963}
964
965crate_def! {
966 #[derive(Serialize)]
967 pub GenericDef;
968}
969
970crate_def_with_ty! {
971 #[derive(Serialize)]
972 pub ConstDef;
973}
974
975crate_def! {
976 #[derive(Serialize)]
978 pub ImplDef;
979}
980
981impl_crate_def_items! {
982 ImplDef;
983}
984
985impl ImplDef {
986 pub fn trait_impl(&self) -> ImplTrait {
988 with(|cx| cx.trait_impl(self))
989 }
990}
991
992crate_def! {
993 #[derive(Serialize)]
994 pub RegionDef;
995}
996
997crate_def! {
998 #[derive(Serialize)]
999 pub CoroutineWitnessDef;
1000}
1001
1002#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1004pub struct GenericArgs(pub Vec<GenericArgKind>);
1005
1006impl std::ops::Index<ParamTy> for GenericArgs {
1007 type Output = Ty;
1008
1009 fn index(&self, index: ParamTy) -> &Self::Output {
1010 self.0[index.index as usize].expect_ty()
1011 }
1012}
1013
1014impl std::ops::Index<ParamConst> for GenericArgs {
1015 type Output = TyConst;
1016
1017 fn index(&self, index: ParamConst) -> &Self::Output {
1018 self.0[index.index as usize].expect_const()
1019 }
1020}
1021
1022#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1023pub enum GenericArgKind {
1024 Lifetime(Region),
1025 Type(Ty),
1026 Const(TyConst),
1027}
1028
1029impl GenericArgKind {
1030 #[track_caller]
1033 pub fn expect_ty(&self) -> &Ty {
1034 match self {
1035 GenericArgKind::Type(ty) => ty,
1036 _ => panic!("{self:?}"),
1037 }
1038 }
1039
1040 #[track_caller]
1043 pub fn expect_const(&self) -> &TyConst {
1044 match self {
1045 GenericArgKind::Const(c) => c,
1046 _ => panic!("{self:?}"),
1047 }
1048 }
1049
1050 pub fn ty(&self) -> Option<&Ty> {
1052 match self {
1053 GenericArgKind::Type(ty) => Some(ty),
1054 _ => None,
1055 }
1056 }
1057}
1058
1059#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1060pub enum TermKind {
1061 Type(Ty),
1062 Const(TyConst),
1063}
1064
1065#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1066pub enum AliasKind {
1067 Projection,
1068 Inherent,
1069 Opaque,
1070 Free,
1071}
1072
1073#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1074pub struct AliasTy {
1075 pub def_id: AliasDef,
1076 pub args: GenericArgs,
1077}
1078
1079#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1080pub struct AliasTerm {
1081 pub def_id: AliasDef,
1082 pub args: GenericArgs,
1083}
1084
1085pub type PolyFnSig = Binder<FnSig>;
1086
1087impl PolyFnSig {
1088 pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> {
1093 with(|cx| cx.fn_ptr_abi(self))
1094 }
1095}
1096
1097#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1098pub struct FnSig {
1099 pub inputs_and_output: Vec<Ty>,
1100 pub c_variadic: bool,
1101 pub safety: Safety,
1102 pub abi: Abi,
1103}
1104
1105impl FnSig {
1106 pub fn output(&self) -> Ty {
1107 self.inputs_and_output[self.inputs_and_output.len() - 1]
1108 }
1109
1110 pub fn inputs(&self) -> &[Ty] {
1111 &self.inputs_and_output[..self.inputs_and_output.len() - 1]
1112 }
1113}
1114
1115#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1116pub enum Abi {
1117 Rust,
1118 C { unwind: bool },
1119 Cdecl { unwind: bool },
1120 Stdcall { unwind: bool },
1121 Fastcall { unwind: bool },
1122 Vectorcall { unwind: bool },
1123 Thiscall { unwind: bool },
1124 Aapcs { unwind: bool },
1125 Win64 { unwind: bool },
1126 SysV64 { unwind: bool },
1127 PtxKernel,
1128 Msp430Interrupt,
1129 X86Interrupt,
1130 GpuKernel,
1131 EfiApi,
1132 AvrInterrupt,
1133 AvrNonBlockingInterrupt,
1134 CCmseNonSecureCall,
1135 CCmseNonSecureEntry,
1136 System { unwind: bool },
1137 RustCall,
1138 Unadjusted,
1139 RustCold,
1140 RiscvInterruptM,
1141 RiscvInterruptS,
1142 RustInvalid,
1143 Custom,
1144}
1145
1146#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1148pub struct Binder<T> {
1149 pub value: T,
1150 pub bound_vars: Vec<BoundVariableKind>,
1151}
1152
1153impl<T> Binder<T> {
1154 pub fn bind_with_vars(value: T, bound_vars: Vec<BoundVariableKind>) -> Self {
1156 Binder { value, bound_vars }
1157 }
1158
1159 pub fn dummy(value: T) -> Self {
1161 Binder { value, bound_vars: vec![] }
1162 }
1163
1164 pub fn skip_binder(self) -> T {
1165 self.value
1166 }
1167
1168 pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
1169 where
1170 F: FnOnce(&T) -> U,
1171 {
1172 let Binder { value, bound_vars } = self;
1173 let new_value = f(value);
1174 Binder { value: new_value, bound_vars: bound_vars.clone() }
1175 }
1176
1177 pub fn map_bound<F, U>(self, f: F) -> Binder<U>
1178 where
1179 F: FnOnce(T) -> U,
1180 {
1181 let Binder { value, bound_vars } = self;
1182 let new_value = f(value);
1183 Binder { value: new_value, bound_vars }
1184 }
1185}
1186
1187#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1188pub struct EarlyBinder<T> {
1189 pub value: T,
1190}
1191
1192#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1193pub enum BoundVariableKind {
1194 Ty(BoundTyKind),
1195 Region(BoundRegionKind),
1196 Const,
1197}
1198
1199#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1200pub enum BoundTyKind {
1201 Anon,
1202 Param(ParamDef, String),
1203}
1204
1205#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1206pub enum BoundRegionKind {
1207 BrAnon,
1208 BrNamed(BrNamedDef, String),
1209 BrEnv,
1210}
1211
1212#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1213pub enum ExistentialPredicate {
1214 Trait(ExistentialTraitRef),
1215 Projection(ExistentialProjection),
1216 AutoTrait(TraitDef),
1217}
1218
1219#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1223pub struct ExistentialTraitRef {
1224 pub def_id: TraitDef,
1225 pub generic_args: GenericArgs,
1226}
1227
1228impl Binder<ExistentialTraitRef> {
1229 pub fn with_self_ty(&self, self_ty: Ty) -> Binder<TraitRef> {
1230 self.map_bound_ref(|trait_ref| trait_ref.with_self_ty(self_ty))
1231 }
1232}
1233
1234impl ExistentialTraitRef {
1235 pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
1236 TraitRef::new(self.def_id, self_ty, &self.generic_args)
1237 }
1238}
1239
1240#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1241pub struct ExistentialProjection {
1242 pub def_id: TraitDef,
1243 pub generic_args: GenericArgs,
1244 pub term: TermKind,
1245}
1246
1247#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1248pub struct ParamTy {
1249 pub index: u32,
1250 pub name: String,
1251}
1252
1253#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1254pub struct BoundTy {
1255 pub var: usize,
1256 pub kind: BoundTyKind,
1257}
1258
1259pub type Bytes = Vec<Option<u8>>;
1260
1261pub type Size = usize;
1263
1264#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1265pub struct Prov(pub AllocId);
1266
1267pub type Align = u64;
1268pub type Promoted = u32;
1269pub type InitMaskMaterialized = Vec<u64>;
1270
1271#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1273pub struct ProvenanceMap {
1274 pub ptrs: Vec<(Size, Prov)>,
1277}
1278
1279#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1280pub struct Allocation {
1281 pub bytes: Bytes,
1282 pub provenance: ProvenanceMap,
1283 pub align: Align,
1284 pub mutability: Mutability,
1285}
1286
1287impl Allocation {
1288 pub fn raw_bytes(&self) -> Result<Vec<u8>, Error> {
1290 self.bytes
1291 .iter()
1292 .copied()
1293 .collect::<Option<Vec<_>>>()
1294 .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))
1295 }
1296
1297 pub fn read_partial_uint(&self, range: Range<usize>) -> Result<u128, Error> {
1299 if range.end - range.start > 16 {
1300 return Err(error!("Allocation is bigger than largest integer"));
1301 }
1302 if range.end > self.bytes.len() {
1303 return Err(error!(
1304 "Range is out of bounds. Allocation length is `{}`, but requested range `{:?}`",
1305 self.bytes.len(),
1306 range
1307 ));
1308 }
1309 let raw = self.bytes[range]
1310 .iter()
1311 .copied()
1312 .collect::<Option<Vec<_>>>()
1313 .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))?;
1314 read_target_uint(&raw)
1315 }
1316
1317 pub fn read_uint(&self) -> Result<u128, Error> {
1319 if self.bytes.len() > 16 {
1320 return Err(error!("Allocation is bigger than largest integer"));
1321 }
1322 let raw = self.raw_bytes()?;
1323 read_target_uint(&raw)
1324 }
1325
1326 pub fn read_int(&self) -> Result<i128, Error> {
1328 if self.bytes.len() > 16 {
1329 return Err(error!("Allocation is bigger than largest integer"));
1330 }
1331 let raw = self.raw_bytes()?;
1332 read_target_int(&raw)
1333 }
1334
1335 pub fn read_bool(&self) -> Result<bool, Error> {
1337 match self.read_int()? {
1338 0 => Ok(false),
1339 1 => Ok(true),
1340 val => Err(error!("Unexpected value for bool: `{val}`")),
1341 }
1342 }
1343
1344 pub fn is_null(&self) -> Result<bool, Error> {
1346 let len = self.bytes.len();
1347 let ptr_len = MachineInfo::target_pointer_width().bytes();
1348 if len != ptr_len {
1349 return Err(error!("Expected width of pointer (`{ptr_len}`), but found: `{len}`"));
1350 }
1351 Ok(self.read_uint()? == 0 && self.provenance.ptrs.is_empty())
1352 }
1353}
1354
1355#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1356pub enum ConstantKind {
1357 Ty(TyConst),
1358 Allocated(Allocation),
1359 Unevaluated(UnevaluatedConst),
1360 Param(ParamConst),
1361 ZeroSized,
1364}
1365
1366#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1367pub struct ParamConst {
1368 pub index: u32,
1369 pub name: String,
1370}
1371
1372#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1373pub struct UnevaluatedConst {
1374 pub def: ConstDef,
1375 pub args: GenericArgs,
1376 pub promoted: Option<Promoted>,
1377}
1378
1379#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
1380pub enum TraitSpecializationKind {
1381 None,
1382 Marker,
1383 AlwaysApplicable,
1384}
1385
1386#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1387pub struct TraitDecl {
1388 pub def_id: TraitDef,
1389 pub safety: Safety,
1390 pub paren_sugar: bool,
1391 pub has_auto_impl: bool,
1392 pub is_marker: bool,
1393 pub is_coinductive: bool,
1394 pub skip_array_during_method_dispatch: bool,
1395 pub skip_boxed_slice_during_method_dispatch: bool,
1396 pub specialization_kind: TraitSpecializationKind,
1397 pub must_implement_one_of: Option<Vec<Ident>>,
1398 pub implement_via_object: bool,
1399 pub deny_explicit_impl: bool,
1400}
1401
1402impl TraitDecl {
1403 pub fn generics_of(&self) -> Generics {
1404 with(|cx| cx.generics_of(self.def_id.0))
1405 }
1406
1407 pub fn predicates_of(&self) -> GenericPredicates {
1408 with(|cx| cx.predicates_of(self.def_id.0))
1409 }
1410
1411 pub fn explicit_predicates_of(&self) -> GenericPredicates {
1412 with(|cx| cx.explicit_predicates_of(self.def_id.0))
1413 }
1414}
1415
1416pub type ImplTrait = EarlyBinder<TraitRef>;
1417
1418#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1420pub struct TraitRef {
1421 pub def_id: TraitDef,
1422 args: GenericArgs,
1425}
1426
1427impl TraitRef {
1428 pub fn new(def_id: TraitDef, self_ty: Ty, gen_args: &GenericArgs) -> TraitRef {
1429 let mut args = vec![GenericArgKind::Type(self_ty)];
1430 args.extend_from_slice(&gen_args.0);
1431 TraitRef { def_id, args: GenericArgs(args) }
1432 }
1433
1434 pub fn try_new(def_id: TraitDef, args: GenericArgs) -> Result<TraitRef, ()> {
1435 match &args.0[..] {
1436 [GenericArgKind::Type(_), ..] => Ok(TraitRef { def_id, args }),
1437 _ => Err(()),
1438 }
1439 }
1440
1441 pub fn args(&self) -> &GenericArgs {
1442 &self.args
1443 }
1444
1445 pub fn self_ty(&self) -> Ty {
1446 let GenericArgKind::Type(self_ty) = self.args.0[0] else {
1447 panic!("Self must be a type, but found: {:?}", self.args.0[0])
1448 };
1449 self_ty
1450 }
1451}
1452
1453#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1454pub struct Generics {
1455 pub parent: Option<GenericDef>,
1456 pub parent_count: usize,
1457 pub params: Vec<GenericParamDef>,
1458 pub param_def_id_to_index: Vec<(GenericDef, u32)>,
1459 pub has_self: bool,
1460 pub has_late_bound_regions: Option<Span>,
1461}
1462
1463#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1464pub enum GenericParamDefKind {
1465 Lifetime,
1466 Type { has_default: bool, synthetic: bool },
1467 Const { has_default: bool },
1468}
1469
1470#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1471pub struct GenericParamDef {
1472 pub name: super::Symbol,
1473 pub def_id: GenericDef,
1474 pub index: u32,
1475 pub pure_wrt_drop: bool,
1476 pub kind: GenericParamDefKind,
1477}
1478
1479pub struct GenericPredicates {
1480 pub parent: Option<TraitDef>,
1481 pub predicates: Vec<(PredicateKind, Span)>,
1482}
1483
1484#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1485pub enum PredicateKind {
1486 Clause(ClauseKind),
1487 DynCompatible(TraitDef),
1488 SubType(SubtypePredicate),
1489 Coerce(CoercePredicate),
1490 ConstEquate(TyConst, TyConst),
1491 Ambiguous,
1492 AliasRelate(TermKind, TermKind, AliasRelationDirection),
1493}
1494
1495#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1496pub enum ClauseKind {
1497 Trait(TraitPredicate),
1498 RegionOutlives(RegionOutlivesPredicate),
1499 TypeOutlives(TypeOutlivesPredicate),
1500 Projection(ProjectionPredicate),
1501 ConstArgHasType(TyConst, Ty),
1502 WellFormed(TermKind),
1503 ConstEvaluatable(TyConst),
1504}
1505
1506#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1507pub enum ClosureKind {
1508 Fn,
1509 FnMut,
1510 FnOnce,
1511}
1512
1513#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1514pub struct SubtypePredicate {
1515 pub a: Ty,
1516 pub b: Ty,
1517}
1518
1519#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1520pub struct CoercePredicate {
1521 pub a: Ty,
1522 pub b: Ty,
1523}
1524
1525#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1526pub enum AliasRelationDirection {
1527 Equate,
1528 Subtype,
1529}
1530
1531#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1532pub struct TraitPredicate {
1533 pub trait_ref: TraitRef,
1534 pub polarity: PredicatePolarity,
1535}
1536
1537#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1538pub struct OutlivesPredicate<A, B>(pub A, pub B);
1539
1540pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
1541pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
1542
1543#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1544pub struct ProjectionPredicate {
1545 pub projection_term: AliasTerm,
1546 pub term: TermKind,
1547}
1548
1549#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1550pub enum ImplPolarity {
1551 Positive,
1552 Negative,
1553 Reservation,
1554}
1555
1556#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1557pub enum PredicatePolarity {
1558 Positive,
1559 Negative,
1560}
1561
1562macro_rules! index_impl {
1563 ($name:ident) => {
1564 impl crate::IndexedVal for $name {
1565 fn to_val(index: usize) -> Self {
1566 $name(index, $crate::ThreadLocalIndex)
1567 }
1568 fn to_index(&self) -> usize {
1569 self.0
1570 }
1571 }
1572 $crate::ty::serialize_index_impl!($name);
1573 };
1574}
1575macro_rules! serialize_index_impl {
1576 ($name:ident) => {
1577 impl ::serde::Serialize for $name {
1578 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1579 where
1580 S: ::serde::Serializer,
1581 {
1582 let n: usize = self.0; ::serde::Serialize::serialize(&n, serializer)
1584 }
1585 }
1586 };
1587}
1588pub(crate) use {index_impl, serialize_index_impl};
1589
1590index_impl!(TyConstId);
1591index_impl!(MirConstId);
1592index_impl!(Ty);
1593index_impl!(Span);
1594
1595#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1609pub struct VariantIdx(usize, ThreadLocalIndex);
1610
1611index_impl!(VariantIdx);
1612
1613crate_def! {
1614 #[derive(Serialize)]
1616 pub OpaqueDef;
1617}
1618
1619crate_def! {
1620 #[derive(Serialize)]
1621 pub AssocDef;
1622}
1623
1624#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1625pub struct AssocItem {
1626 pub def_id: AssocDef,
1627 pub kind: AssocKind,
1628 pub container: AssocContainer,
1629}
1630
1631#[derive(Clone, PartialEq, Debug, Eq, Serialize)]
1632pub enum AssocTypeData {
1633 Normal(Symbol),
1634 Rpitit(ImplTraitInTraitData),
1638}
1639
1640#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1641pub enum AssocKind {
1642 Const { name: Symbol },
1643 Fn { name: Symbol, has_self: bool },
1644 Type { data: AssocTypeData },
1645}
1646
1647#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1648pub enum AssocContainer {
1649 InherentImpl,
1650 TraitImpl(AssocDef),
1652 Trait,
1653}
1654
1655#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1656pub enum ImplTraitInTraitData {
1657 Trait { fn_def_id: FnDef, opaque_def_id: OpaqueDef },
1658 Impl { fn_def_id: FnDef },
1659}
1660
1661impl AssocItem {
1662 pub fn is_impl_trait_in_trait(&self) -> bool {
1663 matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) })
1664 }
1665}