diff options
author | Aleksey Kladov <[email protected]> | 2020-07-17 09:57:49 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-07-17 11:04:10 +0100 |
commit | 371c5aec1c4ad18f37e96b4bf85c49563fc4a01d (patch) | |
tree | 99f9d4757248115f7e5f30a53395f1cb99c089b3 /crates | |
parent | f88a737a439f7801b7521c66c124ea5a44736e13 (diff) |
call_info works with closures
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 33 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 11 | ||||
-rw-r--r-- | crates/ra_ide/src/call_info.rs | 20 | ||||
-rw-r--r-- | crates/ra_ide/src/inlay_hints.rs | 4 |
4 files changed, 42 insertions, 26 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 0f6953158..859bdfb3b 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -1233,9 +1233,13 @@ impl Type { | |||
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { | 1235 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { |
1236 | let (id, substs) = self.ty.value.as_callable()?; | 1236 | let def = match self.ty.value { |
1237 | let sig = db.callable_item_signature(id).subst(substs); | 1237 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def), |
1238 | Some(Callable { ty: self.clone(), sig, id, is_bound_method: false }) | 1238 | _ => None, |
1239 | }; | ||
1240 | |||
1241 | let sig = self.ty.value.callable_sig(db)?; | ||
1242 | Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) | ||
1239 | } | 1243 | } |
1240 | 1244 | ||
1241 | pub fn is_closure(&self) -> bool { | 1245 | pub fn is_closure(&self) -> bool { |
@@ -1525,7 +1529,7 @@ impl HirDisplay for Type { | |||
1525 | pub struct Callable { | 1529 | pub struct Callable { |
1526 | ty: Type, | 1530 | ty: Type, |
1527 | sig: FnSig, | 1531 | sig: FnSig, |
1528 | id: CallableDefId, | 1532 | def: Option<CallableDefId>, |
1529 | pub(crate) is_bound_method: bool, | 1533 | pub(crate) is_bound_method: bool, |
1530 | } | 1534 | } |
1531 | 1535 | ||
@@ -1533,19 +1537,21 @@ pub enum CallableKind { | |||
1533 | Function(Function), | 1537 | Function(Function), |
1534 | TupleStruct(Struct), | 1538 | TupleStruct(Struct), |
1535 | TupleEnumVariant(EnumVariant), | 1539 | TupleEnumVariant(EnumVariant), |
1540 | Closure, | ||
1536 | } | 1541 | } |
1537 | 1542 | ||
1538 | impl Callable { | 1543 | impl Callable { |
1539 | pub fn kind(&self) -> CallableKind { | 1544 | pub fn kind(&self) -> CallableKind { |
1540 | match self.id { | 1545 | match self.def { |
1541 | CallableDefId::FunctionId(it) => CallableKind::Function(it.into()), | 1546 | Some(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()), |
1542 | CallableDefId::StructId(it) => CallableKind::TupleStruct(it.into()), | 1547 | Some(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()), |
1543 | CallableDefId::EnumVariantId(it) => CallableKind::TupleEnumVariant(it.into()), | 1548 | Some(CallableDefId::EnumVariantId(it)) => CallableKind::TupleEnumVariant(it.into()), |
1549 | None => CallableKind::Closure, | ||
1544 | } | 1550 | } |
1545 | } | 1551 | } |
1546 | pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<ast::SelfParam> { | 1552 | pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<ast::SelfParam> { |
1547 | let func = match self.id { | 1553 | let func = match self.def { |
1548 | CallableDefId::FunctionId(it) if self.is_bound_method => it, | 1554 | Some(CallableDefId::FunctionId(it)) if self.is_bound_method => it, |
1549 | _ => return None, | 1555 | _ => return None, |
1550 | }; | 1556 | }; |
1551 | let src = func.lookup(db.upcast()).source(db.upcast()); | 1557 | let src = func.lookup(db.upcast()).source(db.upcast()); |
@@ -1565,8 +1571,8 @@ impl Callable { | |||
1565 | .iter() | 1571 | .iter() |
1566 | .skip(if self.is_bound_method { 1 } else { 0 }) | 1572 | .skip(if self.is_bound_method { 1 } else { 0 }) |
1567 | .map(|ty| self.ty.derived(ty.clone())); | 1573 | .map(|ty| self.ty.derived(ty.clone())); |
1568 | let patterns = match self.id { | 1574 | let patterns = match self.def { |
1569 | CallableDefId::FunctionId(func) => { | 1575 | Some(CallableDefId::FunctionId(func)) => { |
1570 | let src = func.lookup(db.upcast()).source(db.upcast()); | 1576 | let src = func.lookup(db.upcast()).source(db.upcast()); |
1571 | src.value.param_list().map(|param_list| { | 1577 | src.value.param_list().map(|param_list| { |
1572 | param_list | 1578 | param_list |
@@ -1577,8 +1583,7 @@ impl Callable { | |||
1577 | .chain(param_list.params().map(|it| it.pat().map(Either::Right))) | 1583 | .chain(param_list.params().map(|it| it.pat().map(Either::Right))) |
1578 | }) | 1584 | }) |
1579 | } | 1585 | } |
1580 | CallableDefId::StructId(_) => None, | 1586 | _ => None, |
1581 | CallableDefId::EnumVariantId(_) => None, | ||
1582 | }; | 1587 | }; |
1583 | patterns.into_iter().flatten().chain(iter::repeat(None)).zip(types).collect() | 1588 | patterns.into_iter().flatten().chain(iter::repeat(None)).zip(types).collect() |
1584 | } | 1589 | } |
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 1f6626c46..7698cb0d4 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -767,15 +767,6 @@ impl Ty { | |||
767 | } | 767 | } |
768 | } | 768 | } |
769 | 769 | ||
770 | pub fn as_callable(&self) -> Option<(CallableDefId, &Substs)> { | ||
771 | match self { | ||
772 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(callable_def), parameters }) => { | ||
773 | Some((*callable_def, parameters)) | ||
774 | } | ||
775 | _ => None, | ||
776 | } | ||
777 | } | ||
778 | |||
779 | pub fn is_never(&self) -> bool { | 770 | pub fn is_never(&self) -> bool { |
780 | matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) | 771 | matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) |
781 | } | 772 | } |
@@ -807,7 +798,7 @@ impl Ty { | |||
807 | } | 798 | } |
808 | } | 799 | } |
809 | 800 | ||
810 | pub(crate) fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { | 801 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { |
811 | match self { | 802 | match self { |
812 | Ty::Apply(a_ty) => match a_ty.ctor { | 803 | Ty::Apply(a_ty) => match a_ty.ctor { |
813 | TypeCtor::FnPtr { is_varargs, .. } => { | 804 | TypeCtor::FnPtr { is_varargs, .. } => { |
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs index 35a8a0dc5..53d56a0a4 100644 --- a/crates/ra_ide/src/call_info.rs +++ b/crates/ra_ide/src/call_info.rs | |||
@@ -70,6 +70,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
70 | variant.name(db) | 70 | variant.name(db) |
71 | ); | 71 | ); |
72 | } | 72 | } |
73 | hir::CallableKind::Closure => (), | ||
73 | } | 74 | } |
74 | 75 | ||
75 | res.signature.push('('); | 76 | res.signature.push('('); |
@@ -93,7 +94,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
93 | res.signature.push(')'); | 94 | res.signature.push(')'); |
94 | 95 | ||
95 | match callable.kind() { | 96 | match callable.kind() { |
96 | hir::CallableKind::Function(_) => { | 97 | hir::CallableKind::Function(_) | hir::CallableKind::Closure => { |
97 | let ret_type = callable.return_type(); | 98 | let ret_type = callable.return_type(); |
98 | if !ret_type.is_unit() { | 99 | if !ret_type.is_unit() { |
99 | format_to!(res.signature, " -> {}", ret_type.display(db)); | 100 | format_to!(res.signature, " -> {}", ret_type.display(db)); |
@@ -702,4 +703,21 @@ id! { | |||
702 | "#]], | 703 | "#]], |
703 | ); | 704 | ); |
704 | } | 705 | } |
706 | |||
707 | #[test] | ||
708 | fn call_info_for_lambdas() { | ||
709 | check( | ||
710 | r#" | ||
711 | struct S; | ||
712 | fn foo(s: S) -> i32 { 92 } | ||
713 | fn main() { | ||
714 | (|s| foo(s))(<|>) | ||
715 | } | ||
716 | "#, | ||
717 | expect![[r#" | ||
718 | (S) -> i32 | ||
719 | (<S>) | ||
720 | "#]], | ||
721 | ) | ||
722 | } | ||
705 | } | 723 | } |
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index cec3b04e8..43a5e29b5 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs | |||
@@ -262,7 +262,9 @@ fn should_show_param_name_hint( | |||
262 | let param_name = param_name.trim_start_matches('_'); | 262 | let param_name = param_name.trim_start_matches('_'); |
263 | let fn_name = match callable.kind() { | 263 | let fn_name = match callable.kind() { |
264 | hir::CallableKind::Function(it) => Some(it.name(sema.db).to_string()), | 264 | hir::CallableKind::Function(it) => Some(it.name(sema.db).to_string()), |
265 | hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_) => None, | 265 | hir::CallableKind::TupleStruct(_) |
266 | | hir::CallableKind::TupleEnumVariant(_) | ||
267 | | hir::CallableKind::Closure => None, | ||
266 | }; | 268 | }; |
267 | if param_name.is_empty() | 269 | if param_name.is_empty() |
268 | || Some(param_name) == fn_name.as_ref().map(|s| s.trim_start_matches('_')) | 270 | || Some(param_name) == fn_name.as_ref().map(|s| s.trim_start_matches('_')) |