From 619a8185a607b216c64b58d230c3949ccef98a37 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 7 Sep 2019 21:03:03 +0200 Subject: Give closures types --- crates/ra_hir/src/ty/infer.rs | 22 ++++++++++++++++++---- crates/ra_hir/src/ty/tests.rs | 30 ++++++++++++++---------------- crates/ra_hir/src/ty/traits/chalk.rs | 4 ++++ 3 files changed, 36 insertions(+), 20 deletions(-) (limited to 'crates/ra_hir/src/ty') 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> { Expr::Lambda { body, args, arg_types } => { assert_eq!(args.len(), arg_types.len()); + let mut sig_tys = Vec::new(); + for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { let expected = if let Some(type_ref) = arg_type { self.make_ty(type_ref) } else { Ty::Unknown }; - self.infer_pat(*arg_pat, &expected, BindingMode::default()); + let arg_ty = self.infer_pat(*arg_pat, &expected, BindingMode::default()); + sig_tys.push(arg_ty); } - // FIXME: infer lambda type etc. - let _body_ty = self.infer_expr(*body, &Expectation::none()); - Ty::Unknown + // add return type + let ret_ty = self.new_type_var(); + sig_tys.push(ret_ty.clone()); + let sig_ty = Ty::apply( + TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, + sig_tys.into(), + ); + let closure_ty = Ty::apply_one( + TypeCtor::Closure { def: self.body.owner(), expr: tgt_expr }, + sig_ty, + ); + + self.infer_expr(*body, &Expectation::has_type(ret_ty)); + closure_ty } Expr::Call { callee, args } => { 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) { } "#), @r###" - [9; 10) 'x': &i32 [18; 369) '{ ...o_x; }': () [28; 29) 'y': &i32 @@ -1107,8 +1106,8 @@ fn test(x: &i32) { [177; 205) '{ ... }': () [191; 192) 'h': {unknown} [195; 198) 'val': {unknown} - [215; 221) 'lambda': {unknown} - [224; 256) '|a: u6...b; c }': {unknown} + [215; 221) 'lambda': |u64, u64, i32| -> i32 + [224; 256) '|a: u6...b; c }': |u64, u64, i32| -> i32 [225; 226) 'a': u64 [233; 234) 'b': u64 [236; 237) 'c': i32 @@ -2836,12 +2835,11 @@ fn test() -> u64 { } "#), @r###" - [44; 102) '{ ...0(2) }': u64 [54; 55) 'a': S [58; 59) 'S': S(fn(u32) -> u64) -> S [58; 68) 'S(|i| 2*i)': S - [60; 67) '|i| 2*i': fn(u32) -> u64 + [60; 67) '|i| 2*i': |i32| -> i32 [61; 62) 'i': i32 [64; 65) '2': i32 [64; 67) '2*i': i32 @@ -4019,20 +4017,20 @@ fn test() { [188; 192) '1i32': i32 [199; 200) 'x': Option [199; 215) 'x.map(...v + 1)': {unknown} - [205; 214) '|v| v + 1': {unknown} + [205; 214) '|v| v + 1': |{unknown}| -> i32 [206; 207) 'v': {unknown} [209; 210) 'v': {unknown} [209; 214) 'v + 1': i32 [213; 214) '1': i32 [221; 222) 'x': Option [221; 237) 'x.map(... 1u64)': {unknown} - [227; 236) '|_v| 1u64': {unknown} + [227; 236) '|_v| 1u64': |{unknown}| -> u64 [228; 230) '_v': {unknown} [232; 236) '1u64': u64 [247; 248) 'y': Option [264; 265) 'x': Option [264; 277) 'x.map(|_v| 1)': Option - [270; 276) '|_v| 1': {unknown} + [270; 276) '|_v| 1': |{unknown}| -> i32 [271; 273) '_v': {unknown} [275; 276) '1': i32 "### @@ -4060,17 +4058,17 @@ fn test u64>(f: F) { [85; 86) 'f': F [85; 89) 'f(1)': {unknown} [87; 88) '1': i32 - [99; 100) 'g': {unknown} - [103; 112) '|v| v + 1': {unknown} - [104; 105) 'v': {unknown} - [107; 108) 'v': {unknown} + [99; 100) 'g': |u64| -> i32 + [103; 112) '|v| v + 1': |u64| -> i32 + [104; 105) 'v': u64 + [107; 108) 'v': u64 [107; 112) 'v + 1': i32 [111; 112) '1': i32 - [118; 119) 'g': {unknown} - [118; 125) 'g(1u64)': {unknown} + [118; 119) 'g': |u64| -> i32 + [118; 125) 'g(1u64)': i32 [120; 124) '1u64': u64 - [135; 136) 'h': {unknown} - [139; 152) '|v| 1u128 + v': {unknown} + [135; 136) 'h': |u128| -> u128 + [139; 152) '|v| 1u128 + v': |u128| -> u128 [140; 141) 'v': u128 [143; 148) '1u128': u128 [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( type_alias.krate(db) != Some(krate), ) } + TypeCtor::Closure { def, .. } => { + let upstream = def.krate(db) != Some(krate); + (1, vec![], upstream) + } }; let flags = chalk_rust_ir::StructFlags { upstream, -- cgit v1.2.3