diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-02-18 12:57:26 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-02-18 12:57:26 +0000 |
commit | c447fe9bc06006a7080da782cf67d739c91b534c (patch) | |
tree | 45cbc9578b24437da3eedc6a234784be22b1f38c | |
parent | 742459c8fe08e359ae380e3e1dc0d059c0b4f871 (diff) | |
parent | 053ccf4121797e4e559e3225d46d3f23cb1ad70b (diff) |
Merge #3026
3026: ra_syntax: reshape SyntaxError for the sake of removing redundancy r=matklad a=Veetaha
Followup of #2911, also puts some crosses to the todo list of #223.
**AHTUNG!** A big part of the diff of this PR are test data files changes.
Simplified `SyntaxError` that was `SyntaxError { kind: { /* big enum */ }, location: Location }` to `SyntaxError(String, TextRange)`. I am not sure whether the tuple struct here is best fit, I am inclined to add names to the fields, because I already provide getters `SyntaxError::message()`, `SyntaxError::range()`.
I also removed `Location` altogether ...
This is currently WIP, because the following is not done:
- [ ] ~~Add tests to `test_data` dir for unescape errors *// I don't know where to put these errors in particular, because they are out of the scope of the lexer and parser. However, I have an idea in mind that we move all validators we have right now to parsing stage, but this is up to discussion...*~~ **[UPD]** I came to a conclusion that tree validation logic, which unescape errors are a part of, should be rethought of, we currently have no tests and no place to put tests for tree validations. So I'd like to extract potential redesign (maybe move of tree validation to ra_parser) and adding tests for this into a separate task.
Co-authored-by: Veetaha <[email protected]>
Co-authored-by: Veetaha <[email protected]>
56 files changed, 452 insertions, 650 deletions
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs index 22bd49723..82596c665 100644 --- a/crates/ra_ide/src/diagnostics.rs +++ b/crates/ra_ide/src/diagnostics.rs | |||
@@ -10,7 +10,7 @@ use ra_prof::profile; | |||
10 | use ra_syntax::{ | 10 | use ra_syntax::{ |
11 | algo, | 11 | algo, |
12 | ast::{self, make, AstNode}, | 12 | ast::{self, make, AstNode}, |
13 | Location, SyntaxNode, TextRange, T, | 13 | SyntaxNode, TextRange, T, |
14 | }; | 14 | }; |
15 | use ra_text_edit::{TextEdit, TextEditBuilder}; | 15 | use ra_text_edit::{TextEdit, TextEditBuilder}; |
16 | 16 | ||
@@ -29,7 +29,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> | |||
29 | let mut res = Vec::new(); | 29 | let mut res = Vec::new(); |
30 | 30 | ||
31 | res.extend(parse.errors().iter().map(|err| Diagnostic { | 31 | res.extend(parse.errors().iter().map(|err| Diagnostic { |
32 | range: location_to_range(err.location()), | 32 | range: err.range(), |
33 | message: format!("Syntax Error: {}", err), | 33 | message: format!("Syntax Error: {}", err), |
34 | severity: Severity::Error, | 34 | severity: Severity::Error, |
35 | fix: None, | 35 | fix: None, |
@@ -116,12 +116,6 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> | |||
116 | drop(sink); | 116 | drop(sink); |
117 | res.into_inner() | 117 | res.into_inner() |
118 | } | 118 | } |
119 | fn location_to_range(location: Location) -> TextRange { | ||
120 | match location { | ||
121 | Location::Offset(offset) => TextRange::offset_len(offset, 1.into()), | ||
122 | Location::Range(range) => range, | ||
123 | } | ||
124 | } | ||
125 | 119 | ||
126 | fn check_unnecessary_braces_in_use_statement( | 120 | fn check_unnecessary_braces_in_use_statement( |
127 | acc: &mut Vec<Diagnostic>, | 121 | acc: &mut Vec<Diagnostic>, |
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index f8f4b64c1..e3f74da6d 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -41,11 +41,9 @@ use crate::syntax_node::GreenNode; | |||
41 | pub use crate::{ | 41 | pub use crate::{ |
42 | algo::InsertPosition, | 42 | algo::InsertPosition, |
43 | ast::{AstNode, AstToken}, | 43 | ast::{AstNode, AstToken}, |
44 | parsing::{ | 44 | parsing::{lex_single_syntax_kind, lex_single_valid_syntax_kind, tokenize, Token}, |
45 | lex_single_syntax_kind, lex_single_valid_syntax_kind, tokenize, Token, TokenizeError, | ||
46 | }, | ||
47 | ptr::{AstPtr, SyntaxNodePtr}, | 45 | ptr::{AstPtr, SyntaxNodePtr}, |
48 | syntax_error::{Location, SyntaxError, SyntaxErrorKind}, | 46 | syntax_error::SyntaxError, |
49 | syntax_node::{ | 47 | syntax_node::{ |
50 | Direction, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken, SyntaxTreeBuilder, | 48 | Direction, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken, SyntaxTreeBuilder, |
51 | }, | 49 | }, |
@@ -117,7 +115,7 @@ impl Parse<SourceFile> { | |||
117 | pub fn debug_dump(&self) -> String { | 115 | pub fn debug_dump(&self) -> String { |
118 | let mut buf = format!("{:#?}", self.tree().syntax()); | 116 | let mut buf = format!("{:#?}", self.tree().syntax()); |
119 | for err in self.errors.iter() { | 117 | for err in self.errors.iter() { |
120 | writeln!(buf, "error {:?}: {}", err.location(), err.kind()).unwrap(); | 118 | writeln!(buf, "error {:?}: {}", err.range(), err).unwrap(); |
121 | } | 119 | } |
122 | buf | 120 | buf |
123 | } | 121 | } |
diff --git a/crates/ra_syntax/src/parsing/lexer.rs b/crates/ra_syntax/src/parsing/lexer.rs index f889e6a1d..f2684c852 100644 --- a/crates/ra_syntax/src/parsing/lexer.rs +++ b/crates/ra_syntax/src/parsing/lexer.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | //! It is just a bridge to `rustc_lexer`. | 2 | //! It is just a bridge to `rustc_lexer`. |
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | SyntaxError, SyntaxErrorKind, | 5 | SyntaxError, |
6 | SyntaxKind::{self, *}, | 6 | SyntaxKind::{self, *}, |
7 | TextRange, TextUnit, | 7 | TextRange, TextUnit, |
8 | }; | 8 | }; |
@@ -41,13 +41,13 @@ pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) { | |||
41 | let token_len = TextUnit::from_usize(rustc_token.len); | 41 | let token_len = TextUnit::from_usize(rustc_token.len); |
42 | let token_range = TextRange::offset_len(TextUnit::from_usize(offset), token_len); | 42 | let token_range = TextRange::offset_len(TextUnit::from_usize(offset), token_len); |
43 | 43 | ||
44 | let (syntax_kind, error) = | 44 | let (syntax_kind, err_message) = |
45 | rustc_token_kind_to_syntax_kind(&rustc_token.kind, &text[token_range]); | 45 | rustc_token_kind_to_syntax_kind(&rustc_token.kind, &text[token_range]); |
46 | 46 | ||
47 | tokens.push(Token { kind: syntax_kind, len: token_len }); | 47 | tokens.push(Token { kind: syntax_kind, len: token_len }); |
48 | 48 | ||
49 | if let Some(error) = error { | 49 | if let Some(err_message) = err_message { |
50 | errors.push(SyntaxError::new(SyntaxErrorKind::TokenizeError(error), token_range)); | 50 | errors.push(SyntaxError::new(err_message, token_range)); |
51 | } | 51 | } |
52 | 52 | ||
53 | offset += rustc_token.len; | 53 | offset += rustc_token.len; |
@@ -94,61 +94,21 @@ fn lex_first_token(text: &str) -> Option<(Token, Option<SyntaxError>)> { | |||
94 | } | 94 | } |
95 | 95 | ||
96 | let rustc_token = rustc_lexer::first_token(text); | 96 | let rustc_token = rustc_lexer::first_token(text); |
97 | let (syntax_kind, error) = rustc_token_kind_to_syntax_kind(&rustc_token.kind, text); | 97 | let (syntax_kind, err_message) = rustc_token_kind_to_syntax_kind(&rustc_token.kind, text); |
98 | 98 | ||
99 | let token = Token { kind: syntax_kind, len: TextUnit::from_usize(rustc_token.len) }; | 99 | let token = Token { kind: syntax_kind, len: TextUnit::from_usize(rustc_token.len) }; |
100 | let error = error.map(|error| { | 100 | let optional_error = err_message.map(|err_message| { |
101 | SyntaxError::new( | 101 | SyntaxError::new(err_message, TextRange::from_to(0.into(), TextUnit::of_str(text))) |
102 | SyntaxErrorKind::TokenizeError(error), | ||
103 | TextRange::from_to(TextUnit::from(0), TextUnit::of_str(text)), | ||
104 | ) | ||
105 | }); | 102 | }); |
106 | 103 | ||
107 | Some((token, error)) | 104 | Some((token, optional_error)) |
108 | } | ||
109 | |||
110 | // FIXME: simplify TokenizeError to `SyntaxError(String, TextRange)` as per @matklad advice: | ||
111 | // https://github.com/rust-analyzer/rust-analyzer/pull/2911/files#r371175067 | ||
112 | |||
113 | /// Describes the values of `SyntaxErrorKind::TokenizeError` enum variant. | ||
114 | /// It describes all the types of errors that may happen during the tokenization | ||
115 | /// of Rust source. | ||
116 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
117 | pub enum TokenizeError { | ||
118 | /// Base prefix was provided, but there were no digits | ||
119 | /// after it, e.g. `0x`, `0b`. | ||
120 | EmptyInt, | ||
121 | /// Float exponent lacks digits e.g. `12.34e+`, `12.3E+`, `12e-`, `1_E-`, | ||
122 | EmptyExponent, | ||
123 | |||
124 | /// Block comment lacks trailing delimiter `*/` | ||
125 | UnterminatedBlockComment, | ||
126 | /// Character literal lacks trailing delimiter `'` | ||
127 | UnterminatedChar, | ||
128 | /// Characterish byte literal lacks trailing delimiter `'` | ||
129 | UnterminatedByte, | ||
130 | /// String literal lacks trailing delimiter `"` | ||
131 | UnterminatedString, | ||
132 | /// Byte string literal lacks trailing delimiter `"` | ||
133 | UnterminatedByteString, | ||
134 | /// Raw literal lacks trailing delimiter e.g. `"##` | ||
135 | UnterminatedRawString, | ||
136 | /// Raw byte string literal lacks trailing delimiter e.g. `"##` | ||
137 | UnterminatedRawByteString, | ||
138 | |||
139 | /// Raw string lacks a quote after the pound characters e.g. `r###` | ||
140 | UnstartedRawString, | ||
141 | /// Raw byte string lacks a quote after the pound characters e.g. `br###` | ||
142 | UnstartedRawByteString, | ||
143 | |||
144 | /// Lifetime starts with a number e.g. `'4ever` | ||
145 | LifetimeStartsWithNumber, | ||
146 | } | 105 | } |
147 | 106 | ||
107 | /// Returns `SyntaxKind` and an optional tokenize error message. | ||
148 | fn rustc_token_kind_to_syntax_kind( | 108 | fn rustc_token_kind_to_syntax_kind( |
149 | rustc_token_kind: &rustc_lexer::TokenKind, | 109 | rustc_token_kind: &rustc_lexer::TokenKind, |
150 | token_text: &str, | 110 | token_text: &str, |
151 | ) -> (SyntaxKind, Option<TokenizeError>) { | 111 | ) -> (SyntaxKind, Option<&'static str>) { |
152 | // A note on an intended tradeoff: | 112 | // A note on an intended tradeoff: |
153 | // We drop some useful infromation here (see patterns with double dots `..`) | 113 | // We drop some useful infromation here (see patterns with double dots `..`) |
154 | // Storing that info in `SyntaxKind` is not possible due to its layout requirements of | 114 | // Storing that info in `SyntaxKind` is not possible due to its layout requirements of |
@@ -156,14 +116,15 @@ fn rustc_token_kind_to_syntax_kind( | |||
156 | 116 | ||
157 | let syntax_kind = { | 117 | let syntax_kind = { |
158 | use rustc_lexer::TokenKind as TK; | 118 | use rustc_lexer::TokenKind as TK; |
159 | use TokenizeError as TE; | ||
160 | |||
161 | match rustc_token_kind { | 119 | match rustc_token_kind { |
162 | TK::LineComment => COMMENT, | 120 | TK::LineComment => COMMENT, |
163 | 121 | ||
164 | TK::BlockComment { terminated: true } => COMMENT, | 122 | TK::BlockComment { terminated: true } => COMMENT, |
165 | TK::BlockComment { terminated: false } => { | 123 | TK::BlockComment { terminated: false } => { |
166 | return (COMMENT, Some(TE::UnterminatedBlockComment)); | 124 | return ( |
125 | COMMENT, | ||
126 | Some("Missing trailing `*/` symbols to terminate the block comment"), | ||
127 | ); | ||
167 | } | 128 | } |
168 | 129 | ||
169 | TK::Whitespace => WHITESPACE, | 130 | TK::Whitespace => WHITESPACE, |
@@ -181,7 +142,7 @@ fn rustc_token_kind_to_syntax_kind( | |||
181 | 142 | ||
182 | TK::Lifetime { starts_with_number: false } => LIFETIME, | 143 | TK::Lifetime { starts_with_number: false } => LIFETIME, |
183 | TK::Lifetime { starts_with_number: true } => { | 144 | TK::Lifetime { starts_with_number: true } => { |
184 | return (LIFETIME, Some(TE::LifetimeStartsWithNumber)) | 145 | return (LIFETIME, Some("Lifetime name cannot start with a number")) |
185 | } | 146 | } |
186 | 147 | ||
187 | TK::Semi => SEMI, | 148 | TK::Semi => SEMI, |
@@ -217,57 +178,56 @@ fn rustc_token_kind_to_syntax_kind( | |||
217 | 178 | ||
218 | return (syntax_kind, None); | 179 | return (syntax_kind, None); |
219 | 180 | ||
220 | fn match_literal_kind(kind: &rustc_lexer::LiteralKind) -> (SyntaxKind, Option<TokenizeError>) { | 181 | fn match_literal_kind(kind: &rustc_lexer::LiteralKind) -> (SyntaxKind, Option<&'static str>) { |
221 | use rustc_lexer::LiteralKind as LK; | 182 | use rustc_lexer::LiteralKind as LK; |
222 | use TokenizeError as TE; | ||
223 | 183 | ||
224 | #[rustfmt::skip] | 184 | #[rustfmt::skip] |
225 | let syntax_kind = match *kind { | 185 | let syntax_kind = match *kind { |
226 | LK::Int { empty_int: false, .. } => INT_NUMBER, | 186 | LK::Int { empty_int: false, .. } => INT_NUMBER, |
227 | LK::Int { empty_int: true, .. } => { | 187 | LK::Int { empty_int: true, .. } => { |
228 | return (INT_NUMBER, Some(TE::EmptyInt)) | 188 | return (INT_NUMBER, Some("Missing digits after the integer base prefix")) |
229 | } | 189 | } |
230 | 190 | ||
231 | LK::Float { empty_exponent: false, .. } => FLOAT_NUMBER, | 191 | LK::Float { empty_exponent: false, .. } => FLOAT_NUMBER, |
232 | LK::Float { empty_exponent: true, .. } => { | 192 | LK::Float { empty_exponent: true, .. } => { |
233 | return (FLOAT_NUMBER, Some(TE::EmptyExponent)) | 193 | return (FLOAT_NUMBER, Some("Missing digits after the exponent symbol")) |
234 | } | 194 | } |
235 | 195 | ||
236 | LK::Char { terminated: true } => CHAR, | 196 | LK::Char { terminated: true } => CHAR, |
237 | LK::Char { terminated: false } => { | 197 | LK::Char { terminated: false } => { |
238 | return (CHAR, Some(TE::UnterminatedChar)) | 198 | return (CHAR, Some("Missing trailing `'` symbol to terminate the character literal")) |
239 | } | 199 | } |
240 | 200 | ||
241 | LK::Byte { terminated: true } => BYTE, | 201 | LK::Byte { terminated: true } => BYTE, |
242 | LK::Byte { terminated: false } => { | 202 | LK::Byte { terminated: false } => { |
243 | return (BYTE, Some(TE::UnterminatedByte)) | 203 | return (BYTE, Some("Missing trailing `'` symbol to terminate the byte literal")) |
244 | } | 204 | } |
245 | 205 | ||
246 | LK::Str { terminated: true } => STRING, | 206 | LK::Str { terminated: true } => STRING, |
247 | LK::Str { terminated: false } => { | 207 | LK::Str { terminated: false } => { |
248 | return (STRING, Some(TE::UnterminatedString)) | 208 | return (STRING, Some("Missing trailing `\"` symbol to terminate the string literal")) |
249 | } | 209 | } |
250 | 210 | ||
251 | 211 | ||
252 | LK::ByteStr { terminated: true } => BYTE_STRING, | 212 | LK::ByteStr { terminated: true } => BYTE_STRING, |
253 | LK::ByteStr { terminated: false } => { | 213 | LK::ByteStr { terminated: false } => { |
254 | return (BYTE_STRING, Some(TE::UnterminatedByteString)) | 214 | return (BYTE_STRING, Some("Missing trailing `\"` symbol to terminate the byte string literal")) |
255 | } | 215 | } |
256 | 216 | ||
257 | LK::RawStr { started: true, terminated: true, .. } => RAW_STRING, | 217 | LK::RawStr { started: true, terminated: true, .. } => RAW_STRING, |
258 | LK::RawStr { started: true, terminated: false, .. } => { | 218 | LK::RawStr { started: true, terminated: false, .. } => { |
259 | return (RAW_STRING, Some(TE::UnterminatedRawString)) | 219 | return (RAW_STRING, Some("Missing trailing `\"` with `#` symbols to terminate the raw string literal")) |
260 | } | 220 | } |
261 | LK::RawStr { started: false, .. } => { | 221 | LK::RawStr { started: false, .. } => { |
262 | return (RAW_STRING, Some(TE::UnstartedRawString)) | 222 | return (RAW_STRING, Some("Missing `\"` symbol after `#` symbols to begin the raw string literal")) |
263 | } | 223 | } |
264 | 224 | ||
265 | LK::RawByteStr { started: true, terminated: true, .. } => RAW_BYTE_STRING, | 225 | LK::RawByteStr { started: true, terminated: true, .. } => RAW_BYTE_STRING, |
266 | LK::RawByteStr { started: true, terminated: false, .. } => { | 226 | LK::RawByteStr { started: true, terminated: false, .. } => { |
267 | return (RAW_BYTE_STRING, Some(TE::UnterminatedRawByteString)) | 227 | return (RAW_BYTE_STRING, Some("Missing trailing `\"` with `#` symbols to terminate the raw byte string literal")) |
268 | } | 228 | } |
269 | LK::RawByteStr { started: false, .. } => { | 229 | LK::RawByteStr { started: false, .. } => { |
270 | return (RAW_BYTE_STRING, Some(TE::UnstartedRawByteString)) | 230 | return (RAW_BYTE_STRING, Some("Missing `\"` symbol after `#` symbols to begin the raw byte string literal")) |
271 | } | 231 | } |
272 | }; | 232 | }; |
273 | 233 | ||
diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index a86da0675..aad70d015 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs | |||
@@ -27,8 +27,8 @@ pub(crate) fn incremental_reparse( | |||
27 | edit: &AtomTextEdit, | 27 | edit: &AtomTextEdit, |
28 | errors: Vec<SyntaxError>, | 28 | errors: Vec<SyntaxError>, |
29 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { | 29 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { |
30 | if let Some((green, old_range)) = reparse_token(node, &edit) { | 30 | if let Some((green, new_errors, old_range)) = reparse_token(node, &edit) { |
31 | return Some((green, merge_errors(errors, Vec::new(), old_range, edit), old_range)); | 31 | return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range)); |
32 | } | 32 | } |
33 | 33 | ||
34 | if let Some((green, new_errors, old_range)) = reparse_block(node, &edit) { | 34 | if let Some((green, new_errors, old_range)) = reparse_block(node, &edit) { |
@@ -40,7 +40,7 @@ pub(crate) fn incremental_reparse( | |||
40 | fn reparse_token<'node>( | 40 | fn reparse_token<'node>( |
41 | root: &'node SyntaxNode, | 41 | root: &'node SyntaxNode, |
42 | edit: &AtomTextEdit, | 42 | edit: &AtomTextEdit, |
43 | ) -> Option<(GreenNode, TextRange)> { | 43 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { |
44 | let prev_token = algo::find_covering_element(root, edit.delete).as_token()?.clone(); | 44 | let prev_token = algo::find_covering_element(root, edit.delete).as_token()?.clone(); |
45 | let prev_token_kind = prev_token.kind(); | 45 | let prev_token_kind = prev_token.kind(); |
46 | match prev_token_kind { | 46 | match prev_token_kind { |
@@ -54,7 +54,7 @@ fn reparse_token<'node>( | |||
54 | } | 54 | } |
55 | 55 | ||
56 | let mut new_text = get_text_after_edit(prev_token.clone().into(), &edit); | 56 | let mut new_text = get_text_after_edit(prev_token.clone().into(), &edit); |
57 | let (new_token_kind, _error) = lex_single_syntax_kind(&new_text)?; | 57 | let (new_token_kind, new_err) = lex_single_syntax_kind(&new_text)?; |
58 | 58 | ||
59 | if new_token_kind != prev_token_kind | 59 | if new_token_kind != prev_token_kind |
60 | || (new_token_kind == IDENT && is_contextual_kw(&new_text)) | 60 | || (new_token_kind == IDENT && is_contextual_kw(&new_text)) |
@@ -76,7 +76,11 @@ fn reparse_token<'node>( | |||
76 | 76 | ||
77 | let new_token = | 77 | let new_token = |
78 | GreenToken::new(rowan::SyntaxKind(prev_token_kind.into()), new_text.into()); | 78 | GreenToken::new(rowan::SyntaxKind(prev_token_kind.into()), new_text.into()); |
79 | Some((prev_token.replace_with(new_token), prev_token.text_range())) | 79 | Some(( |
80 | prev_token.replace_with(new_token), | ||
81 | new_err.into_iter().collect(), | ||
82 | prev_token.text_range(), | ||
83 | )) | ||
80 | } | 84 | } |
81 | _ => None, | 85 | _ => None, |
82 | } | 86 | } |
@@ -87,7 +91,7 @@ fn reparse_block<'node>( | |||
87 | edit: &AtomTextEdit, | 91 | edit: &AtomTextEdit, |
88 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { | 92 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { |
89 | let (node, reparser) = find_reparsable_node(root, edit.delete)?; | 93 | let (node, reparser) = find_reparsable_node(root, edit.delete)?; |
90 | let text = get_text_after_edit(node.clone().into(), &edit); | 94 | let text = get_text_after_edit(node.clone().into(), edit); |
91 | 95 | ||
92 | let (tokens, new_lexer_errors) = tokenize(&text); | 96 | let (tokens, new_lexer_errors) = tokenize(&text); |
93 | if !is_balanced(&tokens) { | 97 | if !is_balanced(&tokens) { |
@@ -162,20 +166,27 @@ fn is_balanced(tokens: &[Token]) -> bool { | |||
162 | fn merge_errors( | 166 | fn merge_errors( |
163 | old_errors: Vec<SyntaxError>, | 167 | old_errors: Vec<SyntaxError>, |
164 | new_errors: Vec<SyntaxError>, | 168 | new_errors: Vec<SyntaxError>, |
165 | old_range: TextRange, | 169 | range_before_reparse: TextRange, |
166 | edit: &AtomTextEdit, | 170 | edit: &AtomTextEdit, |
167 | ) -> Vec<SyntaxError> { | 171 | ) -> Vec<SyntaxError> { |
168 | let mut res = Vec::new(); | 172 | let mut res = Vec::new(); |
169 | for e in old_errors { | 173 | |
170 | if e.offset() <= old_range.start() { | 174 | for old_err in old_errors { |
171 | res.push(e) | 175 | let old_err_range = old_err.range(); |
172 | } else if e.offset() >= old_range.end() { | 176 | // FIXME: make sure that .start() was here previously by a mistake |
173 | res.push(e.add_offset(TextUnit::of_str(&edit.insert), edit.delete.len())); | 177 | if old_err_range.end() <= range_before_reparse.start() { |
178 | res.push(old_err); | ||
179 | } else if old_err_range.start() >= range_before_reparse.end() { | ||
180 | let inserted_len = TextUnit::of_str(&edit.insert); | ||
181 | res.push(old_err.with_range((old_err_range + inserted_len) - edit.delete.len())); | ||
182 | // Note: extra parens are intentional to prevent uint underflow, HWAB (here was a bug) | ||
174 | } | 183 | } |
175 | } | 184 | } |
176 | for e in new_errors { | 185 | res.extend(new_errors.into_iter().map(|new_err| { |
177 | res.push(e.add_offset(old_range.start(), 0.into())); | 186 | // fighting borrow checker with a variable ;) |
178 | } | 187 | let offseted_range = new_err.range() + range_before_reparse.start(); |
188 | new_err.with_range(offseted_range) | ||
189 | })); | ||
179 | res | 190 | res |
180 | } | 191 | } |
181 | 192 | ||
@@ -193,9 +204,9 @@ mod tests { | |||
193 | 204 | ||
194 | let fully_reparsed = SourceFile::parse(&after); | 205 | let fully_reparsed = SourceFile::parse(&after); |
195 | let incrementally_reparsed: Parse<SourceFile> = { | 206 | let incrementally_reparsed: Parse<SourceFile> = { |
196 | let f = SourceFile::parse(&before); | 207 | let before = SourceFile::parse(&before); |
197 | let (green, new_errors, range) = | 208 | let (green, new_errors, range) = |
198 | incremental_reparse(f.tree().syntax(), &edit, f.errors.to_vec()).unwrap(); | 209 | incremental_reparse(before.tree().syntax(), &edit, before.errors.to_vec()).unwrap(); |
199 | assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length"); | 210 | assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length"); |
200 | Parse::new(green, new_errors) | 211 | Parse::new(green, new_errors) |
201 | }; | 212 | }; |
@@ -204,6 +215,7 @@ mod tests { | |||
204 | &format!("{:#?}", fully_reparsed.tree().syntax()), | 215 | &format!("{:#?}", fully_reparsed.tree().syntax()), |
205 | &format!("{:#?}", incrementally_reparsed.tree().syntax()), | 216 | &format!("{:#?}", incrementally_reparsed.tree().syntax()), |
206 | ); | 217 | ); |
218 | assert_eq!(fully_reparsed.errors(), incrementally_reparsed.errors()); | ||
207 | } | 219 | } |
208 | 220 | ||
209 | #[test] // FIXME: some test here actually test token reparsing | 221 | #[test] // FIXME: some test here actually test token reparsing |
@@ -402,4 +414,42 @@ enum Foo { | |||
402 | 4, | 414 | 4, |
403 | ); | 415 | ); |
404 | } | 416 | } |
417 | |||
418 | #[test] | ||
419 | fn reparse_str_token_with_error_unchanged() { | ||
420 | do_check(r#""<|>Unclosed<|> string literal"#, "Still unclosed", 24); | ||
421 | } | ||
422 | |||
423 | #[test] | ||
424 | fn reparse_str_token_with_error_fixed() { | ||
425 | do_check(r#""unterinated<|><|>"#, "\"", 12); | ||
426 | } | ||
427 | |||
428 | #[test] | ||
429 | fn reparse_block_with_error_in_middle_unchanged() { | ||
430 | do_check( | ||
431 | r#"fn main() { | ||
432 | if {} | ||
433 | 32 + 4<|><|> | ||
434 | return | ||
435 | if {} | ||
436 | }"#, | ||
437 | "23", | ||
438 | 105, | ||
439 | ) | ||
440 | } | ||
441 | |||
442 | #[test] | ||
443 | fn reparse_block_with_error_in_middle_fixed() { | ||
444 | do_check( | ||
445 | r#"fn main() { | ||
446 | if {} | ||
447 | 32 + 4<|><|> | ||
448 | return | ||
449 | if {} | ||
450 | }"#, | ||
451 | ";", | ||
452 | 105, | ||
453 | ) | ||
454 | } | ||
405 | } | 455 | } |
diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index 7f9d36618..54acf7847 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs | |||
@@ -1,209 +1,44 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! See docs for `SyntaxError`. |
2 | 2 | ||
3 | use std::fmt; | 3 | use std::fmt; |
4 | 4 | ||
5 | use ra_parser::ParseError; | 5 | use crate::{TextRange, TextUnit}; |
6 | |||
7 | use crate::{validation::EscapeError, TextRange, TextUnit, TokenizeError}; | ||
8 | 6 | ||
7 | /// Represents the result of unsuccessful tokenization, parsing | ||
8 | /// or tree validation. | ||
9 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 9 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
10 | pub struct SyntaxError { | 10 | pub struct SyntaxError(String, TextRange); |
11 | kind: SyntaxErrorKind, | 11 | |
12 | location: Location, | 12 | // FIXME: there was an unused SyntaxErrorKind previously (before this enum was removed) |
13 | } | 13 | // It was introduced in this PR: https://github.com/rust-analyzer/rust-analyzer/pull/846/files#diff-827da9b03b8f9faa1bade5cdd44d5dafR95 |
14 | 14 | // but it was not removed by a mistake. | |
15 | // FIXME: Location should be just `Location(TextRange)` | 15 | // |
16 | // TextUnit enum member just unnecessarily compicates things, | 16 | // So, we need to find a place where to stick validation for attributes in match clauses. |
17 | // we should'n treat it specially, it just as a `TextRange { start: x, end: x + 1 }` | 17 | // Code before refactor: |
18 | // see `location_to_range()` in ra_ide/src/diagnostics | 18 | // InvalidMatchInnerAttr => { |
19 | #[derive(Clone, PartialEq, Eq, Hash)] | 19 | // write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression") |
20 | pub enum Location { | 20 | // } |
21 | Offset(TextUnit), | ||
22 | Range(TextRange), | ||
23 | } | ||
24 | |||
25 | impl From<TextUnit> for Location { | ||
26 | fn from(offset: TextUnit) -> Location { | ||
27 | Location::Offset(offset) | ||
28 | } | ||
29 | } | ||
30 | |||
31 | impl From<TextRange> for Location { | ||
32 | fn from(range: TextRange) -> Location { | ||
33 | Location::Range(range) | ||
34 | } | ||
35 | } | ||
36 | |||
37 | impl fmt::Debug for Location { | ||
38 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
39 | match self { | ||
40 | Location::Offset(it) => fmt::Debug::fmt(it, f), | ||
41 | Location::Range(it) => fmt::Debug::fmt(it, f), | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | 21 | ||
46 | impl SyntaxError { | 22 | impl SyntaxError { |
47 | pub fn new<L: Into<Location>>(kind: SyntaxErrorKind, loc: L) -> SyntaxError { | 23 | pub fn new(message: impl Into<String>, range: TextRange) -> Self { |
48 | SyntaxError { kind, location: loc.into() } | 24 | Self(message.into(), range) |
49 | } | 25 | } |
50 | 26 | pub fn new_at_offset(message: impl Into<String>, offset: TextUnit) -> Self { | |
51 | pub fn kind(&self) -> SyntaxErrorKind { | 27 | Self(message.into(), TextRange::offset_len(offset, 0.into())) |
52 | self.kind.clone() | ||
53 | } | 28 | } |
54 | 29 | ||
55 | pub fn location(&self) -> Location { | 30 | pub fn range(&self) -> TextRange { |
56 | self.location.clone() | 31 | self.1 |
57 | } | 32 | } |
58 | 33 | ||
59 | pub fn offset(&self) -> TextUnit { | 34 | pub fn with_range(mut self, range: TextRange) -> Self { |
60 | match self.location { | 35 | self.1 = range; |
61 | Location::Offset(offset) => offset, | ||
62 | Location::Range(range) => range.start(), | ||
63 | } | ||
64 | } | ||
65 | |||
66 | pub fn add_offset(mut self, plus_offset: TextUnit, minus_offset: TextUnit) -> SyntaxError { | ||
67 | self.location = match self.location { | ||
68 | Location::Range(range) => Location::Range(range + plus_offset - minus_offset), | ||
69 | Location::Offset(offset) => Location::Offset(offset + plus_offset - minus_offset), | ||
70 | }; | ||
71 | |||
72 | self | 36 | self |
73 | } | 37 | } |
74 | |||
75 | pub fn debug_dump(&self, acc: &mut impl fmt::Write) { | ||
76 | writeln!(acc, "error {:?}: {}", self.location(), self.kind()).unwrap(); | ||
77 | } | ||
78 | } | 38 | } |
79 | 39 | ||
80 | impl fmt::Display for SyntaxError { | 40 | impl fmt::Display for SyntaxError { |
81 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 41 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
82 | self.kind.fmt(f) | 42 | self.0.fmt(f) |
83 | } | ||
84 | } | ||
85 | |||
86 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
87 | pub enum SyntaxErrorKind { | ||
88 | ParseError(ParseError), | ||
89 | EscapeError(EscapeError), | ||
90 | TokenizeError(TokenizeError), | ||
91 | // FIXME: the obvious pattern of this enum dictates that the following enum variants | ||
92 | // should be wrapped into something like `SemmanticError(SemmanticError)` | ||
93 | // or `ValidateError(ValidateError)` or `SemmanticValidateError(...)` | ||
94 | InvalidBlockAttr, | ||
95 | InvalidMatchInnerAttr, | ||
96 | InvalidTupleIndexFormat, | ||
97 | VisibilityNotAllowed, | ||
98 | InclusiveRangeMissingEnd, | ||
99 | } | ||
100 | |||
101 | impl fmt::Display for SyntaxErrorKind { | ||
102 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
103 | use self::SyntaxErrorKind::*; | ||
104 | match self { | ||
105 | InvalidBlockAttr => { | ||
106 | write!(f, "A block in this position cannot accept inner attributes") | ||
107 | } | ||
108 | InvalidMatchInnerAttr => { | ||
109 | write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression") | ||
110 | } | ||
111 | InvalidTupleIndexFormat => { | ||
112 | write!(f, "Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix") | ||
113 | } | ||
114 | ParseError(msg) => write!(f, "{}", msg.0), | ||
115 | EscapeError(err) => write!(f, "{}", err), | ||
116 | TokenizeError(err) => write!(f, "{}", err), | ||
117 | VisibilityNotAllowed => { | ||
118 | write!(f, "unnecessary visibility qualifier") | ||
119 | } | ||
120 | InclusiveRangeMissingEnd => { | ||
121 | write!(f, "An inclusive range must have an end expression") | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | |||
127 | impl fmt::Display for TokenizeError { | ||
128 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
129 | #[rustfmt::skip] | ||
130 | let msg = match self { | ||
131 | TokenizeError::EmptyInt => { | ||
132 | "Missing digits after the integer base prefix" | ||
133 | } | ||
134 | TokenizeError::EmptyExponent => { | ||
135 | "Missing digits after the exponent symbol" | ||
136 | } | ||
137 | TokenizeError::UnterminatedBlockComment => { | ||
138 | "Missing trailing `*/` symbols to terminate the block comment" | ||
139 | } | ||
140 | TokenizeError::UnterminatedChar => { | ||
141 | "Missing trailing `'` symbol to terminate the character literal" | ||
142 | } | ||
143 | TokenizeError::UnterminatedByte => { | ||
144 | "Missing trailing `'` symbol to terminate the byte literal" | ||
145 | } | ||
146 | TokenizeError::UnterminatedString => { | ||
147 | "Missing trailing `\"` symbol to terminate the string literal" | ||
148 | } | ||
149 | TokenizeError::UnterminatedByteString => { | ||
150 | "Missing trailing `\"` symbol to terminate the byte string literal" | ||
151 | } | ||
152 | TokenizeError::UnterminatedRawString => { | ||
153 | "Missing trailing `\"` with `#` symbols to terminate the raw string literal" | ||
154 | } | ||
155 | TokenizeError::UnterminatedRawByteString => { | ||
156 | "Missing trailing `\"` with `#` symbols to terminate the raw byte string literal" | ||
157 | } | ||
158 | TokenizeError::UnstartedRawString => { | ||
159 | "Missing `\"` symbol after `#` symbols to begin the raw string literal" | ||
160 | } | ||
161 | TokenizeError::UnstartedRawByteString => { | ||
162 | "Missing `\"` symbol after `#` symbols to begin the raw byte string literal" | ||
163 | } | ||
164 | TokenizeError::LifetimeStartsWithNumber => { | ||
165 | "Lifetime name cannot start with a number" | ||
166 | } | ||
167 | }; | ||
168 | write!(f, "{}", msg) | ||
169 | } | ||
170 | } | ||
171 | |||
172 | impl fmt::Display for EscapeError { | ||
173 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
174 | let msg = match self { | ||
175 | EscapeError::ZeroChars => "Empty literal", | ||
176 | EscapeError::MoreThanOneChar => "Literal should be one character long", | ||
177 | EscapeError::LoneSlash => "Character must be escaped: '\\'", | ||
178 | EscapeError::InvalidEscape => "Invalid escape sequence", | ||
179 | EscapeError::BareCarriageReturn => "Character must be escaped: '\r'", | ||
180 | EscapeError::EscapeOnlyChar => "Character must be escaped", | ||
181 | EscapeError::TooShortHexEscape => "Escape sequence should have two digits", | ||
182 | EscapeError::InvalidCharInHexEscape => "Escape sequence should be a hexadecimal number", | ||
183 | EscapeError::OutOfRangeHexEscape => "Escape sequence should be ASCII", | ||
184 | EscapeError::NoBraceInUnicodeEscape => "Invalid escape sequence", | ||
185 | EscapeError::InvalidCharInUnicodeEscape => "Invalid escape sequence", | ||
186 | EscapeError::EmptyUnicodeEscape => "Invalid escape sequence", | ||
187 | EscapeError::UnclosedUnicodeEscape => "Missing '}'", | ||
188 | EscapeError::LeadingUnderscoreUnicodeEscape => "Invalid escape sequence", | ||
189 | EscapeError::OverlongUnicodeEscape => { | ||
190 | "Unicode escape sequence should have at most 6 digits" | ||
191 | } | ||
192 | EscapeError::LoneSurrogateUnicodeEscape => { | ||
193 | "Unicode escape code should not be a surrogate" | ||
194 | } | ||
195 | EscapeError::OutOfRangeUnicodeEscape => { | ||
196 | "Unicode escape code should be at most 0x10FFFF" | ||
197 | } | ||
198 | EscapeError::UnicodeEscapeInByte => "Unicode escapes are not allowed in bytes", | ||
199 | EscapeError::NonAsciiCharInByte => "Non ASCII characters are not allowed in bytes", | ||
200 | }; | ||
201 | write!(f, "{}", msg) | ||
202 | } | ||
203 | } | ||
204 | |||
205 | impl From<EscapeError> for SyntaxErrorKind { | ||
206 | fn from(err: EscapeError) -> Self { | ||
207 | SyntaxErrorKind::EscapeError(err) | ||
208 | } | 43 | } |
209 | } | 44 | } |
diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index 7c2b18af3..4e3a1460d 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs | |||
@@ -6,13 +6,9 @@ | |||
6 | //! The *real* implementation is in the (language-agnostic) `rowan` crate, this | 6 | //! The *real* implementation is in the (language-agnostic) `rowan` crate, this |
7 | //! module just wraps its API. | 7 | //! module just wraps its API. |
8 | 8 | ||
9 | use ra_parser::ParseError; | ||
10 | use rowan::{GreenNodeBuilder, Language}; | 9 | use rowan::{GreenNodeBuilder, Language}; |
11 | 10 | ||
12 | use crate::{ | 11 | use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextUnit}; |
13 | syntax_error::{SyntaxError, SyntaxErrorKind}, | ||
14 | Parse, SmolStr, SyntaxKind, TextUnit, | ||
15 | }; | ||
16 | 12 | ||
17 | pub(crate) use rowan::{GreenNode, GreenToken}; | 13 | pub(crate) use rowan::{GreenNode, GreenToken}; |
18 | 14 | ||
@@ -73,8 +69,7 @@ impl SyntaxTreeBuilder { | |||
73 | self.inner.finish_node() | 69 | self.inner.finish_node() |
74 | } | 70 | } |
75 | 71 | ||
76 | pub fn error(&mut self, error: ParseError, text_pos: TextUnit) { | 72 | pub fn error(&mut self, error: ra_parser::ParseError, text_pos: TextUnit) { |
77 | let error = SyntaxError::new(SyntaxErrorKind::ParseError(error), text_pos); | 73 | self.errors.push(SyntaxError::new_at_offset(error.0, text_pos)) |
78 | self.errors.push(error) | ||
79 | } | 74 | } |
80 | } | 75 | } |
diff --git a/crates/ra_syntax/src/tests.rs b/crates/ra_syntax/src/tests.rs index fb22b9e54..912e6aec0 100644 --- a/crates/ra_syntax/src/tests.rs +++ b/crates/ra_syntax/src/tests.rs | |||
@@ -5,7 +5,7 @@ use std::{ | |||
5 | 5 | ||
6 | use test_utils::{collect_tests, dir_tests, project_dir, read_text}; | 6 | use test_utils::{collect_tests, dir_tests, project_dir, read_text}; |
7 | 7 | ||
8 | use crate::{fuzz, tokenize, Location, SourceFile, SyntaxError, TextRange, Token}; | 8 | use crate::{fuzz, tokenize, SourceFile, SyntaxError, Token}; |
9 | 9 | ||
10 | #[test] | 10 | #[test] |
11 | fn lexer_tests() { | 11 | fn lexer_tests() { |
@@ -128,25 +128,8 @@ fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) | |||
128 | writeln!(acc, "{:?} {} {:?}", token.kind, token_len, token_text).unwrap(); | 128 | writeln!(acc, "{:?} {} {:?}", token.kind, token_len, token_text).unwrap(); |
129 | } | 129 | } |
130 | for err in errors { | 130 | for err in errors { |
131 | let err_range = location_to_range(err.location()); | 131 | writeln!(acc, "> error{:?} token({:?}) msg({})", err.range(), &text[err.range()], err) |
132 | writeln!( | 132 | .unwrap(); |
133 | acc, | ||
134 | "> error{:?} token({:?}) msg({})", | ||
135 | err.location(), | ||
136 | &text[err_range], | ||
137 | err.kind() | ||
138 | ) | ||
139 | .unwrap(); | ||
140 | } | ||
141 | return acc; | ||
142 | |||
143 | // FIXME: copy-pasted this from `ra_ide/src/diagnostics.rs` | ||
144 | // `Location` will be refactored soon in new PR, see todos here: | ||
145 | // https://github.com/rust-analyzer/rust-analyzer/issues/223 | ||
146 | fn location_to_range(location: Location) -> TextRange { | ||
147 | match location { | ||
148 | Location::Offset(offset) => TextRange::offset_len(offset, 1.into()), | ||
149 | Location::Range(range) => range, | ||
150 | } | ||
151 | } | 133 | } |
134 | acc | ||
152 | } | 135 | } |
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index 8a5f0e4b7..863859dca 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs | |||
@@ -5,92 +5,76 @@ mod block; | |||
5 | use rustc_lexer::unescape; | 5 | use rustc_lexer::unescape; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | ast, match_ast, AstNode, SyntaxError, SyntaxErrorKind, | 8 | ast, match_ast, AstNode, SyntaxError, |
9 | SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST_DEF, FN_DEF, INT_NUMBER, STRING, TYPE_ALIAS_DEF}, | 9 | SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST_DEF, FN_DEF, INT_NUMBER, STRING, TYPE_ALIAS_DEF}, |
10 | SyntaxNode, SyntaxToken, TextUnit, T, | 10 | SyntaxNode, SyntaxToken, TextUnit, T, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] | 13 | fn rustc_unescape_error_to_string(err: unescape::EscapeError) -> &'static str { |
14 | pub enum EscapeError { | 14 | use unescape::EscapeError as EE; |
15 | ZeroChars, | ||
16 | MoreThanOneChar, | ||
17 | LoneSlash, | ||
18 | InvalidEscape, | ||
19 | BareCarriageReturn, | ||
20 | EscapeOnlyChar, | ||
21 | TooShortHexEscape, | ||
22 | InvalidCharInHexEscape, | ||
23 | OutOfRangeHexEscape, | ||
24 | NoBraceInUnicodeEscape, | ||
25 | InvalidCharInUnicodeEscape, | ||
26 | EmptyUnicodeEscape, | ||
27 | UnclosedUnicodeEscape, | ||
28 | LeadingUnderscoreUnicodeEscape, | ||
29 | OverlongUnicodeEscape, | ||
30 | LoneSurrogateUnicodeEscape, | ||
31 | OutOfRangeUnicodeEscape, | ||
32 | UnicodeEscapeInByte, | ||
33 | NonAsciiCharInByte, | ||
34 | } | ||
35 | 15 | ||
36 | impl From<rustc_lexer::unescape::EscapeError> for EscapeError { | 16 | #[rustfmt::skip] |
37 | fn from(err: rustc_lexer::unescape::EscapeError) -> Self { | 17 | let err_message = match err { |
38 | match err { | 18 | EE::ZeroChars => { |
39 | rustc_lexer::unescape::EscapeError::ZeroChars => EscapeError::ZeroChars, | 19 | "Literal must not be empty" |
40 | rustc_lexer::unescape::EscapeError::MoreThanOneChar => EscapeError::MoreThanOneChar, | ||
41 | rustc_lexer::unescape::EscapeError::LoneSlash => EscapeError::LoneSlash, | ||
42 | rustc_lexer::unescape::EscapeError::InvalidEscape => EscapeError::InvalidEscape, | ||
43 | rustc_lexer::unescape::EscapeError::BareCarriageReturn | ||
44 | | rustc_lexer::unescape::EscapeError::BareCarriageReturnInRawString => { | ||
45 | EscapeError::BareCarriageReturn | ||
46 | } | ||
47 | rustc_lexer::unescape::EscapeError::EscapeOnlyChar => EscapeError::EscapeOnlyChar, | ||
48 | rustc_lexer::unescape::EscapeError::TooShortHexEscape => EscapeError::TooShortHexEscape, | ||
49 | rustc_lexer::unescape::EscapeError::InvalidCharInHexEscape => { | ||
50 | EscapeError::InvalidCharInHexEscape | ||
51 | } | ||
52 | rustc_lexer::unescape::EscapeError::OutOfRangeHexEscape => { | ||
53 | EscapeError::OutOfRangeHexEscape | ||
54 | } | ||
55 | rustc_lexer::unescape::EscapeError::NoBraceInUnicodeEscape => { | ||
56 | EscapeError::NoBraceInUnicodeEscape | ||
57 | } | ||
58 | rustc_lexer::unescape::EscapeError::InvalidCharInUnicodeEscape => { | ||
59 | EscapeError::InvalidCharInUnicodeEscape | ||
60 | } | ||
61 | rustc_lexer::unescape::EscapeError::EmptyUnicodeEscape => { | ||
62 | EscapeError::EmptyUnicodeEscape | ||
63 | } | ||
64 | rustc_lexer::unescape::EscapeError::UnclosedUnicodeEscape => { | ||
65 | EscapeError::UnclosedUnicodeEscape | ||
66 | } | ||
67 | rustc_lexer::unescape::EscapeError::LeadingUnderscoreUnicodeEscape => { | ||
68 | EscapeError::LeadingUnderscoreUnicodeEscape | ||
69 | } | ||
70 | rustc_lexer::unescape::EscapeError::OverlongUnicodeEscape => { | ||
71 | EscapeError::OverlongUnicodeEscape | ||
72 | } | ||
73 | rustc_lexer::unescape::EscapeError::LoneSurrogateUnicodeEscape => { | ||
74 | EscapeError::LoneSurrogateUnicodeEscape | ||
75 | } | ||
76 | rustc_lexer::unescape::EscapeError::OutOfRangeUnicodeEscape => { | ||
77 | EscapeError::OutOfRangeUnicodeEscape | ||
78 | } | ||
79 | rustc_lexer::unescape::EscapeError::UnicodeEscapeInByte => { | ||
80 | EscapeError::UnicodeEscapeInByte | ||
81 | } | ||
82 | rustc_lexer::unescape::EscapeError::NonAsciiCharInByte | ||
83 | | rustc_lexer::unescape::EscapeError::NonAsciiCharInByteString => { | ||
84 | EscapeError::NonAsciiCharInByte | ||
85 | } | ||
86 | } | 20 | } |
87 | } | 21 | EE::MoreThanOneChar => { |
88 | } | 22 | "Literal must be one character long" |
23 | } | ||
24 | EE::LoneSlash => { | ||
25 | "Character must be escaped: `\\`" | ||
26 | } | ||
27 | EE::InvalidEscape => { | ||
28 | "Invalid escape" | ||
29 | } | ||
30 | EE::BareCarriageReturn | EE::BareCarriageReturnInRawString => { | ||
31 | "Character must be escaped: `\r`" | ||
32 | } | ||
33 | EE::EscapeOnlyChar => { | ||
34 | "Escape character `\\` must be escaped itself" | ||
35 | } | ||
36 | EE::TooShortHexEscape => { | ||
37 | "ASCII hex escape code must have exactly two digits" | ||
38 | } | ||
39 | EE::InvalidCharInHexEscape => { | ||
40 | "ASCII hex escape code must contain only hex characters" | ||
41 | } | ||
42 | EE::OutOfRangeHexEscape => { | ||
43 | "ASCII hex escape code must be at most 0x7F" | ||
44 | } | ||
45 | EE::NoBraceInUnicodeEscape => { | ||
46 | "Missing `{` to begin the unicode escape" | ||
47 | } | ||
48 | EE::InvalidCharInUnicodeEscape => { | ||
49 | "Unicode escape must contain only hex characters and underscores" | ||
50 | } | ||
51 | EE::EmptyUnicodeEscape => { | ||
52 | "Unicode escape must not be empty" | ||
53 | } | ||
54 | EE::UnclosedUnicodeEscape => { | ||
55 | "Missing '}' to terminate the unicode escape" | ||
56 | } | ||
57 | EE::LeadingUnderscoreUnicodeEscape => { | ||
58 | "Unicode escape code must not begin with an underscore" | ||
59 | } | ||
60 | EE::OverlongUnicodeEscape => { | ||
61 | "Unicode escape code must have at most 6 digits" | ||
62 | } | ||
63 | EE::LoneSurrogateUnicodeEscape => { | ||
64 | "Unicode escape code must not be a surrogate" | ||
65 | } | ||
66 | EE::OutOfRangeUnicodeEscape => { | ||
67 | "Unicode escape code must be at most 0x10FFFF" | ||
68 | } | ||
69 | EE::UnicodeEscapeInByte => { | ||
70 | "Byte literals must not contain unicode escapes" | ||
71 | } | ||
72 | EE::NonAsciiCharInByte | EE::NonAsciiCharInByteString => { | ||
73 | "Byte literals must not contain non-ASCII characters" | ||
74 | } | ||
75 | }; | ||
89 | 76 | ||
90 | impl From<rustc_lexer::unescape::EscapeError> for SyntaxErrorKind { | 77 | err_message |
91 | fn from(err: rustc_lexer::unescape::EscapeError) -> Self { | ||
92 | SyntaxErrorKind::EscapeError(err.into()) | ||
93 | } | ||
94 | } | 78 | } |
95 | 79 | ||
96 | pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> { | 80 | pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> { |
@@ -118,6 +102,7 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> { | |||
118 | } | 102 | } |
119 | 103 | ||
120 | fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) { | 104 | fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) { |
105 | // FIXME: move this function to outer scope (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366196658) | ||
121 | fn unquote(text: &str, prefix_len: usize, end_delimiter: char) -> Option<&str> { | 106 | fn unquote(text: &str, prefix_len: usize, end_delimiter: char) -> Option<&str> { |
122 | text.rfind(end_delimiter).and_then(|end| text.get(prefix_len..end)) | 107 | text.rfind(end_delimiter).and_then(|end| text.get(prefix_len..end)) |
123 | } | 108 | } |
@@ -125,9 +110,10 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) { | |||
125 | let token = literal.token(); | 110 | let token = literal.token(); |
126 | let text = token.text().as_str(); | 111 | let text = token.text().as_str(); |
127 | 112 | ||
113 | // FIXME: lift this lambda refactor to `fn` (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366199205) | ||
128 | let mut push_err = |prefix_len, (off, err): (usize, unescape::EscapeError)| { | 114 | let mut push_err = |prefix_len, (off, err): (usize, unescape::EscapeError)| { |
129 | let off = token.text_range().start() + TextUnit::from_usize(off + prefix_len); | 115 | let off = token.text_range().start() + TextUnit::from_usize(off + prefix_len); |
130 | acc.push(SyntaxError::new(err.into(), off)); | 116 | acc.push(SyntaxError::new_at_offset(rustc_unescape_error_to_string(err), off)); |
131 | }; | 117 | }; |
132 | 118 | ||
133 | match token.kind() { | 119 | match token.kind() { |
@@ -195,7 +181,8 @@ fn validate_numeric_name(name_ref: Option<ast::NameRef>, errors: &mut Vec<Syntax | |||
195 | if let Some(int_token) = int_token(name_ref) { | 181 | if let Some(int_token) = int_token(name_ref) { |
196 | if int_token.text().chars().any(|c| !c.is_digit(10)) { | 182 | if int_token.text().chars().any(|c| !c.is_digit(10)) { |
197 | errors.push(SyntaxError::new( | 183 | errors.push(SyntaxError::new( |
198 | SyntaxErrorKind::InvalidTupleIndexFormat, | 184 | "Tuple (struct) field access is only allowed through \ |
185 | decimal integers with no underscores or suffix", | ||
199 | int_token.text_range(), | 186 | int_token.text_range(), |
200 | )); | 187 | )); |
201 | } | 188 | } |
@@ -215,21 +202,21 @@ fn validate_visibility(vis: ast::Visibility, errors: &mut Vec<SyntaxError>) { | |||
215 | FN_DEF | CONST_DEF | TYPE_ALIAS_DEF => (), | 202 | FN_DEF | CONST_DEF | TYPE_ALIAS_DEF => (), |
216 | _ => return, | 203 | _ => return, |
217 | } | 204 | } |
205 | |||
218 | let impl_block = match parent.parent().and_then(|it| it.parent()).and_then(ast::ImplBlock::cast) | 206 | let impl_block = match parent.parent().and_then(|it| it.parent()).and_then(ast::ImplBlock::cast) |
219 | { | 207 | { |
220 | Some(it) => it, | 208 | Some(it) => it, |
221 | None => return, | 209 | None => return, |
222 | }; | 210 | }; |
223 | if impl_block.target_trait().is_some() { | 211 | if impl_block.target_trait().is_some() { |
224 | errors | 212 | errors.push(SyntaxError::new("Unnecessary visibility qualifier", vis.syntax.text_range())); |
225 | .push(SyntaxError::new(SyntaxErrorKind::VisibilityNotAllowed, vis.syntax.text_range())) | ||
226 | } | 213 | } |
227 | } | 214 | } |
228 | 215 | ||
229 | fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec<SyntaxError>) { | 216 | fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec<SyntaxError>) { |
230 | if expr.op_kind() == Some(ast::RangeOp::Inclusive) && expr.end().is_none() { | 217 | if expr.op_kind() == Some(ast::RangeOp::Inclusive) && expr.end().is_none() { |
231 | errors.push(SyntaxError::new( | 218 | errors.push(SyntaxError::new( |
232 | SyntaxErrorKind::InclusiveRangeMissingEnd, | 219 | "An inclusive range must have an end expression", |
233 | expr.syntax().text_range(), | 220 | expr.syntax().text_range(), |
234 | )); | 221 | )); |
235 | } | 222 | } |
diff --git a/crates/ra_syntax/src/validation/block.rs b/crates/ra_syntax/src/validation/block.rs index c85bbc1f4..8e962ab5b 100644 --- a/crates/ra_syntax/src/validation/block.rs +++ b/crates/ra_syntax/src/validation/block.rs | |||
@@ -1,9 +1,8 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! Logic for validating block expressions i.e. `ast::BlockExpr`. |
2 | 2 | ||
3 | use crate::{ | 3 | use crate::{ |
4 | ast::{self, AstNode, AttrsOwner}, | 4 | ast::{self, AstNode, AttrsOwner}, |
5 | SyntaxError, | 5 | SyntaxError, |
6 | SyntaxErrorKind::*, | ||
7 | SyntaxKind::*, | 6 | SyntaxKind::*, |
8 | }; | 7 | }; |
9 | 8 | ||
@@ -15,10 +14,11 @@ pub(crate) fn validate_block_expr(expr: ast::BlockExpr, errors: &mut Vec<SyntaxE | |||
15 | } | 14 | } |
16 | } | 15 | } |
17 | if let Some(block) = expr.block() { | 16 | if let Some(block) = expr.block() { |
18 | errors.extend( | 17 | errors.extend(block.attrs().map(|attr| { |
19 | block | 18 | SyntaxError::new( |
20 | .attrs() | 19 | "A block in this position cannot accept inner attributes", |
21 | .map(|attr| SyntaxError::new(InvalidBlockAttr, attr.syntax().text_range())), | 20 | attr.syntax().text_range(), |
22 | ) | 21 | ) |
22 | })) | ||
23 | } | 23 | } |
24 | } | 24 | } |
diff --git a/crates/ra_syntax/test_data/parser/err/0000_struct_field_missing_comma.txt b/crates/ra_syntax/test_data/parser/err/0000_struct_field_missing_comma.txt index dc143945a..edcd936b0 100644 --- a/crates/ra_syntax/test_data/parser/err/0000_struct_field_missing_comma.txt +++ b/crates/ra_syntax/test_data/parser/err/0000_struct_field_missing_comma.txt | |||
@@ -31,4 +31,4 @@ SOURCE_FILE@[0; 34) | |||
31 | IDENT@[29; 32) "u32" | 31 | IDENT@[29; 32) "u32" |
32 | WHITESPACE@[32; 33) "\n" | 32 | WHITESPACE@[32; 33) "\n" |
33 | R_CURLY@[33; 34) "}" | 33 | R_CURLY@[33; 34) "}" |
34 | error 21: expected COMMA | 34 | error [21; 21): expected COMMA |
diff --git a/crates/ra_syntax/test_data/parser/err/0001_item_recovery_in_file.txt b/crates/ra_syntax/test_data/parser/err/0001_item_recovery_in_file.txt index 181bcdb9e..2d653715e 100644 --- a/crates/ra_syntax/test_data/parser/err/0001_item_recovery_in_file.txt +++ b/crates/ra_syntax/test_data/parser/err/0001_item_recovery_in_file.txt | |||
@@ -14,5 +14,5 @@ SOURCE_FILE@[0; 21) | |||
14 | RECORD_FIELD_DEF_LIST@[19; 21) | 14 | RECORD_FIELD_DEF_LIST@[19; 21) |
15 | L_CURLY@[19; 20) "{" | 15 | L_CURLY@[19; 20) "{" |
16 | R_CURLY@[20; 21) "}" | 16 | R_CURLY@[20; 21) "}" |
17 | error 0: expected an item | 17 | error [0; 0): expected an item |
18 | error 3: expected an item | 18 | error [3; 3): expected an item |
diff --git a/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt b/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt index bdb5fa6c5..002680583 100644 --- a/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt +++ b/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt | |||
@@ -26,14 +26,14 @@ SOURCE_FILE@[0; 42) | |||
26 | NAME@[36; 41) | 26 | NAME@[36; 41) |
27 | IDENT@[36; 41) "rusti" | 27 | IDENT@[36; 41) "rusti" |
28 | WHITESPACE@[41; 42) "\n" | 28 | WHITESPACE@[41; 42) "\n" |
29 | error 23: expected `[` | 29 | error [23; 23): expected `[` |
30 | error 23: expected an item | 30 | error [23; 23): expected an item |
31 | error 27: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | 31 | error [27; 27): expected one of `*`, `::`, `{`, `self`, `super` or an identifier |
32 | error 28: expected SEMI | 32 | error [28; 28): expected SEMI |
33 | error 31: expected EXCL | 33 | error [31; 31): expected EXCL |
34 | error 31: expected `{`, `[`, `(` | 34 | error [31; 31): expected `{`, `[`, `(` |
35 | error 31: expected SEMI | 35 | error [31; 31): expected SEMI |
36 | error 31: expected an item | 36 | error [31; 31): expected an item |
37 | error 35: expected EXCL | 37 | error [35; 35): expected EXCL |
38 | error 41: expected `{`, `[`, `(` | 38 | error [41; 41): expected `{`, `[`, `(` |
39 | error 41: expected SEMI | 39 | error [41; 41): expected SEMI |
diff --git a/crates/ra_syntax/test_data/parser/err/0003_C++_semicolon.txt b/crates/ra_syntax/test_data/parser/err/0003_C++_semicolon.txt index 58d005902..8039a8913 100644 --- a/crates/ra_syntax/test_data/parser/err/0003_C++_semicolon.txt +++ b/crates/ra_syntax/test_data/parser/err/0003_C++_semicolon.txt | |||
@@ -35,5 +35,5 @@ SOURCE_FILE@[0; 40) | |||
35 | R_CURLY@[38; 39) "}" | 35 | R_CURLY@[38; 39) "}" |
36 | ERROR@[39; 40) | 36 | ERROR@[39; 40) |
37 | SEMI@[39; 40) ";" | 37 | SEMI@[39; 40) ";" |
38 | error 39: expected item, found `;` | 38 | error [39; 39): expected item, found `;` |
39 | consider removing this semicolon | 39 | consider removing this semicolon |
diff --git a/crates/ra_syntax/test_data/parser/err/0004_use_path_bad_segment.txt b/crates/ra_syntax/test_data/parser/err/0004_use_path_bad_segment.txt index 5210a884d..5f6e10986 100644 --- a/crates/ra_syntax/test_data/parser/err/0004_use_path_bad_segment.txt +++ b/crates/ra_syntax/test_data/parser/err/0004_use_path_bad_segment.txt | |||
@@ -13,4 +13,4 @@ SOURCE_FILE@[0; 12) | |||
13 | ERROR@[9; 11) | 13 | ERROR@[9; 11) |
14 | INT_NUMBER@[9; 11) "92" | 14 | INT_NUMBER@[9; 11) "92" |
15 | SEMI@[11; 12) ";" | 15 | SEMI@[11; 12) ";" |
16 | error 9: expected identifier | 16 | error [9; 9): expected identifier |
diff --git a/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt b/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt index 7c1a23170..cc11421a9 100644 --- a/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt +++ b/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt | |||
@@ -55,6 +55,6 @@ SOURCE_FILE@[0; 54) | |||
55 | WHITESPACE@[51; 52) "\n" | 55 | WHITESPACE@[51; 52) "\n" |
56 | R_CURLY@[52; 53) "}" | 56 | R_CURLY@[52; 53) "}" |
57 | WHITESPACE@[53; 54) "\n" | 57 | WHITESPACE@[53; 54) "\n" |
58 | error 53: expected R_PAREN | 58 | error [53; 53): expected R_PAREN |
59 | error 53: expected `]` | 59 | error [53; 53): expected `]` |
60 | error 53: expected an item | 60 | error [53; 53): expected an item |
diff --git a/crates/ra_syntax/test_data/parser/err/0006_named_field_recovery.txt b/crates/ra_syntax/test_data/parser/err/0006_named_field_recovery.txt index 5f5198b31..84fd92862 100644 --- a/crates/ra_syntax/test_data/parser/err/0006_named_field_recovery.txt +++ b/crates/ra_syntax/test_data/parser/err/0006_named_field_recovery.txt | |||
@@ -64,11 +64,11 @@ SOURCE_FILE@[0; 74) | |||
64 | WHITESPACE@[71; 72) "\n" | 64 | WHITESPACE@[71; 72) "\n" |
65 | R_CURLY@[72; 73) "}" | 65 | R_CURLY@[72; 73) "}" |
66 | WHITESPACE@[73; 74) "\n" | 66 | WHITESPACE@[73; 74) "\n" |
67 | error 31: expected field declaration | 67 | error [31; 31): expected field declaration |
68 | error 33: expected COMMA | 68 | error [33; 33): expected COMMA |
69 | error 38: expected field declaration | 69 | error [38; 38): expected field declaration |
70 | error 39: expected COMMA | 70 | error [39; 39): expected COMMA |
71 | error 40: expected field declaration | 71 | error [40; 40): expected field declaration |
72 | error 41: expected COMMA | 72 | error [41; 41): expected COMMA |
73 | error 42: expected field declaration | 73 | error [42; 42): expected field declaration |
74 | error 43: expected COMMA | 74 | error [43; 43): expected COMMA |
diff --git a/crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.txt b/crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.txt index 7ae417441..1978f30fa 100644 --- a/crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.txt +++ b/crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.txt | |||
@@ -28,6 +28,6 @@ SOURCE_FILE@[0; 31) | |||
28 | ERROR@[29; 30) | 28 | ERROR@[29; 30) |
29 | R_CURLY@[29; 30) "}" | 29 | R_CURLY@[29; 30) "}" |
30 | WHITESPACE@[30; 31) "\n" | 30 | WHITESPACE@[30; 31) "\n" |
31 | error 0: unmatched `}` | 31 | error [0; 0): unmatched `}` |
32 | error 14: unmatched `}` | 32 | error [14; 14): unmatched `}` |
33 | error 29: unmatched `}` | 33 | error [29; 29): unmatched `}` |
diff --git a/crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.txt b/crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.txt index 1a4b40a2b..98248227d 100644 --- a/crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.txt +++ b/crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.txt | |||
@@ -76,6 +76,6 @@ SOURCE_FILE@[0; 95) | |||
76 | WHITESPACE@[92; 93) "\n" | 76 | WHITESPACE@[92; 93) "\n" |
77 | R_CURLY@[93; 94) "}" | 77 | R_CURLY@[93; 94) "}" |
78 | WHITESPACE@[94; 95) "\n" | 78 | WHITESPACE@[94; 95) "\n" |
79 | error 17: expected EXCL | 79 | error [17; 17): expected EXCL |
80 | error 19: expected SEMI | 80 | error [19; 19): expected SEMI |
81 | error 20: expected an item | 81 | error [20; 20): expected an item |
diff --git a/crates/ra_syntax/test_data/parser/err/0009_broken_struct_type_parameter.txt b/crates/ra_syntax/test_data/parser/err/0009_broken_struct_type_parameter.txt index e147d6424..ca508ac7c 100644 --- a/crates/ra_syntax/test_data/parser/err/0009_broken_struct_type_parameter.txt +++ b/crates/ra_syntax/test_data/parser/err/0009_broken_struct_type_parameter.txt | |||
@@ -45,14 +45,14 @@ SOURCE_FILE@[0; 43) | |||
45 | IDENT@[40; 41) "T" | 45 | IDENT@[40; 41) "T" |
46 | SEMI@[41; 42) ";" | 46 | SEMI@[41; 42) ";" |
47 | WHITESPACE@[42; 43) "\n" | 47 | WHITESPACE@[42; 43) "\n" |
48 | error 9: expected type parameter | 48 | error [9; 9): expected type parameter |
49 | error 11: expected COMMA | 49 | error [11; 11): expected COMMA |
50 | error 11: expected R_ANGLE | 50 | error [11; 11): expected R_ANGLE |
51 | error 11: expected `;`, `{`, or `(` | 51 | error [11; 11): expected `;`, `{`, or `(` |
52 | error 12: expected an item | 52 | error [12; 12): expected an item |
53 | error 14: expected an item | 53 | error [14; 14): expected an item |
54 | error 15: expected an item | 54 | error [15; 15): expected an item |
55 | error 17: expected an item | 55 | error [17; 17): expected an item |
56 | error 24: expected SEMI | 56 | error [24; 24): expected SEMI |
57 | error 24: expected expression | 57 | error [24; 24): expected expression |
58 | error 25: expected SEMI | 58 | error [25; 25): expected SEMI |
diff --git a/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt b/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt index b73dda5ad..e0edf6a2d 100644 --- a/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt +++ b/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt | |||
@@ -40,4 +40,4 @@ SOURCE_FILE@[0; 42) | |||
40 | WHITESPACE@[39; 40) "\n" | 40 | WHITESPACE@[39; 40) "\n" |
41 | R_CURLY@[40; 41) "}" | 41 | R_CURLY@[40; 41) "}" |
42 | WHITESPACE@[41; 42) "\n" | 42 | WHITESPACE@[41; 42) "\n" |
43 | error 24: expected `{` | 43 | error [24; 24): expected `{` |
diff --git a/crates/ra_syntax/test_data/parser/err/0011_extern_struct.txt b/crates/ra_syntax/test_data/parser/err/0011_extern_struct.txt index 381147dc0..900894dcf 100644 --- a/crates/ra_syntax/test_data/parser/err/0011_extern_struct.txt +++ b/crates/ra_syntax/test_data/parser/err/0011_extern_struct.txt | |||
@@ -10,4 +10,4 @@ SOURCE_FILE@[0; 19) | |||
10 | IDENT@[14; 17) "Foo" | 10 | IDENT@[14; 17) "Foo" |
11 | SEMI@[17; 18) ";" | 11 | SEMI@[17; 18) ";" |
12 | WHITESPACE@[18; 19) "\n" | 12 | WHITESPACE@[18; 19) "\n" |
13 | error 6: expected existential, fn, trait or impl | 13 | error [6; 6): expected existential, fn, trait or impl |
diff --git a/crates/ra_syntax/test_data/parser/err/0013_invalid_type.txt b/crates/ra_syntax/test_data/parser/err/0013_invalid_type.txt index 4907bac6d..7a934cf66 100644 --- a/crates/ra_syntax/test_data/parser/err/0013_invalid_type.txt +++ b/crates/ra_syntax/test_data/parser/err/0013_invalid_type.txt | |||
@@ -69,21 +69,21 @@ SOURCE_FILE@[0; 86) | |||
69 | ERROR@[83; 84) | 69 | ERROR@[83; 84) |
70 | SEMI@[83; 84) ";" | 70 | SEMI@[83; 84) ";" |
71 | WHITESPACE@[84; 86) "\n\n" | 71 | WHITESPACE@[84; 86) "\n\n" |
72 | error 67: expected type | 72 | error [67; 67): expected type |
73 | error 68: expected COMMA | 73 | error [68; 68): expected COMMA |
74 | error 68: expected R_ANGLE | 74 | error [68; 68): expected R_ANGLE |
75 | error 68: expected COMMA | 75 | error [68; 68): expected COMMA |
76 | error 68: expected R_ANGLE | 76 | error [68; 68): expected R_ANGLE |
77 | error 68: expected COMMA | 77 | error [68; 68): expected COMMA |
78 | error 68: expected R_ANGLE | 78 | error [68; 68): expected R_ANGLE |
79 | error 68: expected COMMA | 79 | error [68; 68): expected COMMA |
80 | error 72: expected COMMA | 80 | error [72; 72): expected COMMA |
81 | error 72: expected a type | 81 | error [72; 72): expected a type |
82 | error 72: expected R_PAREN | 82 | error [72; 72): expected R_PAREN |
83 | error 72: expected SEMI | 83 | error [72; 72): expected SEMI |
84 | error 72: expected an item | 84 | error [72; 72): expected an item |
85 | error 73: expected an item | 85 | error [73; 73): expected an item |
86 | error 79: expected an item | 86 | error [79; 79): expected an item |
87 | error 80: expected an item | 87 | error [80; 80): expected an item |
88 | error 82: expected an item | 88 | error [82; 82): expected an item |
89 | error 83: expected an item | 89 | error [83; 83): expected an item |
diff --git a/crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.txt b/crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.txt index 0ba17cf8d..a25d641b8 100644 --- a/crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.txt +++ b/crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.txt | |||
@@ -29,4 +29,4 @@ SOURCE_FILE@[0; 23) | |||
29 | L_CURLY@[20; 21) "{" | 29 | L_CURLY@[20; 21) "{" |
30 | R_CURLY@[21; 22) "}" | 30 | R_CURLY@[21; 22) "}" |
31 | WHITESPACE@[22; 23) "\n" | 31 | WHITESPACE@[22; 23) "\n" |
32 | error 19: expected colon | 32 | error [19; 19): expected colon |
diff --git a/crates/ra_syntax/test_data/parser/err/0015_curly_in_params.txt b/crates/ra_syntax/test_data/parser/err/0015_curly_in_params.txt index 23ca0c446..36b848be3 100644 --- a/crates/ra_syntax/test_data/parser/err/0015_curly_in_params.txt +++ b/crates/ra_syntax/test_data/parser/err/0015_curly_in_params.txt | |||
@@ -16,9 +16,9 @@ SOURCE_FILE@[0; 14) | |||
16 | WHITESPACE@[11; 12) "\n" | 16 | WHITESPACE@[11; 12) "\n" |
17 | R_CURLY@[12; 13) "}" | 17 | R_CURLY@[12; 13) "}" |
18 | WHITESPACE@[13; 14) "\n" | 18 | WHITESPACE@[13; 14) "\n" |
19 | error 7: expected value parameter | 19 | error [7; 7): expected value parameter |
20 | error 7: expected R_PAREN | 20 | error [7; 7): expected R_PAREN |
21 | error 7: expected a block | 21 | error [7; 7): expected a block |
22 | error 7: unmatched `}` | 22 | error [7; 7): unmatched `}` |
23 | error 8: expected an item | 23 | error [8; 8): expected an item |
24 | error 10: expected an item | 24 | error [10; 10): expected an item |
diff --git a/crates/ra_syntax/test_data/parser/err/0016_missing_semi.txt b/crates/ra_syntax/test_data/parser/err/0016_missing_semi.txt index bc5be6a66..6343580e0 100644 --- a/crates/ra_syntax/test_data/parser/err/0016_missing_semi.txt +++ b/crates/ra_syntax/test_data/parser/err/0016_missing_semi.txt | |||
@@ -41,4 +41,4 @@ SOURCE_FILE@[0; 56) | |||
41 | WHITESPACE@[53; 54) "\n" | 41 | WHITESPACE@[53; 54) "\n" |
42 | R_CURLY@[54; 55) "}" | 42 | R_CURLY@[54; 55) "}" |
43 | WHITESPACE@[55; 56) "\n" | 43 | WHITESPACE@[55; 56) "\n" |
44 | error 38: expected SEMI | 44 | error [38; 38): expected SEMI |
diff --git a/crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.txt b/crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.txt index 9033a5b38..59480e999 100644 --- a/crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.txt +++ b/crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.txt | |||
@@ -44,4 +44,4 @@ SOURCE_FILE@[0; 47) | |||
44 | WHITESPACE@[44; 45) "\n" | 44 | WHITESPACE@[44; 45) "\n" |
45 | R_CURLY@[45; 46) "}" | 45 | R_CURLY@[45; 46) "}" |
46 | WHITESPACE@[46; 47) "\n" | 46 | WHITESPACE@[46; 47) "\n" |
47 | error 44: expected expression | 47 | error [44; 44): expected expression |
diff --git a/crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.txt b/crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.txt index d12f4c99b..b9e60f6c1 100644 --- a/crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.txt +++ b/crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.txt | |||
@@ -125,8 +125,8 @@ SOURCE_FILE@[0; 183) | |||
125 | WHITESPACE@[180; 181) "\n" | 125 | WHITESPACE@[180; 181) "\n" |
126 | R_CURLY@[181; 182) "}" | 126 | R_CURLY@[181; 182) "}" |
127 | WHITESPACE@[182; 183) "\n" | 127 | WHITESPACE@[182; 183) "\n" |
128 | error 34: expected pattern | 128 | error [34; 34): expected pattern |
129 | error 34: expected COLON | 129 | error [34; 34): expected COLON |
130 | error 34: expected type | 130 | error [34; 34): expected type |
131 | error 180: expected function arguments | 131 | error [180; 180): expected function arguments |
132 | error 180: expected a block | 132 | error [180; 180): expected a block |
diff --git a/crates/ra_syntax/test_data/parser/err/0019_let_recover.txt b/crates/ra_syntax/test_data/parser/err/0019_let_recover.txt index cc3578e54..97e91a94f 100644 --- a/crates/ra_syntax/test_data/parser/err/0019_let_recover.txt +++ b/crates/ra_syntax/test_data/parser/err/0019_let_recover.txt | |||
@@ -95,13 +95,13 @@ SOURCE_FILE@[0; 139) | |||
95 | WHITESPACE@[136; 137) "\n" | 95 | WHITESPACE@[136; 137) "\n" |
96 | R_CURLY@[137; 138) "}" | 96 | R_CURLY@[137; 138) "}" |
97 | WHITESPACE@[138; 139) "\n" | 97 | WHITESPACE@[138; 139) "\n" |
98 | error 24: expected expression | 98 | error [24; 24): expected expression |
99 | error 24: expected SEMI | 99 | error [24; 24): expected SEMI |
100 | error 49: expected pattern | 100 | error [49; 49): expected pattern |
101 | error 49: expected SEMI | 101 | error [49; 49): expected SEMI |
102 | error 75: expected pattern | 102 | error [75; 75): expected pattern |
103 | error 75: expected SEMI | 103 | error [75; 75): expected SEMI |
104 | error 98: expected pattern | 104 | error [98; 98): expected pattern |
105 | error 98: expected SEMI | 105 | error [98; 98): expected SEMI |
106 | error 124: expected pattern | 106 | error [124; 124): expected pattern |
107 | error 124: expected SEMI | 107 | error [124; 124): expected SEMI |
diff --git a/crates/ra_syntax/test_data/parser/err/0020_fn_recover.txt b/crates/ra_syntax/test_data/parser/err/0020_fn_recover.txt index 70727d059..c11dc23f5 100644 --- a/crates/ra_syntax/test_data/parser/err/0020_fn_recover.txt +++ b/crates/ra_syntax/test_data/parser/err/0020_fn_recover.txt | |||
@@ -16,6 +16,6 @@ SOURCE_FILE@[0; 16) | |||
16 | L_CURLY@[13; 14) "{" | 16 | L_CURLY@[13; 14) "{" |
17 | R_CURLY@[14; 15) "}" | 17 | R_CURLY@[14; 15) "}" |
18 | WHITESPACE@[15; 16) "\n" | 18 | WHITESPACE@[15; 16) "\n" |
19 | error 2: expected a name | 19 | error [2; 2): expected a name |
20 | error 2: expected function arguments | 20 | error [2; 2): expected function arguments |
21 | error 2: expected a block | 21 | error [2; 2): expected a block |
diff --git a/crates/ra_syntax/test_data/parser/err/0021_incomplete_param.txt b/crates/ra_syntax/test_data/parser/err/0021_incomplete_param.txt index 333782480..ae04122d8 100644 --- a/crates/ra_syntax/test_data/parser/err/0021_incomplete_param.txt +++ b/crates/ra_syntax/test_data/parser/err/0021_incomplete_param.txt | |||
@@ -31,5 +31,5 @@ SOURCE_FILE@[0; 22) | |||
31 | WHITESPACE@[19; 20) "\n" | 31 | WHITESPACE@[19; 20) "\n" |
32 | R_CURLY@[20; 21) "}" | 32 | R_CURLY@[20; 21) "}" |
33 | WHITESPACE@[21; 22) "\n" | 33 | WHITESPACE@[21; 22) "\n" |
34 | error 16: expected COLON | 34 | error [16; 16): expected COLON |
35 | error 16: expected type | 35 | error [16; 16): expected type |
diff --git a/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt b/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt index cb45eb2fc..bb87022b0 100644 --- a/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt +++ b/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt | |||
@@ -148,36 +148,36 @@ SOURCE_FILE@[0; 112) | |||
148 | WHITESPACE@[109; 110) " " | 148 | WHITESPACE@[109; 110) " " |
149 | R_CURLY@[110; 111) "}" | 149 | R_CURLY@[110; 111) "}" |
150 | WHITESPACE@[111; 112) "\n" | 150 | WHITESPACE@[111; 112) "\n" |
151 | error 16: expected expression | 151 | error [16; 16): expected expression |
152 | error 17: expected R_BRACK | 152 | error [17; 17): expected R_BRACK |
153 | error 17: expected SEMI | 153 | error [17; 17): expected SEMI |
154 | error 17: expected expression | 154 | error [17; 17): expected expression |
155 | error 18: expected SEMI | 155 | error [18; 18): expected SEMI |
156 | error 25: expected a name | 156 | error [25; 25): expected a name |
157 | error 26: expected `;`, `{`, or `(` | 157 | error [26; 26): expected `;`, `{`, or `(` |
158 | error 30: expected pattern | 158 | error [30; 30): expected pattern |
159 | error 31: expected SEMI | 159 | error [31; 31): expected SEMI |
160 | error 53: expected expression | 160 | error [53; 53): expected expression |
161 | error 54: expected SEMI | 161 | error [54; 54): expected SEMI |
162 | error 54: expected expression | 162 | error [54; 54): expected expression |
163 | error 55: expected SEMI | 163 | error [55; 55): expected SEMI |
164 | error 60: expected type | 164 | error [60; 60): expected type |
165 | error 60: expected `{` | 165 | error [60; 60): expected `{` |
166 | error 60: expected expression | 166 | error [60; 60): expected expression |
167 | error 61: expected SEMI | 167 | error [61; 61): expected SEMI |
168 | error 65: expected pattern | 168 | error [65; 65): expected pattern |
169 | error 65: expected SEMI | 169 | error [65; 65): expected SEMI |
170 | error 65: expected expression | 170 | error [65; 65): expected expression |
171 | error 92: expected expression | 171 | error [92; 92): expected expression |
172 | error 93: expected SEMI | 172 | error [93; 93): expected SEMI |
173 | error 93: expected expression | 173 | error [93; 93): expected expression |
174 | error 94: expected SEMI | 174 | error [94; 94): expected SEMI |
175 | error 95: expected expression | 175 | error [95; 95): expected expression |
176 | error 96: expected SEMI | 176 | error [96; 96): expected SEMI |
177 | error 96: expected expression | 177 | error [96; 96): expected expression |
178 | error 97: expected SEMI | 178 | error [97; 97): expected SEMI |
179 | error 103: expected a name | 179 | error [103; 103): expected a name |
180 | error 104: expected `{` | 180 | error [104; 104): expected `{` |
181 | error 108: expected pattern | 181 | error [108; 108): expected pattern |
182 | error 108: expected SEMI | 182 | error [108; 108): expected SEMI |
183 | error 108: expected expression | 183 | error [108; 108): expected expression |
diff --git a/crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.txt b/crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.txt index 6dd04f80e..775e4b0da 100644 --- a/crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.txt +++ b/crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.txt | |||
@@ -40,5 +40,5 @@ SOURCE_FILE@[0; 94) | |||
40 | ERROR@[92; 93) | 40 | ERROR@[92; 93) |
41 | R_CURLY@[92; 93) "}" | 41 | R_CURLY@[92; 93) "}" |
42 | WHITESPACE@[93; 94) "\n" | 42 | WHITESPACE@[93; 94) "\n" |
43 | error 49: unmatched `}` | 43 | error [49; 49): unmatched `}` |
44 | error 92: unmatched `}` | 44 | error [92; 92): unmatched `}` |
diff --git a/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt b/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt index 0a93e11a5..c5c8a29ba 100644 --- a/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt +++ b/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt | |||
@@ -290,32 +290,32 @@ SOURCE_FILE@[0; 240) | |||
290 | WHITESPACE@[237; 238) "\n" | 290 | WHITESPACE@[237; 238) "\n" |
291 | R_CURLY@[238; 239) "}" | 291 | R_CURLY@[238; 239) "}" |
292 | WHITESPACE@[239; 240) "\n" | 292 | WHITESPACE@[239; 240) "\n" |
293 | error 88: expected COMMA | 293 | error [88; 88): expected COMMA |
294 | error 88: expected R_ANGLE | 294 | error [88; 88): expected R_ANGLE |
295 | error 121: expected SEMI | 295 | error [121; 121): expected SEMI |
296 | error 121: expected expression | 296 | error [121; 121): expected expression |
297 | error 140: expected type | 297 | error [140; 140): expected type |
298 | error 141: expected R_PAREN | 298 | error [141; 141): expected R_PAREN |
299 | error 141: expected COMMA | 299 | error [141; 141): expected COMMA |
300 | error 141: expected R_ANGLE | 300 | error [141; 141): expected R_ANGLE |
301 | error 141: expected SEMI | 301 | error [141; 141): expected SEMI |
302 | error 146: expected SEMI | 302 | error [146; 146): expected SEMI |
303 | error 146: expected expression | 303 | error [146; 146): expected expression |
304 | error 147: expected SEMI | 304 | error [147; 147): expected SEMI |
305 | error 148: expected expression | 305 | error [148; 148): expected expression |
306 | error 149: expected SEMI | 306 | error [149; 149): expected SEMI |
307 | error 154: expected pattern | 307 | error [154; 154): expected pattern |
308 | error 155: expected IN_KW | 308 | error [155; 155): expected IN_KW |
309 | error 155: expected expression | 309 | error [155; 155): expected expression |
310 | error 157: expected a block | 310 | error [157; 157): expected a block |
311 | error 165: expected expression | 311 | error [165; 165): expected expression |
312 | error 168: expected expression | 312 | error [168; 168): expected expression |
313 | error 179: expected expression | 313 | error [179; 179): expected expression |
314 | error 180: expected COMMA | 314 | error [180; 180): expected COMMA |
315 | error 180: expected expression | 315 | error [180; 180): expected expression |
316 | error 180: expected R_PAREN | 316 | error [180; 180): expected R_PAREN |
317 | error 180: expected SEMI | 317 | error [180; 180): expected SEMI |
318 | error 215: expected COMMA | 318 | error [215; 215): expected COMMA |
319 | error 215: expected R_ANGLE | 319 | error [215; 215): expected R_ANGLE |
320 | error 235: expected SEMI | 320 | error [235; 235): expected SEMI |
321 | error 235: expected expression | 321 | error [235; 235): expected expression |
diff --git a/crates/ra_syntax/test_data/parser/err/0025_nope.txt b/crates/ra_syntax/test_data/parser/err/0025_nope.txt index 8369f4bda..ca7f2d255 100644 --- a/crates/ra_syntax/test_data/parser/err/0025_nope.txt +++ b/crates/ra_syntax/test_data/parser/err/0025_nope.txt | |||
@@ -191,14 +191,14 @@ SOURCE_FILE@[0; 575) | |||
191 | WHITESPACE@[572; 573) "\n" | 191 | WHITESPACE@[572; 573) "\n" |
192 | R_CURLY@[573; 574) "}" | 192 | R_CURLY@[573; 574) "}" |
193 | WHITESPACE@[574; 575) "\n" | 193 | WHITESPACE@[574; 575) "\n" |
194 | error 95: expected type | 194 | error [95; 95): expected type |
195 | error 95: expected COMMA | 195 | error [95; 95): expected COMMA |
196 | error 96: expected field | 196 | error [96; 96): expected field |
197 | error 98: expected field declaration | 197 | error [98; 98): expected field declaration |
198 | error 371: expected COMMA | 198 | error [371; 371): expected COMMA |
199 | error 372: expected a type | 199 | error [372; 372): expected a type |
200 | error 372: expected R_PAREN | 200 | error [372; 372): expected R_PAREN |
201 | error 372: expected COMMA | 201 | error [372; 372): expected COMMA |
202 | error 372: expected enum variant | 202 | error [372; 372): expected enum variant |
203 | error 374: expected enum variant | 203 | error [374; 374): expected enum variant |
204 | error 508: expected expression | 204 | error [508; 508): expected expression |
diff --git a/crates/ra_syntax/test_data/parser/err/0026_imp_recovery.txt b/crates/ra_syntax/test_data/parser/err/0026_imp_recovery.txt index d3da2f54f..3942e0904 100644 --- a/crates/ra_syntax/test_data/parser/err/0026_imp_recovery.txt +++ b/crates/ra_syntax/test_data/parser/err/0026_imp_recovery.txt | |||
@@ -45,5 +45,5 @@ SOURCE_FILE@[0; 38) | |||
45 | L_CURLY@[35; 36) "{" | 45 | L_CURLY@[35; 36) "{" |
46 | R_CURLY@[36; 37) "}" | 46 | R_CURLY@[36; 37) "}" |
47 | WHITESPACE@[37; 38) "\n" | 47 | WHITESPACE@[37; 38) "\n" |
48 | error 14: expected trait or type | 48 | error [14; 14): expected trait or type |
49 | error 14: expected `{` | 49 | error [14; 14): expected `{` |
diff --git a/crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.txt b/crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.txt index 9298b45a4..4a28bcabf 100644 --- a/crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.txt +++ b/crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.txt | |||
@@ -25,5 +25,5 @@ SOURCE_FILE@[0; 30) | |||
25 | L_CURLY@[27; 28) "{" | 25 | L_CURLY@[27; 28) "{" |
26 | R_CURLY@[28; 29) "}" | 26 | R_CURLY@[28; 29) "}" |
27 | WHITESPACE@[29; 30) "\n" | 27 | WHITESPACE@[29; 30) "\n" |
28 | error 26: expected a path | 28 | error [26; 26): expected a path |
29 | error 26: expected colon | 29 | error [26; 26): expected colon |
diff --git a/crates/ra_syntax/test_data/parser/err/0029_field_completion.txt b/crates/ra_syntax/test_data/parser/err/0029_field_completion.txt index e3e1282ec..177849476 100644 --- a/crates/ra_syntax/test_data/parser/err/0029_field_completion.txt +++ b/crates/ra_syntax/test_data/parser/err/0029_field_completion.txt | |||
@@ -33,4 +33,4 @@ SOURCE_FILE@[0; 24) | |||
33 | WHITESPACE@[21; 22) "\n" | 33 | WHITESPACE@[21; 22) "\n" |
34 | R_CURLY@[22; 23) "}" | 34 | R_CURLY@[22; 23) "}" |
35 | WHITESPACE@[23; 24) "\n" | 35 | WHITESPACE@[23; 24) "\n" |
36 | error 21: expected field name or number | 36 | error [21; 21): expected field name or number |
diff --git a/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt b/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt index dbc0081ac..c36e2f770 100644 --- a/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt +++ b/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt | |||
@@ -191,14 +191,14 @@ SOURCE_FILE@[0; 293) | |||
191 | WHITESPACE@[290; 291) "\n" | 191 | WHITESPACE@[290; 291) "\n" |
192 | R_CURLY@[291; 292) "}" | 192 | R_CURLY@[291; 292) "}" |
193 | WHITESPACE@[292; 293) "\n" | 193 | WHITESPACE@[292; 293) "\n" |
194 | error 52: expected `[` | 194 | error [52; 52): expected `[` |
195 | error 52: expected pattern | 195 | error [52; 52): expected pattern |
196 | error 53: expected FAT_ARROW | 196 | error [53; 53): expected FAT_ARROW |
197 | error 78: expected COMMA | 197 | error [78; 78): expected COMMA |
198 | error 161: expected `[` | 198 | error [161; 161): expected `[` |
199 | error 161: expected pattern | 199 | error [161; 161): expected pattern |
200 | error 162: expected FAT_ARROW | 200 | error [162; 162): expected FAT_ARROW |
201 | error 232: expected `[` | 201 | error [232; 232): expected `[` |
202 | error 232: expected pattern | 202 | error [232; 232): expected pattern |
203 | error 233: expected FAT_ARROW | 203 | error [233; 233): expected FAT_ARROW |
204 | error 250: expected COMMA | 204 | error [250; 250): expected COMMA |
diff --git a/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt b/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt index fd5ccc3f2..e914e688b 100644 --- a/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt +++ b/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt | |||
@@ -62,6 +62,6 @@ SOURCE_FILE@[0; 89) | |||
62 | WHITESPACE@[86; 87) "\n" | 62 | WHITESPACE@[86; 87) "\n" |
63 | R_CURLY@[87; 88) "}" | 63 | R_CURLY@[87; 88) "}" |
64 | WHITESPACE@[88; 89) "\n" | 64 | WHITESPACE@[88; 89) "\n" |
65 | error 80: expected pattern | 65 | error [80; 80): expected pattern |
66 | error 80: expected FAT_ARROW | 66 | error [80; 80): expected FAT_ARROW |
67 | error 80: expected expression | 67 | error [80; 80): expected expression |
diff --git a/crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.txt b/crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.txt index 21269fb02..2c91b6841 100644 --- a/crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.txt +++ b/crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.txt | |||
@@ -88,9 +88,9 @@ SOURCE_FILE@[0; 91) | |||
88 | WHITESPACE@[87; 88) "\n" | 88 | WHITESPACE@[87; 88) "\n" |
89 | R_CURLY@[88; 89) "}" | 89 | R_CURLY@[88; 89) "}" |
90 | WHITESPACE@[89; 91) "\n\n" | 90 | WHITESPACE@[89; 91) "\n\n" |
91 | error 24: expected a name | 91 | error [24; 24): expected a name |
92 | error 27: expected SEMI | 92 | error [27; 27): expected SEMI |
93 | error 48: expected a name | 93 | error [48; 48): expected a name |
94 | error 51: expected SEMI | 94 | error [51; 51): expected SEMI |
95 | error 76: expected a name | 95 | error [76; 76): expected a name |
96 | error 79: expected SEMI | 96 | error [79; 79): expected SEMI |
diff --git a/crates/ra_syntax/test_data/parser/err/0035_use_recover.txt b/crates/ra_syntax/test_data/parser/err/0035_use_recover.txt index 636840828..8cb4ea796 100644 --- a/crates/ra_syntax/test_data/parser/err/0035_use_recover.txt +++ b/crates/ra_syntax/test_data/parser/err/0035_use_recover.txt | |||
@@ -48,7 +48,7 @@ SOURCE_FILE@[0; 48) | |||
48 | L_CURLY@[45; 46) "{" | 48 | L_CURLY@[45; 46) "{" |
49 | R_CURLY@[46; 47) "}" | 49 | R_CURLY@[46; 47) "}" |
50 | WHITESPACE@[47; 48) "\n" | 50 | WHITESPACE@[47; 48) "\n" |
51 | error 17: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | 51 | error [17; 17): expected one of `*`, `::`, `{`, `self`, `super` or an identifier |
52 | error 17: expected SEMI | 52 | error [17; 17): expected SEMI |
53 | error 37: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | 53 | error [37; 37): expected one of `*`, `::`, `{`, `self`, `super` or an identifier |
54 | error 37: expected SEMI | 54 | error [37; 37): expected SEMI |
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 index 181f408c8..f5490fbe8 100644 --- a/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt +++ b/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt | |||
@@ -39,13 +39,13 @@ SOURCE_FILE@[0; 37) | |||
39 | ERROR@[35; 36) | 39 | ERROR@[35; 36) |
40 | SEMI@[35; 36) ";" | 40 | SEMI@[35; 36) ";" |
41 | WHITESPACE@[36; 37) "\n" | 41 | WHITESPACE@[36; 37) "\n" |
42 | error 22: expected COMMA | 42 | error [22; 22): expected COMMA |
43 | error 22: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | 43 | error [22; 22): expected one of `*`, `::`, `{`, `self`, `super` or an identifier |
44 | error 23: expected COMMA | 44 | error [23; 23): expected COMMA |
45 | error 24: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | 45 | error [24; 24): expected one of `*`, `::`, `{`, `self`, `super` or an identifier |
46 | error 27: expected COMMA | 46 | error [27; 27): expected COMMA |
47 | error 35: expected COMMA | 47 | error [35; 35): expected COMMA |
48 | error 35: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | 48 | error [35; 35): expected one of `*`, `::`, `{`, `self`, `super` or an identifier |
49 | error 36: expected COMMA | 49 | error [36; 36): expected COMMA |
50 | error 36: expected R_CURLY | 50 | error [36; 36): expected R_CURLY |
51 | error 36: expected SEMI | 51 | error [36; 36): expected SEMI |
diff --git a/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt b/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt index 749c8cddb..d0a128a5f 100644 --- a/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt +++ b/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt | |||
@@ -94,6 +94,6 @@ SOURCE_FILE@[0; 118) | |||
94 | WHITESPACE@[115; 116) "\n" | 94 | WHITESPACE@[115; 116) "\n" |
95 | R_CURLY@[116; 117) "}" | 95 | R_CURLY@[116; 117) "}" |
96 | WHITESPACE@[117; 118) "\n" | 96 | WHITESPACE@[117; 118) "\n" |
97 | error [36; 39): unnecessary visibility qualifier | 97 | error [36; 39): Unnecessary visibility qualifier |
98 | error [56; 66): unnecessary visibility qualifier | 98 | error [56; 66): Unnecessary visibility qualifier |
99 | error [86; 96): unnecessary visibility qualifier | 99 | error [86; 96): Unnecessary visibility qualifier |
diff --git a/crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.txt b/crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.txt index d1544634c..4a2f0a696 100644 --- a/crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.txt +++ b/crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.txt | |||
@@ -80,4 +80,4 @@ SOURCE_FILE@[0; 83) | |||
80 | WHITESPACE@[80; 81) "\n" | 80 | WHITESPACE@[80; 81) "\n" |
81 | R_CURLY@[81; 82) "}" | 81 | R_CURLY@[81; 82) "}" |
82 | WHITESPACE@[82; 83) "\n" | 82 | WHITESPACE@[82; 83) "\n" |
83 | error 56: expected expression | 83 | error [56; 56): expected expression |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0001_array_type_missing_semi.txt b/crates/ra_syntax/test_data/parser/inline/err/0001_array_type_missing_semi.txt index 3f0f1b480..530533b71 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0001_array_type_missing_semi.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0001_array_type_missing_semi.txt | |||
@@ -20,8 +20,8 @@ SOURCE_FILE@[0; 18) | |||
20 | ERROR@[16; 17) | 20 | ERROR@[16; 17) |
21 | SEMI@[16; 17) ";" | 21 | SEMI@[16; 17) ";" |
22 | WHITESPACE@[17; 18) "\n" | 22 | WHITESPACE@[17; 18) "\n" |
23 | error 12: expected `;` or `]` | 23 | error [12; 12): expected `;` or `]` |
24 | error 12: expected SEMI | 24 | error [12; 12): expected SEMI |
25 | error 13: expected an item | 25 | error [13; 13): expected an item |
26 | error 15: expected an item | 26 | error [15; 15): expected an item |
27 | error 16: expected an item | 27 | error [16; 16): expected an item |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.txt b/crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.txt index 2950d77ef..0187d872d 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.txt | |||
@@ -23,7 +23,7 @@ SOURCE_FILE@[0; 30) | |||
23 | WHITESPACE@[27; 28) "\n" | 23 | WHITESPACE@[27; 28) "\n" |
24 | R_CURLY@[28; 29) "}" | 24 | R_CURLY@[28; 29) "}" |
25 | WHITESPACE@[29; 30) "\n" | 25 | WHITESPACE@[29; 30) "\n" |
26 | error 22: expected a loop | 26 | error [22; 22): expected a loop |
27 | error 22: expected SEMI | 27 | error [22; 22): expected SEMI |
28 | error 27: expected type | 28 | error [27; 27): expected type |
29 | error 27: expected `{` | 29 | error [27; 27): expected `{` |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.txt b/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.txt index b97e339bb..2ab29eecc 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.txt | |||
@@ -14,4 +14,4 @@ SOURCE_FILE@[0; 14) | |||
14 | R_PAREN@[11; 12) ")" | 14 | R_PAREN@[11; 12) ")" |
15 | SEMI@[12; 13) ";" | 15 | SEMI@[12; 13) ";" |
16 | WHITESPACE@[13; 14) "\n" | 16 | WHITESPACE@[13; 14) "\n" |
17 | error 10: expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate) | 17 | error [10; 10): expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate) |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0004_impl_type.txt b/crates/ra_syntax/test_data/parser/inline/err/0004_impl_type.txt index 43321b1ed..d5aea05c2 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0004_impl_type.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0004_impl_type.txt | |||
@@ -73,7 +73,7 @@ SOURCE_FILE@[0; 87) | |||
73 | L_CURLY@[84; 85) "{" | 73 | L_CURLY@[84; 85) "{" |
74 | R_CURLY@[85; 86) "}" | 74 | R_CURLY@[85; 86) "}" |
75 | WHITESPACE@[86; 87) "\n" | 75 | WHITESPACE@[86; 87) "\n" |
76 | error 38: expected trait or type | 76 | error [38; 38): expected trait or type |
77 | error 38: expected `{` | 77 | error [38; 38): expected `{` |
78 | error 70: expected trait or type | 78 | error [70; 70): expected trait or type |
79 | error 70: expected `{` | 79 | error [70; 70): expected `{` |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt b/crates/ra_syntax/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt index 451f29d39..9e9186ad4 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt | |||
@@ -16,8 +16,8 @@ SOURCE_FILE@[0; 20) | |||
16 | ERROR@[18; 19) | 16 | ERROR@[18; 19) |
17 | SEMI@[18; 19) ";" | 17 | SEMI@[18; 19) ";" |
18 | WHITESPACE@[19; 20) "\n" | 18 | WHITESPACE@[19; 20) "\n" |
19 | error 15: expected `fn` | 19 | error [15; 15): expected `fn` |
20 | error 15: expected SEMI | 20 | error [15; 15): expected SEMI |
21 | error 16: expected an item | 21 | error [16; 16): expected an item |
22 | error 17: expected an item | 22 | error [17; 17): expected an item |
23 | error 18: expected an item | 23 | error [18; 18): expected an item |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.txt b/crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.txt index f3fbc4828..690acdca3 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.txt | |||
@@ -33,5 +33,5 @@ SOURCE_FILE@[0; 33) | |||
33 | L_CURLY@[30; 31) "{" | 33 | L_CURLY@[30; 31) "{" |
34 | R_CURLY@[31; 32) "}" | 34 | R_CURLY@[31; 32) "}" |
35 | WHITESPACE@[32; 33) "\n" | 35 | WHITESPACE@[32; 33) "\n" |
36 | error 11: expected an item | 36 | error [11; 11): expected an item |
37 | error 18: expected an item | 37 | error [18; 18): expected an item |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.txt b/crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.txt index 5cfe766d7..a4002a998 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.txt | |||
@@ -29,4 +29,4 @@ SOURCE_FILE@[0; 30) | |||
29 | WHITESPACE@[27; 28) " " | 29 | WHITESPACE@[27; 28) " " |
30 | R_CURLY@[28; 29) "}" | 30 | R_CURLY@[28; 29) "}" |
31 | WHITESPACE@[29; 30) "\n" | 31 | WHITESPACE@[29; 30) "\n" |
32 | error 27: expected SEMI | 32 | error [27; 27): expected SEMI |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.txt b/crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.txt index 0594f148f..6f45a4fa6 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.txt | |||
@@ -23,4 +23,4 @@ SOURCE_FILE@[0; 21) | |||
23 | WHITESPACE@[18; 19) " " | 23 | WHITESPACE@[18; 19) " " |
24 | R_CURLY@[19; 20) "}" | 24 | R_CURLY@[19; 20) "}" |
25 | WHITESPACE@[20; 21) "\n" | 25 | WHITESPACE@[20; 21) "\n" |
26 | error 14: expected an item | 26 | error [14; 14): expected an item |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt b/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt index 2ca5b8f32..e6d3a5c95 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt | |||
@@ -57,5 +57,5 @@ SOURCE_FILE@[0; 48) | |||
57 | WHITESPACE@[45; 46) "\n" | 57 | WHITESPACE@[45; 46) "\n" |
58 | R_CURLY@[46; 47) "}" | 58 | R_CURLY@[46; 47) "}" |
59 | WHITESPACE@[47; 48) "\n" | 59 | WHITESPACE@[47; 48) "\n" |
60 | error 24: attributes are not allowed on BIN_EXPR | 60 | error [24; 24): attributes are not allowed on BIN_EXPR |
61 | error 44: attributes are not allowed on IF_EXPR | 61 | error [44; 44): attributes are not allowed on IF_EXPR |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.txt b/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.txt index 289193b9e..f6ac0feaf 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.txt | |||
@@ -37,5 +37,5 @@ SOURCE_FILE@[0; 50) | |||
37 | L_CURLY@[47; 48) "{" | 37 | L_CURLY@[47; 48) "{" |
38 | R_CURLY@[48; 49) "}" | 38 | R_CURLY@[48; 49) "}" |
39 | WHITESPACE@[49; 50) "\n" | 39 | WHITESPACE@[49; 50) "\n" |
40 | error 6: expected existential, fn, trait or impl | 40 | error [6; 6): expected existential, fn, trait or impl |
41 | error 31: expected existential, fn, trait or impl | 41 | error [31; 31): expected existential, fn, trait or impl |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0013_static_underscore.txt b/crates/ra_syntax/test_data/parser/inline/err/0013_static_underscore.txt index 28f75a341..5b3dc5af2 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0013_static_underscore.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0013_static_underscore.txt | |||
@@ -18,4 +18,4 @@ SOURCE_FILE@[0; 19) | |||
18 | INT_NUMBER@[16; 17) "5" | 18 | INT_NUMBER@[16; 17) "5" |
19 | SEMI@[17; 18) ";" | 19 | SEMI@[17; 18) ";" |
20 | WHITESPACE@[18; 19) "\n" | 20 | WHITESPACE@[18; 19) "\n" |
21 | error 7: expected a name | 21 | error [7; 7): expected a name |
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.txt b/crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.txt index a1a0bd7c4..25d80be1d 100644 --- a/crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.txt +++ b/crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.txt | |||
@@ -51,9 +51,9 @@ SOURCE_FILE@[0; 62) | |||
51 | WHITESPACE@[59; 60) "\n" | 51 | WHITESPACE@[59; 60) "\n" |
52 | R_CURLY@[60; 61) "}" | 52 | R_CURLY@[60; 61) "}" |
53 | WHITESPACE@[61; 62) "\n" | 53 | WHITESPACE@[61; 62) "\n" |
54 | error 21: expected EXCL | 54 | error [21; 21): expected EXCL |
55 | error 21: expected `{`, `[`, `(` | 55 | error [21; 21): expected `{`, `[`, `(` |
56 | error 21: expected SEMI | 56 | error [21; 21): expected SEMI |
57 | error 47: expected EXCL | 57 | error [47; 47): expected EXCL |
58 | error 47: expected `{`, `[`, `(` | 58 | error [47; 47): expected `{`, `[`, `(` |
59 | error 47: expected SEMI | 59 | error [47; 47): expected SEMI |