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 | |
parent | 36fb3f53d712a11b7e3fc4bbd92094d1c8f19522 (diff) |
Give closures types
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 23 | ||||
-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 |
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 | ||
556 | pub trait HasBody: Copy { | 564 | pub 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; | |||
16 | use std::sync::Arc; | 16 | use std::sync::Arc; |
17 | use std::{fmt, mem}; | 17 | use std::{fmt, mem}; |
18 | 18 | ||
19 | use crate::{db::HirDatabase, type_ref::Mutability, Adt, GenericParams, Name, Trait, TypeAlias}; | 19 | use crate::{ |
20 | db::HirDatabase, expr::ExprId, type_ref::Mutability, Adt, DefWithBody, GenericParams, Name, | ||
21 | Trait, TypeAlias, | ||
22 | }; | ||
20 | use display::{HirDisplay, HirFormatter}; | 23 | use display::{HirDisplay, HirFormatter}; |
21 | 24 | ||
22 | pub(crate) use autoderef::autoderef; | 25 | pub(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, |