fix: support existential type

This commit is contained in:
csmoe 2019-06-11 21:24:14 +08:00
parent 3f5f9f0560
commit 2ca9f71897
7 changed files with 53 additions and 6 deletions

View File

@ -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);
}

View File

@ -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 @@ pub fn is_keyword(self) -> bool {
| TRY_KW
| AUTO_KW
| DEFAULT_KW
| EXISTENTIAL_KW
| UNION_KW
=> true,
_ => false
@ -566,6 +569,7 @@ pub(crate) fn info(self) -> &'static SyntaxInfo {
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" },

View File

@ -100,6 +100,7 @@ Grammar(
contextual_keywords: [
"auto",
"default",
"existential",
"union",
],
literals: [

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
existential type Foo: Fn() -> usize;

View File

@ -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"