diff options
5 files changed, 33 insertions, 11 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index cf69da25a..81d4f75f9 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -300,9 +300,6 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> (Option<CompletedMarker>, | |||
300 | let has_trailing_expression = | 300 | let has_trailing_expression = |
301 | p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])); | 301 | p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])); |
302 | if !has_trailing_expression { | 302 | if !has_trailing_expression { |
303 | if op == T![..=] { | ||
304 | p.error("expected expression to end inclusive range"); | ||
305 | } | ||
306 | // no RHS | 303 | // no RHS |
307 | lhs = m.complete(p, RANGE_EXPR); | 304 | lhs = m.complete(p, RANGE_EXPR); |
308 | break; | 305 | break; |
diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index 1f60a7aab..6c171df8d 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs | |||
@@ -83,6 +83,7 @@ pub enum SyntaxErrorKind { | |||
83 | InvalidMatchInnerAttr, | 83 | InvalidMatchInnerAttr, |
84 | InvalidTupleIndexFormat, | 84 | InvalidTupleIndexFormat, |
85 | VisibilityNotAllowed, | 85 | VisibilityNotAllowed, |
86 | InclusiveRangeMissingEnd, | ||
86 | } | 87 | } |
87 | 88 | ||
88 | impl fmt::Display for SyntaxErrorKind { | 89 | impl fmt::Display for SyntaxErrorKind { |
@@ -103,6 +104,9 @@ impl fmt::Display for SyntaxErrorKind { | |||
103 | VisibilityNotAllowed => { | 104 | VisibilityNotAllowed => { |
104 | write!(f, "unnecessary visibility qualifier") | 105 | write!(f, "unnecessary visibility qualifier") |
105 | } | 106 | } |
107 | InclusiveRangeMissingEnd => { | ||
108 | write!(f, "An inclusive range must have an end expression") | ||
109 | } | ||
106 | } | 110 | } |
107 | } | 111 | } |
108 | } | 112 | } |
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index 2d596763e..e01333e23 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs | |||
@@ -103,6 +103,7 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> { | |||
103 | ast::FieldExpr(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, | 103 | ast::FieldExpr(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, |
104 | ast::RecordField(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, | 104 | ast::RecordField(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, |
105 | ast::Visibility(it) => { validate_visibility(it, &mut errors) }, | 105 | ast::Visibility(it) => { validate_visibility(it, &mut errors) }, |
106 | ast::RangeExpr(it) => { validate_range_expr(it, &mut errors) }, | ||
106 | _ => (), | 107 | _ => (), |
107 | } | 108 | } |
108 | } | 109 | } |
@@ -227,3 +228,16 @@ fn validate_visibility(vis: ast::Visibility, errors: &mut Vec<SyntaxError>) { | |||
227 | .push(SyntaxError::new(SyntaxErrorKind::VisibilityNotAllowed, vis.syntax.text_range())) | 228 | .push(SyntaxError::new(SyntaxErrorKind::VisibilityNotAllowed, vis.syntax.text_range())) |
228 | } | 229 | } |
229 | } | 230 | } |
231 | |||
232 | fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec<SyntaxError>) { | ||
233 | let last_child = match expr.syntax().last_child_or_token() { | ||
234 | Some(it) => it, | ||
235 | None => return, | ||
236 | }; | ||
237 | if last_child.kind() == T![..=] { | ||
238 | errors.push(SyntaxError::new( | ||
239 | SyntaxErrorKind::InclusiveRangeMissingEnd, | ||
240 | last_child.text_range(), | ||
241 | )); | ||
242 | } | ||
243 | } | ||
diff --git a/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.rs b/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.rs index ecd25afaf..0b4ed7a2b 100644 --- a/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.rs +++ b/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.rs | |||
@@ -1,3 +1,4 @@ | |||
1 | fn main() { | 1 | fn main() { |
2 | 0..=; | 2 | 0..=; |
3 | ..=; | ||
3 | } | 4 | } |
diff --git a/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt b/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt index 3efe98164..749d53609 100644 --- a/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt +++ b/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt | |||
@@ -1,5 +1,5 @@ | |||
1 | SOURCE_FILE@[0; 24) | 1 | SOURCE_FILE@[0; 33) |
2 | FN_DEF@[0; 23) | 2 | FN_DEF@[0; 32) |
3 | FN_KW@[0; 2) "fn" | 3 | FN_KW@[0; 2) "fn" |
4 | WHITESPACE@[2; 3) " " | 4 | WHITESPACE@[2; 3) " " |
5 | NAME@[3; 7) | 5 | NAME@[3; 7) |
@@ -8,8 +8,8 @@ SOURCE_FILE@[0; 24) | |||
8 | L_PAREN@[7; 8) "(" | 8 | L_PAREN@[7; 8) "(" |
9 | R_PAREN@[8; 9) ")" | 9 | R_PAREN@[8; 9) ")" |
10 | WHITESPACE@[9; 10) " " | 10 | WHITESPACE@[9; 10) " " |
11 | BLOCK_EXPR@[10; 23) | 11 | BLOCK_EXPR@[10; 32) |
12 | BLOCK@[10; 23) | 12 | BLOCK@[10; 32) |
13 | L_CURLY@[10; 11) "{" | 13 | L_CURLY@[10; 11) "{" |
14 | WHITESPACE@[11; 16) "\n " | 14 | WHITESPACE@[11; 16) "\n " |
15 | EXPR_STMT@[16; 21) | 15 | EXPR_STMT@[16; 21) |
@@ -18,7 +18,13 @@ SOURCE_FILE@[0; 24) | |||
18 | INT_NUMBER@[16; 17) "0" | 18 | INT_NUMBER@[16; 17) "0" |
19 | DOTDOTEQ@[17; 20) "..=" | 19 | DOTDOTEQ@[17; 20) "..=" |
20 | SEMI@[20; 21) ";" | 20 | SEMI@[20; 21) ";" |
21 | WHITESPACE@[21; 22) "\n" | 21 | WHITESPACE@[21; 26) "\n " |
22 | R_CURLY@[22; 23) "}" | 22 | EXPR_STMT@[26; 30) |
23 | WHITESPACE@[23; 24) "\n" | 23 | RANGE_EXPR@[26; 29) |
24 | error 20: expected expression to end inclusive range | 24 | DOTDOTEQ@[26; 29) "..=" |
25 | SEMI@[29; 30) ";" | ||
26 | WHITESPACE@[30; 31) "\n" | ||
27 | R_CURLY@[31; 32) "}" | ||
28 | WHITESPACE@[32; 33) "\n" | ||
29 | error [17; 20): An inclusive range must have an end expression | ||
30 | error [26; 29): An inclusive range must have an end expression | ||