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