diff options
author | Florian Diebold <[email protected]> | 2018-12-29 20:32:07 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-01-04 18:10:50 +0000 |
commit | 111126ed3c4f6358e0c833f80226e5192778f749 (patch) | |
tree | 83ddf3395d8f8eb97323bb8581bef80fd9eda846 /crates | |
parent | ae9530addc4c5e9bbfd5c0287d3c3adb2de95e40 (diff) |
Type the self parameter
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/mock.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/0007_self.txt | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 31 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 47 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 3 |
6 files changed, 116 insertions, 9 deletions
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index ef245ec7a..2419d256a 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -30,6 +30,10 @@ impl MockDatabase { | |||
30 | let file_id = db.add_file(&mut source_root, "/main.rs", text); | 30 | let file_id = db.add_file(&mut source_root, "/main.rs", text); |
31 | db.query_mut(ra_db::SourceRootQuery) | 31 | db.query_mut(ra_db::SourceRootQuery) |
32 | .set(WORKSPACE, Arc::new(source_root.clone())); | 32 | .set(WORKSPACE, Arc::new(source_root.clone())); |
33 | |||
34 | let mut crate_graph = CrateGraph::default(); | ||
35 | crate_graph.add_crate_root(file_id); | ||
36 | db.set_crate_graph(crate_graph); | ||
33 | (db, source_root, file_id) | 37 | (db, source_root, file_id) |
34 | } | 38 | } |
35 | 39 | ||
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 719b3f7cd..c762ec606 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -918,22 +918,46 @@ pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceRe | |||
918 | let node = syntax.borrowed(); | 918 | let node = syntax.borrowed(); |
919 | 919 | ||
920 | if let Some(param_list) = node.param_list() { | 920 | if let Some(param_list) = node.param_list() { |
921 | if let Some(self_param) = param_list.self_param() { | ||
922 | let self_type = if let Some(impl_block) = function.impl_block(db)? { | ||
923 | if let Some(type_ref) = self_param.type_ref() { | ||
924 | let ty = Ty::from_ast(db, &ctx.module, type_ref)?; | ||
925 | ctx.insert_type_vars(ty) | ||
926 | } else { | ||
927 | let ty = Ty::from_hir(db, &ctx.module, impl_block.target())?; | ||
928 | let ty = match self_param.flavor() { | ||
929 | ast::SelfParamFlavor::Owned => ty, | ||
930 | ast::SelfParamFlavor::Ref => Ty::Ref(Arc::new(ty), Mutability::Shared), | ||
931 | ast::SelfParamFlavor::MutRef => Ty::Ref(Arc::new(ty), Mutability::Mut), | ||
932 | }; | ||
933 | ctx.insert_type_vars(ty) | ||
934 | } | ||
935 | } else { | ||
936 | log::debug!( | ||
937 | "No impl block found, but self param for function {:?}", | ||
938 | def_id | ||
939 | ); | ||
940 | ctx.new_type_var() | ||
941 | }; | ||
942 | if let Some(self_kw) = self_param.self_kw() { | ||
943 | ctx.type_of | ||
944 | .insert(LocalSyntaxPtr::new(self_kw.syntax()), self_type); | ||
945 | } | ||
946 | } | ||
921 | for param in param_list.params() { | 947 | for param in param_list.params() { |
922 | let pat = if let Some(pat) = param.pat() { | 948 | let pat = if let Some(pat) = param.pat() { |
923 | pat | 949 | pat |
924 | } else { | 950 | } else { |
925 | continue; | 951 | continue; |
926 | }; | 952 | }; |
927 | if let Some(type_ref) = param.type_ref() { | 953 | let ty = if let Some(type_ref) = param.type_ref() { |
928 | let ty = Ty::from_ast(db, &ctx.module, type_ref)?; | 954 | let ty = Ty::from_ast(db, &ctx.module, type_ref)?; |
929 | let ty = ctx.insert_type_vars(ty); | 955 | ctx.insert_type_vars(ty) |
930 | ctx.type_of.insert(LocalSyntaxPtr::new(pat.syntax()), ty); | ||
931 | } else { | 956 | } else { |
932 | // TODO self param | 957 | // missing type annotation |
933 | let type_var = ctx.new_type_var(); | 958 | ctx.new_type_var() |
934 | ctx.type_of | ||
935 | .insert(LocalSyntaxPtr::new(pat.syntax()), type_var); | ||
936 | }; | 959 | }; |
960 | ctx.type_of.insert(LocalSyntaxPtr::new(pat.syntax()), ty); | ||
937 | } | 961 | } |
938 | } | 962 | } |
939 | 963 | ||
diff --git a/crates/ra_hir/src/ty/tests/data/0007_self.txt b/crates/ra_hir/src/ty/tests/data/0007_self.txt index 18cd796c2..3d3c8b260 100644 --- a/crates/ra_hir/src/ty/tests/data/0007_self.txt +++ b/crates/ra_hir/src/ty/tests/data/0007_self.txt | |||
@@ -1,4 +1,6 @@ | |||
1 | [50; 54) 'self': [unknown] | 1 | [50; 54) 'self': [unknown] |
2 | [34; 38) 'self': &S | ||
2 | [40; 61) '{ ... }': () | 3 | [40; 61) '{ ... }': () |
3 | [88; 109) '{ ... }': () | 4 | [88; 109) '{ ... }': () |
4 | [98; 102) 'self': [unknown] | 5 | [98; 102) 'self': [unknown] |
6 | [75; 79) 'self': &[unknown] | ||
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 7f986d322..2a3bd27e2 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -482,6 +482,37 @@ impl<'a> PrefixExpr<'a> { | |||
482 | } | 482 | } |
483 | } | 483 | } |
484 | 484 | ||
485 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
486 | pub enum SelfParamFlavor { | ||
487 | /// self | ||
488 | Owned, | ||
489 | /// &self | ||
490 | Ref, | ||
491 | /// &mut self | ||
492 | MutRef, | ||
493 | } | ||
494 | |||
495 | impl<'a> SelfParam<'a> { | ||
496 | pub fn flavor(&self) -> SelfParamFlavor { | ||
497 | let borrowed = self.syntax().children().any(|n| n.kind() == AMP); | ||
498 | if borrowed { | ||
499 | // check for a `mut` coming after the & -- `mut &self` != `&mut self` | ||
500 | if self | ||
501 | .syntax() | ||
502 | .children() | ||
503 | .skip_while(|n| n.kind() != AMP) | ||
504 | .any(|n| n.kind() == MUT_KW) | ||
505 | { | ||
506 | SelfParamFlavor::MutRef | ||
507 | } else { | ||
508 | SelfParamFlavor::Ref | ||
509 | } | ||
510 | } else { | ||
511 | SelfParamFlavor::Owned | ||
512 | } | ||
513 | } | ||
514 | } | ||
515 | |||
485 | #[test] | 516 | #[test] |
486 | fn test_doc_comment_of_items() { | 517 | fn test_doc_comment_of_items() { |
487 | let file = SourceFileNode::parse( | 518 | let file = SourceFileNode::parse( |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 91de17ddf..7df6a9c46 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -3488,6 +3488,43 @@ impl<'a> ReturnExpr<'a> { | |||
3488 | } | 3488 | } |
3489 | } | 3489 | } |
3490 | 3490 | ||
3491 | // SelfKw | ||
3492 | #[derive(Debug, Clone, Copy,)] | ||
3493 | pub struct SelfKwNode<R: TreeRoot<RaTypes> = OwnedRoot> { | ||
3494 | pub(crate) syntax: SyntaxNode<R>, | ||
3495 | } | ||
3496 | pub type SelfKw<'a> = SelfKwNode<RefRoot<'a>>; | ||
3497 | |||
3498 | impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<SelfKwNode<R1>> for SelfKwNode<R2> { | ||
3499 | fn eq(&self, other: &SelfKwNode<R1>) -> bool { self.syntax == other.syntax } | ||
3500 | } | ||
3501 | impl<R: TreeRoot<RaTypes>> Eq for SelfKwNode<R> {} | ||
3502 | impl<R: TreeRoot<RaTypes>> Hash for SelfKwNode<R> { | ||
3503 | fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) } | ||
3504 | } | ||
3505 | |||
3506 | impl<'a> AstNode<'a> for SelfKw<'a> { | ||
3507 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
3508 | match syntax.kind() { | ||
3509 | SELF_KW => Some(SelfKw { syntax }), | ||
3510 | _ => None, | ||
3511 | } | ||
3512 | } | ||
3513 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
3514 | } | ||
3515 | |||
3516 | impl<R: TreeRoot<RaTypes>> SelfKwNode<R> { | ||
3517 | pub fn borrowed(&self) -> SelfKw { | ||
3518 | SelfKwNode { syntax: self.syntax.borrowed() } | ||
3519 | } | ||
3520 | pub fn owned(&self) -> SelfKwNode { | ||
3521 | SelfKwNode { syntax: self.syntax.owned() } | ||
3522 | } | ||
3523 | } | ||
3524 | |||
3525 | |||
3526 | impl<'a> SelfKw<'a> {} | ||
3527 | |||
3491 | // SelfParam | 3528 | // SelfParam |
3492 | #[derive(Debug, Clone, Copy,)] | 3529 | #[derive(Debug, Clone, Copy,)] |
3493 | pub struct SelfParamNode<R: TreeRoot<RaTypes> = OwnedRoot> { | 3530 | pub struct SelfParamNode<R: TreeRoot<RaTypes> = OwnedRoot> { |
@@ -3523,7 +3560,15 @@ impl<R: TreeRoot<RaTypes>> SelfParamNode<R> { | |||
3523 | } | 3560 | } |
3524 | 3561 | ||
3525 | 3562 | ||
3526 | impl<'a> SelfParam<'a> {} | 3563 | impl<'a> SelfParam<'a> { |
3564 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
3565 | super::child_opt(self) | ||
3566 | } | ||
3567 | |||
3568 | pub fn self_kw(self) -> Option<SelfKw<'a>> { | ||
3569 | super::child_opt(self) | ||
3570 | } | ||
3571 | } | ||
3527 | 3572 | ||
3528 | // SlicePat | 3573 | // SlicePat |
3529 | #[derive(Debug, Clone, Copy,)] | 3574 | #[derive(Debug, Clone, Copy,)] |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 688a4af1e..c55e9e07a 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -534,7 +534,8 @@ Grammar( | |||
534 | ["params", "Param"] | 534 | ["params", "Param"] |
535 | ] | 535 | ] |
536 | ), | 536 | ), |
537 | "SelfParam": (), | 537 | "SelfParam": (options: ["TypeRef", "SelfKw"]), |
538 | "SelfKw": (), | ||
538 | "Param": ( | 539 | "Param": ( |
539 | options: [ "Pat", "TypeRef" ], | 540 | options: [ "Pat", "TypeRef" ], |
540 | ), | 541 | ), |