From 2ca9f718978b20e8cffb669dc61b63ad7d5e82cd Mon Sep 17 00:00:00 2001 From: csmoe Date: Tue, 11 Jun 2019 21:24:14 +0800 Subject: fix: support existential type --- crates/ra_parser/src/grammar/items.rs | 16 ++++++++--- crates/ra_parser/src/syntax_kind/generated.rs | 4 +++ crates/ra_syntax/src/grammar.ron | 1 + .../tests/data/parser/err/0011_extern_struct.txt | 2 +- .../parser/inline/err/0010_wrong_order_fns.txt | 4 +-- .../data/parser/inline/ok/0131_existential_type.rs | 1 + .../parser/inline/ok/0131_existential_type.txt | 31 ++++++++++++++++++++++ 7 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 crates/ra_syntax/tests/data/parser/inline/ok/0131_existential_type.rs create mode 100644 crates/ra_syntax/tests/data/parser/inline/ok/0131_existential_type.txt diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index 7718fbe6a..e85147e9e 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs @@ -107,6 +107,10 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul p.bump_remap(T![default]); has_mods = true; } + if p.at(IDENT) && p.at_contextual_kw("existential") && p.nth(1) == T![type] { + p.bump_remap(T![existential]); + has_mods = true; + } // items match p.current() { @@ -165,12 +169,17 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul traits::impl_block(p); m.complete(p, IMPL_BLOCK); } + // test existential_type + // existential type Foo: Fn() -> usize; + T![type] => { + type_def(p, m); + } _ => { if !has_visibility && !has_mods { return Err(m); } else { if has_mods { - p.error("expected fn, trait or impl"); + p.error("expected existential, fn, trait or impl"); } else { p.error("expected an item"); } @@ -187,7 +196,9 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { // test extern_crate // extern crate foo; T![extern] if la == T![crate] => extern_crate_item(p, m), - T![type] => type_def(p, m), + T![type] => { + type_def(p, m); + } T![mod] => mod_item(p, m), T![struct] => { // test struct_items @@ -308,7 +319,6 @@ fn type_def(p: &mut Parser, m: Marker) { // test type_item_where_clause // type Foo where Foo: Copy = (); type_params::opt_where_clause(p); - if p.eat(T![=]) { types::type_(p); } diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 2c021f3e9..036415eac 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs @@ -106,6 +106,7 @@ pub enum SyntaxKind { TRY_KW, AUTO_KW, DEFAULT_KW, + EXISTENTIAL_KW, UNION_KW, INT_NUMBER, FLOAT_NUMBER, @@ -336,6 +337,7 @@ macro_rules! T { (try) => { $crate::SyntaxKind::TRY_KW }; (auto) => { $crate::SyntaxKind::AUTO_KW }; (default) => { $crate::SyntaxKind::DEFAULT_KW }; + (existential) => { $crate::SyntaxKind::EXISTENTIAL_KW }; (union) => { $crate::SyntaxKind::UNION_KW }; } @@ -394,6 +396,7 @@ impl SyntaxKind { | TRY_KW | AUTO_KW | DEFAULT_KW + | EXISTENTIAL_KW | UNION_KW => true, _ => false @@ -566,6 +569,7 @@ impl SyntaxKind { TRY_KW => &SyntaxInfo { name: "TRY_KW" }, AUTO_KW => &SyntaxInfo { name: "AUTO_KW" }, DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" }, + EXISTENTIAL_KW => &SyntaxInfo { name: "EXISTENTIAL_KW" }, UNION_KW => &SyntaxInfo { name: "UNION_KW" }, INT_NUMBER => &SyntaxInfo { name: "INT_NUMBER" }, FLOAT_NUMBER => &SyntaxInfo { name: "FLOAT_NUMBER" }, diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 1c2714307..eab55058b 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -100,6 +100,7 @@ Grammar( contextual_keywords: [ "auto", "default", + "existential", "union", ], literals: [ diff --git a/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt index 033dac2aa..381147dc0 100644 --- a/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt +++ b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt @@ -10,4 +10,4 @@ SOURCE_FILE@[0; 19) IDENT@[14; 17) "Foo" SEMI@[17; 18) ";" WHITESPACE@[18; 19) "\n" -error 6: expected fn, trait or impl +error 6: expected existential, fn, trait or impl diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt b/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt index 9eb4c9b36..b1ef210d3 100644 --- a/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt +++ b/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt @@ -35,5 +35,5 @@ SOURCE_FILE@[0; 50) L_CURLY@[47; 48) "{" R_CURLY@[48; 49) "}" WHITESPACE@[49; 50) "\n" -error 5: expected fn, trait or impl -error 31: expected fn, trait or impl +error 5: expected existential, fn, trait or impl +error 31: expected existential, fn, trait or impl diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0131_existential_type.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0131_existential_type.rs new file mode 100644 index 000000000..23baf7145 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0131_existential_type.rs @@ -0,0 +1 @@ +existential type Foo: Fn() -> usize; diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0131_existential_type.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0131_existential_type.txt new file mode 100644 index 000000000..6bfac985a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0131_existential_type.txt @@ -0,0 +1,31 @@ +SOURCE_FILE@[0; 37) + TYPE_ALIAS_DEF@[0; 36) + EXISTENTIAL_KW@[0; 11) "existential" + WHITESPACE@[11; 12) " " + TYPE_KW@[12; 16) "type" + WHITESPACE@[16; 17) " " + NAME@[17; 20) + IDENT@[17; 20) "Foo" + COLON@[20; 21) ":" + WHITESPACE@[21; 22) " " + TYPE_BOUND_LIST@[22; 35) + TYPE_BOUND@[22; 35) + PATH_TYPE@[22; 35) + PATH@[22; 35) + PATH_SEGMENT@[22; 35) + NAME_REF@[22; 24) + IDENT@[22; 24) "Fn" + PARAM_LIST@[24; 26) + L_PAREN@[24; 25) "(" + R_PAREN@[25; 26) ")" + WHITESPACE@[26; 27) " " + RET_TYPE@[27; 35) + THIN_ARROW@[27; 29) "->" + WHITESPACE@[29; 30) " " + PATH_TYPE@[30; 35) + PATH@[30; 35) + PATH_SEGMENT@[30; 35) + NAME_REF@[30; 35) + IDENT@[30; 35) "usize" + SEMI@[35; 36) ";" + WHITESPACE@[36; 37) "\n" -- cgit v1.2.3