From 1059ec74e2147559b43aab9b12f84849319910cc Mon Sep 17 00:00:00 2001 From: Erlend Tobiassen Date: Tue, 22 Jan 2019 01:11:35 +0100 Subject: Allow types to the left of : in where predicates. --- crates/ra_syntax/src/grammar/type_params.rs | 51 +++++++++++++++-------------- 1 file changed, 27 insertions(+), 24 deletions(-) (limited to 'crates/ra_syntax/src/grammar') diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs index 7db25beba..fe9dba2ae 100644 --- a/crates/ra_syntax/src/grammar/type_params.rs +++ b/crates/ra_syntax/src/grammar/type_params.rs @@ -104,22 +104,32 @@ 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) - { - break; - } - where_predicate(p); - if p.current() != L_CURLY && p.current() != SEMI && p.current() != EQ { - p.expect(COMMA); + + if is_where_clause_end(p) { + // Empty where clause + } else { + loop { + where_predicate(p); + + let comma = p.eat(COMMA); + + if is_where_clause_end(p) { + break; + } + + if !comma { + p.error("expected comma") + } } } + m.complete(p, WHERE_CLAUSE); } +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 +141,13 @@ fn where_predicate(p: &mut Parser) { p.error("expected colon"); } } + IMPL_KW => { + p.error("expected lifetime or type"); + return; + } _ => { - // test where_pred_for - // fn test() - // 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 { -- cgit v1.2.3 From 1aba42128f79993a092a8c0b3747acdc8f1b1be7 Mon Sep 17 00:00:00 2001 From: Erlend Tobiassen Date: Tue, 22 Jan 2019 01:25:00 +0100 Subject: Don't leave a marker hanging without completing it. --- crates/ra_syntax/src/grammar/type_params.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'crates/ra_syntax/src/grammar') diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs index fe9dba2ae..f33ec10f5 100644 --- a/crates/ra_syntax/src/grammar/type_params.rs +++ b/crates/ra_syntax/src/grammar/type_params.rs @@ -118,7 +118,7 @@ pub(super) fn opt_where_clause(p: &mut Parser) { } if !comma { - p.error("expected comma") + p.error("expected comma"); } } } @@ -143,7 +143,6 @@ fn where_predicate(p: &mut Parser) { } IMPL_KW => { p.error("expected lifetime or type"); - return; } _ => { types::type_(p); -- cgit v1.2.3 From 2b22f5fb4398378d999db98ea270ceb415dfff22 Mon Sep 17 00:00:00 2001 From: Erlend Tobiassen Date: Tue, 22 Jan 2019 13:17:10 +0100 Subject: Optimistically bail out of where clause loop if not at start of a type or lifetime --- crates/ra_syntax/src/grammar/type_params.rs | 28 ++++++++++++++++------------ crates/ra_syntax/src/grammar/types.rs | 8 ++++++++ 2 files changed, 24 insertions(+), 12 deletions(-) (limited to 'crates/ra_syntax/src/grammar') diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs index f33ec10f5..a7eacf97a 100644 --- a/crates/ra_syntax/src/grammar/type_params.rs +++ b/crates/ra_syntax/src/grammar/type_params.rs @@ -105,27 +105,31 @@ pub(super) fn opt_where_clause(p: &mut Parser) { let m = p.start(); p.bump(); - if is_where_clause_end(p) { - // Empty where clause - } else { - loop { - where_predicate(p); + while is_where_predicate(p) { + where_predicate(p); - let comma = p.eat(COMMA); + let comma = p.eat(COMMA); - if is_where_clause_end(p) { - break; - } + if is_where_clause_end(p) { + break; + } - if !comma { - p.error("expected 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, + _ => types::is_type_start(p), + } +} + fn is_where_clause_end(p: &mut Parser) -> bool { p.current() == L_CURLY || p.current() == SEMI || p.current() == EQ } diff --git a/crates/ra_syntax/src/grammar/types.rs b/crates/ra_syntax/src/grammar/types.rs index 21d89d83b..83a54c190 100644 --- a/crates/ra_syntax/src/grammar/types.rs +++ b/crates/ra_syntax/src/grammar/types.rs @@ -36,6 +36,14 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) { } } +pub(super) fn is_type_start(p: &mut Parser) -> bool { + match p.current() { + L_PAREN | EXCL | STAR | L_BRACK | AMP | UNDERSCORE | FN_KW | FOR_KW | IMPL_KW | DYN_KW + | L_ANGLE => true, + _ => paths::is_path_start(p), + } +} + pub(super) fn ascription(p: &mut Parser) { p.expect(COLON); type_(p) -- cgit v1.2.3 From 8198cde13b8dc7c04190e5341bce3f6a0315e99b Mon Sep 17 00:00:00 2001 From: Erlend Tobiassen Date: Tue, 22 Jan 2019 14:32:23 +0100 Subject: Update tests after allowing where predicate to accept types --- crates/ra_syntax/src/grammar/type_params.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'crates/ra_syntax/src/grammar') diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs index a7eacf97a..369125b39 100644 --- a/crates/ra_syntax/src/grammar/type_params.rs +++ b/crates/ra_syntax/src/grammar/type_params.rs @@ -149,6 +149,11 @@ fn where_predicate(p: &mut Parser) { p.error("expected lifetime or type"); } _ => { + // test where_pred_for + // fn test() + // where + // for<'a> F: Fn(&'a str) + // { } types::type_(p); if p.at(COLON) { -- cgit v1.2.3 From 9f3d133813e519ea769c23565843587dea8d55b2 Mon Sep 17 00:00:00 2001 From: Erlend Tobiassen Date: Tue, 22 Jan 2019 14:36:57 +0100 Subject: Prefer TYPE_FIRST --- crates/ra_syntax/src/grammar/types.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'crates/ra_syntax/src/grammar') diff --git a/crates/ra_syntax/src/grammar/types.rs b/crates/ra_syntax/src/grammar/types.rs index 83a54c190..c626abcfd 100644 --- a/crates/ra_syntax/src/grammar/types.rs +++ b/crates/ra_syntax/src/grammar/types.rs @@ -37,10 +37,10 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) { } pub(super) fn is_type_start(p: &mut Parser) -> bool { - match p.current() { - L_PAREN | EXCL | STAR | L_BRACK | AMP | UNDERSCORE | FN_KW | FOR_KW | IMPL_KW | DYN_KW - | L_ANGLE => true, - _ => paths::is_path_start(p), + if TYPE_FIRST.contains(p.current()) { + true + } else { + paths::is_path_start(p) } } -- cgit v1.2.3 From 84f888e93ddfcaa573f65ddf49180a4665f14b50 Mon Sep 17 00:00:00 2001 From: Erlend Tobiassen Date: Tue, 22 Jan 2019 14:46:06 +0100 Subject: No need for is_type_start --- crates/ra_syntax/src/grammar/type_params.rs | 2 +- crates/ra_syntax/src/grammar/types.rs | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'crates/ra_syntax/src/grammar') diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs index 369125b39..1ec813b3e 100644 --- a/crates/ra_syntax/src/grammar/type_params.rs +++ b/crates/ra_syntax/src/grammar/type_params.rs @@ -126,7 +126,7 @@ fn is_where_predicate(p: &mut Parser) -> bool { match p.current() { LIFETIME => true, IMPL_KW => false, - _ => types::is_type_start(p), + token => types::TYPE_FIRST.contains(token), } } diff --git a/crates/ra_syntax/src/grammar/types.rs b/crates/ra_syntax/src/grammar/types.rs index c626abcfd..21d89d83b 100644 --- a/crates/ra_syntax/src/grammar/types.rs +++ b/crates/ra_syntax/src/grammar/types.rs @@ -36,14 +36,6 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) { } } -pub(super) fn is_type_start(p: &mut Parser) -> bool { - if TYPE_FIRST.contains(p.current()) { - true - } else { - paths::is_path_start(p) - } -} - pub(super) fn ascription(p: &mut Parser) { p.expect(COLON); type_(p) -- cgit v1.2.3