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::{
12 GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
13};
14
15use self::TyKind::*;
16pub use self::closure::*;
17use crate::inherent::*;
18#[cfg(feature = "nightly")]
19use crate::visit::TypeVisitable;
20use crate::{self as ty, BoundVarIndexKind, FloatTy, IntTy, Interner, UintTy};
21
22mod closure;
23
24#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
25#[derive(GenericTypeVisitable)]
26#[cfg_attr(
27 feature = "nightly",
28 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
29)]
30pub enum AliasTyKind {
31 Projection,
34 Inherent,
36 Opaque,
39 Free,
43}
44
45impl AliasTyKind {
46 pub fn descr(self) -> &'static str {
47 match self {
48 AliasTyKind::Projection => "associated type",
49 AliasTyKind::Inherent => "inherent associated type",
50 AliasTyKind::Opaque => "opaque type",
51 AliasTyKind::Free => "type alias",
52 }
53 }
54}
55
56#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
61#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
62#[derive(GenericTypeVisitable)]
63#[cfg_attr(
64 feature = "nightly",
65 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
66)]
67pub enum TyKind<I: Interner> {
68 Bool,
70
71 Char,
74
75 Int(IntTy),
77
78 Uint(UintTy),
80
81 Float(FloatTy),
83
84 Adt(I::AdtDef, I::GenericArgs),
92
93 Foreign(I::ForeignId),
95
96 Str,
98
99 Array(I::Ty, I::Const),
101
102 Pat(I::Ty, I::Pat),
108
109 Slice(I::Ty),
111
112 RawPtr(I::Ty, Mutability),
114
115 Ref(I::Region, I::Ty, Mutability),
118
119 FnDef(I::FunctionId, I::GenericArgs),
131
132 FnPtr(ty::Binder<I, FnSigTys<I>>, FnHeader<I>),
149
150 UnsafeBinder(UnsafeBinderInner<I>),
156
157 Dynamic(I::BoundExistentialPredicates, I::Region),
159
160 Closure(I::ClosureId, I::GenericArgs),
166
167 CoroutineClosure(I::CoroutineClosureId, I::GenericArgs),
173
174 Coroutine(I::CoroutineId, I::GenericArgs),
180
181 CoroutineWitness(I::CoroutineId, I::GenericArgs),
205
206 Never,
208
209 Tuple(I::Tys),
211
212 Alias(AliasTyKind, AliasTy<I>),
216
217 Param(I::ParamTy),
219
220 Bound(BoundVarIndexKind, I::BoundTy),
237
238 Placeholder(I::PlaceholderTy),
247
248 Infer(InferTy),
255
256 Error(I::ErrorGuaranteed),
259}
260
261impl<I: Interner> Eq for TyKind<I> {}
262
263impl<I: Interner> TyKind<I> {
264 pub fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
265 match self {
266 ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
267 ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
268 ty::Error(_) => {
269 ty::Binder::dummy(ty::FnSig {
271 inputs_and_output: Default::default(),
272 c_variadic: false,
273 safety: I::Safety::safe(),
274 abi: I::Abi::rust(),
275 })
276 }
277 ty::Closure(..) => panic!(
278 "to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
279 ),
280 _ => panic!("Ty::fn_sig() called on non-fn type: {:?}", self),
281 }
282 }
283
284 pub fn is_known_rigid(self) -> bool {
290 match self {
291 ty::Bool
292 | ty::Char
293 | ty::Int(_)
294 | ty::Uint(_)
295 | ty::Float(_)
296 | ty::Adt(_, _)
297 | ty::Foreign(_)
298 | ty::Str
299 | ty::Array(_, _)
300 | ty::Pat(_, _)
301 | ty::Slice(_)
302 | ty::RawPtr(_, _)
303 | ty::Ref(_, _, _)
304 | ty::FnDef(_, _)
305 | ty::FnPtr(..)
306 | ty::UnsafeBinder(_)
307 | ty::Dynamic(_, _)
308 | ty::Closure(_, _)
309 | ty::CoroutineClosure(_, _)
310 | ty::Coroutine(_, _)
311 | ty::CoroutineWitness(..)
312 | ty::Never
313 | ty::Tuple(_) => true,
314
315 ty::Error(_)
316 | ty::Infer(_)
317 | ty::Alias(_, _)
318 | ty::Param(_)
319 | ty::Bound(_, _)
320 | ty::Placeholder(_) => false,
321 }
322 }
323}
324
325impl<I: Interner> fmt::Debug for TyKind<I> {
327 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328 match self {
329 Bool => write!(f, "bool"),
330 Char => write!(f, "char"),
331 Int(i) => write!(f, "{i:?}"),
332 Uint(u) => write!(f, "{u:?}"),
333 Float(float) => write!(f, "{float:?}"),
334 Adt(d, s) => {
335 write!(f, "{d:?}")?;
336 let mut s = s.iter();
337 let first = s.next();
338 match first {
339 Some(first) => write!(f, "<{:?}", first)?,
340 None => return Ok(()),
341 };
342
343 for arg in s {
344 write!(f, ", {:?}", arg)?;
345 }
346
347 write!(f, ">")
348 }
349 Foreign(d) => f.debug_tuple("Foreign").field(d).finish(),
350 Str => write!(f, "str"),
351 Array(t, c) => write!(f, "[{t:?}; {c:?}]"),
352 Pat(t, p) => write!(f, "pattern_type!({t:?} is {p:?})"),
353 Slice(t) => write!(f, "[{:?}]", &t),
354 RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), ty),
355 Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
356 FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(),
357 FnPtr(sig_tys, hdr) => write!(f, "{:?}", sig_tys.with(*hdr)),
358 UnsafeBinder(binder) => write!(f, "{:?}", binder),
360 Dynamic(p, r) => write!(f, "dyn {p:?} + {r:?}"),
361 Closure(d, s) => f.debug_tuple("Closure").field(d).field(&s).finish(),
362 CoroutineClosure(d, s) => f.debug_tuple("CoroutineClosure").field(d).field(&s).finish(),
363 Coroutine(d, s) => f.debug_tuple("Coroutine").field(d).field(&s).finish(),
364 CoroutineWitness(d, s) => f.debug_tuple("CoroutineWitness").field(d).field(&s).finish(),
365 Never => write!(f, "!"),
366 Tuple(t) => {
367 write!(f, "(")?;
368 let mut count = 0;
369 for ty in t.iter() {
370 if count > 0 {
371 write!(f, ", ")?;
372 }
373 write!(f, "{ty:?}")?;
374 count += 1;
375 }
376 if count == 1 {
378 write!(f, ",")?;
379 }
380 write!(f, ")")
381 }
382 Alias(i, a) => f.debug_tuple("Alias").field(i).field(&a).finish(),
383 Param(p) => write!(f, "{p:?}"),
384 Bound(d, b) => crate::debug_bound_var(f, *d, b),
385 Placeholder(p) => write!(f, "{p:?}"),
386 Infer(t) => write!(f, "{:?}", t),
387 TyKind::Error(_) => write!(f, "{{type error}}"),
388 }
389 }
390}
391
392#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
398#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
399#[cfg_attr(
400 feature = "nightly",
401 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
402)]
403pub struct AliasTy<I: Interner> {
404 pub args: I::GenericArgs,
415
416 pub def_id: I::DefId,
427
428 #[derive_where(skip(Debug))]
430 pub(crate) _use_alias_ty_new_instead: (),
431}
432
433impl<I: Interner> Eq for AliasTy<I> {}
434
435impl<I: Interner> AliasTy<I> {
436 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy<I> {
437 interner.debug_assert_args_compatible(def_id, args);
438 AliasTy { def_id, args, _use_alias_ty_new_instead: () }
439 }
440
441 pub fn new(
442 interner: I,
443 def_id: I::DefId,
444 args: impl IntoIterator<Item: Into<I::GenericArg>>,
445 ) -> AliasTy<I> {
446 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
447 Self::new_from_args(interner, def_id, args)
448 }
449
450 pub fn kind(self, interner: I) -> AliasTyKind {
451 interner.alias_ty_kind(self)
452 }
453
454 pub fn is_opaque(self, interner: I) -> bool {
456 matches!(self.kind(interner), AliasTyKind::Opaque)
457 }
458
459 pub fn to_ty(self, interner: I) -> I::Ty {
460 Ty::new_alias(interner, self.kind(interner), self)
461 }
462}
463
464impl<I: Interner> AliasTy<I> {
466 pub fn self_ty(self) -> I::Ty {
467 self.args.type_at(0)
468 }
469
470 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
471 AliasTy::new(
472 interner,
473 self.def_id,
474 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
475 )
476 }
477
478 pub fn trait_def_id(self, interner: I) -> I::DefId {
479 assert_eq!(self.kind(interner), AliasTyKind::Projection, "expected a projection");
480 interner.parent(self.def_id)
481 }
482
483 pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef<I>, I::GenericArgsSlice) {
488 debug_assert_eq!(self.kind(interner), AliasTyKind::Projection);
489 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
490 }
491
492 pub fn trait_ref(self, interner: I) -> ty::TraitRef<I> {
500 self.trait_ref_and_own_args(interner).0
501 }
502}
503
504#[derive(Clone, Copy, PartialEq, Eq, Debug)]
505pub enum IntVarValue {
506 Unknown,
507 IntType(IntTy),
508 UintType(UintTy),
509}
510
511impl IntVarValue {
512 pub fn is_known(self) -> bool {
513 match self {
514 IntVarValue::IntType(_) | IntVarValue::UintType(_) => true,
515 IntVarValue::Unknown => false,
516 }
517 }
518
519 pub fn is_unknown(self) -> bool {
520 !self.is_known()
521 }
522}
523
524#[derive(Clone, Copy, PartialEq, Eq, Debug)]
525pub enum FloatVarValue {
526 Unknown,
527 Known(FloatTy),
528}
529
530impl FloatVarValue {
531 pub fn is_known(self) -> bool {
532 match self {
533 FloatVarValue::Known(_) => true,
534 FloatVarValue::Unknown => false,
535 }
536 }
537
538 pub fn is_unknown(self) -> bool {
539 !self.is_known()
540 }
541}
542
543rustc_index::newtype_index! {
544 #[encodable]
546 #[orderable]
547 #[debug_format = "?{}t"]
548 #[gate_rustc_only]
549 pub struct TyVid {}
550}
551
552rustc_index::newtype_index! {
553 #[encodable]
555 #[orderable]
556 #[debug_format = "?{}i"]
557 #[gate_rustc_only]
558 pub struct IntVid {}
559}
560
561rustc_index::newtype_index! {
562 #[encodable]
564 #[orderable]
565 #[debug_format = "?{}f"]
566 #[gate_rustc_only]
567 pub struct FloatVid {}
568}
569
570#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
576#[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext))]
577pub enum InferTy {
578 TyVar(TyVid),
580 IntVar(IntVid),
587 FloatVar(FloatVid),
594
595 FreshTy(u32),
601 FreshIntTy(u32),
603 FreshFloatTy(u32),
605}
606
607impl UnifyValue for IntVarValue {
608 type Error = NoError;
609
610 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
611 match (*value1, *value2) {
612 (IntVarValue::Unknown, IntVarValue::Unknown) => Ok(IntVarValue::Unknown),
613 (
614 IntVarValue::Unknown,
615 known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
616 )
617 | (
618 known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
619 IntVarValue::Unknown,
620 ) => Ok(known),
621 _ => panic!("differing ints should have been resolved first"),
622 }
623 }
624}
625
626impl UnifyKey for IntVid {
627 type Value = IntVarValue;
628 #[inline] fn index(&self) -> u32 {
630 self.as_u32()
631 }
632 #[inline]
633 fn from_index(i: u32) -> IntVid {
634 IntVid::from_u32(i)
635 }
636 fn tag() -> &'static str {
637 "IntVid"
638 }
639}
640
641impl UnifyValue for FloatVarValue {
642 type Error = NoError;
643
644 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
645 match (*value1, *value2) {
646 (FloatVarValue::Unknown, FloatVarValue::Unknown) => Ok(FloatVarValue::Unknown),
647 (FloatVarValue::Unknown, FloatVarValue::Known(known))
648 | (FloatVarValue::Known(known), FloatVarValue::Unknown) => {
649 Ok(FloatVarValue::Known(known))
650 }
651 (FloatVarValue::Known(_), FloatVarValue::Known(_)) => {
652 panic!("differing floats should have been resolved first")
653 }
654 }
655 }
656}
657
658impl UnifyKey for FloatVid {
659 type Value = FloatVarValue;
660 #[inline]
661 fn index(&self) -> u32 {
662 self.as_u32()
663 }
664 #[inline]
665 fn from_index(i: u32) -> FloatVid {
666 FloatVid::from_u32(i)
667 }
668 fn tag() -> &'static str {
669 "FloatVid"
670 }
671}
672
673#[cfg(feature = "nightly")]
674impl<CTX> HashStable<CTX> for InferTy {
675 fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
676 use InferTy::*;
677 std::mem::discriminant(self).hash_stable(ctx, hasher);
678 match self {
679 TyVar(_) | IntVar(_) | FloatVar(_) => {
680 panic!("type variables should not be hashed: {self:?}")
681 }
682 FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher),
683 }
684 }
685}
686
687impl fmt::Display for InferTy {
688 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
689 use InferTy::*;
690 match *self {
691 TyVar(_) => write!(f, "_"),
692 IntVar(_) => write!(f, "{}", "{integer}"),
693 FloatVar(_) => write!(f, "{}", "{float}"),
694 FreshTy(v) => write!(f, "FreshTy({v})"),
695 FreshIntTy(v) => write!(f, "FreshIntTy({v})"),
696 FreshFloatTy(v) => write!(f, "FreshFloatTy({v})"),
697 }
698 }
699}
700
701impl fmt::Debug for InferTy {
702 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
703 use InferTy::*;
704 match *self {
705 TyVar(ref v) => v.fmt(f),
706 IntVar(ref v) => v.fmt(f),
707 FloatVar(ref v) => v.fmt(f),
708 FreshTy(v) => write!(f, "FreshTy({v:?})"),
709 FreshIntTy(v) => write!(f, "FreshIntTy({v:?})"),
710 FreshFloatTy(v) => write!(f, "FreshFloatTy({v:?})"),
711 }
712 }
713}
714
715#[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)]
716#[cfg_attr(
717 feature = "nightly",
718 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
719)]
720#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
721pub struct TypeAndMut<I: Interner> {
722 pub ty: I::Ty,
723 pub mutbl: Mutability,
724}
725
726impl<I: Interner> Eq for TypeAndMut<I> {}
727
728#[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)]
729#[cfg_attr(
730 feature = "nightly",
731 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
732)]
733#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
734pub struct FnSig<I: Interner> {
735 pub inputs_and_output: I::Tys,
736 pub c_variadic: bool,
737 #[type_visitable(ignore)]
738 #[type_foldable(identity)]
739 pub safety: I::Safety,
740 #[type_visitable(ignore)]
741 #[type_foldable(identity)]
742 pub abi: I::Abi,
743}
744
745impl<I: Interner> Eq for FnSig<I> {}
746
747impl<I: Interner> FnSig<I> {
748 pub fn inputs(self) -> I::FnInputTys {
749 self.inputs_and_output.inputs()
750 }
751
752 pub fn output(self) -> I::Ty {
753 self.inputs_and_output.output()
754 }
755
756 pub fn is_fn_trait_compatible(self) -> bool {
757 let FnSig { safety, abi, c_variadic, .. } = self;
758 !c_variadic && safety.is_safe() && abi.is_rust()
759 }
760}
761
762impl<I: Interner> ty::Binder<I, FnSig<I>> {
763 #[inline]
764 pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
765 self.map_bound(|fn_sig| fn_sig.inputs())
766 }
767
768 #[inline]
769 #[track_caller]
770 pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
771 self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap())
772 }
773
774 pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
775 self.map_bound(|fn_sig| fn_sig.inputs_and_output)
776 }
777
778 #[inline]
779 pub fn output(self) -> ty::Binder<I, I::Ty> {
780 self.map_bound(|fn_sig| fn_sig.output())
781 }
782
783 pub fn c_variadic(self) -> bool {
784 self.skip_binder().c_variadic
785 }
786
787 pub fn safety(self) -> I::Safety {
788 self.skip_binder().safety
789 }
790
791 pub fn abi(self) -> I::Abi {
792 self.skip_binder().abi
793 }
794
795 pub fn is_fn_trait_compatible(&self) -> bool {
796 self.skip_binder().is_fn_trait_compatible()
797 }
798
799 pub fn split(self) -> (ty::Binder<I, FnSigTys<I>>, FnHeader<I>) {
801 let hdr =
802 FnHeader { c_variadic: self.c_variadic(), safety: self.safety(), abi: self.abi() };
803 (self.map_bound(|sig| FnSigTys { inputs_and_output: sig.inputs_and_output }), hdr)
804 }
805}
806
807impl<I: Interner> fmt::Debug for FnSig<I> {
808 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
809 let sig = self;
810 let FnSig { inputs_and_output: _, c_variadic, safety, abi } = sig;
811
812 write!(f, "{}", safety.prefix_str())?;
813 if !abi.is_rust() {
814 write!(f, "extern \"{abi:?}\" ")?;
815 }
816
817 write!(f, "fn(")?;
818 let inputs = sig.inputs();
819 for (i, ty) in inputs.iter().enumerate() {
820 if i > 0 {
821 write!(f, ", ")?;
822 }
823 write!(f, "{ty:?}")?;
824 }
825 if *c_variadic {
826 if inputs.is_empty() {
827 write!(f, "...")?;
828 } else {
829 write!(f, ", ...")?;
830 }
831 }
832 write!(f, ")")?;
833
834 let output = sig.output();
835 match output.kind() {
836 Tuple(list) if list.is_empty() => Ok(()),
837 _ => write!(f, " -> {:?}", sig.output()),
838 }
839 }
840}
841
842#[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)]
845#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
846#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
847pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>);
848
849impl<I: Interner> Eq for UnsafeBinderInner<I> {}
850
851impl<I: Interner> From<ty::Binder<I, I::Ty>> for UnsafeBinderInner<I> {
852 fn from(value: ty::Binder<I, I::Ty>) -> Self {
853 UnsafeBinderInner(value)
854 }
855}
856
857impl<I: Interner> From<UnsafeBinderInner<I>> for ty::Binder<I, I::Ty> {
858 fn from(value: UnsafeBinderInner<I>) -> Self {
859 value.0
860 }
861}
862
863impl<I: Interner> fmt::Debug for UnsafeBinderInner<I> {
864 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
865 self.0.fmt(f)
866 }
867}
868
869impl<I: Interner> Deref for UnsafeBinderInner<I> {
870 type Target = ty::Binder<I, I::Ty>;
871
872 fn deref(&self) -> &Self::Target {
873 &self.0
874 }
875}
876
877#[cfg(feature = "nightly")]
878impl<I: Interner, E: rustc_serialize::Encoder> rustc_serialize::Encodable<E>
879 for UnsafeBinderInner<I>
880where
881 I::Ty: rustc_serialize::Encodable<E>,
882 I::BoundVarKinds: rustc_serialize::Encodable<E>,
883{
884 fn encode(&self, e: &mut E) {
885 self.bound_vars().encode(e);
886 self.as_ref().skip_binder().encode(e);
887 }
888}
889
890#[cfg(feature = "nightly")]
891impl<I: Interner, D: rustc_serialize::Decoder> rustc_serialize::Decodable<D>
892 for UnsafeBinderInner<I>
893where
894 I::Ty: TypeVisitable<I> + rustc_serialize::Decodable<D>,
895 I::BoundVarKinds: rustc_serialize::Decodable<D>,
896{
897 fn decode(decoder: &mut D) -> Self {
898 let bound_vars = rustc_serialize::Decodable::decode(decoder);
899 UnsafeBinderInner(ty::Binder::bind_with_vars(
900 rustc_serialize::Decodable::decode(decoder),
901 bound_vars,
902 ))
903 }
904}
905
906#[derive_where(Clone, Copy, Debug, PartialEq, Hash; I: Interner)]
908#[cfg_attr(
909 feature = "nightly",
910 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
911)]
912#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
913pub struct FnSigTys<I: Interner> {
914 pub inputs_and_output: I::Tys,
915}
916
917impl<I: Interner> Eq for FnSigTys<I> {}
918
919impl<I: Interner> FnSigTys<I> {
920 pub fn inputs(self) -> I::FnInputTys {
921 self.inputs_and_output.inputs()
922 }
923
924 pub fn output(self) -> I::Ty {
925 self.inputs_and_output.output()
926 }
927}
928
929impl<I: Interner> ty::Binder<I, FnSigTys<I>> {
930 pub fn with(self, hdr: FnHeader<I>) -> ty::Binder<I, FnSig<I>> {
932 self.map_bound(|sig_tys| FnSig {
933 inputs_and_output: sig_tys.inputs_and_output,
934 c_variadic: hdr.c_variadic,
935 safety: hdr.safety,
936 abi: hdr.abi,
937 })
938 }
939
940 #[inline]
941 pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
942 self.map_bound(|sig_tys| sig_tys.inputs())
943 }
944
945 #[inline]
946 #[track_caller]
947 pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
948 self.map_bound(|sig_tys| sig_tys.inputs().get(index).unwrap())
949 }
950
951 pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
952 self.map_bound(|sig_tys| sig_tys.inputs_and_output)
953 }
954
955 #[inline]
956 pub fn output(self) -> ty::Binder<I, I::Ty> {
957 self.map_bound(|sig_tys| sig_tys.output())
958 }
959}
960
961#[derive_where(Clone, Copy, Debug, PartialEq, Hash; I: Interner)]
962#[cfg_attr(
963 feature = "nightly",
964 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
965)]
966#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
967pub struct FnHeader<I: Interner> {
968 pub c_variadic: bool,
969 pub safety: I::Safety,
970 pub abi: I::Abi,
971}
972
973impl<I: Interner> Eq for FnHeader<I> {}
974
975#[derive_where(Clone, Copy, Debug, PartialEq, Hash; I: Interner)]
976#[cfg_attr(
977 feature = "nightly",
978 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
979)]
980#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
981pub struct CoroutineWitnessTypes<I: Interner> {
982 pub types: I::Tys,
983 pub assumptions: I::RegionAssumptions,
984}
985
986impl<I: Interner> Eq for CoroutineWitnessTypes<I> {}