592: Allow types to the left of `:` in where predicates r=matklad a=regiontog

Adresses #584 

Co-authored-by: Erlend Tobiassen <erlend.tobiassen@gmail.com>
This commit is contained in:
bors[bot] 2019-01-22 13:49:33 +00:00
commit 9e0abfc0c9
5 changed files with 91 additions and 37 deletions

View File

@ -104,22 +104,36 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
}
let m = p.start();
p.bump();
loop {
if !(paths::is_path_start(p)
|| p.current() == LIFETIME
|| p.current() == FOR_KW
|| p.current() == L_ANGLE)
{
while is_where_predicate(p) {
where_predicate(p);
let comma = p.eat(COMMA);
if is_where_clause_end(p) {
break;
}
where_predicate(p);
if p.current() != L_CURLY && p.current() != SEMI && p.current() != EQ {
p.expect(COMMA);
if !comma {
p.error("expected comma");
}
}
m.complete(p, WHERE_CLAUSE);
}
fn is_where_predicate(p: &mut Parser) -> bool {
match p.current() {
LIFETIME => true,
IMPL_KW => false,
token => types::TYPE_FIRST.contains(token),
}
}
fn is_where_clause_end(p: &mut Parser) -> bool {
p.current() == L_CURLY || p.current() == SEMI || p.current() == EQ
}
fn where_predicate(p: &mut Parser) {
let m = p.start();
match p.current() {
@ -131,20 +145,17 @@ fn where_predicate(p: &mut Parser) {
p.error("expected colon");
}
}
IMPL_KW => {
p.error("expected lifetime or type");
}
_ => {
// test where_pred_for
// fn test<F>()
// where
// for<'a> F: Fn(&'a str)
// { }
if p.at(FOR_KW) {
types::for_binder(p);
}
if paths::is_path_start(p) || p.at(L_ANGLE) {
types::path_type_(p, false);
} else {
p.error("expected a type");
}
types::type_(p);
if p.at(COLON) {
bounds(p);
} else {

View File

@ -12,14 +12,15 @@ SOURCE_FILE@[0; 30)
WHERE_KW@[13; 18)
WHITESPACE@[18; 19)
WHERE_PRED@[19; 26)
FOR_KW@[19; 22)
TYPE_PARAM_LIST@[22; 26)
L_ANGLE@[22; 23)
LIFETIME_PARAM@[23; 25)
LIFETIME@[23; 25) "'a"
R_ANGLE@[25; 26)
err: `expected a type`
err: `expected colon`
FOR_TYPE@[19; 26)
FOR_KW@[19; 22)
TYPE_PARAM_LIST@[22; 26)
L_ANGLE@[22; 23)
LIFETIME_PARAM@[23; 25)
LIFETIME@[23; 25) "'a"
R_ANGLE@[25; 26)
err: `expected a path`
err: `expected colon`
WHITESPACE@[26; 27)
BLOCK@[27; 29)
L_CURLY@[27; 28)

View File

@ -18,18 +18,19 @@ SOURCE_FILE@[0; 49)
WHERE_KW@[13; 18)
WHITESPACE@[18; 22)
WHERE_PRED@[22; 44)
FOR_KW@[22; 25)
TYPE_PARAM_LIST@[25; 29)
L_ANGLE@[25; 26)
LIFETIME_PARAM@[26; 28)
LIFETIME@[26; 28) "'a"
R_ANGLE@[28; 29)
WHITESPACE@[29; 30)
PATH_TYPE@[30; 31)
PATH@[30; 31)
PATH_SEGMENT@[30; 31)
NAME_REF@[30; 31)
IDENT@[30; 31) "F"
FOR_TYPE@[22; 31)
FOR_KW@[22; 25)
TYPE_PARAM_LIST@[25; 29)
L_ANGLE@[25; 26)
LIFETIME_PARAM@[26; 28)
LIFETIME@[26; 28) "'a"
R_ANGLE@[28; 29)
WHITESPACE@[29; 30)
PATH_TYPE@[30; 31)
PATH@[30; 31)
PATH_SEGMENT@[30; 31)
NAME_REF@[30; 31)
IDENT@[30; 31) "F"
COLON@[31; 32)
WHITESPACE@[32; 33)
PATH_TYPE@[33; 44)

View File

@ -0,0 +1 @@
fn test() where (u64, u64): Foo {}

View File

@ -0,0 +1,40 @@
SOURCE_FILE@[0; 34)
FN_DEF@[0; 34)
FN_KW@[0; 2)
WHITESPACE@[2; 3)
NAME@[3; 7)
IDENT@[3; 7) "test"
PARAM_LIST@[7; 9)
L_PAREN@[7; 8)
R_PAREN@[8; 9)
WHITESPACE@[9; 10)
WHERE_CLAUSE@[10; 31)
WHERE_KW@[10; 15)
WHITESPACE@[15; 16)
WHERE_PRED@[16; 31)
TUPLE_TYPE@[16; 26)
L_PAREN@[16; 17)
PATH_TYPE@[17; 20)
PATH@[17; 20)
PATH_SEGMENT@[17; 20)
NAME_REF@[17; 20)
IDENT@[17; 20) "u64"
COMMA@[20; 21)
WHITESPACE@[21; 22)
PATH_TYPE@[22; 25)
PATH@[22; 25)
PATH_SEGMENT@[22; 25)
NAME_REF@[22; 25)
IDENT@[22; 25) "u64"
R_PAREN@[25; 26)
COLON@[26; 27)
WHITESPACE@[27; 28)
PATH_TYPE@[28; 31)
PATH@[28; 31)
PATH_SEGMENT@[28; 31)
NAME_REF@[28; 31)
IDENT@[28; 31) "Foo"
WHITESPACE@[31; 32)
BLOCK@[32; 34)
L_CURLY@[32; 33)
R_CURLY@[33; 34)