aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-09-07 20:03:03 +0100
committerFlorian Diebold <[email protected]>2019-09-24 22:05:12 +0100
commit619a8185a607b216c64b58d230c3949ccef98a37 (patch)
tree7d0691791f25b351248545ca8d415c4a3734a346
parent36fb3f53d712a11b7e3fc4bbd92094d1c8f19522 (diff)
Give closures types
-rw-r--r--crates/ra_hir/src/code_model.rs20
-rw-r--r--crates/ra_hir/src/ty.rs23
-rw-r--r--crates/ra_hir/src/ty/infer.rs22
-rw-r--r--crates/ra_hir/src/ty/tests.rs30
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs4
5 files changed, 78 insertions, 21 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 12399c6ac..99c247a0b 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -551,6 +551,14 @@ impl DefWithBody {
551 DefWithBody::Static(s) => s.resolver(db), 551 DefWithBody::Static(s) => s.resolver(db),
552 } 552 }
553 } 553 }
554
555 pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
556 match self {
557 DefWithBody::Const(c) => c.krate(db),
558 DefWithBody::Function(f) => f.krate(db),
559 DefWithBody::Static(s) => s.krate(db),
560 }
561 }
554} 562}
555 563
556pub trait HasBody: Copy { 564pub trait HasBody: Copy {
@@ -671,6 +679,10 @@ impl Function {
671 self.id.module(db) 679 self.id.module(db)
672 } 680 }
673 681
682 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
683 self.module(db).krate(db)
684 }
685
674 pub fn name(self, db: &impl HirDatabase) -> Name { 686 pub fn name(self, db: &impl HirDatabase) -> Name {
675 self.data(db).name.clone() 687 self.data(db).name.clone()
676 } 688 }
@@ -745,6 +757,10 @@ impl Const {
745 self.id.module(db) 757 self.id.module(db)
746 } 758 }
747 759
760 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
761 self.module(db).krate(db)
762 }
763
748 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { 764 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> {
749 db.const_data(self) 765 db.const_data(self)
750 } 766 }
@@ -824,6 +840,10 @@ impl Static {
824 self.id.module(db) 840 self.id.module(db)
825 } 841 }
826 842
843 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
844 self.module(db).krate(db)
845 }
846
827 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { 847 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> {
828 db.static_data(self) 848 db.static_data(self)
829 } 849 }
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 36bfb10ce..e6ecbe1ea 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -16,7 +16,10 @@ use std::ops::Deref;
16use std::sync::Arc; 16use std::sync::Arc;
17use std::{fmt, mem}; 17use std::{fmt, mem};
18 18
19use crate::{db::HirDatabase, type_ref::Mutability, Adt, GenericParams, Name, Trait, TypeAlias}; 19use crate::{
20 db::HirDatabase, expr::ExprId, type_ref::Mutability, Adt, DefWithBody, GenericParams, Name,
21 Trait, TypeAlias,
22};
20use display::{HirDisplay, HirFormatter}; 23use display::{HirDisplay, HirFormatter};
21 24
22pub(crate) use autoderef::autoderef; 25pub(crate) use autoderef::autoderef;
@@ -100,6 +103,12 @@ pub enum TypeCtor {
100 /// couldn't find a better representation. In that case, we generate 103 /// couldn't find a better representation. In that case, we generate
101 /// an **application type** like `(Iterator::Item)<T>`. 104 /// an **application type** like `(Iterator::Item)<T>`.
102 AssociatedType(TypeAlias), 105 AssociatedType(TypeAlias),
106
107 /// The type of a specific closure.
108 ///
109 /// The closure signature is stored in a `FnPtr` type in the first type
110 /// parameter.
111 Closure { def: DefWithBody, expr: ExprId },
103} 112}
104 113
105/// A nominal type with (maybe 0) type parameters. This might be a primitive 114/// A nominal type with (maybe 0) type parameters. This might be a primitive
@@ -481,6 +490,10 @@ impl Ty {
481 let sig = db.callable_item_signature(def); 490 let sig = db.callable_item_signature(def);
482 Some(sig.subst(&a_ty.parameters)) 491 Some(sig.subst(&a_ty.parameters))
483 } 492 }
493 TypeCtor::Closure { .. } => {
494 let sig_param = &a_ty.parameters[0];
495 sig_param.callable_sig(db)
496 }
484 _ => None, 497 _ => None,
485 }, 498 },
486 _ => None, 499 _ => None,
@@ -720,6 +733,14 @@ impl HirDisplay for ApplicationTy {
720 write!(f, ">")?; 733 write!(f, ">")?;
721 } 734 }
722 } 735 }
736 TypeCtor::Closure { .. } => {
737 let sig = self.parameters[0]
738 .callable_sig(f.db)
739 .expect("first closure parameter should contain signature");
740 write!(f, "|")?;
741 f.write_joined(sig.params(), ", ")?;
742 write!(f, "| -> {}", sig.ret().display(f.db))?;
743 }
723 } 744 }
724 Ok(()) 745 Ok(())
725 } 746 }
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 81a8623bf..c04f2a0c4 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -885,18 +885,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
885 Expr::Lambda { body, args, arg_types } => { 885 Expr::Lambda { body, args, arg_types } => {
886 assert_eq!(args.len(), arg_types.len()); 886 assert_eq!(args.len(), arg_types.len());
887 887
888 let mut sig_tys = Vec::new();
889
888 for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { 890 for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) {
889 let expected = if let Some(type_ref) = arg_type { 891 let expected = if let Some(type_ref) = arg_type {
890 self.make_ty(type_ref) 892 self.make_ty(type_ref)
891 } else { 893 } else {
892 Ty::Unknown 894 Ty::Unknown
893 }; 895 };
894 self.infer_pat(*arg_pat, &expected, BindingMode::default()); 896 let arg_ty = self.infer_pat(*arg_pat, &expected, BindingMode::default());
897 sig_tys.push(arg_ty);
895 } 898 }
896 899
897 // FIXME: infer lambda type etc. 900 // add return type
898 let _body_ty = self.infer_expr(*body, &Expectation::none()); 901 let ret_ty = self.new_type_var();
899 Ty::Unknown 902 sig_tys.push(ret_ty.clone());
903 let sig_ty = Ty::apply(
904 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 },
905 sig_tys.into(),
906 );
907 let closure_ty = Ty::apply_one(
908 TypeCtor::Closure { def: self.body.owner(), expr: tgt_expr },
909 sig_ty,
910 );
911
912 self.infer_expr(*body, &Expectation::has_type(ret_ty));
913 closure_ty
900 } 914 }
901 Expr::Call { callee, args } => { 915 Expr::Call { callee, args } => {
902 let callee_ty = self.infer_expr(*callee, &Expectation::none()); 916 let callee_ty = self.infer_expr(*callee, &Expectation::none());
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 3ac1fbdd5..eb8770ec4 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -1077,7 +1077,6 @@ fn test(x: &i32) {
1077} 1077}
1078"#), 1078"#),
1079 @r###" 1079 @r###"
1080
1081 [9; 10) 'x': &i32 1080 [9; 10) 'x': &i32
1082 [18; 369) '{ ...o_x; }': () 1081 [18; 369) '{ ...o_x; }': ()
1083 [28; 29) 'y': &i32 1082 [28; 29) 'y': &i32
@@ -1107,8 +1106,8 @@ fn test(x: &i32) {
1107 [177; 205) '{ ... }': () 1106 [177; 205) '{ ... }': ()
1108 [191; 192) 'h': {unknown} 1107 [191; 192) 'h': {unknown}
1109 [195; 198) 'val': {unknown} 1108 [195; 198) 'val': {unknown}
1110 [215; 221) 'lambda': {unknown} 1109 [215; 221) 'lambda': |u64, u64, i32| -> i32
1111 [224; 256) '|a: u6...b; c }': {unknown} 1110 [224; 256) '|a: u6...b; c }': |u64, u64, i32| -> i32
1112 [225; 226) 'a': u64 1111 [225; 226) 'a': u64
1113 [233; 234) 'b': u64 1112 [233; 234) 'b': u64
1114 [236; 237) 'c': i32 1113 [236; 237) 'c': i32
@@ -2836,12 +2835,11 @@ fn test() -> u64 {
2836} 2835}
2837"#), 2836"#),
2838 @r###" 2837 @r###"
2839
2840 [44; 102) '{ ...0(2) }': u64 2838 [44; 102) '{ ...0(2) }': u64
2841 [54; 55) 'a': S 2839 [54; 55) 'a': S
2842 [58; 59) 'S': S(fn(u32) -> u64) -> S 2840 [58; 59) 'S': S(fn(u32) -> u64) -> S
2843 [58; 68) 'S(|i| 2*i)': S 2841 [58; 68) 'S(|i| 2*i)': S
2844 [60; 67) '|i| 2*i': fn(u32) -> u64 2842 [60; 67) '|i| 2*i': |i32| -> i32
2845 [61; 62) 'i': i32 2843 [61; 62) 'i': i32
2846 [64; 65) '2': i32 2844 [64; 65) '2': i32
2847 [64; 67) '2*i': i32 2845 [64; 67) '2*i': i32
@@ -4019,20 +4017,20 @@ fn test() {
4019 [188; 192) '1i32': i32 4017 [188; 192) '1i32': i32
4020 [199; 200) 'x': Option<i32> 4018 [199; 200) 'x': Option<i32>
4021 [199; 215) 'x.map(...v + 1)': {unknown} 4019 [199; 215) 'x.map(...v + 1)': {unknown}
4022 [205; 214) '|v| v + 1': {unknown} 4020 [205; 214) '|v| v + 1': |{unknown}| -> i32
4023 [206; 207) 'v': {unknown} 4021 [206; 207) 'v': {unknown}
4024 [209; 210) 'v': {unknown} 4022 [209; 210) 'v': {unknown}
4025 [209; 214) 'v + 1': i32 4023 [209; 214) 'v + 1': i32
4026 [213; 214) '1': i32 4024 [213; 214) '1': i32
4027 [221; 222) 'x': Option<i32> 4025 [221; 222) 'x': Option<i32>
4028 [221; 237) 'x.map(... 1u64)': {unknown} 4026 [221; 237) 'x.map(... 1u64)': {unknown}
4029 [227; 236) '|_v| 1u64': {unknown} 4027 [227; 236) '|_v| 1u64': |{unknown}| -> u64
4030 [228; 230) '_v': {unknown} 4028 [228; 230) '_v': {unknown}
4031 [232; 236) '1u64': u64 4029 [232; 236) '1u64': u64
4032 [247; 248) 'y': Option<i64> 4030 [247; 248) 'y': Option<i64>
4033 [264; 265) 'x': Option<i32> 4031 [264; 265) 'x': Option<i32>
4034 [264; 277) 'x.map(|_v| 1)': Option<i64> 4032 [264; 277) 'x.map(|_v| 1)': Option<i64>
4035 [270; 276) '|_v| 1': {unknown} 4033 [270; 276) '|_v| 1': |{unknown}| -> i32
4036 [271; 273) '_v': {unknown} 4034 [271; 273) '_v': {unknown}
4037 [275; 276) '1': i32 4035 [275; 276) '1': i32
4038 "### 4036 "###
@@ -4060,17 +4058,17 @@ fn test<F: FnOnce(u32) -> u64>(f: F) {
4060 [85; 86) 'f': F 4058 [85; 86) 'f': F
4061 [85; 89) 'f(1)': {unknown} 4059 [85; 89) 'f(1)': {unknown}
4062 [87; 88) '1': i32 4060 [87; 88) '1': i32
4063 [99; 100) 'g': {unknown} 4061 [99; 100) 'g': |u64| -> i32
4064 [103; 112) '|v| v + 1': {unknown} 4062 [103; 112) '|v| v + 1': |u64| -> i32
4065 [104; 105) 'v': {unknown} 4063 [104; 105) 'v': u64
4066 [107; 108) 'v': {unknown} 4064 [107; 108) 'v': u64
4067 [107; 112) 'v + 1': i32 4065 [107; 112) 'v + 1': i32
4068 [111; 112) '1': i32 4066 [111; 112) '1': i32
4069 [118; 119) 'g': {unknown} 4067 [118; 119) 'g': |u64| -> i32
4070 [118; 125) 'g(1u64)': {unknown} 4068 [118; 125) 'g(1u64)': i32
4071 [120; 124) '1u64': u64 4069 [120; 124) '1u64': u64
4072 [135; 136) 'h': {unknown} 4070 [135; 136) 'h': |u128| -> u128
4073 [139; 152) '|v| 1u128 + v': {unknown} 4071 [139; 152) '|v| 1u128 + v': |u128| -> u128
4074 [140; 141) 'v': u128 4072 [140; 141) 'v': u128
4075 [143; 148) '1u128': u128 4073 [143; 148) '1u128': u128
4076 [143; 152) '1u128 + v': u128 4074 [143; 152) '1u128 + v': u128
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 462156021..34e623931 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -571,6 +571,10 @@ pub(crate) fn struct_datum_query(
571 type_alias.krate(db) != Some(krate), 571 type_alias.krate(db) != Some(krate),
572 ) 572 )
573 } 573 }
574 TypeCtor::Closure { def, .. } => {
575 let upstream = def.krate(db) != Some(krate);
576 (1, vec![], upstream)
577 }
574 }; 578 };
575 let flags = chalk_rust_ir::StructFlags { 579 let flags = chalk_rust_ir::StructFlags {
576 upstream, 580 upstream,