1use std::fmt;
2use std::ops::Deref;
3
4use derive_where::derive_where;
5use rustc_ast_ir::Mutability;
6#[cfg(feature = "nightly")]
7use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
8#[cfg(feature = "nightly")]
9use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
10use rustc_type_ir::data_structures::{NoError, UnifyKey, UnifyValue};
11use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
12
13use self::TyKind::*;
14pub use self::closure::*;
15use crate::inherent::*;
16#[cfg(feature = "nightly")]
17use crate::visit::TypeVisitable;
18use crate::{self as ty, DebruijnIndex, Interner};
19
20mod closure;
21
22#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
27#[cfg_attr(
28 feature = "nightly",
29 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
30)]
31pub enum DynKind {
32 Dyn,
34}
35
36#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
37#[cfg_attr(
38 feature = "nightly",
39 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
40)]
41pub enum AliasTyKind {
42 Projection,
45 Inherent,
47 Opaque,
50 Free,
54}
55
56impl AliasTyKind {
57 pub fn descr(self) -> &'static str {
58 match self {
59 AliasTyKind::Projection => "associated type",
60 AliasTyKind::Inherent => "inherent associated type",
61 AliasTyKind::Opaque => "opaque type",
62 AliasTyKind::Free => "type alias",
63 }
64 }
65}
66
67#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
72#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
73#[cfg_attr(
74 feature = "nightly",
75 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
76)]
77pub enum TyKind<I: Interner> {
78 Bool,
80
81 Char,
84
85 Int(IntTy),
87
88 Uint(UintTy),
90
91 Float(FloatTy),
93
94 Adt(I::AdtDef, I::GenericArgs),
102
103 Foreign(I::DefId),
105
106 Str,
108
109 Array(I::Ty, I::Const),
111
112 Pat(I::Ty, I::Pat),
118
119 Slice(I::Ty),
121
122 RawPtr(I::Ty, Mutability),
124
125 Ref(I::Region, I::Ty, Mutability),
128
129 FnDef(I::DefId, I::GenericArgs),
141
142 FnPtr(ty::Binder<I, FnSigTys<I>>, FnHeader<I>),
159
160 UnsafeBinder(UnsafeBinderInner<I>),
166
167 Dynamic(I::BoundExistentialPredicates, I::Region, DynKind),
169
170 Closure(I::DefId, I::GenericArgs),
176
177 CoroutineClosure(I::DefId, I::GenericArgs),
183
184 Coroutine(I::DefId, I::GenericArgs),
190
191 CoroutineWitness(I::DefId, I::GenericArgs),
215
216 Never,
218
219 Tuple(I::Tys),
221
222 Alias(AliasTyKind, AliasTy<I>),
226
227 Param(I::ParamTy),
229
230 Bound(DebruijnIndex, I::BoundTy),
247
248 Placeholder(I::PlaceholderTy),
257
258 Infer(InferTy),
265
266 Error(I::ErrorGuaranteed),
269}
270
271impl<I: Interner> TyKind<I> {
272 pub fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
273 match self {
274 ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
275 ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
276 ty::Error(_) => {
277 ty::Binder::dummy(ty::FnSig {
279 inputs_and_output: Default::default(),
280 c_variadic: false,
281 safety: I::Safety::safe(),
282 abi: I::Abi::rust(),
283 })
284 }
285 ty::Closure(..) => panic!(
286 "to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
287 ),
288 _ => panic!("Ty::fn_sig() called on non-fn type: {:?}", self),
289 }
290 }
291
292 pub fn is_known_rigid(self) -> bool {
298 match self {
299 ty::Bool
300 | ty::Char
301 | ty::Int(_)
302 | ty::Uint(_)
303 | ty::Float(_)
304 | ty::Adt(_, _)
305 | ty::Foreign(_)
306 | ty::Str
307 | ty::Array(_, _)
308 | ty::Pat(_, _)
309 | ty::Slice(_)
310 | ty::RawPtr(_, _)
311 | ty::Ref(_, _, _)
312 | ty::FnDef(_, _)
313 | ty::FnPtr(..)
314 | ty::UnsafeBinder(_)
315 | ty::Dynamic(_, _, _)
316 | ty::Closure(_, _)
317 | ty::CoroutineClosure(_, _)
318 | ty::Coroutine(_, _)
319 | ty::CoroutineWitness(..)
320 | ty::Never
321 | ty::Tuple(_) => true,
322
323 ty::Error(_)
324 | ty::Infer(_)
325 | ty::Alias(_, _)
326 | ty::Param(_)
327 | ty::Bound(_, _)
328 | ty::Placeholder(_) => false,
329 }
330 }
331}
332
333impl<I: Interner> fmt::Debug for TyKind<I> {
335 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
336 match self {
337 Bool => write!(f, "bool"),
338 Char => write!(f, "char"),
339 Int(i) => write!(f, "{i:?}"),
340 Uint(u) => write!(f, "{u:?}"),
341 Float(float) => write!(f, "{float:?}"),
342 Adt(d, s) => {
343 write!(f, "{d:?}")?;
344 let mut s = s.iter();
345 let first = s.next();
346 match first {
347 Some(first) => write!(f, "<{:?}", first)?,
348 None => return Ok(()),
349 };
350
351 for arg in s {
352 write!(f, ", {:?}", arg)?;
353 }
354
355 write!(f, ">")
356 }
357 Foreign(d) => f.debug_tuple("Foreign").field(d).finish(),
358 Str => write!(f, "str"),
359 Array(t, c) => write!(f, "[{t:?}; {c:?}]"),
360 Pat(t, p) => write!(f, "pattern_type!({t:?} is {p:?})"),
361 Slice(t) => write!(f, "[{:?}]", &t),
362 RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), ty),
363 Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
364 FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(),
365 FnPtr(sig_tys, hdr) => write!(f, "{:?}", sig_tys.with(*hdr)),
366 UnsafeBinder(binder) => write!(f, "{:?}", binder),
368 Dynamic(p, r, repr) => match repr {
369 DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
370 },
371 Closure(d, s) => f.debug_tuple("Closure").field(d).field(&s).finish(),
372 CoroutineClosure(d, s) => f.debug_tuple("CoroutineClosure").field(d).field(&s).finish(),
373 Coroutine(d, s) => f.debug_tuple("Coroutine").field(d).field(&s).finish(),
374 CoroutineWitness(d, s) => f.debug_tuple("CoroutineWitness").field(d).field(&s).finish(),
375 Never => write!(f, "!"),
376 Tuple(t) => {
377 write!(f, "(")?;
378 let mut count = 0;
379 for ty in t.iter() {
380 if count > 0 {
381 write!(f, ", ")?;
382 }
383 write!(f, "{ty:?}")?;
384 count += 1;
385 }
386 if count == 1 {
388 write!(f, ",")?;
389 }
390 write!(f, ")")
391 }
392 Alias(i, a) => f.debug_tuple("Alias").field(i).field(&a).finish(),
393 Param(p) => write!(f, "{p:?}"),
394 Bound(d, b) => crate::debug_bound_var(f, *d, b),
395 Placeholder(p) => write!(f, "{p:?}"),
396 Infer(t) => write!(f, "{:?}", t),
397 TyKind::Error(_) => write!(f, "{{type error}}"),
398 }
399 }
400}
401
402#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
408#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
409#[cfg_attr(
410 feature = "nightly",
411 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
412)]
413pub struct AliasTy<I: Interner> {
414 pub args: I::GenericArgs,
425
426 pub def_id: I::DefId,
437
438 #[derive_where(skip(Debug))]
440 pub(crate) _use_alias_ty_new_instead: (),
441}
442
443impl<I: Interner> AliasTy<I> {
444 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy<I> {
445 interner.debug_assert_args_compatible(def_id, args);
446 AliasTy { def_id, args, _use_alias_ty_new_instead: () }
447 }
448
449 pub fn new(
450 interner: I,
451 def_id: I::DefId,
452 args: impl IntoIterator<Item: Into<I::GenericArg>>,
453 ) -> AliasTy<I> {
454 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
455 Self::new_from_args(interner, def_id, args)
456 }
457
458 pub fn kind(self, interner: I) -> AliasTyKind {
459 interner.alias_ty_kind(self)
460 }
461
462 pub fn is_opaque(self, interner: I) -> bool {
464 matches!(self.kind(interner), AliasTyKind::Opaque)
465 }
466
467 pub fn to_ty(self, interner: I) -> I::Ty {
468 Ty::new_alias(interner, self.kind(interner), self)
469 }
470}
471
472impl<I: Interner> AliasTy<I> {
474 pub fn self_ty(self) -> I::Ty {
475 self.args.type_at(0)
476 }
477
478 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
479 AliasTy::new(
480 interner,
481 self.def_id,
482 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
483 )
484 }
485
486 pub fn trait_def_id(self, interner: I) -> I::DefId {
487 assert_eq!(self.kind(interner), AliasTyKind::Projection, "expected a projection");
488 interner.parent(self.def_id)
489 }
490
491 pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef<I>, I::GenericArgsSlice) {
496 debug_assert_eq!(self.kind(interner), AliasTyKind::Projection);
497 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
498 }
499
500 pub fn trait_ref(self, interner: I) -> ty::TraitRef<I> {
508 self.trait_ref_and_own_args(interner).0
509 }
510}
511
512#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
513#[cfg_attr(
514 feature = "nightly",
515 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
516)]
517pub enum IntTy {
518 Isize,
519 I8,
520 I16,
521 I32,
522 I64,
523 I128,
524}
525
526impl IntTy {
527 pub fn name_str(&self) -> &'static str {
528 match *self {
529 IntTy::Isize => "isize",
530 IntTy::I8 => "i8",
531 IntTy::I16 => "i16",
532 IntTy::I32 => "i32",
533 IntTy::I64 => "i64",
534 IntTy::I128 => "i128",
535 }
536 }
537
538 pub fn bit_width(&self) -> Option<u64> {
539 Some(match *self {
540 IntTy::Isize => return None,
541 IntTy::I8 => 8,
542 IntTy::I16 => 16,
543 IntTy::I32 => 32,
544 IntTy::I64 => 64,
545 IntTy::I128 => 128,
546 })
547 }
548
549 pub fn normalize(&self, target_width: u32) -> Self {
550 match self {
551 IntTy::Isize => match target_width {
552 16 => IntTy::I16,
553 32 => IntTy::I32,
554 64 => IntTy::I64,
555 _ => unreachable!(),
556 },
557 _ => *self,
558 }
559 }
560
561 pub fn to_unsigned(self) -> UintTy {
562 match self {
563 IntTy::Isize => UintTy::Usize,
564 IntTy::I8 => UintTy::U8,
565 IntTy::I16 => UintTy::U16,
566 IntTy::I32 => UintTy::U32,
567 IntTy::I64 => UintTy::U64,
568 IntTy::I128 => UintTy::U128,
569 }
570 }
571}
572
573#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
574#[cfg_attr(
575 feature = "nightly",
576 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
577)]
578pub enum UintTy {
579 Usize,
580 U8,
581 U16,
582 U32,
583 U64,
584 U128,
585}
586
587impl UintTy {
588 pub fn name_str(&self) -> &'static str {
589 match *self {
590 UintTy::Usize => "usize",
591 UintTy::U8 => "u8",
592 UintTy::U16 => "u16",
593 UintTy::U32 => "u32",
594 UintTy::U64 => "u64",
595 UintTy::U128 => "u128",
596 }
597 }
598
599 pub fn bit_width(&self) -> Option<u64> {
600 Some(match *self {
601 UintTy::Usize => return None,
602 UintTy::U8 => 8,
603 UintTy::U16 => 16,
604 UintTy::U32 => 32,
605 UintTy::U64 => 64,
606 UintTy::U128 => 128,
607 })
608 }
609
610 pub fn normalize(&self, target_width: u32) -> Self {
611 match self {
612 UintTy::Usize => match target_width {
613 16 => UintTy::U16,
614 32 => UintTy::U32,
615 64 => UintTy::U64,
616 _ => unreachable!(),
617 },
618 _ => *self,
619 }
620 }
621
622 pub fn to_signed(self) -> IntTy {
623 match self {
624 UintTy::Usize => IntTy::Isize,
625 UintTy::U8 => IntTy::I8,
626 UintTy::U16 => IntTy::I16,
627 UintTy::U32 => IntTy::I32,
628 UintTy::U64 => IntTy::I64,
629 UintTy::U128 => IntTy::I128,
630 }
631 }
632}
633
634#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
635#[cfg_attr(
636 feature = "nightly",
637 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
638)]
639pub enum FloatTy {
640 F16,
641 F32,
642 F64,
643 F128,
644}
645
646impl FloatTy {
647 pub fn name_str(self) -> &'static str {
648 match self {
649 FloatTy::F16 => "f16",
650 FloatTy::F32 => "f32",
651 FloatTy::F64 => "f64",
652 FloatTy::F128 => "f128",
653 }
654 }
655
656 pub fn bit_width(self) -> u64 {
657 match self {
658 FloatTy::F16 => 16,
659 FloatTy::F32 => 32,
660 FloatTy::F64 => 64,
661 FloatTy::F128 => 128,
662 }
663 }
664}
665
666#[derive(Clone, Copy, PartialEq, Eq, Debug)]
667pub enum IntVarValue {
668 Unknown,
669 IntType(IntTy),
670 UintType(UintTy),
671}
672
673impl IntVarValue {
674 pub fn is_known(self) -> bool {
675 match self {
676 IntVarValue::IntType(_) | IntVarValue::UintType(_) => true,
677 IntVarValue::Unknown => false,
678 }
679 }
680
681 pub fn is_unknown(self) -> bool {
682 !self.is_known()
683 }
684}
685
686#[derive(Clone, Copy, PartialEq, Eq, Debug)]
687pub enum FloatVarValue {
688 Unknown,
689 Known(FloatTy),
690}
691
692impl FloatVarValue {
693 pub fn is_known(self) -> bool {
694 match self {
695 FloatVarValue::Known(_) => true,
696 FloatVarValue::Unknown => false,
697 }
698 }
699
700 pub fn is_unknown(self) -> bool {
701 !self.is_known()
702 }
703}
704
705rustc_index::newtype_index! {
706 #[encodable]
708 #[orderable]
709 #[debug_format = "?{}t"]
710 #[gate_rustc_only]
711 pub struct TyVid {}
712}
713
714rustc_index::newtype_index! {
715 #[encodable]
717 #[orderable]
718 #[debug_format = "?{}i"]
719 #[gate_rustc_only]
720 pub struct IntVid {}
721}
722
723rustc_index::newtype_index! {
724 #[encodable]
726 #[orderable]
727 #[debug_format = "?{}f"]
728 #[gate_rustc_only]
729 pub struct FloatVid {}
730}
731
732#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
738#[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext))]
739pub enum InferTy {
740 TyVar(TyVid),
742 IntVar(IntVid),
749 FloatVar(FloatVid),
756
757 FreshTy(u32),
763 FreshIntTy(u32),
765 FreshFloatTy(u32),
767}
768
769impl UnifyValue for IntVarValue {
770 type Error = NoError;
771
772 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
773 match (*value1, *value2) {
774 (IntVarValue::Unknown, IntVarValue::Unknown) => Ok(IntVarValue::Unknown),
775 (
776 IntVarValue::Unknown,
777 known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
778 )
779 | (
780 known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
781 IntVarValue::Unknown,
782 ) => Ok(known),
783 _ => panic!("differing ints should have been resolved first"),
784 }
785 }
786}
787
788impl UnifyKey for IntVid {
789 type Value = IntVarValue;
790 #[inline] fn index(&self) -> u32 {
792 self.as_u32()
793 }
794 #[inline]
795 fn from_index(i: u32) -> IntVid {
796 IntVid::from_u32(i)
797 }
798 fn tag() -> &'static str {
799 "IntVid"
800 }
801}
802
803impl UnifyValue for FloatVarValue {
804 type Error = NoError;
805
806 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
807 match (*value1, *value2) {
808 (FloatVarValue::Unknown, FloatVarValue::Unknown) => Ok(FloatVarValue::Unknown),
809 (FloatVarValue::Unknown, FloatVarValue::Known(known))
810 | (FloatVarValue::Known(known), FloatVarValue::Unknown) => {
811 Ok(FloatVarValue::Known(known))
812 }
813 (FloatVarValue::Known(_), FloatVarValue::Known(_)) => {
814 panic!("differing floats should have been resolved first")
815 }
816 }
817 }
818}
819
820impl UnifyKey for FloatVid {
821 type Value = FloatVarValue;
822 #[inline]
823 fn index(&self) -> u32 {
824 self.as_u32()
825 }
826 #[inline]
827 fn from_index(i: u32) -> FloatVid {
828 FloatVid::from_u32(i)
829 }
830 fn tag() -> &'static str {
831 "FloatVid"
832 }
833}
834
835#[cfg(feature = "nightly")]
836impl<CTX> HashStable<CTX> for InferTy {
837 fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
838 use InferTy::*;
839 std::mem::discriminant(self).hash_stable(ctx, hasher);
840 match self {
841 TyVar(_) | IntVar(_) | FloatVar(_) => {
842 panic!("type variables should not be hashed: {self:?}")
843 }
844 FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher),
845 }
846 }
847}
848
849impl fmt::Display for InferTy {
850 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
851 use InferTy::*;
852 match *self {
853 TyVar(_) => write!(f, "_"),
854 IntVar(_) => write!(f, "{}", "{integer}"),
855 FloatVar(_) => write!(f, "{}", "{float}"),
856 FreshTy(v) => write!(f, "FreshTy({v})"),
857 FreshIntTy(v) => write!(f, "FreshIntTy({v})"),
858 FreshFloatTy(v) => write!(f, "FreshFloatTy({v})"),
859 }
860 }
861}
862
863impl fmt::Debug for IntTy {
864 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
865 write!(f, "{}", self.name_str())
866 }
867}
868
869impl fmt::Debug for UintTy {
870 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
871 write!(f, "{}", self.name_str())
872 }
873}
874
875impl fmt::Debug for FloatTy {
876 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
877 write!(f, "{}", self.name_str())
878 }
879}
880
881impl fmt::Debug for InferTy {
882 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
883 use InferTy::*;
884 match *self {
885 TyVar(ref v) => v.fmt(f),
886 IntVar(ref v) => v.fmt(f),
887 FloatVar(ref v) => v.fmt(f),
888 FreshTy(v) => write!(f, "FreshTy({v:?})"),
889 FreshIntTy(v) => write!(f, "FreshIntTy({v:?})"),
890 FreshFloatTy(v) => write!(f, "FreshFloatTy({v:?})"),
891 }
892 }
893}
894
895#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
896#[cfg_attr(
897 feature = "nightly",
898 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
899)]
900#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
901pub struct TypeAndMut<I: Interner> {
902 pub ty: I::Ty,
903 pub mutbl: Mutability,
904}
905
906#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
907#[cfg_attr(
908 feature = "nightly",
909 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
910)]
911#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
912pub struct FnSig<I: Interner> {
913 pub inputs_and_output: I::Tys,
914 pub c_variadic: bool,
915 #[type_visitable(ignore)]
916 #[type_foldable(identity)]
917 pub safety: I::Safety,
918 #[type_visitable(ignore)]
919 #[type_foldable(identity)]
920 pub abi: I::Abi,
921}
922
923impl<I: Interner> FnSig<I> {
924 pub fn inputs(self) -> I::FnInputTys {
925 self.inputs_and_output.inputs()
926 }
927
928 pub fn output(self) -> I::Ty {
929 self.inputs_and_output.output()
930 }
931
932 pub fn is_fn_trait_compatible(self) -> bool {
933 let FnSig { safety, abi, c_variadic, .. } = self;
934 !c_variadic && safety.is_safe() && abi.is_rust()
935 }
936}
937
938impl<I: Interner> ty::Binder<I, FnSig<I>> {
939 #[inline]
940 pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
941 self.map_bound(|fn_sig| fn_sig.inputs())
942 }
943
944 #[inline]
945 #[track_caller]
946 pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
947 self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap())
948 }
949
950 pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
951 self.map_bound(|fn_sig| fn_sig.inputs_and_output)
952 }
953
954 #[inline]
955 pub fn output(self) -> ty::Binder<I, I::Ty> {
956 self.map_bound(|fn_sig| fn_sig.output())
957 }
958
959 pub fn c_variadic(self) -> bool {
960 self.skip_binder().c_variadic
961 }
962
963 pub fn safety(self) -> I::Safety {
964 self.skip_binder().safety
965 }
966
967 pub fn abi(self) -> I::Abi {
968 self.skip_binder().abi
969 }
970
971 pub fn is_fn_trait_compatible(&self) -> bool {
972 self.skip_binder().is_fn_trait_compatible()
973 }
974
975 pub fn split(self) -> (ty::Binder<I, FnSigTys<I>>, FnHeader<I>) {
977 let hdr =
978 FnHeader { c_variadic: self.c_variadic(), safety: self.safety(), abi: self.abi() };
979 (self.map_bound(|sig| FnSigTys { inputs_and_output: sig.inputs_and_output }), hdr)
980 }
981}
982
983impl<I: Interner> fmt::Debug for FnSig<I> {
984 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
985 let sig = self;
986 let FnSig { inputs_and_output: _, c_variadic, safety, abi } = sig;
987
988 write!(f, "{}", safety.prefix_str())?;
989 if !abi.is_rust() {
990 write!(f, "extern \"{abi:?}\" ")?;
991 }
992
993 write!(f, "fn(")?;
994 let inputs = sig.inputs();
995 for (i, ty) in inputs.iter().enumerate() {
996 if i > 0 {
997 write!(f, ", ")?;
998 }
999 write!(f, "{ty:?}")?;
1000 }
1001 if *c_variadic {
1002 if inputs.is_empty() {
1003 write!(f, "...")?;
1004 } else {
1005 write!(f, ", ...")?;
1006 }
1007 }
1008 write!(f, ")")?;
1009
1010 let output = sig.output();
1011 match output.kind() {
1012 Tuple(list) if list.is_empty() => Ok(()),
1013 _ => write!(f, " -> {:?}", sig.output()),
1014 }
1015 }
1016}
1017
1018#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
1021#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
1022#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1023pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>);
1024
1025impl<I: Interner> From<ty::Binder<I, I::Ty>> for UnsafeBinderInner<I> {
1026 fn from(value: ty::Binder<I, I::Ty>) -> Self {
1027 UnsafeBinderInner(value)
1028 }
1029}
1030
1031impl<I: Interner> From<UnsafeBinderInner<I>> for ty::Binder<I, I::Ty> {
1032 fn from(value: UnsafeBinderInner<I>) -> Self {
1033 value.0
1034 }
1035}
1036
1037impl<I: Interner> fmt::Debug for UnsafeBinderInner<I> {
1038 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1039 self.0.fmt(f)
1040 }
1041}
1042
1043impl<I: Interner> Deref for UnsafeBinderInner<I> {
1044 type Target = ty::Binder<I, I::Ty>;
1045
1046 fn deref(&self) -> &Self::Target {
1047 &self.0
1048 }
1049}
1050
1051#[cfg(feature = "nightly")]
1052impl<I: Interner, E: rustc_serialize::Encoder> rustc_serialize::Encodable<E>
1053 for UnsafeBinderInner<I>
1054where
1055 I::Ty: rustc_serialize::Encodable<E>,
1056 I::BoundVarKinds: rustc_serialize::Encodable<E>,
1057{
1058 fn encode(&self, e: &mut E) {
1059 self.bound_vars().encode(e);
1060 self.as_ref().skip_binder().encode(e);
1061 }
1062}
1063
1064#[cfg(feature = "nightly")]
1065impl<I: Interner, D: rustc_serialize::Decoder> rustc_serialize::Decodable<D>
1066 for UnsafeBinderInner<I>
1067where
1068 I::Ty: TypeVisitable<I> + rustc_serialize::Decodable<D>,
1069 I::BoundVarKinds: rustc_serialize::Decodable<D>,
1070{
1071 fn decode(decoder: &mut D) -> Self {
1072 let bound_vars = rustc_serialize::Decodable::decode(decoder);
1073 UnsafeBinderInner(ty::Binder::bind_with_vars(
1074 rustc_serialize::Decodable::decode(decoder),
1075 bound_vars,
1076 ))
1077 }
1078}
1079
1080#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
1082#[cfg_attr(
1083 feature = "nightly",
1084 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
1085)]
1086#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1087pub struct FnSigTys<I: Interner> {
1088 pub inputs_and_output: I::Tys,
1089}
1090
1091impl<I: Interner> FnSigTys<I> {
1092 pub fn inputs(self) -> I::FnInputTys {
1093 self.inputs_and_output.inputs()
1094 }
1095
1096 pub fn output(self) -> I::Ty {
1097 self.inputs_and_output.output()
1098 }
1099}
1100
1101impl<I: Interner> ty::Binder<I, FnSigTys<I>> {
1102 pub fn with(self, hdr: FnHeader<I>) -> ty::Binder<I, FnSig<I>> {
1104 self.map_bound(|sig_tys| FnSig {
1105 inputs_and_output: sig_tys.inputs_and_output,
1106 c_variadic: hdr.c_variadic,
1107 safety: hdr.safety,
1108 abi: hdr.abi,
1109 })
1110 }
1111
1112 #[inline]
1113 pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
1114 self.map_bound(|sig_tys| sig_tys.inputs())
1115 }
1116
1117 #[inline]
1118 #[track_caller]
1119 pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
1120 self.map_bound(|sig_tys| sig_tys.inputs().get(index).unwrap())
1121 }
1122
1123 pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
1124 self.map_bound(|sig_tys| sig_tys.inputs_and_output)
1125 }
1126
1127 #[inline]
1128 pub fn output(self) -> ty::Binder<I, I::Ty> {
1129 self.map_bound(|sig_tys| sig_tys.output())
1130 }
1131}
1132
1133#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
1134#[cfg_attr(
1135 feature = "nightly",
1136 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
1137)]
1138#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1139pub struct FnHeader<I: Interner> {
1140 pub c_variadic: bool,
1141 pub safety: I::Safety,
1142 pub abi: I::Abi,
1143}
1144
1145#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
1146#[cfg_attr(
1147 feature = "nightly",
1148 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
1149)]
1150#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1151pub struct CoroutineWitnessTypes<I: Interner> {
1152 pub types: I::Tys,
1153}