aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide_api_light/src/folding_ranges.rs13
-rw-r--r--crates/ra_syntax/src/grammar/type_params.rs45
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0027_incomplere_where_for.txt17
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0003_where_pred_for.txt25
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0038_where_pred_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0038_where_pred_type.txt40
6 files changed, 103 insertions, 38 deletions
diff --git a/crates/ra_ide_api_light/src/folding_ranges.rs b/crates/ra_ide_api_light/src/folding_ranges.rs
index 6f3106889..288bba0ce 100644
--- a/crates/ra_ide_api_light/src/folding_ranges.rs
+++ b/crates/ra_ide_api_light/src/folding_ranges.rs
@@ -63,7 +63,7 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
63 COMMENT => Some(FoldKind::Comment), 63 COMMENT => Some(FoldKind::Comment),
64 USE_ITEM => Some(FoldKind::Imports), 64 USE_ITEM => Some(FoldKind::Imports),
65 NAMED_FIELD_DEF_LIST | FIELD_PAT_LIST | ITEM_LIST | EXTERN_ITEM_LIST | USE_TREE_LIST 65 NAMED_FIELD_DEF_LIST | FIELD_PAT_LIST | ITEM_LIST | EXTERN_ITEM_LIST | USE_TREE_LIST
66 | BLOCK | ENUM_VARIANT_LIST => Some(FoldKind::Block), 66 | BLOCK | ENUM_VARIANT_LIST | TOKEN_TREE => Some(FoldKind::Block),
67 _ => None, 67 _ => None,
68 } 68 }
69} 69}
@@ -294,4 +294,15 @@ fn main() <fold>{
294 do_check(text, folds); 294 do_check(text, folds);
295 } 295 }
296 296
297 #[test]
298 fn test_folds_macros() {
299 let text = r#"
300macro_rules! foo <fold>{
301 ($($tt:tt)*) => { $($tt)* }
302}</fold>
303"#;
304
305 let folds = &[FoldKind::Block];
306 do_check(text, folds);
307 }
297} 308}
diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs
index 7db25beba..1ec813b3e 100644
--- a/crates/ra_syntax/src/grammar/type_params.rs
+++ b/crates/ra_syntax/src/grammar/type_params.rs
@@ -104,22 +104,36 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
104 } 104 }
105 let m = p.start(); 105 let m = p.start();
106 p.bump(); 106 p.bump();
107 loop { 107
108 if !(paths::is_path_start(p) 108 while is_where_predicate(p) {
109 || p.current() == LIFETIME 109 where_predicate(p);
110 || p.current() == FOR_KW 110
111 || p.current() == L_ANGLE) 111 let comma = p.eat(COMMA);
112 { 112
113 if is_where_clause_end(p) {
113 break; 114 break;
114 } 115 }
115 where_predicate(p); 116
116 if p.current() != L_CURLY && p.current() != SEMI && p.current() != EQ { 117 if !comma {
117 p.expect(COMMA); 118 p.error("expected comma");
118 } 119 }
119 } 120 }
121
120 m.complete(p, WHERE_CLAUSE); 122 m.complete(p, WHERE_CLAUSE);
121} 123}
122 124
125fn is_where_predicate(p: &mut Parser) -> bool {
126 match p.current() {
127 LIFETIME => true,
128 IMPL_KW => false,
129 token => types::TYPE_FIRST.contains(token),
130 }
131}
132
133fn is_where_clause_end(p: &mut Parser) -> bool {
134 p.current() == L_CURLY || p.current() == SEMI || p.current() == EQ
135}
136
123fn where_predicate(p: &mut Parser) { 137fn where_predicate(p: &mut Parser) {
124 let m = p.start(); 138 let m = p.start();
125 match p.current() { 139 match p.current() {
@@ -131,20 +145,17 @@ fn where_predicate(p: &mut Parser) {
131 p.error("expected colon"); 145 p.error("expected colon");
132 } 146 }
133 } 147 }
148 IMPL_KW => {
149 p.error("expected lifetime or type");
150 }
134 _ => { 151 _ => {
135 // test where_pred_for 152 // test where_pred_for
136 // fn test<F>() 153 // fn test<F>()
137 // where 154 // where
138 // for<'a> F: Fn(&'a str) 155 // for<'a> F: Fn(&'a str)
139 // { } 156 // { }
140 if p.at(FOR_KW) { 157 types::type_(p);
141 types::for_binder(p); 158
142 }
143 if paths::is_path_start(p) || p.at(L_ANGLE) {
144 types::path_type_(p, false);
145 } else {
146 p.error("expected a type");
147 }
148 if p.at(COLON) { 159 if p.at(COLON) {
149 bounds(p); 160 bounds(p);
150 } else { 161 } else {
diff --git a/crates/ra_syntax/tests/data/parser/err/0027_incomplere_where_for.txt b/crates/ra_syntax/tests/data/parser/err/0027_incomplere_where_for.txt
index 694295a60..8a2a73b9b 100644
--- a/crates/ra_syntax/tests/data/parser/err/0027_incomplere_where_for.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0027_incomplere_where_for.txt
@@ -12,14 +12,15 @@ SOURCE_FILE@[0; 30)
12 WHERE_KW@[13; 18) 12 WHERE_KW@[13; 18)
13 WHITESPACE@[18; 19) 13 WHITESPACE@[18; 19)
14 WHERE_PRED@[19; 26) 14 WHERE_PRED@[19; 26)
15 FOR_KW@[19; 22) 15 FOR_TYPE@[19; 26)
16 TYPE_PARAM_LIST@[22; 26) 16 FOR_KW@[19; 22)
17 L_ANGLE@[22; 23) 17 TYPE_PARAM_LIST@[22; 26)
18 LIFETIME_PARAM@[23; 25) 18 L_ANGLE@[22; 23)
19 LIFETIME@[23; 25) "'a" 19 LIFETIME_PARAM@[23; 25)
20 R_ANGLE@[25; 26) 20 LIFETIME@[23; 25) "'a"
21 err: `expected a type` 21 R_ANGLE@[25; 26)
22 err: `expected colon` 22 err: `expected a path`
23 err: `expected colon`
23 WHITESPACE@[26; 27) 24 WHITESPACE@[26; 27)
24 BLOCK@[27; 29) 25 BLOCK@[27; 29)
25 L_CURLY@[27; 28) 26 L_CURLY@[27; 28)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0003_where_pred_for.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0003_where_pred_for.txt
index 921bdacf4..41420ea92 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0003_where_pred_for.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0003_where_pred_for.txt
@@ -18,18 +18,19 @@ SOURCE_FILE@[0; 49)
18 WHERE_KW@[13; 18) 18 WHERE_KW@[13; 18)
19 WHITESPACE@[18; 22) 19 WHITESPACE@[18; 22)
20 WHERE_PRED@[22; 44) 20 WHERE_PRED@[22; 44)
21 FOR_KW@[22; 25) 21 FOR_TYPE@[22; 31)
22 TYPE_PARAM_LIST@[25; 29) 22 FOR_KW@[22; 25)
23 L_ANGLE@[25; 26) 23 TYPE_PARAM_LIST@[25; 29)
24 LIFETIME_PARAM@[26; 28) 24 L_ANGLE@[25; 26)
25 LIFETIME@[26; 28) "'a" 25 LIFETIME_PARAM@[26; 28)
26 R_ANGLE@[28; 29) 26 LIFETIME@[26; 28) "'a"
27 WHITESPACE@[29; 30) 27 R_ANGLE@[28; 29)
28 PATH_TYPE@[30; 31) 28 WHITESPACE@[29; 30)
29 PATH@[30; 31) 29 PATH_TYPE@[30; 31)
30 PATH_SEGMENT@[30; 31) 30 PATH@[30; 31)
31 NAME_REF@[30; 31) 31 PATH_SEGMENT@[30; 31)
32 IDENT@[30; 31) "F" 32 NAME_REF@[30; 31)
33 IDENT@[30; 31) "F"
33 COLON@[31; 32) 34 COLON@[31; 32)
34 WHITESPACE@[32; 33) 35 WHITESPACE@[32; 33)
35 PATH_TYPE@[33; 44) 36 PATH_TYPE@[33; 44)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0038_where_pred_type.rs b/crates/ra_syntax/tests/data/parser/ok/0038_where_pred_type.rs
new file mode 100644
index 000000000..8bfc341a5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0038_where_pred_type.rs
@@ -0,0 +1 @@
fn test() where (u64, u64): Foo {} \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/ok/0038_where_pred_type.txt b/crates/ra_syntax/tests/data/parser/ok/0038_where_pred_type.txt
new file mode 100644
index 000000000..4842e9b90
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0038_where_pred_type.txt
@@ -0,0 +1,40 @@
1SOURCE_FILE@[0; 34)
2 FN_DEF@[0; 34)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "test"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 WHERE_CLAUSE@[10; 31)
12 WHERE_KW@[10; 15)
13 WHITESPACE@[15; 16)
14 WHERE_PRED@[16; 31)
15 TUPLE_TYPE@[16; 26)
16 L_PAREN@[16; 17)
17 PATH_TYPE@[17; 20)
18 PATH@[17; 20)
19 PATH_SEGMENT@[17; 20)
20 NAME_REF@[17; 20)
21 IDENT@[17; 20) "u64"
22 COMMA@[20; 21)
23 WHITESPACE@[21; 22)
24 PATH_TYPE@[22; 25)
25 PATH@[22; 25)
26 PATH_SEGMENT@[22; 25)
27 NAME_REF@[22; 25)
28 IDENT@[22; 25) "u64"
29 R_PAREN@[25; 26)
30 COLON@[26; 27)
31 WHITESPACE@[27; 28)
32 PATH_TYPE@[28; 31)
33 PATH@[28; 31)
34 PATH_SEGMENT@[28; 31)
35 NAME_REF@[28; 31)
36 IDENT@[28; 31) "Foo"
37 WHITESPACE@[31; 32)
38 BLOCK@[32; 34)
39 L_CURLY@[32; 33)
40 R_CURLY@[33; 34)