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)]
27#[cfg_attr(
28 feature = "nightly",
29 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
30)]
31pub enum DynKind {
32 Dyn,
34}
35
36#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
37#[cfg_attr(
38 feature = "nightly",
39 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
40)]
41pub enum AliasTyKind {
42 Projection,
45 Inherent,
47 Opaque,
50 Free,
54}
55
56impl AliasTyKind {
57 pub fn descr(self) -> &'static str {
58 match self {
59 AliasTyKind::Projection => "associated type",
60 AliasTyKind::Inherent => "inherent associated type",
61 AliasTyKind::Opaque => "opaque type",
62 AliasTyKind::Free => "type alias",
63 }
64 }
65}
66
67#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
72#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
73#[cfg_attr(
74 feature = "nightly",
75 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
76)]
77pub enum TyKind<I: Interner> {
78 Bool,
80
81 Char,
84
85 Int(IntTy),
87
88 Uint(UintTy),
90
91 Float(FloatTy),
93
94 Adt(I::AdtDef, I::GenericArgs),
102
103 Foreign(I::DefId),
105
106 Str,
108
109 Array(I::Ty, I::Const),
111
112 Pat(I::Ty, I::Pat),
118
119 Slice(I::Ty),
121
122 RawPtr(I::Ty, Mutability),
124
125 Ref(I::Region, I::Ty, Mutability),
128
129 FnDef(I::DefId, I::GenericArgs),
141
142 FnPtr(ty::Binder<I, FnSigTys<I>>, FnHeader<I>),
159
160 UnsafeBinder(UnsafeBinderInner<I>),
166
167 Dynamic(I::BoundExistentialPredicates, I::Region, DynKind),
169
170 Closure(I::DefId, I::GenericArgs),
176
177 CoroutineClosure(I::DefId, I::GenericArgs),
183
184 Coroutine(I::DefId, I::GenericArgs),
190
191 CoroutineWitness(I::DefId, I::GenericArgs),
215
216 Never,
218
219 Tuple(I::Tys),
221
222 Alias(AliasTyKind, AliasTy<I>),
226
227 Param(I::ParamTy),
229
230 Bound(DebruijnIndex, I::BoundTy),
247
248 Placeholder(I::PlaceholderTy),
257
258 Infer(InferTy),
265
266 Error(I::ErrorGuaranteed),
269}
270
271impl<I: Interner> TyKind<I> {
272 pub fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
273 match self {
274 ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
275 ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
276 ty::Error(_) => {
277 ty::Binder::dummy(ty::FnSig {
279 inputs_and_output: Default::default(),
280 c_variadic: false,
281 safety: I::Safety::safe(),
282 abi: I::Abi::rust(),
283 })
284 }
285 ty::Closure(..) => panic!(
286 "to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
287 ),
288 _ => panic!("Ty::fn_sig() called on non-fn type: {:?}", self),
289 }
290 }
291
292 pub fn is_known_rigid(self) -> bool {
298 match self {
299 ty::Bool
300 | ty::Char
301 | ty::Int(_)
302 | ty::Uint(_)
303 | ty::Float(_)
304 | ty::Adt(_, _)
305 | ty::Foreign(_)
306 | ty::Str
307 | ty::Array(_, _)
308 | ty::Pat(_, _)
309 | ty::Slice(_)
310 | ty::RawPtr(_, _)
311 | ty::Ref(_, _, _)
312 | ty::FnDef(_, _)
313 | ty::FnPtr(..)
314 | ty::UnsafeBinder(_)
315 | ty::Dynamic(_, _, _)
316 | ty::Closure(_, _)
317 | ty::CoroutineClosure(_, _)
318 | ty::Coroutine(_, _)
319 | ty::CoroutineWitness(..)
320 | ty::Never
321 | ty::Tuple(_) => true,
322
323 ty::Error(_)
324 | ty::Infer(_)
325 | ty::Alias(_, _)
326 | ty::Param(_)
327 | ty::Bound(_, _)
328 | ty::Placeholder(_) => false,
329 }
330 }
331}
332
333impl<I: Interner> fmt::Debug for TyKind<I> {
335 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
336 match self {
337 Bool => write!(f, "bool"),
338 Char => write!(f, "char"),
339 Int(i) => write!(f, "{i:?}"),
340 Uint(u) => write!(f, "{u:?}"),
341 Float(float) => write!(f, "{float:?}"),
342 Adt(d, s) => {
343 write!(f, "{d:?}")?;
344 let mut s = s.iter();
345 let first = s.next();
346 match first {
347 Some(first) => write!(f, "<{:?}", first)?,
348 None => return Ok(()),
349 };
350
351 for arg in s {
352 write!(f, ", {:?}", arg)?;
353 }
354
355 write!(f, ">")
356 }
357 Foreign(d) => f.debug_tuple("Foreign").field(d).finish(),
358 Str => write!(f, "str"),
359 Array(t, c) => write!(f, "[{t:?}; {c:?}]"),
360 Pat(t, p) => write!(f, "pattern_type!({t:?} is {p:?})"),
361 Slice(t) => write!(f, "[{:?}]", &t),
362 RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), ty),
363 Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
364 FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(),
365 FnPtr(sig_tys, hdr) => write!(f, "{:?}", sig_tys.with(*hdr)),
366 UnsafeBinder(binder) => write!(f, "{:?}", binder),
368 Dynamic(p, r, repr) => match repr {
369 DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
370 },
371 Closure(d, s) => f.debug_tuple("Closure").field(d).field(&s).finish(),
372 CoroutineClosure(d, s) => f.debug_tuple("CoroutineClosure").field(d).field(&s).finish(),
373 Coroutine(d, s) => f.debug_tuple("Coroutine").field(d).field(&s).finish(),
374 CoroutineWitness(d, s) => f.debug_tuple("CoroutineWitness").field(d).field(&s).finish(),
375 Never => write!(f, "!"),
376 Tuple(t) => {
377 write!(f, "(")?;
378 let mut count = 0;
379 for ty in t.iter() {
380 if count > 0 {
381 write!(f, ", ")?;
382 }
383 write!(f, "{ty:?}")?;
384 count += 1;
385 }
386 if count == 1 {
388 write!(f, ",")?;
389 }
390 write!(f, ")")
391 }
392 Alias(i, a) => f.debug_tuple("Alias").field(i).field(&a).finish(),
393 Param(p) => write!(f, "{p:?}"),
394 Bound(d, b) => crate::debug_bound_var(f, *d, b),
395 Placeholder(p) => write!(f, "{p:?}"),
396 Infer(t) => write!(f, "{:?}", t),
397 TyKind::Error(_) => write!(f, "{{type error}}"),
398 }
399 }
400}
401
402#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
408#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
409#[cfg_attr(
410 feature = "nightly",
411 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
412)]
413pub struct AliasTy<I: Interner> {
414 pub args: I::GenericArgs,
425
426 pub def_id: I::DefId,
437
438 #[derive_where(skip(Debug))]
440 pub(crate) _use_alias_ty_new_instead: (),
441}
442
443impl<I: Interner> AliasTy<I> {
444 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy<I> {
445 interner.debug_assert_args_compatible(def_id, args);
446 AliasTy { def_id, args, _use_alias_ty_new_instead: () }
447 }
448
449 pub fn new(
450 interner: I,
451 def_id: I::DefId,
452 args: impl IntoIterator<Item: Into<I::GenericArg>>,
453 ) -> AliasTy<I> {
454 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
455 Self::new_from_args(interner, def_id, args)
456 }
457
458 pub fn kind(self, interner: I) -> AliasTyKind {
459 interner.alias_ty_kind(self)
460 }
461
462 pub fn is_opaque(self, interner: I) -> bool {
464 matches!(self.kind(interner), AliasTyKind::Opaque)
465 }
466
467 pub fn to_ty(self, interner: I) -> I::Ty {
468 Ty::new_alias(interner, self.kind(interner), self)
469 }
470}
471
472impl<I: Interner> AliasTy<I> {
474 pub fn self_ty(self) -> I::Ty {
475 self.args.type_at(0)
476 }
477
478 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
479 AliasTy::new(
480 interner,
481 self.def_id,
482 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
483 )
484 }
485
486 pub fn trait_def_id(self, interner: I) -> I::DefId {
487 assert_eq!(self.kind(interner), AliasTyKind::Projection, "expected a projection");
488 interner.parent(self.def_id)
489 }
490
491 pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef<I>, I::GenericArgsSlice) {
496 debug_assert_eq!(self.kind(interner), AliasTyKind::Projection);
497 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
498 }
499
500 pub fn trait_ref(self, interner: I) -> ty::TraitRef<I> {
508 self.trait_ref_and_own_args(interner).0
509 }
510}
511
512#[derive(Clone, Copy, PartialEq, Eq, Debug)]
513pub enum IntVarValue {
514 Unknown,
515 IntType(IntTy),
516 UintType(UintTy),
517}
518
519impl IntVarValue {
520 pub fn is_known(self) -> bool {
521 match self {
522 IntVarValue::IntType(_) | IntVarValue::UintType(_) => true,
523 IntVarValue::Unknown => false,
524 }
525 }
526
527 pub fn is_unknown(self) -> bool {
528 !self.is_known()
529 }
530}
531
532#[derive(Clone, Copy, PartialEq, Eq, Debug)]
533pub enum FloatVarValue {
534 Unknown,
535 Known(FloatTy),
536}
537
538impl FloatVarValue {
539 pub fn is_known(self) -> bool {
540 match self {
541 FloatVarValue::Known(_) => true,
542 FloatVarValue::Unknown => false,
543 }
544 }
545
546 pub fn is_unknown(self) -> bool {
547 !self.is_known()
548 }
549}
550
551rustc_index::newtype_index! {
552 #[encodable]
554 #[orderable]
555 #[debug_format = "?{}t"]
556 #[gate_rustc_only]
557 pub struct TyVid {}
558}
559
560rustc_index::newtype_index! {
561 #[encodable]
563 #[orderable]
564 #[debug_format = "?{}i"]
565 #[gate_rustc_only]
566 pub struct IntVid {}
567}
568
569rustc_index::newtype_index! {
570 #[encodable]
572 #[orderable]
573 #[debug_format = "?{}f"]
574 #[gate_rustc_only]
575 pub struct FloatVid {}
576}
577
578#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
584#[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext))]
585pub enum InferTy {
586 TyVar(TyVid),
588 IntVar(IntVid),
595 FloatVar(FloatVid),
602
603 FreshTy(u32),
609 FreshIntTy(u32),
611 FreshFloatTy(u32),
613}
614
615impl UnifyValue for IntVarValue {
616 type Error = NoError;
617
618 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
619 match (*value1, *value2) {
620 (IntVarValue::Unknown, IntVarValue::Unknown) => Ok(IntVarValue::Unknown),
621 (
622 IntVarValue::Unknown,
623 known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
624 )
625 | (
626 known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
627 IntVarValue::Unknown,
628 ) => Ok(known),
629 _ => panic!("differing ints should have been resolved first"),
630 }
631 }
632}
633
634impl UnifyKey for IntVid {
635 type Value = IntVarValue;
636 #[inline] fn index(&self) -> u32 {
638 self.as_u32()
639 }
640 #[inline]
641 fn from_index(i: u32) -> IntVid {
642 IntVid::from_u32(i)
643 }
644 fn tag() -> &'static str {
645 "IntVid"
646 }
647}
648
649impl UnifyValue for FloatVarValue {
650 type Error = NoError;
651
652 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
653 match (*value1, *value2) {
654 (FloatVarValue::Unknown, FloatVarValue::Unknown) => Ok(FloatVarValue::Unknown),
655 (FloatVarValue::Unknown, FloatVarValue::Known(known))
656 | (FloatVarValue::Known(known), FloatVarValue::Unknown) => {
657 Ok(FloatVarValue::Known(known))
658 }
659 (FloatVarValue::Known(_), FloatVarValue::Known(_)) => {
660 panic!("differing floats should have been resolved first")
661 }
662 }
663 }
664}
665
666impl UnifyKey for FloatVid {
667 type Value = FloatVarValue;
668 #[inline]
669 fn index(&self) -> u32 {
670 self.as_u32()
671 }
672 #[inline]
673 fn from_index(i: u32) -> FloatVid {
674 FloatVid::from_u32(i)
675 }
676 fn tag() -> &'static str {
677 "FloatVid"
678 }
679}
680
681#[cfg(feature = "nightly")]
682impl<CTX> HashStable<CTX> for InferTy {
683 fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
684 use InferTy::*;
685 std::mem::discriminant(self).hash_stable(ctx, hasher);
686 match self {
687 TyVar(_) | IntVar(_) | FloatVar(_) => {
688 panic!("type variables should not be hashed: {self:?}")
689 }
690 FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher),
691 }
692 }
693}
694
695impl fmt::Display for InferTy {
696 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
697 use InferTy::*;
698 match *self {
699 TyVar(_) => write!(f, "_"),
700 IntVar(_) => write!(f, "{}", "{integer}"),
701 FloatVar(_) => write!(f, "{}", "{float}"),
702 FreshTy(v) => write!(f, "FreshTy({v})"),
703 FreshIntTy(v) => write!(f, "FreshIntTy({v})"),
704 FreshFloatTy(v) => write!(f, "FreshFloatTy({v})"),
705 }
706 }
707}
708
709impl fmt::Debug for InferTy {
710 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
711 use InferTy::*;
712 match *self {
713 TyVar(ref v) => v.fmt(f),
714 IntVar(ref v) => v.fmt(f),
715 FloatVar(ref v) => v.fmt(f),
716 FreshTy(v) => write!(f, "FreshTy({v:?})"),
717 FreshIntTy(v) => write!(f, "FreshIntTy({v:?})"),
718 FreshFloatTy(v) => write!(f, "FreshFloatTy({v:?})"),
719 }
720 }
721}
722
723#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
724#[cfg_attr(
725 feature = "nightly",
726 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
727)]
728#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
729pub struct TypeAndMut<I: Interner> {
730 pub ty: I::Ty,
731 pub mutbl: Mutability,
732}
733
734#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
735#[cfg_attr(
736 feature = "nightly",
737 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
738)]
739#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
740pub struct FnSig<I: Interner> {
741 pub inputs_and_output: I::Tys,
742 pub c_variadic: bool,
743 #[type_visitable(ignore)]
744 #[type_foldable(identity)]
745 pub safety: I::Safety,
746 #[type_visitable(ignore)]
747 #[type_foldable(identity)]
748 pub abi: I::Abi,
749}
750
751impl<I: Interner> FnSig<I> {
752 pub fn inputs(self) -> I::FnInputTys {
753 self.inputs_and_output.inputs()
754 }
755
756 pub fn output(self) -> I::Ty {
757 self.inputs_and_output.output()
758 }
759
760 pub fn is_fn_trait_compatible(self) -> bool {
761 let FnSig { safety, abi, c_variadic, .. } = self;
762 !c_variadic && safety.is_safe() && abi.is_rust()
763 }
764}
765
766impl<I: Interner> ty::Binder<I, FnSig<I>> {
767 #[inline]
768 pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
769 self.map_bound(|fn_sig| fn_sig.inputs())
770 }
771
772 #[inline]
773 #[track_caller]
774 pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
775 self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap())
776 }
777
778 pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
779 self.map_bound(|fn_sig| fn_sig.inputs_and_output)
780 }
781
782 #[inline]
783 pub fn output(self) -> ty::Binder<I, I::Ty> {
784 self.map_bound(|fn_sig| fn_sig.output())
785 }
786
787 pub fn c_variadic(self) -> bool {
788 self.skip_binder().c_variadic
789 }
790
791 pub fn safety(self) -> I::Safety {
792 self.skip_binder().safety
793 }
794
795 pub fn abi(self) -> I::Abi {
796 self.skip_binder().abi
797 }
798
799 pub fn is_fn_trait_compatible(&self) -> bool {
800 self.skip_binder().is_fn_trait_compatible()
801 }
802
803 pub fn split(self) -> (ty::Binder<I, FnSigTys<I>>, FnHeader<I>) {
805 let hdr =
806 FnHeader { c_variadic: self.c_variadic(), safety: self.safety(), abi: self.abi() };
807 (self.map_bound(|sig| FnSigTys { inputs_and_output: sig.inputs_and_output }), hdr)
808 }
809}
810
811impl<I: Interner> fmt::Debug for FnSig<I> {
812 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
813 let sig = self;
814 let FnSig { inputs_and_output: _, c_variadic, safety, abi } = sig;
815
816 write!(f, "{}", safety.prefix_str())?;
817 if !abi.is_rust() {
818 write!(f, "extern \"{abi:?}\" ")?;
819 }
820
821 write!(f, "fn(")?;
822 let inputs = sig.inputs();
823 for (i, ty) in inputs.iter().enumerate() {
824 if i > 0 {
825 write!(f, ", ")?;
826 }
827 write!(f, "{ty:?}")?;
828 }
829 if *c_variadic {
830 if inputs.is_empty() {
831 write!(f, "...")?;
832 } else {
833 write!(f, ", ...")?;
834 }
835 }
836 write!(f, ")")?;
837
838 let output = sig.output();
839 match output.kind() {
840 Tuple(list) if list.is_empty() => Ok(()),
841 _ => write!(f, " -> {:?}", sig.output()),
842 }
843 }
844}
845
846#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
849#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
850#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
851pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>);
852
853impl<I: Interner> From<ty::Binder<I, I::Ty>> for UnsafeBinderInner<I> {
854 fn from(value: ty::Binder<I, I::Ty>) -> Self {
855 UnsafeBinderInner(value)
856 }
857}
858
859impl<I: Interner> From<UnsafeBinderInner<I>> for ty::Binder<I, I::Ty> {
860 fn from(value: UnsafeBinderInner<I>) -> Self {
861 value.0
862 }
863}
864
865impl<I: Interner> fmt::Debug for UnsafeBinderInner<I> {
866 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
867 self.0.fmt(f)
868 }
869}
870
871impl<I: Interner> Deref for UnsafeBinderInner<I> {
872 type Target = ty::Binder<I, I::Ty>;
873
874 fn deref(&self) -> &Self::Target {
875 &self.0
876 }
877}
878
879#[cfg(feature = "nightly")]
880impl<I: Interner, E: rustc_serialize::Encoder> rustc_serialize::Encodable<E>
881 for UnsafeBinderInner<I>
882where
883 I::Ty: rustc_serialize::Encodable<E>,
884 I::BoundVarKinds: rustc_serialize::Encodable<E>,
885{
886 fn encode(&self, e: &mut E) {
887 self.bound_vars().encode(e);
888 self.as_ref().skip_binder().encode(e);
889 }
890}
891
892#[cfg(feature = "nightly")]
893impl<I: Interner, D: rustc_serialize::Decoder> rustc_serialize::Decodable<D>
894 for UnsafeBinderInner<I>
895where
896 I::Ty: TypeVisitable<I> + rustc_serialize::Decodable<D>,
897 I::BoundVarKinds: rustc_serialize::Decodable<D>,
898{
899 fn decode(decoder: &mut D) -> Self {
900 let bound_vars = rustc_serialize::Decodable::decode(decoder);
901 UnsafeBinderInner(ty::Binder::bind_with_vars(
902 rustc_serialize::Decodable::decode(decoder),
903 bound_vars,
904 ))
905 }
906}
907
908#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
910#[cfg_attr(
911 feature = "nightly",
912 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
913)]
914#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
915pub struct FnSigTys<I: Interner> {
916 pub inputs_and_output: I::Tys,
917}
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, Eq, Hash; I: Interner)]
962#[cfg_attr(
963 feature = "nightly",
964 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
965)]
966#[derive(TypeVisitable_Generic, 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
973#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
974#[cfg_attr(
975 feature = "nightly",
976 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
977)]
978#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
979pub struct CoroutineWitnessTypes<I: Interner> {
980 pub types: I::Tys,
981 pub assumptions: I::RegionAssumptions,
982}