aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-04 19:55:23 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-04 19:55:23 +0000
commit4a3ef8fe63c5eedfbb6d3038e88f0b1349a1c382 (patch)
treea2666ef628451437aea9b99a9e18d27bb54b53e8 /crates/ra_syntax/src
parent04e6b26758003550633e41df14fe9bc0ac7f8e4a (diff)
parente6aeabf96f9cf339c81f3e79502d477269d141ed (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.rs31
-rw-r--r--crates/ra_syntax/src/ast/generated.rs87
-rw-r--r--crates/ra_syntax/src/grammar.ron9
-rw-r--r--crates/ra_syntax/src/grammar/items.rs2
-rw-r--r--crates/ra_syntax/src/grammar/items/traits.rs6
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)]
486pub enum SelfParamFlavor {
487 /// self
488 Owned,
489 /// &self
490 Ref,
491 /// &mut self
492 MutRef,
493}
494
495impl<'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]
486fn test_doc_comment_of_items() { 517fn 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
1445impl<'a> ImplBlock<'a> {} 1445impl<'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)]
1453pub enum ImplItem<'a> {
1454 FnDef(FnDef<'a>),
1455 TypeDef(TypeDef<'a>),
1456 ConstDef(ConstDef<'a>),
1457}
1458
1459impl<'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
1477impl<'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
1556impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {} 1588impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {}
1557impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {} 1589impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {}
1558impl<'a> ItemList<'a> {} 1590impl<'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,)]
3493pub struct SelfKwNode<R: TreeRoot<RaTypes> = OwnedRoot> {
3494 pub(crate) syntax: SyntaxNode<R>,
3495}
3496pub type SelfKw<'a> = SelfKwNode<RefRoot<'a>>;
3497
3498impl<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}
3501impl<R: TreeRoot<RaTypes>> Eq for SelfKwNode<R> {}
3502impl<R: TreeRoot<RaTypes>> Hash for SelfKwNode<R> {
3503 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
3504}
3505
3506impl<'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
3516impl<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
3526impl<'a> SelfKw<'a> {}
3527
3455// SelfParam 3528// SelfParam
3456#[derive(Debug, Clone, Copy,)] 3529#[derive(Debug, Clone, Copy,)]
3457pub struct SelfParamNode<R: TreeRoot<RaTypes> = OwnedRoot> { 3530pub struct SelfParamNode<R: TreeRoot<RaTypes> = OwnedRoot> {
@@ -3487,7 +3560,15 @@ impl<R: TreeRoot<RaTypes>> SelfParamNode<R> {
3487} 3560}
3488 3561
3489 3562
3490impl<'a> SelfParam<'a> {} 3563impl<'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 {}
45pub(super) fn impl_item(p: &mut Parser) { 45pub(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);