diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-04 19:55:23 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-04 19:55:23 +0000 |
commit | 4a3ef8fe63c5eedfbb6d3038e88f0b1349a1c382 (patch) | |
tree | a2666ef628451437aea9b99a9e18d27bb54b53e8 /crates/ra_syntax/src | |
parent | 04e6b26758003550633e41df14fe9bc0ac7f8e4a (diff) | |
parent | e6aeabf96f9cf339c81f3e79502d477269d141ed (diff) |
Merge #370
370: Self params & type r=matklad a=flodiebold
This implements type inference for `self`, so field completion for methods taking `self` works now.
- rename `IMPL_ITEM` to `IMPL_BLOCK` -- rustc calls the methods etc. inside an impl `ImplItem`s, and the impl itself doesn't define an item, so I thought this name was clearer.
- add HIR for impl blocks -- we collect all impls in a crate at once, so we can go from methods to containing impls, and since we will later also need to find all impls for a certain type (which may be anywhere in the crate, I think?). We could be more lazy here, but I don't know if it's worth the complexity.
- resolve `self` and `Self` during type inference
- refactor a bit in ty.rs as well
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 31 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 87 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 9 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar/items.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar/items/traits.rs | 6 |
5 files changed, 126 insertions, 9 deletions
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 c1c63f555..7df6a9c46 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -1442,7 +1442,39 @@ impl<R: TreeRoot<RaTypes>> ImplBlockNode<R> { | |||
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | 1444 | ||
1445 | impl<'a> ImplBlock<'a> {} | 1445 | impl<'a> ImplBlock<'a> { |
1446 | pub fn item_list(self) -> Option<ItemList<'a>> { | ||
1447 | super::child_opt(self) | ||
1448 | } | ||
1449 | } | ||
1450 | |||
1451 | // ImplItem | ||
1452 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
1453 | pub enum ImplItem<'a> { | ||
1454 | FnDef(FnDef<'a>), | ||
1455 | TypeDef(TypeDef<'a>), | ||
1456 | ConstDef(ConstDef<'a>), | ||
1457 | } | ||
1458 | |||
1459 | impl<'a> AstNode<'a> for ImplItem<'a> { | ||
1460 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1461 | match syntax.kind() { | ||
1462 | FN_DEF => Some(ImplItem::FnDef(FnDef { syntax })), | ||
1463 | TYPE_DEF => Some(ImplItem::TypeDef(TypeDef { syntax })), | ||
1464 | CONST_DEF => Some(ImplItem::ConstDef(ConstDef { syntax })), | ||
1465 | _ => None, | ||
1466 | } | ||
1467 | } | ||
1468 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
1469 | match self { | ||
1470 | ImplItem::FnDef(inner) => inner.syntax(), | ||
1471 | ImplItem::TypeDef(inner) => inner.syntax(), | ||
1472 | ImplItem::ConstDef(inner) => inner.syntax(), | ||
1473 | } | ||
1474 | } | ||
1475 | } | ||
1476 | |||
1477 | impl<'a> ImplItem<'a> {} | ||
1446 | 1478 | ||
1447 | // ImplTraitType | 1479 | // ImplTraitType |
1448 | #[derive(Debug, Clone, Copy,)] | 1480 | #[derive(Debug, Clone, Copy,)] |
@@ -1555,7 +1587,11 @@ impl<R: TreeRoot<RaTypes>> ItemListNode<R> { | |||
1555 | 1587 | ||
1556 | impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {} | 1588 | impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {} |
1557 | impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {} | 1589 | impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {} |
1558 | impl<'a> ItemList<'a> {} | 1590 | impl<'a> ItemList<'a> { |
1591 | pub fn impl_items(self) -> impl Iterator<Item = ImplItem<'a>> + 'a { | ||
1592 | super::children(self) | ||
1593 | } | ||
1594 | } | ||
1559 | 1595 | ||
1560 | // Label | 1596 | // Label |
1561 | #[derive(Debug, Clone, Copy,)] | 1597 | #[derive(Debug, Clone, Copy,)] |
@@ -3452,6 +3488,43 @@ impl<'a> ReturnExpr<'a> { | |||
3452 | } | 3488 | } |
3453 | } | 3489 | } |
3454 | 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 | |||
3455 | // SelfParam | 3528 | // SelfParam |
3456 | #[derive(Debug, Clone, Copy,)] | 3529 | #[derive(Debug, Clone, Copy,)] |
3457 | pub struct SelfParamNode<R: TreeRoot<RaTypes> = OwnedRoot> { | 3530 | pub struct SelfParamNode<R: TreeRoot<RaTypes> = OwnedRoot> { |
@@ -3487,7 +3560,15 @@ impl<R: TreeRoot<RaTypes>> SelfParamNode<R> { | |||
3487 | } | 3560 | } |
3488 | 3561 | ||
3489 | 3562 | ||
3490 | 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 | } | ||
3491 | 3572 | ||
3492 | // SlicePat | 3573 | // SlicePat |
3493 | #[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 9a4a96fac..c55e9e07a 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -284,6 +284,7 @@ Grammar( | |||
284 | options: [ "ItemList" ] | 284 | options: [ "ItemList" ] |
285 | ), | 285 | ), |
286 | "ItemList": ( | 286 | "ItemList": ( |
287 | collections: [["impl_items", "ImplItem"]], | ||
287 | traits: [ "FnDefOwner", "ModuleItemOwner" ], | 288 | traits: [ "FnDefOwner", "ModuleItemOwner" ], |
288 | ), | 289 | ), |
289 | "ConstDef": ( traits: [ | 290 | "ConstDef": ( traits: [ |
@@ -307,7 +308,7 @@ Grammar( | |||
307 | "AttrsOwner", | 308 | "AttrsOwner", |
308 | "DocCommentsOwner" | 309 | "DocCommentsOwner" |
309 | ] ), | 310 | ] ), |
310 | "ImplBlock": (collections: []), | 311 | "ImplBlock": (options: ["ItemList"]), |
311 | 312 | ||
312 | "ParenType": (options: ["TypeRef"]), | 313 | "ParenType": (options: ["TypeRef"]), |
313 | "TupleType": ( collections: [["fields", "TypeRef"]] ), | 314 | "TupleType": ( collections: [["fields", "TypeRef"]] ), |
@@ -351,6 +352,9 @@ Grammar( | |||
351 | enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeDef", "ImplBlock", | 352 | enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeDef", "ImplBlock", |
352 | "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ] | 353 | "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ] |
353 | ), | 354 | ), |
355 | "ImplItem": ( | ||
356 | enum: ["FnDef", "TypeDef", "ConstDef"] | ||
357 | ), | ||
354 | 358 | ||
355 | "TupleExpr": (), | 359 | "TupleExpr": (), |
356 | "ArrayExpr": (), | 360 | "ArrayExpr": (), |
@@ -530,7 +534,8 @@ Grammar( | |||
530 | ["params", "Param"] | 534 | ["params", "Param"] |
531 | ] | 535 | ] |
532 | ), | 536 | ), |
533 | "SelfParam": (), | 537 | "SelfParam": (options: ["TypeRef", "SelfKw"]), |
538 | "SelfKw": (), | ||
534 | "Param": ( | 539 | "Param": ( |
535 | options: [ "Pat", "TypeRef" ], | 540 | options: [ "Pat", "TypeRef" ], |
536 | ), | 541 | ), |
diff --git a/crates/ra_syntax/src/grammar/items.rs b/crates/ra_syntax/src/grammar/items.rs index b9a00b565..265e84570 100644 --- a/crates/ra_syntax/src/grammar/items.rs +++ b/crates/ra_syntax/src/grammar/items.rs | |||
@@ -151,7 +151,7 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { | |||
151 | // test unsafe_default_impl | 151 | // test unsafe_default_impl |
152 | // unsafe default impl Foo {} | 152 | // unsafe default impl Foo {} |
153 | IMPL_KW => { | 153 | IMPL_KW => { |
154 | traits::impl_item(p); | 154 | traits::impl_block(p); |
155 | IMPL_BLOCK | 155 | IMPL_BLOCK |
156 | } | 156 | } |
157 | _ => { | 157 | _ => { |
diff --git a/crates/ra_syntax/src/grammar/items/traits.rs b/crates/ra_syntax/src/grammar/items/traits.rs index d4da8b2f7..0a0621753 100644 --- a/crates/ra_syntax/src/grammar/items/traits.rs +++ b/crates/ra_syntax/src/grammar/items/traits.rs | |||
@@ -40,9 +40,9 @@ pub(crate) fn trait_item_list(p: &mut Parser) { | |||
40 | m.complete(p, ITEM_LIST); | 40 | m.complete(p, ITEM_LIST); |
41 | } | 41 | } |
42 | 42 | ||
43 | // test impl_item | 43 | // test impl_block |
44 | // impl Foo {} | 44 | // impl Foo {} |
45 | pub(super) fn impl_item(p: &mut Parser) { | 45 | pub(super) fn impl_block(p: &mut Parser) { |
46 | assert!(p.at(IMPL_KW)); | 46 | assert!(p.at(IMPL_KW)); |
47 | p.bump(); | 47 | p.bump(); |
48 | if choose_type_params_over_qpath(p) { | 48 | if choose_type_params_over_qpath(p) { |
@@ -52,7 +52,7 @@ pub(super) fn impl_item(p: &mut Parser) { | |||
52 | // TODO: never type | 52 | // TODO: never type |
53 | // impl ! {} | 53 | // impl ! {} |
54 | 54 | ||
55 | // test impl_item_neg | 55 | // test impl_block_neg |
56 | // impl !Send for X {} | 56 | // impl !Send for X {} |
57 | p.eat(EXCL); | 57 | p.eat(EXCL); |
58 | impl_type(p); | 58 | impl_type(p); |