aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-02-28 21:12:07 +0000
committerLukas Wirth <[email protected]>2021-02-28 22:53:21 +0000
commit407196b8c0f23e3ddc26e789b84542b1fd9b0eb8 (patch)
tree8f088d09b8a7a017335b90aefbc33211568eb4c3 /crates/hir_ty/src/lib.rs
parent23d7dbfa5e7ba2cebf8c3f79b5d31285d79c1527 (diff)
Lift FnPointer into a struct
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs80
1 files changed, 48 insertions, 32 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 4c0ebcfe3..1abb0440f 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -99,6 +99,18 @@ impl TypeWalk for ProjectionTy {
99 } 99 }
100} 100}
101 101
102#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
103pub struct FnSig {
104 pub variadic: bool,
105}
106
107#[derive(Clone, PartialEq, Eq, Debug, Hash)]
108pub struct FnPointer {
109 pub num_args: usize,
110 pub sig: FnSig,
111 pub substs: Substs,
112}
113
102/// A type. 114/// A type.
103/// 115///
104/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents 116/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
@@ -166,7 +178,7 @@ pub enum Ty {
166 /// 178 ///
167 /// The closure signature is stored in a `FnPtr` type in the first type 179 /// The closure signature is stored in a `FnPtr` type in the first type
168 /// parameter. 180 /// parameter.
169 Closure { def: DefWithBodyId, expr: ExprId, substs: Substs }, 181 Closure(DefWithBodyId, ExprId, Substs),
170 182
171 /// Represents a foreign type declared in external blocks. 183 /// Represents a foreign type declared in external blocks.
172 ForeignType(TypeAliasId), 184 ForeignType(TypeAliasId),
@@ -179,8 +191,7 @@ pub enum Ty {
179 /// fn foo() -> i32 { 1 } 191 /// fn foo() -> i32 { 1 }
180 /// let bar: fn() -> i32 = foo; 192 /// let bar: fn() -> i32 = foo;
181 /// ``` 193 /// ```
182 // FIXME make this a Ty variant like in Chalk 194 Function(FnPointer),
183 FnPtr { num_args: u16, is_varargs: bool, substs: Substs },
184 195
185 /// A "projection" type corresponds to an (unnormalized) 196 /// A "projection" type corresponds to an (unnormalized)
186 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 197 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
@@ -535,22 +546,29 @@ pub enum TyKind {
535/// A function signature as seen by type inference: Several parameter types and 546/// A function signature as seen by type inference: Several parameter types and
536/// one return type. 547/// one return type.
537#[derive(Clone, PartialEq, Eq, Debug)] 548#[derive(Clone, PartialEq, Eq, Debug)]
538pub struct FnSig { 549pub struct CallableSig {
539 params_and_return: Arc<[Ty]>, 550 params_and_return: Arc<[Ty]>,
540 is_varargs: bool, 551 is_varargs: bool,
541} 552}
542 553
543/// A polymorphic function signature. 554/// A polymorphic function signature.
544pub type PolyFnSig = Binders<FnSig>; 555pub type PolyFnSig = Binders<CallableSig>;
545 556
546impl FnSig { 557impl CallableSig {
547 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig { 558 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig {
548 params.push(ret); 559 params.push(ret);
549 FnSig { params_and_return: params.into(), is_varargs } 560 CallableSig { params_and_return: params.into(), is_varargs }
561 }
562
563 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
564 CallableSig {
565 params_and_return: Arc::clone(&fn_ptr.substs.0),
566 is_varargs: fn_ptr.sig.variadic,
567 }
550 } 568 }
551 569
552 pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { 570 pub fn from_substs(substs: &Substs) -> CallableSig {
553 FnSig { params_and_return: Arc::clone(&substs.0), is_varargs } 571 CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false }
554 } 572 }
555 573
556 pub fn params(&self) -> &[Ty] { 574 pub fn params(&self) -> &[Ty] {
@@ -562,7 +580,7 @@ impl FnSig {
562 } 580 }
563} 581}
564 582
565impl TypeWalk for FnSig { 583impl TypeWalk for CallableSig {
566 fn walk(&self, f: &mut impl FnMut(&Ty)) { 584 fn walk(&self, f: &mut impl FnMut(&Ty)) {
567 for t in self.params_and_return.iter() { 585 for t in self.params_and_return.iter() {
568 t.walk(f); 586 t.walk(f);
@@ -585,12 +603,12 @@ impl Ty {
585 Ty::Tuple(0, Substs::empty()) 603 Ty::Tuple(0, Substs::empty())
586 } 604 }
587 605
588 pub fn fn_ptr(sig: FnSig) -> Self { 606 pub fn fn_ptr(sig: CallableSig) -> Self {
589 Ty::FnPtr { 607 Ty::Function(FnPointer {
590 num_args: sig.params().len() as u16, 608 num_args: sig.params().len(),
591 is_varargs: sig.is_varargs, 609 sig: FnSig { variadic: sig.is_varargs },
592 substs: Substs(sig.params_and_return), 610 substs: Substs(sig.params_and_return),
593 } 611 })
594 } 612 }
595 613
596 pub fn builtin(builtin: BuiltinType) -> Self { 614 pub fn builtin(builtin: BuiltinType) -> Self {
@@ -673,7 +691,7 @@ impl Ty {
673 (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, 691 (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
674 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) 692 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..))
675 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, 693 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
676 (Ty::Closure { def, expr, .. }, Ty::Closure { def: def2, expr: expr2, .. }) => { 694 (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => {
677 expr == expr2 && def == def2 695 expr == expr2 && def == def2
678 } 696 }
679 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..)) 697 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
@@ -681,9 +699,9 @@ impl Ty {
681 mutability == mutability2 699 mutability == mutability2
682 } 700 }
683 ( 701 (
684 Ty::FnPtr { num_args, is_varargs, .. }, 702 Ty::Function(FnPointer { num_args, sig, .. }),
685 Ty::FnPtr { num_args: num_args2, is_varargs: is_varargs2, .. }, 703 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
686 ) => num_args == num_args2 && is_varargs == is_varargs2, 704 ) => num_args == num_args2 && sig == sig2,
687 (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2, 705 (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2,
688 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, 706 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true,
689 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, 707 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2,
@@ -722,17 +740,15 @@ impl Ty {
722 } 740 }
723 } 741 }
724 742
725 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { 743 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
726 match self { 744 match self {
727 Ty::FnPtr { is_varargs, substs: parameters, .. } => { 745 Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
728 Some(FnSig::from_fn_ptr_substs(&parameters, *is_varargs))
729 }
730 Ty::FnDef(def, parameters) => { 746 Ty::FnDef(def, parameters) => {
731 let sig = db.callable_item_signature(*def); 747 let sig = db.callable_item_signature(*def);
732 Some(sig.subst(&parameters)) 748 Some(sig.subst(&parameters))
733 } 749 }
734 Ty::Closure { substs: parameters, .. } => { 750 Ty::Closure(.., substs) => {
735 let sig_param = &parameters[0]; 751 let sig_param = &substs[0];
736 sig_param.callable_sig(db) 752 sig_param.callable_sig(db)
737 } 753 }
738 _ => None, 754 _ => None,
@@ -751,11 +767,11 @@ impl Ty {
751 | Ty::RawPtr(_, substs) 767 | Ty::RawPtr(_, substs)
752 | Ty::Ref(_, substs) 768 | Ty::Ref(_, substs)
753 | Ty::FnDef(_, substs) 769 | Ty::FnDef(_, substs)
754 | Ty::FnPtr { substs, .. } 770 | Ty::Function(FnPointer { substs, .. })
755 | Ty::Tuple(_, substs) 771 | Ty::Tuple(_, substs)
756 | Ty::OpaqueType(_, substs) 772 | Ty::OpaqueType(_, substs)
757 | Ty::AssociatedType(_, substs) 773 | Ty::AssociatedType(_, substs)
758 | Ty::Closure { substs, .. } => { 774 | Ty::Closure(.., substs) => {
759 assert_eq!(substs.len(), new_substs.len()); 775 assert_eq!(substs.len(), new_substs.len());
760 *substs = new_substs; 776 *substs = new_substs;
761 } 777 }
@@ -774,11 +790,11 @@ impl Ty {
774 | Ty::RawPtr(_, substs) 790 | Ty::RawPtr(_, substs)
775 | Ty::Ref(_, substs) 791 | Ty::Ref(_, substs)
776 | Ty::FnDef(_, substs) 792 | Ty::FnDef(_, substs)
777 | Ty::FnPtr { substs, .. } 793 | Ty::Function(FnPointer { substs, .. })
778 | Ty::Tuple(_, substs) 794 | Ty::Tuple(_, substs)
779 | Ty::OpaqueType(_, substs) 795 | Ty::OpaqueType(_, substs)
780 | Ty::AssociatedType(_, substs) 796 | Ty::AssociatedType(_, substs)
781 | Ty::Closure { substs, .. } => Some(substs), 797 | Ty::Closure(.., substs) => Some(substs),
782 _ => None, 798 _ => None,
783 } 799 }
784 } 800 }
@@ -791,11 +807,11 @@ impl Ty {
791 | Ty::RawPtr(_, substs) 807 | Ty::RawPtr(_, substs)
792 | Ty::Ref(_, substs) 808 | Ty::Ref(_, substs)
793 | Ty::FnDef(_, substs) 809 | Ty::FnDef(_, substs)
794 | Ty::FnPtr { substs, .. } 810 | Ty::Function(FnPointer { substs, .. })
795 | Ty::Tuple(_, substs) 811 | Ty::Tuple(_, substs)
796 | Ty::OpaqueType(_, substs) 812 | Ty::OpaqueType(_, substs)
797 | Ty::AssociatedType(_, substs) 813 | Ty::AssociatedType(_, substs)
798 | Ty::Closure { substs, .. } => Some(substs), 814 | Ty::Closure(.., substs) => Some(substs),
799 _ => None, 815 _ => None,
800 } 816 }
801 } 817 }