aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_parser/src/grammar/items/use_item.rs18
-rw-r--r--crates/ra_parser/src/grammar/types.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/err/0036_partial_use.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/err/0036_partial_use.txt51
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.rs3
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.txt66
6 files changed, 134 insertions, 8 deletions
diff --git a/crates/ra_parser/src/grammar/items/use_item.rs b/crates/ra_parser/src/grammar/items/use_item.rs
index 2af2ad315..63ac37e9e 100644
--- a/crates/ra_parser/src/grammar/items/use_item.rs
+++ b/crates/ra_parser/src/grammar/items/use_item.rs
@@ -3,7 +3,7 @@ use super::*;
3pub(super) fn use_item(p: &mut Parser, m: Marker) { 3pub(super) fn use_item(p: &mut Parser, m: Marker) {
4 assert!(p.at(T![use])); 4 assert!(p.at(T![use]));
5 p.bump(T![use]); 5 p.bump(T![use]);
6 use_tree(p); 6 use_tree(p, true);
7 p.expect(T![;]); 7 p.expect(T![;]);
8 m.complete(p, USE_ITEM); 8 m.complete(p, USE_ITEM);
9} 9}
@@ -12,7 +12,7 @@ pub(super) fn use_item(p: &mut Parser, m: Marker) {
12/// Note that this is called both by `use_item` and `use_tree_list`, 12/// Note that this is called both by `use_item` and `use_tree_list`,
13/// so handles both `some::path::{inner::path}` and `inner::path` in 13/// so handles both `some::path::{inner::path}` and `inner::path` in
14/// `use some::path::{inner::path};` 14/// `use some::path::{inner::path};`
15fn use_tree(p: &mut Parser) { 15fn use_tree(p: &mut Parser, top_level: bool) {
16 let m = p.start(); 16 let m = p.start();
17 match p.current() { 17 match p.current() {
18 // Finish the use_tree for cases of e.g. 18 // Finish the use_tree for cases of e.g.
@@ -101,10 +101,14 @@ fn use_tree(p: &mut Parser) {
101 } 101 }
102 _ => { 102 _ => {
103 m.abandon(p); 103 m.abandon(p);
104 p.err_recover( 104 let msg = "expected one of `*`, `::`, `{`, `self`, `super` or an identifier";
105 "expected one of `*`, `::`, `{`, `self`, `super` or an identifier", 105 if top_level {
106 ITEM_RECOVERY_SET, 106 p.err_recover(msg, ITEM_RECOVERY_SET);
107 ); 107 } else {
108 // if we are parsing a nested tree, we have to eat a token to
109 // main balanced `{}`
110 p.err_and_bump(msg);
111 }
108 return; 112 return;
109 } 113 }
110 } 114 }
@@ -116,7 +120,7 @@ pub(crate) fn use_tree_list(p: &mut Parser) {
116 let m = p.start(); 120 let m = p.start();
117 p.bump(T!['{']); 121 p.bump(T!['{']);
118 while !p.at(EOF) && !p.at(T!['}']) { 122 while !p.at(EOF) && !p.at(T!['}']) {
119 use_tree(p); 123 use_tree(p, false);
120 if !p.at(T!['}']) { 124 if !p.at(T!['}']) {
121 p.expect(T![,]); 125 p.expect(T![,]);
122 } 126 }
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs
index bd3829f41..4e3522d48 100644
--- a/crates/ra_parser/src/grammar/types.rs
+++ b/crates/ra_parser/src/grammar/types.rs
@@ -256,7 +256,7 @@ fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) {
256 let m = p.start(); 256 let m = p.start();
257 paths::type_path(p); 257 paths::type_path(p);
258 258
259 let kind = if p.at(T![!]) { 259 let kind = if p.at(T![!]) && !p.at(T![!=]) {
260 items::macro_call_after_excl(p); 260 items::macro_call_after_excl(p);
261 MACRO_CALL 261 MACRO_CALL
262 } else { 262 } else {
diff --git a/crates/ra_syntax/test_data/parser/err/0036_partial_use.rs b/crates/ra_syntax/test_data/parser/err/0036_partial_use.rs
new file mode 100644
index 000000000..d521a5bb2
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/err/0036_partial_use.rs
@@ -0,0 +1,2 @@
1use std::{error::Error;
2use std::io;
diff --git a/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt b/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt
new file mode 100644
index 000000000..181f408c8
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt
@@ -0,0 +1,51 @@
1SOURCE_FILE@[0; 37)
2 USE_ITEM@[0; 36)
3 USE_KW@[0; 3) "use"
4 WHITESPACE@[3; 4) " "
5 USE_TREE@[4; 36)
6 PATH@[4; 7)
7 PATH_SEGMENT@[4; 7)
8 NAME_REF@[4; 7)
9 IDENT@[4; 7) "std"
10 COLONCOLON@[7; 9) "::"
11 USE_TREE_LIST@[9; 36)
12 L_CURLY@[9; 10) "{"
13 USE_TREE@[10; 22)
14 PATH@[10; 22)
15 PATH@[10; 15)
16 PATH_SEGMENT@[10; 15)
17 NAME_REF@[10; 15)
18 IDENT@[10; 15) "error"
19 COLONCOLON@[15; 17) "::"
20 PATH_SEGMENT@[17; 22)
21 NAME_REF@[17; 22)
22 IDENT@[17; 22) "Error"
23 ERROR@[22; 23)
24 SEMI@[22; 23) ";"
25 WHITESPACE@[23; 24) "\n"
26 ERROR@[24; 27)
27 USE_KW@[24; 27) "use"
28 WHITESPACE@[27; 28) " "
29 USE_TREE@[28; 35)
30 PATH@[28; 35)
31 PATH@[28; 31)
32 PATH_SEGMENT@[28; 31)
33 NAME_REF@[28; 31)
34 IDENT@[28; 31) "std"
35 COLONCOLON@[31; 33) "::"
36 PATH_SEGMENT@[33; 35)
37 NAME_REF@[33; 35)
38 IDENT@[33; 35) "io"
39 ERROR@[35; 36)
40 SEMI@[35; 36) ";"
41 WHITESPACE@[36; 37) "\n"
42error 22: expected COMMA
43error 22: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
44error 23: expected COMMA
45error 24: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
46error 27: expected COMMA
47error 35: expected COMMA
48error 35: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
49error 36: expected COMMA
50error 36: expected R_CURLY
51error 36: expected SEMI
diff --git a/crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.rs b/crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.rs
new file mode 100644
index 000000000..6210683ce
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.rs
@@ -0,0 +1,3 @@
1fn main() {
2 if 1.0f32.floor() as i64 != 1.0f32.floor() as i64 {}
3}
diff --git a/crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.txt b/crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.txt
new file mode 100644
index 000000000..4a4ad84ca
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.txt
@@ -0,0 +1,66 @@
1SOURCE_FILE@[0; 71)
2 FN_DEF@[0; 70)
3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " "
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8) "("
9 R_PAREN@[8; 9) ")"
10 WHITESPACE@[9; 10) " "
11 BLOCK_EXPR@[10; 70)
12 BLOCK@[10; 70)
13 L_CURLY@[10; 11) "{"
14 WHITESPACE@[11; 16) "\n "
15 IF_EXPR@[16; 68)
16 IF_KW@[16; 18) "if"
17 WHITESPACE@[18; 19) " "
18 CONDITION@[19; 65)
19 BIN_EXPR@[19; 65)
20 CAST_EXPR@[19; 40)
21 METHOD_CALL_EXPR@[19; 33)
22 LITERAL@[19; 25)
23 FLOAT_NUMBER@[19; 25) "1.0f32"
24 DOT@[25; 26) "."
25 NAME_REF@[26; 31)
26 IDENT@[26; 31) "floor"
27 ARG_LIST@[31; 33)
28 L_PAREN@[31; 32) "("
29 R_PAREN@[32; 33) ")"
30 WHITESPACE@[33; 34) " "
31 AS_KW@[34; 36) "as"
32 WHITESPACE@[36; 37) " "
33 PATH_TYPE@[37; 40)
34 PATH@[37; 40)
35 PATH_SEGMENT@[37; 40)
36 NAME_REF@[37; 40)
37 IDENT@[37; 40) "i64"
38 WHITESPACE@[40; 41) " "
39 NEQ@[41; 43) "!="
40 WHITESPACE@[43; 44) " "
41 CAST_EXPR@[44; 65)
42 METHOD_CALL_EXPR@[44; 58)
43 LITERAL@[44; 50)
44 FLOAT_NUMBER@[44; 50) "1.0f32"
45 DOT@[50; 51) "."
46 NAME_REF@[51; 56)
47 IDENT@[51; 56) "floor"
48 ARG_LIST@[56; 58)
49 L_PAREN@[56; 57) "("
50 R_PAREN@[57; 58) ")"
51 WHITESPACE@[58; 59) " "
52 AS_KW@[59; 61) "as"
53 WHITESPACE@[61; 62) " "
54 PATH_TYPE@[62; 65)
55 PATH@[62; 65)
56 PATH_SEGMENT@[62; 65)
57 NAME_REF@[62; 65)
58 IDENT@[62; 65) "i64"
59 WHITESPACE@[65; 66) " "
60 BLOCK_EXPR@[66; 68)
61 BLOCK@[66; 68)
62 L_CURLY@[66; 67) "{"
63 R_CURLY@[67; 68) "}"
64 WHITESPACE@[68; 69) "\n"
65 R_CURLY@[69; 70) "}"
66 WHITESPACE@[70; 71) "\n"