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, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
12use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
13
14use self::TyKind::*;
15pub use self::closure::*;
16use crate::inherent::*;
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(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
25pub enum DynKind {
26 Dyn,
28 DynStar,
35}
36
37#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
38#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
39pub enum AliasTyKind {
40 Projection,
43 Inherent,
45 Opaque,
48 Weak,
52}
53
54impl AliasTyKind {
55 pub fn descr(self) -> &'static str {
56 match self {
57 AliasTyKind::Projection => "associated type",
58 AliasTyKind::Inherent => "inherent associated type",
59 AliasTyKind::Opaque => "opaque type",
60 AliasTyKind::Weak => "type alias",
61 }
62 }
63}
64
65#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
70#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
71#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
72pub enum TyKind<I: Interner> {
73 Bool,
75
76 Char,
79
80 Int(IntTy),
82
83 Uint(UintTy),
85
86 Float(FloatTy),
88
89 Adt(I::AdtDef, I::GenericArgs),
97
98 Foreign(I::DefId),
100
101 Str,
103
104 Array(I::Ty, I::Const),
106
107 Pat(I::Ty, I::Pat),
113
114 Slice(I::Ty),
116
117 RawPtr(I::Ty, Mutability),
119
120 Ref(I::Region, I::Ty, Mutability),
123
124 FnDef(I::DefId, I::GenericArgs),
136
137 FnPtr(ty::Binder<I, FnSigTys<I>>, FnHeader<I>),
154
155 UnsafeBinder(UnsafeBinderInner<I>),
161
162 Dynamic(I::BoundExistentialPredicates, I::Region, DynKind),
164
165 Closure(I::DefId, I::GenericArgs),
171
172 CoroutineClosure(I::DefId, I::GenericArgs),
178
179 Coroutine(I::DefId, I::GenericArgs),
185
186 CoroutineWitness(I::DefId, I::GenericArgs),
210
211 Never,
213
214 Tuple(I::Tys),
216
217 Alias(AliasTyKind, AliasTy<I>),
221
222 Param(I::ParamTy),
224
225 Bound(DebruijnIndex, I::BoundTy),
242
243 Placeholder(I::PlaceholderTy),
252
253 Infer(InferTy),
260
261 Error(I::ErrorGuaranteed),
264}
265
266impl<I: Interner> fmt::Debug for TyKind<I> {
268 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
269 match self {
270 Bool => write!(f, "bool"),
271 Char => write!(f, "char"),
272 Int(i) => write!(f, "{i:?}"),
273 Uint(u) => write!(f, "{u:?}"),
274 Float(float) => write!(f, "{float:?}"),
275 Adt(d, s) => {
276 write!(f, "{d:?}")?;
277 let mut s = s.iter();
278 let first = s.next();
279 match first {
280 Some(first) => write!(f, "<{:?}", first)?,
281 None => return Ok(()),
282 };
283
284 for arg in s {
285 write!(f, ", {:?}", arg)?;
286 }
287
288 write!(f, ">")
289 }
290 Foreign(d) => f.debug_tuple("Foreign").field(d).finish(),
291 Str => write!(f, "str"),
292 Array(t, c) => write!(f, "[{t:?}; {c:?}]"),
293 Pat(t, p) => write!(f, "pattern_type!({t:?} is {p:?})"),
294 Slice(t) => write!(f, "[{:?}]", &t),
295 RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), ty),
296 Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
297 FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(),
298 FnPtr(sig_tys, hdr) => write!(f, "{:?}", sig_tys.with(*hdr)),
299 UnsafeBinder(binder) => write!(f, "{:?}", binder),
301 Dynamic(p, r, repr) => match repr {
302 DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
303 DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"),
304 },
305 Closure(d, s) => f.debug_tuple("Closure").field(d).field(&s).finish(),
306 CoroutineClosure(d, s) => f.debug_tuple("CoroutineClosure").field(d).field(&s).finish(),
307 Coroutine(d, s) => f.debug_tuple("Coroutine").field(d).field(&s).finish(),
308 CoroutineWitness(d, s) => f.debug_tuple("CoroutineWitness").field(d).field(&s).finish(),
309 Never => write!(f, "!"),
310 Tuple(t) => {
311 write!(f, "(")?;
312 let mut count = 0;
313 for ty in t.iter() {
314 if count > 0 {
315 write!(f, ", ")?;
316 }
317 write!(f, "{ty:?}")?;
318 count += 1;
319 }
320 if count == 1 {
322 write!(f, ",")?;
323 }
324 write!(f, ")")
325 }
326 Alias(i, a) => f.debug_tuple("Alias").field(i).field(&a).finish(),
327 Param(p) => write!(f, "{p:?}"),
328 Bound(d, b) => crate::debug_bound_var(f, *d, b),
329 Placeholder(p) => write!(f, "{p:?}"),
330 Infer(t) => write!(f, "{:?}", t),
331 TyKind::Error(_) => write!(f, "{{type error}}"),
332 }
333 }
334}
335
336#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
342#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
343#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
344pub struct AliasTy<I: Interner> {
345 pub args: I::GenericArgs,
356
357 pub def_id: I::DefId,
368
369 #[derive_where(skip(Debug))]
371 pub(crate) _use_alias_ty_new_instead: (),
372}
373
374impl<I: Interner> AliasTy<I> {
375 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy<I> {
376 interner.debug_assert_args_compatible(def_id, args);
377 AliasTy { def_id, args, _use_alias_ty_new_instead: () }
378 }
379
380 pub fn new(
381 interner: I,
382 def_id: I::DefId,
383 args: impl IntoIterator<Item: Into<I::GenericArg>>,
384 ) -> AliasTy<I> {
385 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
386 Self::new_from_args(interner, def_id, args)
387 }
388
389 pub fn kind(self, interner: I) -> AliasTyKind {
390 interner.alias_ty_kind(self)
391 }
392
393 pub fn is_opaque(self, interner: I) -> bool {
395 matches!(self.kind(interner), AliasTyKind::Opaque)
396 }
397
398 pub fn to_ty(self, interner: I) -> I::Ty {
399 Ty::new_alias(interner, self.kind(interner), self)
400 }
401}
402
403impl<I: Interner> AliasTy<I> {
405 pub fn self_ty(self) -> I::Ty {
406 self.args.type_at(0)
407 }
408
409 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
410 AliasTy::new(
411 interner,
412 self.def_id,
413 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
414 )
415 }
416
417 pub fn trait_def_id(self, interner: I) -> I::DefId {
418 assert_eq!(self.kind(interner), AliasTyKind::Projection, "expected a projection");
419 interner.parent(self.def_id)
420 }
421
422 pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef<I>, I::GenericArgsSlice) {
427 debug_assert_eq!(self.kind(interner), AliasTyKind::Projection);
428 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
429 }
430
431 pub fn trait_ref(self, interner: I) -> ty::TraitRef<I> {
439 self.trait_ref_and_own_args(interner).0
440 }
441}
442
443impl<I: Interner> AliasTy<I> {
445 pub fn rebase_inherent_args_onto_impl(
456 self,
457 impl_args: I::GenericArgs,
458 interner: I,
459 ) -> I::GenericArgs {
460 debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent);
461 interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
462 }
463}
464
465#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
466#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
467pub enum IntTy {
468 Isize,
469 I8,
470 I16,
471 I32,
472 I64,
473 I128,
474}
475
476impl IntTy {
477 pub fn name_str(&self) -> &'static str {
478 match *self {
479 IntTy::Isize => "isize",
480 IntTy::I8 => "i8",
481 IntTy::I16 => "i16",
482 IntTy::I32 => "i32",
483 IntTy::I64 => "i64",
484 IntTy::I128 => "i128",
485 }
486 }
487
488 pub fn bit_width(&self) -> Option<u64> {
489 Some(match *self {
490 IntTy::Isize => return None,
491 IntTy::I8 => 8,
492 IntTy::I16 => 16,
493 IntTy::I32 => 32,
494 IntTy::I64 => 64,
495 IntTy::I128 => 128,
496 })
497 }
498
499 pub fn normalize(&self, target_width: u32) -> Self {
500 match self {
501 IntTy::Isize => match target_width {
502 16 => IntTy::I16,
503 32 => IntTy::I32,
504 64 => IntTy::I64,
505 _ => unreachable!(),
506 },
507 _ => *self,
508 }
509 }
510
511 pub fn to_unsigned(self) -> UintTy {
512 match self {
513 IntTy::Isize => UintTy::Usize,
514 IntTy::I8 => UintTy::U8,
515 IntTy::I16 => UintTy::U16,
516 IntTy::I32 => UintTy::U32,
517 IntTy::I64 => UintTy::U64,
518 IntTy::I128 => UintTy::U128,
519 }
520 }
521}
522
523#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
524#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
525pub enum UintTy {
526 Usize,
527 U8,
528 U16,
529 U32,
530 U64,
531 U128,
532}
533
534impl UintTy {
535 pub fn name_str(&self) -> &'static str {
536 match *self {
537 UintTy::Usize => "usize",
538 UintTy::U8 => "u8",
539 UintTy::U16 => "u16",
540 UintTy::U32 => "u32",
541 UintTy::U64 => "u64",
542 UintTy::U128 => "u128",
543 }
544 }
545
546 pub fn bit_width(&self) -> Option<u64> {
547 Some(match *self {
548 UintTy::Usize => return None,
549 UintTy::U8 => 8,
550 UintTy::U16 => 16,
551 UintTy::U32 => 32,
552 UintTy::U64 => 64,
553 UintTy::U128 => 128,
554 })
555 }
556
557 pub fn normalize(&self, target_width: u32) -> Self {
558 match self {
559 UintTy::Usize => match target_width {
560 16 => UintTy::U16,
561 32 => UintTy::U32,
562 64 => UintTy::U64,
563 _ => unreachable!(),
564 },
565 _ => *self,
566 }
567 }
568
569 pub fn to_signed(self) -> IntTy {
570 match self {
571 UintTy::Usize => IntTy::Isize,
572 UintTy::U8 => IntTy::I8,
573 UintTy::U16 => IntTy::I16,
574 UintTy::U32 => IntTy::I32,
575 UintTy::U64 => IntTy::I64,
576 UintTy::U128 => IntTy::I128,
577 }
578 }
579}
580
581#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
582#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
583pub enum FloatTy {
584 F16,
585 F32,
586 F64,
587 F128,
588}
589
590impl FloatTy {
591 pub fn name_str(self) -> &'static str {
592 match self {
593 FloatTy::F16 => "f16",
594 FloatTy::F32 => "f32",
595 FloatTy::F64 => "f64",
596 FloatTy::F128 => "f128",
597 }
598 }
599
600 pub fn bit_width(self) -> u64 {
601 match self {
602 FloatTy::F16 => 16,
603 FloatTy::F32 => 32,
604 FloatTy::F64 => 64,
605 FloatTy::F128 => 128,
606 }
607 }
608}
609
610#[derive(Clone, Copy, PartialEq, Eq, Debug)]
611pub enum IntVarValue {
612 Unknown,
613 IntType(IntTy),
614 UintType(UintTy),
615}
616
617impl IntVarValue {
618 pub fn is_known(self) -> bool {
619 match self {
620 IntVarValue::IntType(_) | IntVarValue::UintType(_) => true,
621 IntVarValue::Unknown => false,
622 }
623 }
624
625 pub fn is_unknown(self) -> bool {
626 !self.is_known()
627 }
628}
629
630#[derive(Clone, Copy, PartialEq, Eq, Debug)]
631pub enum FloatVarValue {
632 Unknown,
633 Known(FloatTy),
634}
635
636impl FloatVarValue {
637 pub fn is_known(self) -> bool {
638 match self {
639 FloatVarValue::Known(_) => true,
640 FloatVarValue::Unknown => false,
641 }
642 }
643
644 pub fn is_unknown(self) -> bool {
645 !self.is_known()
646 }
647}
648
649rustc_index::newtype_index! {
650 #[encodable]
652 #[orderable]
653 #[debug_format = "?{}t"]
654 #[gate_rustc_only]
655 pub struct TyVid {}
656}
657
658rustc_index::newtype_index! {
659 #[encodable]
661 #[orderable]
662 #[debug_format = "?{}i"]
663 #[gate_rustc_only]
664 pub struct IntVid {}
665}
666
667rustc_index::newtype_index! {
668 #[encodable]
670 #[orderable]
671 #[debug_format = "?{}f"]
672 #[gate_rustc_only]
673 pub struct FloatVid {}
674}
675
676#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
682#[cfg_attr(feature = "nightly", derive(Encodable, Decodable))]
683pub enum InferTy {
684 TyVar(TyVid),
686 IntVar(IntVid),
693 FloatVar(FloatVid),
700
701 FreshTy(u32),
707 FreshIntTy(u32),
709 FreshFloatTy(u32),
711}
712
713#[cfg(feature = "nightly")]
716impl UnifyKey for TyVid {
717 type Value = ();
718 #[inline]
719 fn index(&self) -> u32 {
720 self.as_u32()
721 }
722 #[inline]
723 fn from_index(i: u32) -> TyVid {
724 TyVid::from_u32(i)
725 }
726 fn tag() -> &'static str {
727 "TyVid"
728 }
729}
730
731#[cfg(feature = "nightly")]
732impl UnifyValue for IntVarValue {
733 type Error = NoError;
734
735 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
736 match (*value1, *value2) {
737 (IntVarValue::Unknown, IntVarValue::Unknown) => Ok(IntVarValue::Unknown),
738 (
739 IntVarValue::Unknown,
740 known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
741 )
742 | (
743 known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
744 IntVarValue::Unknown,
745 ) => Ok(known),
746 _ => panic!("differing ints should have been resolved first"),
747 }
748 }
749}
750
751#[cfg(feature = "nightly")]
752impl UnifyKey for IntVid {
753 type Value = IntVarValue;
754 #[inline] fn index(&self) -> u32 {
756 self.as_u32()
757 }
758 #[inline]
759 fn from_index(i: u32) -> IntVid {
760 IntVid::from_u32(i)
761 }
762 fn tag() -> &'static str {
763 "IntVid"
764 }
765}
766
767#[cfg(feature = "nightly")]
768impl UnifyValue for FloatVarValue {
769 type Error = NoError;
770
771 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
772 match (*value1, *value2) {
773 (FloatVarValue::Unknown, FloatVarValue::Unknown) => Ok(FloatVarValue::Unknown),
774 (FloatVarValue::Unknown, FloatVarValue::Known(known))
775 | (FloatVarValue::Known(known), FloatVarValue::Unknown) => {
776 Ok(FloatVarValue::Known(known))
777 }
778 (FloatVarValue::Known(_), FloatVarValue::Known(_)) => {
779 panic!("differing floats should have been resolved first")
780 }
781 }
782 }
783}
784
785#[cfg(feature = "nightly")]
786impl UnifyKey for FloatVid {
787 type Value = FloatVarValue;
788 #[inline]
789 fn index(&self) -> u32 {
790 self.as_u32()
791 }
792 #[inline]
793 fn from_index(i: u32) -> FloatVid {
794 FloatVid::from_u32(i)
795 }
796 fn tag() -> &'static str {
797 "FloatVid"
798 }
799}
800
801#[cfg(feature = "nightly")]
802impl<CTX> HashStable<CTX> for InferTy {
803 fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
804 use InferTy::*;
805 std::mem::discriminant(self).hash_stable(ctx, hasher);
806 match self {
807 TyVar(_) | IntVar(_) | FloatVar(_) => {
808 panic!("type variables should not be hashed: {self:?}")
809 }
810 FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher),
811 }
812 }
813}
814
815impl fmt::Display for InferTy {
816 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
817 use InferTy::*;
818 match *self {
819 TyVar(_) => write!(f, "_"),
820 IntVar(_) => write!(f, "{}", "{integer}"),
821 FloatVar(_) => write!(f, "{}", "{float}"),
822 FreshTy(v) => write!(f, "FreshTy({v})"),
823 FreshIntTy(v) => write!(f, "FreshIntTy({v})"),
824 FreshFloatTy(v) => write!(f, "FreshFloatTy({v})"),
825 }
826 }
827}
828
829impl fmt::Debug for IntTy {
830 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
831 write!(f, "{}", self.name_str())
832 }
833}
834
835impl fmt::Debug for UintTy {
836 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
837 write!(f, "{}", self.name_str())
838 }
839}
840
841impl fmt::Debug for FloatTy {
842 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
843 write!(f, "{}", self.name_str())
844 }
845}
846
847impl fmt::Debug for InferTy {
848 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
849 use InferTy::*;
850 match *self {
851 TyVar(ref v) => v.fmt(f),
852 IntVar(ref v) => v.fmt(f),
853 FloatVar(ref v) => v.fmt(f),
854 FreshTy(v) => write!(f, "FreshTy({v:?})"),
855 FreshIntTy(v) => write!(f, "FreshIntTy({v:?})"),
856 FreshFloatTy(v) => write!(f, "FreshFloatTy({v:?})"),
857 }
858 }
859}
860
861#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
862#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
863#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
864pub struct TypeAndMut<I: Interner> {
865 pub ty: I::Ty,
866 pub mutbl: Mutability,
867}
868
869#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
870#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
871#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
872pub struct FnSig<I: Interner> {
873 pub inputs_and_output: I::Tys,
874 pub c_variadic: bool,
875 #[type_visitable(ignore)]
876 #[type_foldable(identity)]
877 pub safety: I::Safety,
878 #[type_visitable(ignore)]
879 #[type_foldable(identity)]
880 pub abi: I::Abi,
881}
882
883impl<I: Interner> FnSig<I> {
884 pub fn inputs(self) -> I::FnInputTys {
885 self.inputs_and_output.inputs()
886 }
887
888 pub fn output(self) -> I::Ty {
889 self.inputs_and_output.output()
890 }
891
892 pub fn is_fn_trait_compatible(self) -> bool {
893 let FnSig { safety, abi, c_variadic, .. } = self;
894 !c_variadic && safety.is_safe() && abi.is_rust()
895 }
896}
897
898impl<I: Interner> ty::Binder<I, FnSig<I>> {
899 #[inline]
900 pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
901 self.map_bound(|fn_sig| fn_sig.inputs())
902 }
903
904 #[inline]
905 #[track_caller]
906 pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
907 self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap())
908 }
909
910 pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
911 self.map_bound(|fn_sig| fn_sig.inputs_and_output)
912 }
913
914 #[inline]
915 pub fn output(self) -> ty::Binder<I, I::Ty> {
916 self.map_bound(|fn_sig| fn_sig.output())
917 }
918
919 pub fn c_variadic(self) -> bool {
920 self.skip_binder().c_variadic
921 }
922
923 pub fn safety(self) -> I::Safety {
924 self.skip_binder().safety
925 }
926
927 pub fn abi(self) -> I::Abi {
928 self.skip_binder().abi
929 }
930
931 pub fn is_fn_trait_compatible(&self) -> bool {
932 self.skip_binder().is_fn_trait_compatible()
933 }
934
935 pub fn split(self) -> (ty::Binder<I, FnSigTys<I>>, FnHeader<I>) {
937 let hdr =
938 FnHeader { c_variadic: self.c_variadic(), safety: self.safety(), abi: self.abi() };
939 (self.map_bound(|sig| FnSigTys { inputs_and_output: sig.inputs_and_output }), hdr)
940 }
941}
942
943impl<I: Interner> fmt::Debug for FnSig<I> {
944 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
945 let sig = self;
946 let FnSig { inputs_and_output: _, c_variadic, safety, abi } = sig;
947
948 write!(f, "{}", safety.prefix_str())?;
949 if !abi.is_rust() {
950 write!(f, "extern \"{abi:?}\" ")?;
951 }
952
953 write!(f, "fn(")?;
954 let inputs = sig.inputs();
955 for (i, ty) in inputs.iter().enumerate() {
956 if i > 0 {
957 write!(f, ", ")?;
958 }
959 write!(f, "{ty:?}")?;
960 }
961 if *c_variadic {
962 if inputs.is_empty() {
963 write!(f, "...")?;
964 } else {
965 write!(f, ", ...")?;
966 }
967 }
968 write!(f, ")")?;
969
970 let output = sig.output();
971 match output.kind() {
972 Tuple(list) if list.is_empty() => Ok(()),
973 _ => write!(f, " -> {:?}", sig.output()),
974 }
975 }
976}
977
978#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
981#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
982#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
983pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>);
984
985impl<I: Interner> From<ty::Binder<I, I::Ty>> for UnsafeBinderInner<I> {
986 fn from(value: ty::Binder<I, I::Ty>) -> Self {
987 UnsafeBinderInner(value)
988 }
989}
990
991impl<I: Interner> From<UnsafeBinderInner<I>> for ty::Binder<I, I::Ty> {
992 fn from(value: UnsafeBinderInner<I>) -> Self {
993 value.0
994 }
995}
996
997impl<I: Interner> fmt::Debug for UnsafeBinderInner<I> {
998 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
999 self.0.fmt(f)
1000 }
1001}
1002
1003impl<I: Interner> Deref for UnsafeBinderInner<I> {
1004 type Target = ty::Binder<I, I::Ty>;
1005
1006 fn deref(&self) -> &Self::Target {
1007 &self.0
1008 }
1009}
1010
1011#[cfg(feature = "nightly")]
1012impl<I: Interner, E: crate::TyEncoder<I = I>> rustc_serialize::Encodable<E> for UnsafeBinderInner<I>
1013where
1014 I::Ty: rustc_serialize::Encodable<E>,
1015 I::BoundVarKinds: rustc_serialize::Encodable<E>,
1016{
1017 fn encode(&self, e: &mut E) {
1018 self.bound_vars().encode(e);
1019 self.as_ref().skip_binder().encode(e);
1020 }
1021}
1022
1023#[cfg(feature = "nightly")]
1024impl<I: Interner, D: crate::TyDecoder<I = I>> rustc_serialize::Decodable<D> for UnsafeBinderInner<I>
1025where
1026 I::Ty: TypeVisitable<I> + rustc_serialize::Decodable<D>,
1027 I::BoundVarKinds: rustc_serialize::Decodable<D>,
1028{
1029 fn decode(decoder: &mut D) -> Self {
1030 let bound_vars = rustc_serialize::Decodable::decode(decoder);
1031 UnsafeBinderInner(ty::Binder::bind_with_vars(
1032 rustc_serialize::Decodable::decode(decoder),
1033 bound_vars,
1034 ))
1035 }
1036}
1037
1038#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
1040#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
1041#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1042pub struct FnSigTys<I: Interner> {
1043 pub inputs_and_output: I::Tys,
1044}
1045
1046impl<I: Interner> FnSigTys<I> {
1047 pub fn inputs(self) -> I::FnInputTys {
1048 self.inputs_and_output.inputs()
1049 }
1050
1051 pub fn output(self) -> I::Ty {
1052 self.inputs_and_output.output()
1053 }
1054}
1055
1056impl<I: Interner> ty::Binder<I, FnSigTys<I>> {
1057 pub fn with(self, hdr: FnHeader<I>) -> ty::Binder<I, FnSig<I>> {
1059 self.map_bound(|sig_tys| FnSig {
1060 inputs_and_output: sig_tys.inputs_and_output,
1061 c_variadic: hdr.c_variadic,
1062 safety: hdr.safety,
1063 abi: hdr.abi,
1064 })
1065 }
1066
1067 #[inline]
1068 pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
1069 self.map_bound(|sig_tys| sig_tys.inputs())
1070 }
1071
1072 #[inline]
1073 #[track_caller]
1074 pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
1075 self.map_bound(|sig_tys| sig_tys.inputs().get(index).unwrap())
1076 }
1077
1078 pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
1079 self.map_bound(|sig_tys| sig_tys.inputs_and_output)
1080 }
1081
1082 #[inline]
1083 pub fn output(self) -> ty::Binder<I, I::Ty> {
1084 self.map_bound(|sig_tys| sig_tys.output())
1085 }
1086}
1087
1088#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
1089#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
1090#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1091pub struct FnHeader<I: Interner> {
1092 pub c_variadic: bool,
1093 pub safety: I::Safety,
1094 pub abi: I::Abi,
1095}