diff options
Diffstat (limited to 'crates/ra_syntax')
55 files changed, 450 insertions, 642 deletions
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 |