diff options
author | Florian Diebold <[email protected]> | 2019-09-07 20:03:03 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-09-24 22:05:12 +0100 |
commit | 619a8185a607b216c64b58d230c3949ccef98a37 (patch) | |
tree | 7d0691791f25b351248545ca8d415c4a3734a346 /crates/ra_hir/src/ty | |
parent | 36fb3f53d712a11b7e3fc4bbd92094d1c8f19522 (diff) |
Give closures types
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 30 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 4 |
3 files changed, 36 insertions, 20 deletions
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, |