aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-06-11 18:33:20 +0100
committerGitHub <[email protected]>2020-06-11 18:33:20 +0100
commit36353bb1827dbd2efcde2d18c8598c4cc5e2e296 (patch)
tree5b08ffc573918a2210abbb5b06ec523770cbab1b /crates/ra_parser
parentbd61ad756cc0a7bfeaa5dae81ac5ab50a2e71697 (diff)
parent8622e4cc1b79f5d23b8a2c6610d749f5b987ea7e (diff)
Merge #4833
4833: Separating parsing of `for` in predicates and types r=matklad a=matthewjasper We now correctly accept `for<'a> (&'a F): Fn(&'a str)` in a where clause and correctly reject `for<'a> &'a u32` as a type. Co-authored-by: Matthew Jasper <[email protected]>
Diffstat (limited to 'crates/ra_parser')
-rw-r--r--crates/ra_parser/src/grammar/type_params.rs6
-rw-r--r--crates/ra_parser/src/grammar/types.rs16
2 files changed, 14 insertions, 8 deletions
diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs
index 50e4900c3..325d566ad 100644
--- a/crates/ra_parser/src/grammar/type_params.rs
+++ b/crates/ra_parser/src/grammar/type_params.rs
@@ -191,10 +191,14 @@ fn where_predicate(p: &mut Parser) {
191 } 191 }
192 _ => { 192 _ => {
193 // test where_pred_for 193 // test where_pred_for
194 // fn test<F>() 194 // fn for_trait<F>()
195 // where 195 // where
196 // for<'a> F: Fn(&'a str) 196 // for<'a> F: Fn(&'a str)
197 // { } 197 // { }
198 if p.at(T![for]) {
199 types::for_binder(p);
200 }
201
198 types::type_(p); 202 types::type_(p);
199 203
200 if p.at(T![:]) { 204 if p.at(T![:]) {
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs
index fe1a039cb..9e8e3bd97 100644
--- a/crates/ra_parser/src/grammar/types.rs
+++ b/crates/ra_parser/src/grammar/types.rs
@@ -216,19 +216,21 @@ pub(super) fn for_binder(p: &mut Parser) {
216 216
217// test for_type 217// test for_type
218// type A = for<'a> fn() -> (); 218// type A = for<'a> fn() -> ();
219// fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {} 219// type B = for<'a> unsafe extern "C" fn(&'a ()) -> ();
220// fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {} 220// type Obj = for<'a> PartialEq<&'a i32>;
221// fn baz<T>(_t: &T) where for<'a> <&'a T as Baz>::Foo: Iterator {}
222pub(super) fn for_type(p: &mut Parser) { 221pub(super) fn for_type(p: &mut Parser) {
223 assert!(p.at(T![for])); 222 assert!(p.at(T![for]));
224 let m = p.start(); 223 let m = p.start();
225 for_binder(p); 224 for_binder(p);
226 match p.current() { 225 match p.current() {
227 T![fn] | T![unsafe] | T![extern] => fn_pointer_type(p), 226 T![fn] | T![unsafe] | T![extern] => {}
228 T![&] => reference_type(p), 227 // OK: legacy trait object format
229 _ if paths::is_path_start(p) => path_type_(p, false), 228 _ if paths::is_use_path_start(p) => {}
230 _ => p.error("expected a path"), 229 _ => {
230 p.error("expected a function pointer or path");
231 }
231 } 232 }
233 type_no_bounds(p);
232 m.complete(p, FOR_TYPE); 234 m.complete(p, FOR_TYPE);
233} 235}
234 236