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_data_structures::unify::{NoError, UnifyKey, UnifyValue};
10#[cfg(feature = "nightly")]
11use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
12use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
13
14use self::TyKind::*;
15pub use self::closure::*;
16use crate::inherent::*;
17#[cfg(feature = "nightly")]
18use crate::visit::TypeVisitable;
19use crate::{self as ty, DebruijnIndex, Interner};
20
21mod closure;
22
23#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
25#[cfg_attr(
26 feature = "nightly",
27 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
28)]
29pub enum DynKind {
30 Dyn,
32 DynStar,
39}
40
41#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
42#[cfg_attr(
43 feature = "nightly",
44 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
45)]
46pub enum AliasTyKind {
47 Projection,
50 Inherent,
52 Opaque,
55 Weak,
59}
60
61impl AliasTyKind {
62 pub fn descr(self) -> &'static str {
63 match self {
64 AliasTyKind::Projection => "associated type",
65 AliasTyKind::Inherent => "inherent associated type",
66 AliasTyKind::Opaque => "opaque type",
67 AliasTyKind::Weak => "type alias",
68 }
69 }
70}
71
72#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
77#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
78#[cfg_attr(
79 feature = "nightly",
80 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
81)]
82pub enum TyKind<I: Interner> {
83 Bool,
85
86 Char,
89
90 Int(IntTy),
92
93 Uint(UintTy),
95
96 Float(FloatTy),
98
99 Adt(I::AdtDef, I::GenericArgs),
107
108 Foreign(I::DefId),
110
111 Str,
113
114 Array(I::Ty, I::Const),
116
117 Pat(I::Ty, I::Pat),
123
124 Slice(I::Ty),
126
127 RawPtr(I::Ty, Mutability),
129
130 Ref(I::Region, I::Ty, Mutability),
133
134 FnDef(I::DefId, I::GenericArgs),
146
147 FnPtr(ty::Binder<I, FnSigTys<I>>, FnHeader<I>),
164
165 UnsafeBinder(UnsafeBinderInner<I>),
171
172 Dynamic(I::BoundExistentialPredicates, I::Region, DynKind),
174
175 Closure(I::DefId, I::GenericArgs),
181
182 CoroutineClosure(I::DefId, I::GenericArgs),
188
189 Coroutine(I::DefId, I::GenericArgs),
195
196 CoroutineWitness(I::DefId, I::GenericArgs),
220
221 Never,
223
224 Tuple(I::Tys),
226
227 Alias(AliasTyKind, AliasTy<I>),
231
232 Param(I::ParamTy),
234
235 Bound(DebruijnIndex, I::BoundTy),
252
253 Placeholder(I::PlaceholderTy),
262
263 Infer(InferTy),
270
271 Error(I::ErrorGuaranteed),
274}
275
276impl<I: Interner> fmt::Debug for TyKind<I> {
278 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279 match self {
280 Bool => write!(f, "bool"),
281 Char => write!(f, "char"),
282 Int(i) => write!(f, "{i:?}"),
283 Uint(u) => write!(f, "{u:?}"),
284 Float(float) => write!(f, "{float:?}"),
285 Adt(d, s) => {
286 write!(f, "{d:?}")?;
287 let mut s = s.iter();
288 let first = s.next();
289 match first {
290 Some(first) => write!(f, "<{:?}", first)?,
291 None => return Ok(()),
292 };
293
294 for arg in s {
295 write!(f, ", {:?}", arg)?;
296 }
297
298 write!(f, ">")
299 }
300 Foreign(d) => f.debug_tuple("Foreign").field(d).finish(),
301 Str => write!(f, "str"),
302 Array(t, c) => write!(f, "[{t:?}; {c:?}]"),
303 Pat(t, p) => write!(f, "pattern_type!({t:?} is {p:?})"),
304 Slice(t) => write!(f, "[{:?}]", &t),
305 RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), ty),
306 Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
307 FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(),
308 FnPtr(sig_tys, hdr) => write!(f, "{:?}", sig_tys.with(*hdr)),
309 UnsafeBinder(binder) => write!(f, "{:?}", binder),
311 Dynamic(p, r, repr) => match repr {
312 DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
313 DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"),
314 },
315 Closure(d, s) => f.debug_tuple("Closure").field(d).field(&s).finish(),
316 CoroutineClosure(d, s) => f.debug_tuple("CoroutineClosure").field(d).field(&s).finish(),
317 Coroutine(d, s) => f.debug_tuple("Coroutine").field(d).field(&s).finish(),
318 CoroutineWitness(d, s) => f.debug_tuple("CoroutineWitness").field(d).field(&s).finish(),
319 Never => write!(f, "!"),
320 Tuple(t) => {
321 write!(f, "(")?;
322 let mut count = 0;
323 for ty in t.iter() {
324 if count > 0 {
325 write!(f, ", ")?;
326 }
327 write!(f, "{ty:?}")?;
328 count += 1;
329 }
330 if count == 1 {
332 write!(f, ",")?;
333 }
334 write!(f, ")")
335 }
336 Alias(i, a) => f.debug_tuple("Alias").field(i).field(&a).finish(),
337 Param(p) => write!(f, "{p:?}"),
338 Bound(d, b) => crate::debug_bound_var(f, *d, b),
339 Placeholder(p) => write!(f, "{p:?}"),
340 Infer(t) => write!(f, "{:?}", t),
341 TyKind::Error(_) => write!(f, "{{type error}}"),
342 }
343 }
344}
345
346#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
352#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
353#[cfg_attr(
354 feature = "nightly",
355 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
356)]
357pub struct AliasTy<I: Interner> {
358 pub args: I::GenericArgs,
369
370 pub def_id: I::DefId,
381
382 #[derive_where(skip(Debug))]
384 pub(crate) _use_alias_ty_new_instead: (),
385}
386
387impl<I: Interner> AliasTy<I> {
388 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy<I> {
389 interner.debug_assert_args_compatible(def_id, args);
390 AliasTy { def_id, args, _use_alias_ty_new_instead: () }
391 }
392
393 pub fn new(
394 interner: I,
395 def_id: I::DefId,
396 args: impl IntoIterator<Item: Into<I::GenericArg>>,
397 ) -> AliasTy<I> {
398 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
399 Self::new_from_args(interner, def_id, args)
400 }
401
402 pub fn kind(self, interner: I) -> AliasTyKind {
403 interner.alias_ty_kind(self)
404 }
405
406 pub fn is_opaque(self, interner: I) -> bool {
408 matches!(self.kind(interner), AliasTyKind::Opaque)
409 }
410
411 pub fn to_ty(self, interner: I) -> I::Ty {
412 Ty::new_alias(interner, self.kind(interner), self)
413 }
414}
415
416impl<I: Interner> AliasTy<I> {
418 pub fn self_ty(self) -> I::Ty {
419 self.args.type_at(0)
420 }
421
422 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
423 AliasTy::new(
424 interner,
425 self.def_id,
426 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
427 )
428 }
429
430 pub fn trait_def_id(self, interner: I) -> I::DefId {
431 assert_eq!(self.kind(interner), AliasTyKind::Projection, "expected a projection");
432 interner.parent(self.def_id)
433 }
434
435 pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef<I>, I::GenericArgsSlice) {
440 debug_assert_eq!(self.kind(interner), AliasTyKind::Projection);
441 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
442 }
443
444 pub fn trait_ref(self, interner: I) -> ty::TraitRef<I> {
452 self.trait_ref_and_own_args(interner).0
453 }
454}
455
456impl<I: Interner> AliasTy<I> {
458 pub fn rebase_inherent_args_onto_impl(
469 self,
470 impl_args: I::GenericArgs,
471 interner: I,
472 ) -> I::GenericArgs {
473 debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent);
474 interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
475 }
476}
477
478#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
479#[cfg_attr(
480 feature = "nightly",
481 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
482)]
483pub enum IntTy {
484 Isize,
485 I8,
486 I16,
487 I32,
488 I64,
489 I128,
490}
491
492impl IntTy {
493 pub fn name_str(&self) -> &'static str {
494 match *self {
495 IntTy::Isize => "isize",
496 IntTy::I8 => "i8",
497 IntTy::I16 => "i16",
498 IntTy::I32 => "i32",
499 IntTy::I64 => "i64",
500 IntTy::I128 => "i128",
501 }
502 }
503
504 pub fn bit_width(&self) -> Option<u64> {
505 Some(match *self {
506 IntTy::Isize => return None,
507 IntTy::I8 => 8,
508 IntTy::I16 => 16,
509 IntTy::I32 => 32,
510 IntTy::I64 => 64,
511 IntTy::I128 => 128,
512 })
513 }
514
515 pub fn normalize(&self, target_width: u32) -> Self {
516 match self {
517 IntTy::Isize => match target_width {
518 16 => IntTy::I16,
519 32 => IntTy::I32,
520 64 => IntTy::I64,
521 _ => unreachable!(),
522 },
523 _ => *self,
524 }
525 }
526
527 pub fn to_unsigned(self) -> UintTy {
528 match self {
529 IntTy::Isize => UintTy::Usize,
530 IntTy::I8 => UintTy::U8,
531 IntTy::I16 => UintTy::U16,
532 IntTy::I32 => UintTy::U32,
533 IntTy::I64 => UintTy::U64,
534 IntTy::I128 => UintTy::U128,
535 }
536 }
537}
538
539#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
540#[cfg_attr(
541 feature = "nightly",
542 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
543)]
544pub enum UintTy {
545 Usize,
546 U8,
547 U16,
548 U32,
549 U64,
550 U128,
551}
552
553impl UintTy {
554 pub fn name_str(&self) -> &'static str {
555 match *self {
556 UintTy::Usize => "usize",
557 UintTy::U8 => "u8",
558 UintTy::U16 => "u16",
559 UintTy::U32 => "u32",
560 UintTy::U64 => "u64",
561 UintTy::U128 => "u128",
562 }
563 }
564
565 pub fn bit_width(&self) -> Option<u64> {
566 Some(match *self {
567 UintTy::Usize => return None,
568 UintTy::U8 => 8,
569 UintTy::U16 => 16,
570 UintTy::U32 => 32,
571 UintTy::U64 => 64,
572 UintTy::U128 => 128,
573 })
574 }
575
576 pub fn normalize(&self, target_width: u32) -> Self {
577 match self {
578 UintTy::Usize => match target_width {
579 16 => UintTy::U16,
580 32 => UintTy::U32,
581 64 => UintTy::U64,
582 _ => unreachable!(),
583 },
584 _ => *self,
585 }
586 }
587
588 pub fn to_signed(self) -> IntTy {
589 match self {
590 UintTy::Usize => IntTy::Isize,
591 UintTy::U8 => IntTy::I8,
592 UintTy::U16 => IntTy::I16,
593 UintTy::U32 => IntTy::I32,
594 UintTy::U64 => IntTy::I64,
595 UintTy::U128 => IntTy::I128,
596 }
597 }
598}
599
600#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
601#[cfg_attr(
602 feature = "nightly",
603 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
604)]
605pub enum FloatTy {
606 F16,
607 F32,
608 F64,
609 F128,
610}
611
612impl FloatTy {
613 pub fn name_str(self) -> &'static str {
614 match self {
615 FloatTy::F16 => "f16",
616 FloatTy::F32 => "f32",
617 FloatTy::F64 => "f64",
618 FloatTy::F128 => "f128",
619 }
620 }
621
622 pub fn bit_width(self) -> u64 {
623 match self {
624 FloatTy::F16 => 16,
625 FloatTy::F32 => 32,
626 FloatTy::F64 => 64,
627 FloatTy::F128 => 128,
628 }
629 }
630}
631
632#[derive(Clone, Copy, PartialEq, Eq, Debug)]
633pub enum IntVarValue {
634 Unknown,
635 IntType(IntTy),
636 UintType(UintTy),
637}
638
639impl IntVarValue {
640 pub fn is_known(self) -> bool {
641 match self {
642 IntVarValue::IntType(_) | IntVarValue::UintType(_) => true,
643 IntVarValue::Unknown => false,
644 }
645 }
646
647 pub fn is_unknown(self) -> bool {
648 !self.is_known()
649 }
650}
651
652#[derive(Clone, Copy, PartialEq, Eq, Debug)]
653pub enum FloatVarValue {
654 Unknown,
655 Known(FloatTy),
656}
657
658impl FloatVarValue {
659 pub fn is_known(self) -> bool {
660 match self {
661 FloatVarValue::Known(_) => true,
662 FloatVarValue::Unknown => false,
663 }
664 }
665
666 pub fn is_unknown(self) -> bool {
667 !self.is_known()
668 }
669}
670
671rustc_index::newtype_index! {
672 #[encodable]
674 #[orderable]
675 #[debug_format = "?{}t"]
676 #[gate_rustc_only]
677 pub struct TyVid {}
678}
679
680rustc_index::newtype_index! {
681 #[encodable]
683 #[orderable]
684 #[debug_format = "?{}i"]
685 #[gate_rustc_only]
686 pub struct IntVid {}
687}
688
689rustc_index::newtype_index! {
690 #[encodable]
692 #[orderable]
693 #[debug_format = "?{}f"]
694 #[gate_rustc_only]
695 pub struct FloatVid {}
696}
697
698#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
704#[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext))]
705pub enum InferTy {
706 TyVar(TyVid),
708 IntVar(IntVid),
715 FloatVar(FloatVid),
722
723 FreshTy(u32),
729 FreshIntTy(u32),
731 FreshFloatTy(u32),
733}
734
735#[cfg(feature = "nightly")]
738impl UnifyKey for TyVid {
739 type Value = ();
740 #[inline]
741 fn index(&self) -> u32 {
742 self.as_u32()
743 }
744 #[inline]
745 fn from_index(i: u32) -> TyVid {
746 TyVid::from_u32(i)
747 }
748 fn tag() -> &'static str {
749 "TyVid"
750 }
751}
752
753#[cfg(feature = "nightly")]
754impl UnifyValue for IntVarValue {
755 type Error = NoError;
756
757 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
758 match (*value1, *value2) {
759 (IntVarValue::Unknown, IntVarValue::Unknown) => Ok(IntVarValue::Unknown),
760 (
761 IntVarValue::Unknown,
762 known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
763 )
764 | (
765 known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
766 IntVarValue::Unknown,
767 ) => Ok(known),
768 _ => panic!("differing ints should have been resolved first"),
769 }
770 }
771}
772
773#[cfg(feature = "nightly")]
774impl UnifyKey for IntVid {
775 type Value = IntVarValue;
776 #[inline] fn index(&self) -> u32 {
778 self.as_u32()
779 }
780 #[inline]
781 fn from_index(i: u32) -> IntVid {
782 IntVid::from_u32(i)
783 }
784 fn tag() -> &'static str {
785 "IntVid"
786 }
787}
788
789#[cfg(feature = "nightly")]
790impl UnifyValue for FloatVarValue {
791 type Error = NoError;
792
793 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
794 match (*value1, *value2) {
795 (FloatVarValue::Unknown, FloatVarValue::Unknown) => Ok(FloatVarValue::Unknown),
796 (FloatVarValue::Unknown, FloatVarValue::Known(known))
797 | (FloatVarValue::Known(known), FloatVarValue::Unknown) => {
798 Ok(FloatVarValue::Known(known))
799 }
800 (FloatVarValue::Known(_), FloatVarValue::Known(_)) => {
801 panic!("differing floats should have been resolved first")
802 }
803 }
804 }
805}
806
807#[cfg(feature = "nightly")]
808impl UnifyKey for FloatVid {
809 type Value = FloatVarValue;
810 #[inline]
811 fn index(&self) -> u32 {
812 self.as_u32()
813 }
814 #[inline]
815 fn from_index(i: u32) -> FloatVid {
816 FloatVid::from_u32(i)
817 }
818 fn tag() -> &'static str {
819 "FloatVid"
820 }
821}
822
823#[cfg(feature = "nightly")]
824impl<CTX> HashStable<CTX> for InferTy {
825 fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
826 use InferTy::*;
827 std::mem::discriminant(self).hash_stable(ctx, hasher);
828 match self {
829 TyVar(_) | IntVar(_) | FloatVar(_) => {
830 panic!("type variables should not be hashed: {self:?}")
831 }
832 FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher),
833 }
834 }
835}
836
837impl fmt::Display for InferTy {
838 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
839 use InferTy::*;
840 match *self {
841 TyVar(_) => write!(f, "_"),
842 IntVar(_) => write!(f, "{}", "{integer}"),
843 FloatVar(_) => write!(f, "{}", "{float}"),
844 FreshTy(v) => write!(f, "FreshTy({v})"),
845 FreshIntTy(v) => write!(f, "FreshIntTy({v})"),
846 FreshFloatTy(v) => write!(f, "FreshFloatTy({v})"),
847 }
848 }
849}
850
851impl fmt::Debug for IntTy {
852 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
853 write!(f, "{}", self.name_str())
854 }
855}
856
857impl fmt::Debug for UintTy {
858 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
859 write!(f, "{}", self.name_str())
860 }
861}
862
863impl fmt::Debug for FloatTy {
864 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
865 write!(f, "{}", self.name_str())
866 }
867}
868
869impl fmt::Debug for InferTy {
870 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
871 use InferTy::*;
872 match *self {
873 TyVar(ref v) => v.fmt(f),
874 IntVar(ref v) => v.fmt(f),
875 FloatVar(ref v) => v.fmt(f),
876 FreshTy(v) => write!(f, "FreshTy({v:?})"),
877 FreshIntTy(v) => write!(f, "FreshIntTy({v:?})"),
878 FreshFloatTy(v) => write!(f, "FreshFloatTy({v:?})"),
879 }
880 }
881}
882
883#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
884#[cfg_attr(
885 feature = "nightly",
886 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
887)]
888#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
889pub struct TypeAndMut<I: Interner> {
890 pub ty: I::Ty,
891 pub mutbl: Mutability,
892}
893
894#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
895#[cfg_attr(
896 feature = "nightly",
897 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
898)]
899#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
900pub struct FnSig<I: Interner> {
901 pub inputs_and_output: I::Tys,
902 pub c_variadic: bool,
903 #[type_visitable(ignore)]
904 #[type_foldable(identity)]
905 pub safety: I::Safety,
906 #[type_visitable(ignore)]
907 #[type_foldable(identity)]
908 pub abi: I::Abi,
909}
910
911impl<I: Interner> FnSig<I> {
912 pub fn inputs(self) -> I::FnInputTys {
913 self.inputs_and_output.inputs()
914 }
915
916 pub fn output(self) -> I::Ty {
917 self.inputs_and_output.output()
918 }
919
920 pub fn is_fn_trait_compatible(self) -> bool {
921 let FnSig { safety, abi, c_variadic, .. } = self;
922 !c_variadic && safety.is_safe() && abi.is_rust()
923 }
924}
925
926impl<I: Interner> ty::Binder<I, FnSig<I>> {
927 #[inline]
928 pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
929 self.map_bound(|fn_sig| fn_sig.inputs())
930 }
931
932 #[inline]
933 #[track_caller]
934 pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
935 self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap())
936 }
937
938 pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
939 self.map_bound(|fn_sig| fn_sig.inputs_and_output)
940 }
941
942 #[inline]
943 pub fn output(self) -> ty::Binder<I, I::Ty> {
944 self.map_bound(|fn_sig| fn_sig.output())
945 }
946
947 pub fn c_variadic(self) -> bool {
948 self.skip_binder().c_variadic
949 }
950
951 pub fn safety(self) -> I::Safety {
952 self.skip_binder().safety
953 }
954
955 pub fn abi(self) -> I::Abi {
956 self.skip_binder().abi
957 }
958
959 pub fn is_fn_trait_compatible(&self) -> bool {
960 self.skip_binder().is_fn_trait_compatible()
961 }
962
963 pub fn split(self) -> (ty::Binder<I, FnSigTys<I>>, FnHeader<I>) {
965 let hdr =
966 FnHeader { c_variadic: self.c_variadic(), safety: self.safety(), abi: self.abi() };
967 (self.map_bound(|sig| FnSigTys { inputs_and_output: sig.inputs_and_output }), hdr)
968 }
969}
970
971impl<I: Interner> fmt::Debug for FnSig<I> {
972 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
973 let sig = self;
974 let FnSig { inputs_and_output: _, c_variadic, safety, abi } = sig;
975
976 write!(f, "{}", safety.prefix_str())?;
977 if !abi.is_rust() {
978 write!(f, "extern \"{abi:?}\" ")?;
979 }
980
981 write!(f, "fn(")?;
982 let inputs = sig.inputs();
983 for (i, ty) in inputs.iter().enumerate() {
984 if i > 0 {
985 write!(f, ", ")?;
986 }
987 write!(f, "{ty:?}")?;
988 }
989 if *c_variadic {
990 if inputs.is_empty() {
991 write!(f, "...")?;
992 } else {
993 write!(f, ", ...")?;
994 }
995 }
996 write!(f, ")")?;
997
998 let output = sig.output();
999 match output.kind() {
1000 Tuple(list) if list.is_empty() => Ok(()),
1001 _ => write!(f, " -> {:?}", sig.output()),
1002 }
1003 }
1004}
1005
1006#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
1009#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
1010#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1011pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>);
1012
1013impl<I: Interner> From<ty::Binder<I, I::Ty>> for UnsafeBinderInner<I> {
1014 fn from(value: ty::Binder<I, I::Ty>) -> Self {
1015 UnsafeBinderInner(value)
1016 }
1017}
1018
1019impl<I: Interner> From<UnsafeBinderInner<I>> for ty::Binder<I, I::Ty> {
1020 fn from(value: UnsafeBinderInner<I>) -> Self {
1021 value.0
1022 }
1023}
1024
1025impl<I: Interner> fmt::Debug for UnsafeBinderInner<I> {
1026 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1027 self.0.fmt(f)
1028 }
1029}
1030
1031impl<I: Interner> Deref for UnsafeBinderInner<I> {
1032 type Target = ty::Binder<I, I::Ty>;
1033
1034 fn deref(&self) -> &Self::Target {
1035 &self.0
1036 }
1037}
1038
1039#[cfg(feature = "nightly")]
1040impl<I: Interner, E: rustc_serialize::Encoder> rustc_serialize::Encodable<E>
1041 for UnsafeBinderInner<I>
1042where
1043 I::Ty: rustc_serialize::Encodable<E>,
1044 I::BoundVarKinds: rustc_serialize::Encodable<E>,
1045{
1046 fn encode(&self, e: &mut E) {
1047 self.bound_vars().encode(e);
1048 self.as_ref().skip_binder().encode(e);
1049 }
1050}
1051
1052#[cfg(feature = "nightly")]
1053impl<I: Interner, D: rustc_serialize::Decoder> rustc_serialize::Decodable<D>
1054 for UnsafeBinderInner<I>
1055where
1056 I::Ty: TypeVisitable<I> + rustc_serialize::Decodable<D>,
1057 I::BoundVarKinds: rustc_serialize::Decodable<D>,
1058{
1059 fn decode(decoder: &mut D) -> Self {
1060 let bound_vars = rustc_serialize::Decodable::decode(decoder);
1061 UnsafeBinderInner(ty::Binder::bind_with_vars(
1062 rustc_serialize::Decodable::decode(decoder),
1063 bound_vars,
1064 ))
1065 }
1066}
1067
1068#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
1070#[cfg_attr(
1071 feature = "nightly",
1072 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
1073)]
1074#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1075pub struct FnSigTys<I: Interner> {
1076 pub inputs_and_output: I::Tys,
1077}
1078
1079impl<I: Interner> FnSigTys<I> {
1080 pub fn inputs(self) -> I::FnInputTys {
1081 self.inputs_and_output.inputs()
1082 }
1083
1084 pub fn output(self) -> I::Ty {
1085 self.inputs_and_output.output()
1086 }
1087}
1088
1089impl<I: Interner> ty::Binder<I, FnSigTys<I>> {
1090 pub fn with(self, hdr: FnHeader<I>) -> ty::Binder<I, FnSig<I>> {
1092 self.map_bound(|sig_tys| FnSig {
1093 inputs_and_output: sig_tys.inputs_and_output,
1094 c_variadic: hdr.c_variadic,
1095 safety: hdr.safety,
1096 abi: hdr.abi,
1097 })
1098 }
1099
1100 #[inline]
1101 pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
1102 self.map_bound(|sig_tys| sig_tys.inputs())
1103 }
1104
1105 #[inline]
1106 #[track_caller]
1107 pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
1108 self.map_bound(|sig_tys| sig_tys.inputs().get(index).unwrap())
1109 }
1110
1111 pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
1112 self.map_bound(|sig_tys| sig_tys.inputs_and_output)
1113 }
1114
1115 #[inline]
1116 pub fn output(self) -> ty::Binder<I, I::Ty> {
1117 self.map_bound(|sig_tys| sig_tys.output())
1118 }
1119}
1120
1121#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
1122#[cfg_attr(
1123 feature = "nightly",
1124 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
1125)]
1126#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1127pub struct FnHeader<I: Interner> {
1128 pub c_variadic: bool,
1129 pub safety: I::Safety,
1130 pub abi: I::Abi,
1131}