aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src
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
parent23d7dbfa5e7ba2cebf8c3f79b5d31285d79c1527 (diff)
Lift FnPointer into a struct
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r--crates/hir_ty/src/display.rs12
-rw-r--r--crates/hir_ty/src/infer/coerce.rs4
-rw-r--r--crates/hir_ty/src/infer/expr.rs15
-rw-r--r--crates/hir_ty/src/lib.rs80
-rw-r--r--crates/hir_ty/src/lower.rs20
-rw-r--r--crates/hir_ty/src/method_resolution.rs10
-rw-r--r--crates/hir_ty/src/traits/chalk.rs5
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs28
8 files changed, 93 insertions, 81 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 4a25a49e3..179f7ff44 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -3,8 +3,8 @@
3use std::{borrow::Cow, fmt}; 3use std::{borrow::Cow, fmt};
4 4
5use crate::{ 5use crate::{
6 db::HirDatabase, primitive, utils::generics, CallableDefId, FnSig, GenericPredicate, Lifetime, 6 db::HirDatabase, primitive, utils::generics, CallableDefId, CallableSig, GenericPredicate,
7 Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, TraitRef, Ty, 7 Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, TraitRef, Ty,
8}; 8};
9use arrayvec::ArrayVec; 9use arrayvec::ArrayVec;
10use hir_def::{ 10use hir_def::{
@@ -341,8 +341,8 @@ impl HirDisplay for Ty {
341 write!(f, ")")?; 341 write!(f, ")")?;
342 } 342 }
343 } 343 }
344 Ty::FnPtr { is_varargs, substs, .. } => { 344 Ty::Function(fn_ptr) => {
345 let sig = FnSig::from_fn_ptr_substs(&substs, *is_varargs); 345 let sig = CallableSig::from_fn_ptr(fn_ptr);
346 sig.hir_fmt(f)?; 346 sig.hir_fmt(f)?;
347 } 347 }
348 Ty::FnDef(def, parameters) => { 348 Ty::FnDef(def, parameters) => {
@@ -494,7 +494,7 @@ impl HirDisplay for Ty {
494 } 494 }
495 } 495 }
496 } 496 }
497 Ty::Closure { substs, .. } => { 497 Ty::Closure(.., substs) => {
498 let sig = substs[0].callable_sig(f.db); 498 let sig = substs[0].callable_sig(f.db);
499 if let Some(sig) = sig { 499 if let Some(sig) = sig {
500 if sig.params().is_empty() { 500 if sig.params().is_empty() {
@@ -571,7 +571,7 @@ impl HirDisplay for Ty {
571 } 571 }
572} 572}
573 573
574impl HirDisplay for FnSig { 574impl HirDisplay for CallableSig {
575 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 575 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
576 write!(f, "fn(")?; 576 write!(f, "fn(")?;
577 f.write_joined(self.params(), ", ")?; 577 f.write_joined(self.params(), ", ")?;
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index cd5fb3252..4cca35904 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -89,14 +89,14 @@ impl<'a> InferenceContext<'a> {
89 | (Ty::Ref(Mutability::Shared, ..), Ty::Ref(Mutability::Mut, ..)) => return false, 89 | (Ty::Ref(Mutability::Shared, ..), Ty::Ref(Mutability::Mut, ..)) => return false,
90 90
91 // `{function_type}` -> `fn()` 91 // `{function_type}` -> `fn()`
92 (Ty::FnDef(..), Ty::FnPtr { .. }) => match from_ty.callable_sig(self.db) { 92 (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) {
93 None => return false, 93 None => return false,
94 Some(sig) => { 94 Some(sig) => {
95 from_ty = Ty::fn_ptr(sig); 95 from_ty = Ty::fn_ptr(sig);
96 } 96 }
97 }, 97 },
98 98
99 (Ty::Closure { substs, .. }, Ty::FnPtr { .. }) => { 99 (Ty::Closure(.., substs), Ty::Function { .. }) => {
100 from_ty = substs[0].clone(); 100 from_ty = substs[0].clone();
101 } 101 }
102 102
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 13240f790..b75d32b85 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -18,8 +18,8 @@ use crate::{
18 primitive::{self, UintTy}, 18 primitive::{self, UintTy},
19 traits::{FnTrait, InEnvironment}, 19 traits::{FnTrait, InEnvironment},
20 utils::{generics, variant_data, Generics}, 20 utils::{generics, variant_data, Generics},
21 Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, Scalar, Substs, 21 Binders, CallableDefId, FnPointer, FnSig, InferTy, Mutability, Obligation, OpaqueTyId, Rawness,
22 TraitRef, Ty, 22 Scalar, Substs, TraitRef, Ty,
23}; 23};
24 24
25use super::{ 25use super::{
@@ -247,13 +247,12 @@ impl<'a> InferenceContext<'a> {
247 None => self.table.new_type_var(), 247 None => self.table.new_type_var(),
248 }; 248 };
249 sig_tys.push(ret_ty.clone()); 249 sig_tys.push(ret_ty.clone());
250 let sig_ty = Ty::FnPtr { 250 let sig_ty = Ty::Function(FnPointer {
251 num_args: sig_tys.len() as u16 - 1, 251 num_args: sig_tys.len() - 1,
252 is_varargs: false, 252 sig: FnSig { variadic: false },
253 substs: Substs(sig_tys.clone().into()), 253 substs: Substs(sig_tys.clone().into()),
254 }; 254 });
255 let closure_ty = 255 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty));
256 Ty::Closure { def: self.owner, expr: tgt_expr, substs: Substs::single(sig_ty) };
257 256
258 // Eagerly try to relate the closure type with the expected 257 // Eagerly try to relate the closure type with the expected
259 // type, otherwise we often won't have enough information to 258 // type, otherwise we often won't have enough information to
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 }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 84734bc0b..44bd95a9a 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -31,9 +31,9 @@ use crate::{
31 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 31 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
32 make_mut_slice, variant_data, 32 make_mut_slice, variant_data,
33 }, 33 },
34 Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig, 34 Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, OpaqueTy,
35 ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs, 35 OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
36 TraitEnvironment, TraitRef, Ty, TypeWalk, 36 ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
37}; 37};
38 38
39#[derive(Debug)] 39#[derive(Debug)]
@@ -173,8 +173,12 @@ impl Ty {
173 } 173 }
174 TypeRef::Placeholder => Ty::Unknown, 174 TypeRef::Placeholder => Ty::Unknown,
175 TypeRef::Fn(params, is_varargs) => { 175 TypeRef::Fn(params, is_varargs) => {
176 let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); 176 let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect());
177 Ty::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs, substs: sig } 177 Ty::Function(FnPointer {
178 num_args: substs.len() - 1,
179 sig: FnSig { variadic: *is_varargs },
180 substs,
181 })
178 } 182 }
179 TypeRef::DynTrait(bounds) => { 183 TypeRef::DynTrait(bounds) => {
180 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 184 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
@@ -1010,7 +1014,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1010 let ret = Ty::from_hir(&ctx_ret, &data.ret_type); 1014 let ret = Ty::from_hir(&ctx_ret, &data.ret_type);
1011 let generics = generics(db.upcast(), def.into()); 1015 let generics = generics(db.upcast(), def.into());
1012 let num_binders = generics.len(); 1016 let num_binders = generics.len();
1013 Binders::new(num_binders, FnSig::from_params_and_return(params, ret, data.is_varargs)) 1017 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs))
1014} 1018}
1015 1019
1016/// Build the declared type of a function. This should not need to look at the 1020/// Build the declared type of a function. This should not need to look at the
@@ -1050,7 +1054,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
1050 let params = 1054 let params =
1051 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 1055 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1052 let ret = type_for_adt(db, def.into()); 1056 let ret = type_for_adt(db, def.into());
1053 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) 1057 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1054} 1058}
1055 1059
1056/// Build the type of a tuple struct constructor. 1060/// Build the type of a tuple struct constructor.
@@ -1074,7 +1078,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
1074 let params = 1078 let params =
1075 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 1079 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1076 let ret = type_for_adt(db, def.parent.into()); 1080 let ret = type_for_adt(db, def.parent.into());
1077 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) 1081 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1078} 1082}
1079 1083
1080/// Build the type of a tuple enum variant constructor. 1084/// Build the type of a tuple enum variant constructor.
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index ff8ce5599..c8a0ad5f1 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -18,8 +18,8 @@ use crate::{
18 db::HirDatabase, 18 db::HirDatabase,
19 primitive::{self, FloatTy, IntTy, UintTy}, 19 primitive::{self, FloatTy, IntTy, UintTy},
20 utils::all_super_traits, 20 utils::all_super_traits,
21 Canonical, DebruijnIndex, InEnvironment, Scalar, Substs, TraitEnvironment, TraitRef, Ty, 21 Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, TraitEnvironment,
22 TyKind, TypeWalk, 22 TraitRef, Ty, TyKind, TypeWalk,
23}; 23};
24 24
25/// This is used as a key for indexing impls. 25/// This is used as a key for indexing impls.
@@ -35,7 +35,7 @@ pub enum TyFingerprint {
35 Dyn(TraitId), 35 Dyn(TraitId),
36 Tuple(usize), 36 Tuple(usize),
37 ForeignType(TypeAliasId), 37 ForeignType(TypeAliasId),
38 FnPtr { num_args: u16, is_varargs: bool }, 38 FnPtr(usize, FnSig),
39} 39}
40 40
41impl TyFingerprint { 41impl TyFingerprint {
@@ -53,9 +53,7 @@ impl TyFingerprint {
53 &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), 53 &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality),
54 &Ty::RawPtr(mutability, ..) => TyFingerprint::RawPtr(mutability), 54 &Ty::RawPtr(mutability, ..) => TyFingerprint::RawPtr(mutability),
55 &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), 55 &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
56 &Ty::FnPtr { num_args, is_varargs, .. } => { 56 &Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig),
57 TyFingerprint::FnPtr { num_args, is_varargs }
58 }
59 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, 57 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
60 _ => return None, 58 _ => return None,
61 }; 59 };
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index c53e327da..3f5f5091f 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -19,7 +19,7 @@ use crate::{
19 display::HirDisplay, 19 display::HirDisplay,
20 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 20 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
21 utils::generics, 21 utils::generics,
22 BoundVar, CallableDefId, DebruijnIndex, FnSig, GenericPredicate, ProjectionPredicate, 22 BoundVar, CallableDefId, CallableSig, DebruijnIndex, GenericPredicate, ProjectionPredicate,
23 ProjectionTy, Substs, TraitRef, Ty, 23 ProjectionTy, Substs, TraitRef, Ty,
24}; 24};
25use mapping::{ 25use mapping::{
@@ -286,9 +286,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
286 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { 286 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
287 let sig_ty: Ty = 287 let sig_ty: Ty =
288 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); 288 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
289 let sig = FnSig::from_fn_ptr_substs( 289 let sig = CallableSig::from_substs(
290 &sig_ty.substs().expect("first closure param should be fn ptr"), 290 &sig_ty.substs().expect("first closure param should be fn ptr"),
291 false,
292 ); 291 );
293 let io = rust_ir::FnDefInputsAndOutputDatum { 292 let io = rust_ir::FnDefInputsAndOutputDatum {
294 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), 293 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(),
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index c17c19638..60d74e21a 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -16,8 +16,8 @@ use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 primitive::UintTy, 17 primitive::UintTy,
18 traits::{Canonical, Obligation}, 18 traits::{Canonical, Obligation},
19 CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, ProjectionPredicate, 19 CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId,
20 ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, 20 ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind,
21}; 21};
22 22
23use super::interner::*; 23use super::interner::*;
@@ -29,15 +29,11 @@ impl ToChalk for Ty {
29 match self { 29 match self {
30 Ty::Ref(m, parameters) => ref_to_chalk(db, m, parameters), 30 Ty::Ref(m, parameters) => ref_to_chalk(db, m, parameters),
31 Ty::Array(parameters) => array_to_chalk(db, parameters), 31 Ty::Array(parameters) => array_to_chalk(db, parameters),
32 Ty::FnPtr { num_args: _, is_varargs, substs } => { 32 Ty::Function(FnPointer { sig: FnSig { variadic }, substs, .. }) => {
33 let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner)); 33 let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner));
34 chalk_ir::TyKind::Function(chalk_ir::FnPointer { 34 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
35 num_binders: 0, 35 num_binders: 0,
36 sig: chalk_ir::FnSig { 36 sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic },
37 abi: (),
38 safety: chalk_ir::Safety::Safe,
39 variadic: is_varargs,
40 },
41 substitution, 37 substitution,
42 }) 38 })
43 .intern(&Interner) 39 .intern(&Interner)
@@ -82,7 +78,7 @@ impl ToChalk for Ty {
82 } 78 }
83 Ty::Never => chalk_ir::TyKind::Never.intern(&Interner), 79 Ty::Never => chalk_ir::TyKind::Never.intern(&Interner),
84 80
85 Ty::Closure { def, expr, substs } => { 81 Ty::Closure(def, expr, substs) => {
86 let closure_id = db.intern_closure((def, expr)); 82 let closure_id = db.intern_closure((def, expr));
87 let substitution = substs.to_chalk(db); 83 let substitution = substs.to_chalk(db);
88 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) 84 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner)
@@ -164,15 +160,15 @@ impl ToChalk for Ty {
164 .. 160 ..
165 }) => { 161 }) => {
166 assert_eq!(num_binders, 0); 162 assert_eq!(num_binders, 0);
167 let parameters: Substs = from_chalk( 163 let substs: Substs = from_chalk(
168 db, 164 db,
169 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), 165 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
170 ); 166 );
171 Ty::FnPtr { 167 Ty::Function(FnPointer {
172 num_args: (parameters.len() - 1) as u16, 168 num_args: (substs.len() - 1),
173 is_varargs: variadic, 169 sig: FnSig { variadic },
174 substs: parameters, 170 substs,
175 } 171 })
176 } 172 }
177 chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx), 173 chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx),
178 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown, 174 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown,
@@ -218,7 +214,7 @@ impl ToChalk for Ty {
218 chalk_ir::TyKind::Closure(id, subst) => { 214 chalk_ir::TyKind::Closure(id, subst) => {
219 let id: crate::db::ClosureId = id.into(); 215 let id: crate::db::ClosureId = id.into();
220 let (def, expr) = db.lookup_intern_closure(id); 216 let (def, expr) = db.lookup_intern_closure(id);
221 Ty::Closure { def, expr, substs: from_chalk(db, subst) } 217 Ty::Closure(def, expr, from_chalk(db, subst))
222 } 218 }
223 219
224 chalk_ir::TyKind::Foreign(foreign_def_id) => { 220 chalk_ir::TyKind::Foreign(foreign_def_id) => {