Where clauses

This commit is contained in:
Aleksey Kladov 2018-08-08 19:26:38 +03:00
parent 8f21afacfc
commit eb8e9043e2
9 changed files with 162 additions and 27 deletions

View File

@ -192,6 +192,7 @@ Grammar(
"ALIAS",
"VISIBILITY",
"WHERE_CLAUSE",
"WHERE_PRED",
"ABI",
"NAME",
"NAME_REF",

View File

@ -24,13 +24,8 @@ pub(super) fn type_param_list(p: &mut Parser) {
assert!(p.at(LIFETIME));
let m = p.start();
p.bump();
if p.eat(COLON) {
while p.at(LIFETIME) {
p.bump();
if !p.eat(PLUS) {
break;
}
}
if p.at(COLON) {
lifetime_bounds(p);
}
m.complete(p, LIFETIME_PARAM);
}
@ -60,6 +55,17 @@ pub(super) fn bounds(p: &mut Parser) {
bounds_without_colon(p);
}
fn lifetime_bounds(p: &mut Parser) {
assert!(p.at(COLON));
p.bump();
while p.at(LIFETIME) {
p.bump();
if !p.eat(PLUS) {
break;
}
}
}
pub(super) fn bounds_without_colon(p: &mut Parser) {
loop {
let has_paren = p.eat(L_PAREN);
@ -83,13 +89,39 @@ pub(super) fn bounds_without_colon(p: &mut Parser) {
}
}
// test where_clause
// fn foo()
// where
// 'a: 'b + 'c,
// T: Clone + Copy + 'static,
// Iterator::Item: 'a,
// {}
pub(super) fn where_clause(p: &mut Parser) {
if p.at(WHERE_KW) {
let m = p.start();
p.bump();
p.expect(IDENT);
p.expect(COLON);
p.expect(IDENT);
m.complete(p, WHERE_CLAUSE);
if !p.at(WHERE_KW) {
return;
}
let m = p.start();
p.bump();
loop {
if !(paths::is_path_start(p) || p.current() == LIFETIME) {
break
}
where_predicate(p);
if p.current() != L_CURLY && p.current() != SEMI {
p.expect(COMMA);
}
}
m.complete(p, WHERE_CLAUSE);
}
fn where_predicate(p: &mut Parser) {
let m = p.start();
if p.at(LIFETIME) {
p.eat(LIFETIME);
lifetime_bounds(p)
} else {
types::path_type(p);
bounds(p);
}
m.complete(p, WHERE_PRED);
}

View File

@ -199,7 +199,7 @@ fn impl_trait_type(p: &mut Parser) {
// type B = ::Foo;
// type C = self::Foo;
// type D = super::Foo;
fn path_type(p: &mut Parser) {
pub(super) fn path_type(p: &mut Parser) {
assert!(paths::is_path_start(p));
let m = p.start();
paths::type_path(p);

View File

@ -175,6 +175,7 @@ pub enum SyntaxKind {
ALIAS,
VISIBILITY,
WHERE_CLAUSE,
WHERE_PRED,
ABI,
NAME,
NAME_REF,
@ -415,6 +416,7 @@ impl SyntaxKind {
ALIAS => &SyntaxInfo { name: "ALIAS" },
VISIBILITY => &SyntaxInfo { name: "VISIBILITY" },
WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" },
WHERE_PRED => &SyntaxInfo { name: "WHERE_PRED" },
ABI => &SyntaxInfo { name: "ABI" },
NAME => &SyntaxInfo { name: "NAME" },
NAME_REF => &SyntaxInfo { name: "NAME_REF" },

View File

@ -8,10 +8,19 @@ FILE@[0; 31)
WHERE_CLAUSE@[9; 24)
WHERE_KW@[9; 14)
WHITESPACE@[14; 15)
IDENT@[15; 18) "Foo"
COLON@[18; 19)
WHITESPACE@[19; 20)
IDENT@[20; 24) "Copy"
WHERE_PRED@[15; 24)
PATH_TYPE@[15; 18)
PATH@[15; 18)
PATH_SEGMENT@[15; 18)
NAME_REF@[15; 18)
IDENT@[15; 18) "Foo"
COLON@[18; 19)
WHITESPACE@[19; 20)
PATH@[20; 24)
PATH_SEGMENT@[20; 24)
NAME_REF@[20; 24)
IDENT@[20; 24) "Copy"
err: `expected COMMA`
WHITESPACE@[24; 25)
EQ@[25; 26)
WHITESPACE@[26; 27)

View File

@ -27,10 +27,18 @@ FILE@[0; 42)
WHERE_CLAUSE@[25; 38)
WHERE_KW@[25; 30)
WHITESPACE@[30; 31)
IDENT@[31; 32) "U"
COLON@[32; 33)
WHITESPACE@[33; 34)
IDENT@[34; 38) "Copy"
WHERE_PRED@[31; 38)
PATH_TYPE@[31; 32)
PATH@[31; 32)
PATH_SEGMENT@[31; 32)
NAME_REF@[31; 32)
IDENT@[31; 32) "U"
COLON@[32; 33)
WHITESPACE@[33; 34)
PATH@[34; 38)
PATH_SEGMENT@[34; 38)
NAME_REF@[34; 38)
IDENT@[34; 38) "Copy"
WHITESPACE@[38; 39)
L_CURLY@[39; 40)
R_CURLY@[40; 41)

View File

@ -17,10 +17,18 @@ FILE@[0; 29)
WHERE_CLAUSE@[12; 25)
WHERE_KW@[12; 17)
WHITESPACE@[17; 18)
IDENT@[18; 19) "T"
COLON@[19; 20)
WHITESPACE@[20; 21)
IDENT@[21; 25) "Copy"
WHERE_PRED@[18; 25)
PATH_TYPE@[18; 19)
PATH@[18; 19)
PATH_SEGMENT@[18; 19)
NAME_REF@[18; 19)
IDENT@[18; 19) "T"
COLON@[19; 20)
WHITESPACE@[20; 21)
PATH@[21; 25)
PATH_SEGMENT@[21; 25)
NAME_REF@[21; 25)
IDENT@[21; 25) "Copy"
WHITESPACE@[25; 26)
BLOCK_EXPR@[26; 28)
L_CURLY@[26; 27)

View File

@ -0,0 +1,6 @@
fn foo()
where
'a: 'b + 'c,
T: Clone + Copy + 'static,
Iterator::Item: 'a,
{}

View File

@ -0,0 +1,69 @@
FILE@[0; 87)
FN_ITEM@[0; 86)
FN_KW@[0; 2)
WHITESPACE@[2; 3)
NAME@[3; 6)
IDENT@[3; 6) "foo"
PARAM_LIST@[6; 8)
L_PAREN@[6; 7)
R_PAREN@[7; 8)
WHITESPACE@[8; 9)
WHERE_CLAUSE@[9; 83)
WHERE_KW@[9; 14)
WHITESPACE@[14; 18)
WHERE_PRED@[18; 29)
LIFETIME@[18; 20) "'a"
COLON@[20; 21)
WHITESPACE@[21; 22)
LIFETIME@[22; 24) "'b"
WHITESPACE@[24; 25)
PLUS@[25; 26)
WHITESPACE@[26; 27)
LIFETIME@[27; 29) "'c"
COMMA@[29; 30)
WHITESPACE@[30; 34)
WHERE_PRED@[34; 59)
PATH_TYPE@[34; 35)
PATH@[34; 35)
PATH_SEGMENT@[34; 35)
NAME_REF@[34; 35)
IDENT@[34; 35) "T"
COLON@[35; 36)
WHITESPACE@[36; 37)
PATH@[37; 42)
PATH_SEGMENT@[37; 42)
NAME_REF@[37; 42)
IDENT@[37; 42) "Clone"
WHITESPACE@[42; 43)
PLUS@[43; 44)
WHITESPACE@[44; 45)
PATH@[45; 49)
PATH_SEGMENT@[45; 49)
NAME_REF@[45; 49)
IDENT@[45; 49) "Copy"
WHITESPACE@[49; 50)
PLUS@[50; 51)
WHITESPACE@[51; 52)
LIFETIME@[52; 59) "'static"
COMMA@[59; 60)
WHITESPACE@[60; 64)
WHERE_PRED@[64; 82)
PATH_TYPE@[64; 78)
PATH@[64; 78)
PATH@[64; 72)
PATH_SEGMENT@[64; 72)
NAME_REF@[64; 72)
IDENT@[64; 72) "Iterator"
COLONCOLON@[72; 74)
PATH_SEGMENT@[74; 78)
NAME_REF@[74; 78)
IDENT@[74; 78) "Item"
COLON@[78; 79)
WHITESPACE@[79; 80)
LIFETIME@[80; 82) "'a"
COMMA@[82; 83)
WHITESPACE@[83; 84)
BLOCK_EXPR@[84; 86)
L_CURLY@[84; 85)
R_CURLY@[85; 86)
WHITESPACE@[86; 87)