From 506e1ddbfa5213f254923da9bbf0efddc6f1fc34 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 10 Jun 2020 11:30:48 +0100 Subject: Separating parsing of `for` in predicates and types --- crates/ra_parser/src/grammar/type_params.rs | 22 +++++++++++++++++++++- crates/ra_parser/src/grammar/types.rs | 15 ++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) (limited to 'crates/ra_parser') diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs index 50e4900c3..b3508c732 100644 --- a/crates/ra_parser/src/grammar/type_params.rs +++ b/crates/ra_parser/src/grammar/type_params.rs @@ -191,10 +191,30 @@ fn where_predicate(p: &mut Parser) { } _ => { // test where_pred_for - // fn test() + // fn for_trait() // where // for<'a> F: Fn(&'a str) // { } + // fn for_ref() + // where + // for<'a> &'a F: Debug + // { } + // fn for_parens() + // where + // for<'a> (&'a F): Fn(&'a str) + // { } + // fn for_slice() + // where + // for<'a> [&'a F]: Eq + // { } + // fn for_qpath(_t: &T) + // where + // for<'a> <&'a T as Baz>::Foo: Iterator + // { } + if p.at(T![for]) { + types::for_binder(p); + } + types::type_(p); if p.at(T![:]) { diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs index fe1a039cb..63dd3774f 100644 --- a/crates/ra_parser/src/grammar/types.rs +++ b/crates/ra_parser/src/grammar/types.rs @@ -216,19 +216,20 @@ pub(super) fn for_binder(p: &mut Parser) { // test for_type // type A = for<'a> fn() -> (); -// fn foo(_t: &T) where for<'a> &'a T: Iterator {} -// fn bar(_t: &T) where for<'a> &'a mut T: Iterator {} -// fn baz(_t: &T) where for<'a> <&'a T as Baz>::Foo: Iterator {} +// type B = for<'a> unsafe extern "C" fn(&'a ()) -> (); pub(super) fn for_type(p: &mut Parser) { assert!(p.at(T![for])); let m = p.start(); for_binder(p); match p.current() { - T![fn] | T![unsafe] | T![extern] => fn_pointer_type(p), - T![&] => reference_type(p), - _ if paths::is_path_start(p) => path_type_(p, false), - _ => p.error("expected a path"), + T![fn] | T![unsafe] | T![extern] => {} + // OK: legacy trait object format + _ if paths::is_use_path_start(p) => {} + _ => { + p.error("expected a function pointer or path"); + } } + type_no_bounds(p); m.complete(p, FOR_TYPE); } -- cgit v1.2.3