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