From 9fdf984958901a6bf16772c2c88b3163f044b390 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Thu, 6 Feb 2020 02:33:18 +0200 Subject: ra_syntax: reshape SyntaxError for the sake of removing redundancy --- crates/ra_syntax/src/lib.rs | 8 +- crates/ra_syntax/src/parsing/lexer.rs | 92 +++------ crates/ra_syntax/src/parsing/reparsing.rs | 27 ++- crates/ra_syntax/src/syntax_error.rs | 214 +++------------------ crates/ra_syntax/src/syntax_node.rs | 14 +- crates/ra_syntax/src/tests.rs | 21 +- crates/ra_syntax/src/validation.rs | 155 +++++++-------- crates/ra_syntax/src/validation/block.rs | 14 +- .../parser/err/0000_struct_field_missing_comma.txt | 2 +- .../parser/err/0001_item_recovery_in_file.txt | 4 +- .../parser/err/0002_duplicate_shebang.txt | 22 +-- .../test_data/parser/err/0003_C++_semicolon.txt | 2 +- .../parser/err/0004_use_path_bad_segment.txt | 2 +- .../parser/err/0005_attribute_recover.txt | 6 +- .../parser/err/0006_named_field_recovery.txt | 16 +- .../parser/err/0007_stray_curly_in_file.txt | 6 +- .../parser/err/0008_item_block_recovery.txt | 6 +- .../err/0009_broken_struct_type_parameter.txt | 22 +-- .../parser/err/0010_unsafe_lambda_block.txt | 2 +- .../test_data/parser/err/0011_extern_struct.txt | 2 +- .../test_data/parser/err/0013_invalid_type.txt | 36 ++-- .../test_data/parser/err/0014_where_no_bounds.txt | 2 +- .../test_data/parser/err/0015_curly_in_params.txt | 12 +- .../test_data/parser/err/0016_missing_semi.txt | 2 +- .../parser/err/0017_incomplete_binexpr.txt | 2 +- .../test_data/parser/err/0018_incomplete_fn.txt | 10 +- .../test_data/parser/err/0019_let_recover.txt | 20 +- .../test_data/parser/err/0020_fn_recover.txt | 6 +- .../test_data/parser/err/0021_incomplete_param.txt | 4 +- .../test_data/parser/err/0022_bad_exprs.txt | 66 +++---- .../test_data/parser/err/0023_mismatched_paren.txt | 4 +- .../test_data/parser/err/0024_many_type_parens.txt | 58 +++--- .../ra_syntax/test_data/parser/err/0025_nope.txt | 22 +-- .../test_data/parser/err/0026_imp_recovery.txt | 4 +- .../parser/err/0027_incomplere_where_for.txt | 4 +- .../test_data/parser/err/0029_field_completion.txt | 2 +- .../parser/err/0032_match_arms_inner_attrs.txt | 22 +-- .../parser/err/0033_match_arms_outer_attrs.txt | 6 +- .../test_data/parser/err/0034_bad_box_pattern.txt | 12 +- .../test_data/parser/err/0035_use_recover.txt | 8 +- .../test_data/parser/err/0036_partial_use.txt | 20 +- .../parser/err/0037_visibility_in_traits.txt | 6 +- .../test_data/parser/err/0039_lambda_recovery.txt | 2 +- .../inline/err/0001_array_type_missing_semi.txt | 10 +- .../parser/inline/err/0002_misplaced_label_err.txt | 8 +- .../inline/err/0003_pointer_type_no_mutability.txt | 2 +- .../test_data/parser/inline/err/0004_impl_type.txt | 8 +- .../inline/err/0005_fn_pointer_type_missing_fn.txt | 10 +- .../parser/inline/err/0006_unsafe_block_in_mod.txt | 4 +- .../inline/err/0007_async_without_semicolon.txt | 2 +- .../test_data/parser/inline/err/0008_pub_expr.txt | 2 +- .../inline/err/0009_attr_on_expr_not_allowed.txt | 4 +- .../parser/inline/err/0013_static_underscore.txt | 2 +- .../parser/inline/err/0014_default_fn_type.txt | 12 +- 54 files changed, 402 insertions(+), 629 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index f8f4b64c1..cc02c4be5 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -41,11 +41,9 @@ use crate::syntax_node::GreenNode; pub use crate::{ algo::InsertPosition, ast::{AstNode, AstToken}, - parsing::{ - lex_single_syntax_kind, lex_single_valid_syntax_kind, tokenize, Token, TokenizeError, - }, + parsing::{lex_single_syntax_kind, lex_single_valid_syntax_kind, tokenize, Token}, ptr::{AstPtr, SyntaxNodePtr}, - syntax_error::{Location, SyntaxError, SyntaxErrorKind}, + syntax_error::SyntaxError, syntax_node::{ Direction, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken, SyntaxTreeBuilder, }, @@ -117,7 +115,7 @@ impl Parse { pub fn debug_dump(&self) -> String { let mut buf = format!("{:#?}", self.tree().syntax()); for err in self.errors.iter() { - writeln!(buf, "error {:?}: {}", err.location(), err.kind()).unwrap(); + writeln!(buf, "error {:?}: {}", err.range(), err.message()).unwrap(); } buf } 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 @@ //! It is just a bridge to `rustc_lexer`. use crate::{ - SyntaxError, SyntaxErrorKind, + SyntaxError, SyntaxKind::{self, *}, TextRange, TextUnit, }; @@ -41,13 +41,13 @@ pub fn tokenize(text: &str) -> (Vec, Vec) { let token_len = TextUnit::from_usize(rustc_token.len); let token_range = TextRange::offset_len(TextUnit::from_usize(offset), token_len); - let (syntax_kind, error) = + let (syntax_kind, err_message) = rustc_token_kind_to_syntax_kind(&rustc_token.kind, &text[token_range]); tokens.push(Token { kind: syntax_kind, len: token_len }); - if let Some(error) = error { - errors.push(SyntaxError::new(SyntaxErrorKind::TokenizeError(error), token_range)); + if let Some(err_message) = err_message { + errors.push(SyntaxError::new(err_message, token_range)); } offset += rustc_token.len; @@ -94,61 +94,21 @@ fn lex_first_token(text: &str) -> Option<(Token, Option)> { } let rustc_token = rustc_lexer::first_token(text); - let (syntax_kind, error) = rustc_token_kind_to_syntax_kind(&rustc_token.kind, text); + let (syntax_kind, err_message) = rustc_token_kind_to_syntax_kind(&rustc_token.kind, text); let token = Token { kind: syntax_kind, len: TextUnit::from_usize(rustc_token.len) }; - let error = error.map(|error| { - SyntaxError::new( - SyntaxErrorKind::TokenizeError(error), - TextRange::from_to(TextUnit::from(0), TextUnit::of_str(text)), - ) + let optional_error = err_message.map(|err_message| { + SyntaxError::new(err_message, TextRange::from_to(0.into(), TextUnit::of_str(text))) }); - Some((token, error)) -} - -// FIXME: simplify TokenizeError to `SyntaxError(String, TextRange)` as per @matklad advice: -// https://github.com/rust-analyzer/rust-analyzer/pull/2911/files#r371175067 - -/// Describes the values of `SyntaxErrorKind::TokenizeError` enum variant. -/// It describes all the types of errors that may happen during the tokenization -/// of Rust source. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TokenizeError { - /// Base prefix was provided, but there were no digits - /// after it, e.g. `0x`, `0b`. - EmptyInt, - /// Float exponent lacks digits e.g. `12.34e+`, `12.3E+`, `12e-`, `1_E-`, - EmptyExponent, - - /// Block comment lacks trailing delimiter `*/` - UnterminatedBlockComment, - /// Character literal lacks trailing delimiter `'` - UnterminatedChar, - /// Characterish byte literal lacks trailing delimiter `'` - UnterminatedByte, - /// String literal lacks trailing delimiter `"` - UnterminatedString, - /// Byte string literal lacks trailing delimiter `"` - UnterminatedByteString, - /// Raw literal lacks trailing delimiter e.g. `"##` - UnterminatedRawString, - /// Raw byte string literal lacks trailing delimiter e.g. `"##` - UnterminatedRawByteString, - - /// Raw string lacks a quote after the pound characters e.g. `r###` - UnstartedRawString, - /// Raw byte string lacks a quote after the pound characters e.g. `br###` - UnstartedRawByteString, - - /// Lifetime starts with a number e.g. `'4ever` - LifetimeStartsWithNumber, + Some((token, optional_error)) } +/// Returns `SyntaxKind` and an optional tokenize error message. fn rustc_token_kind_to_syntax_kind( rustc_token_kind: &rustc_lexer::TokenKind, token_text: &str, -) -> (SyntaxKind, Option) { +) -> (SyntaxKind, Option<&'static str>) { // A note on an intended tradeoff: // We drop some useful infromation here (see patterns with double dots `..`) // 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( let syntax_kind = { use rustc_lexer::TokenKind as TK; - use TokenizeError as TE; - match rustc_token_kind { TK::LineComment => COMMENT, TK::BlockComment { terminated: true } => COMMENT, TK::BlockComment { terminated: false } => { - return (COMMENT, Some(TE::UnterminatedBlockComment)); + return ( + COMMENT, + Some("Missing trailing `*/` symbols to terminate the block comment"), + ); } TK::Whitespace => WHITESPACE, @@ -181,7 +142,7 @@ fn rustc_token_kind_to_syntax_kind( TK::Lifetime { starts_with_number: false } => LIFETIME, TK::Lifetime { starts_with_number: true } => { - return (LIFETIME, Some(TE::LifetimeStartsWithNumber)) + return (LIFETIME, Some("Lifetime name cannot start with a number")) } TK::Semi => SEMI, @@ -217,57 +178,56 @@ fn rustc_token_kind_to_syntax_kind( return (syntax_kind, None); - fn match_literal_kind(kind: &rustc_lexer::LiteralKind) -> (SyntaxKind, Option) { + fn match_literal_kind(kind: &rustc_lexer::LiteralKind) -> (SyntaxKind, Option<&'static str>) { use rustc_lexer::LiteralKind as LK; - use TokenizeError as TE; #[rustfmt::skip] let syntax_kind = match *kind { LK::Int { empty_int: false, .. } => INT_NUMBER, LK::Int { empty_int: true, .. } => { - return (INT_NUMBER, Some(TE::EmptyInt)) + return (INT_NUMBER, Some("Missing digits after the integer base prefix")) } LK::Float { empty_exponent: false, .. } => FLOAT_NUMBER, LK::Float { empty_exponent: true, .. } => { - return (FLOAT_NUMBER, Some(TE::EmptyExponent)) + return (FLOAT_NUMBER, Some("Missing digits after the exponent symbol")) } LK::Char { terminated: true } => CHAR, LK::Char { terminated: false } => { - return (CHAR, Some(TE::UnterminatedChar)) + return (CHAR, Some("Missing trailing `'` symbol to terminate the character literal")) } LK::Byte { terminated: true } => BYTE, LK::Byte { terminated: false } => { - return (BYTE, Some(TE::UnterminatedByte)) + return (BYTE, Some("Missing trailing `'` symbol to terminate the byte literal")) } LK::Str { terminated: true } => STRING, LK::Str { terminated: false } => { - return (STRING, Some(TE::UnterminatedString)) + return (STRING, Some("Missing trailing `\"` symbol to terminate the string literal")) } LK::ByteStr { terminated: true } => BYTE_STRING, LK::ByteStr { terminated: false } => { - return (BYTE_STRING, Some(TE::UnterminatedByteString)) + return (BYTE_STRING, Some("Missing trailing `\"` symbol to terminate the byte string literal")) } LK::RawStr { started: true, terminated: true, .. } => RAW_STRING, LK::RawStr { started: true, terminated: false, .. } => { - return (RAW_STRING, Some(TE::UnterminatedRawString)) + return (RAW_STRING, Some("Missing trailing `\"` with `#` symbols to terminate the raw string literal")) } LK::RawStr { started: false, .. } => { - return (RAW_STRING, Some(TE::UnstartedRawString)) + return (RAW_STRING, Some("Missing `\"` symbol after `#` symbols to begin the raw string literal")) } LK::RawByteStr { started: true, terminated: true, .. } => RAW_BYTE_STRING, LK::RawByteStr { started: true, terminated: false, .. } => { - return (RAW_BYTE_STRING, Some(TE::UnterminatedRawByteString)) + return (RAW_BYTE_STRING, Some("Missing trailing `\"` with `#` symbols to terminate the raw byte string literal")) } LK::RawByteStr { started: false, .. } => { - return (RAW_BYTE_STRING, Some(TE::UnstartedRawByteString)) + return (RAW_BYTE_STRING, Some("Missing `\"` symbol after `#` symbols to begin the raw byte string literal")) } }; diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index a86da0675..41a355ec7 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs @@ -87,7 +87,7 @@ fn reparse_block<'node>( edit: &AtomTextEdit, ) -> Option<(GreenNode, Vec, TextRange)> { let (node, reparser) = find_reparsable_node(root, edit.delete)?; - let text = get_text_after_edit(node.clone().into(), &edit); + let text = get_text_after_edit(node.clone().into(), edit); let (tokens, new_lexer_errors) = tokenize(&text); if !is_balanced(&tokens) { @@ -162,20 +162,27 @@ fn is_balanced(tokens: &[Token]) -> bool { fn merge_errors( old_errors: Vec, new_errors: Vec, - old_range: TextRange, + range_before_reparse: TextRange, edit: &AtomTextEdit, ) -> Vec { let mut res = Vec::new(); - for e in old_errors { - if e.offset() <= old_range.start() { - res.push(e) - } else if e.offset() >= old_range.end() { - res.push(e.add_offset(TextUnit::of_str(&edit.insert), edit.delete.len())); + + for old_err in old_errors { + let old_err_range = *old_err.range(); + // FIXME: make sure that .start() was here previously by a mistake + if old_err_range.end() <= range_before_reparse.start() { + res.push(old_err); + } else if old_err_range.start() >= range_before_reparse.end() { + let inserted_len = TextUnit::of_str(&edit.insert); + res.push(old_err.with_range((old_err_range + inserted_len) - edit.delete.len())); + // Note: extra parens are intentional to prevent uint underflow, HWAB (here was a bug) } } - for e in new_errors { - res.push(e.add_offset(old_range.start(), 0.into())); - } + res.extend(new_errors.into_iter().map(|new_err| { + // fighting borrow checker with a variable ;) + let offseted_range = *new_err.range() + range_before_reparse.start(); + new_err.with_range(offseted_range) + })); res } diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index 7f9d36618..460552103 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs @@ -1,209 +1,47 @@ -//! FIXME: write short doc here +//! Module that defines `SyntaxError`. use std::fmt; -use ra_parser::ParseError; - -use crate::{validation::EscapeError, TextRange, TextUnit, TokenizeError}; +use crate::{TextRange, TextUnit}; +/// Represents the result of unsuccessful tokenization, parsing +/// or semmantical analyzis. #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct SyntaxError { - kind: SyntaxErrorKind, - location: Location, -} - -// FIXME: Location should be just `Location(TextRange)` -// TextUnit enum member just unnecessarily compicates things, -// we should'n treat it specially, it just as a `TextRange { start: x, end: x + 1 }` -// see `location_to_range()` in ra_ide/src/diagnostics -#[derive(Clone, PartialEq, Eq, Hash)] -pub enum Location { - Offset(TextUnit), - Range(TextRange), -} - -impl From for Location { - fn from(offset: TextUnit) -> Location { - Location::Offset(offset) - } -} - -impl From for Location { - fn from(range: TextRange) -> Location { - Location::Range(range) - } -} - -impl fmt::Debug for Location { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Location::Offset(it) => fmt::Debug::fmt(it, f), - Location::Range(it) => fmt::Debug::fmt(it, f), - } - } -} +pub struct SyntaxError(String, TextRange); + +// FIXME: there was an unused SyntaxErrorKind previously (before this enum was removed) +// It was introduced in this PR: https://github.com/rust-analyzer/rust-analyzer/pull/846/files#diff-827da9b03b8f9faa1bade5cdd44d5dafR95 +// but it was not removed by a mistake. +// +// So, we need to find a place where to stick validation for attributes in match clauses. +// Code before refactor: +// InvalidMatchInnerAttr => { +// write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression") +// } impl SyntaxError { - pub fn new>(kind: SyntaxErrorKind, loc: L) -> SyntaxError { - SyntaxError { kind, location: loc.into() } + pub fn new(message: impl Into, range: TextRange) -> Self { + Self(message.into(), range) } - - pub fn kind(&self) -> SyntaxErrorKind { - self.kind.clone() + pub fn new_at_offset(message: impl Into, offset: TextUnit) -> Self { + Self(message.into(), TextRange::offset_len(offset, 1.into())) } - pub fn location(&self) -> Location { - self.location.clone() + pub fn message(&self) -> &str { + &self.0 } - - pub fn offset(&self) -> TextUnit { - match self.location { - Location::Offset(offset) => offset, - Location::Range(range) => range.start(), - } + pub fn range(&self) -> &TextRange { + &self.1 } - pub fn add_offset(mut self, plus_offset: TextUnit, minus_offset: TextUnit) -> SyntaxError { - self.location = match self.location { - Location::Range(range) => Location::Range(range + plus_offset - minus_offset), - Location::Offset(offset) => Location::Offset(offset + plus_offset - minus_offset), - }; - + pub fn with_range(mut self, range: TextRange) -> Self { + self.1 = range; self } - - pub fn debug_dump(&self, acc: &mut impl fmt::Write) { - writeln!(acc, "error {:?}: {}", self.location(), self.kind()).unwrap(); - } } impl fmt::Display for SyntaxError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.kind.fmt(f) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum SyntaxErrorKind { - ParseError(ParseError), - EscapeError(EscapeError), - TokenizeError(TokenizeError), - // FIXME: the obvious pattern of this enum dictates that the following enum variants - // should be wrapped into something like `SemmanticError(SemmanticError)` - // or `ValidateError(ValidateError)` or `SemmanticValidateError(...)` - InvalidBlockAttr, - InvalidMatchInnerAttr, - InvalidTupleIndexFormat, - VisibilityNotAllowed, - InclusiveRangeMissingEnd, -} - -impl fmt::Display for SyntaxErrorKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::SyntaxErrorKind::*; - match self { - InvalidBlockAttr => { - write!(f, "A block in this position cannot accept inner attributes") - } - InvalidMatchInnerAttr => { - write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression") - } - InvalidTupleIndexFormat => { - write!(f, "Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix") - } - ParseError(msg) => write!(f, "{}", msg.0), - EscapeError(err) => write!(f, "{}", err), - TokenizeError(err) => write!(f, "{}", err), - VisibilityNotAllowed => { - write!(f, "unnecessary visibility qualifier") - } - InclusiveRangeMissingEnd => { - write!(f, "An inclusive range must have an end expression") - } - } - } -} - -impl fmt::Display for TokenizeError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - #[rustfmt::skip] - let msg = match self { - TokenizeError::EmptyInt => { - "Missing digits after the integer base prefix" - } - TokenizeError::EmptyExponent => { - "Missing digits after the exponent symbol" - } - TokenizeError::UnterminatedBlockComment => { - "Missing trailing `*/` symbols to terminate the block comment" - } - TokenizeError::UnterminatedChar => { - "Missing trailing `'` symbol to terminate the character literal" - } - TokenizeError::UnterminatedByte => { - "Missing trailing `'` symbol to terminate the byte literal" - } - TokenizeError::UnterminatedString => { - "Missing trailing `\"` symbol to terminate the string literal" - } - TokenizeError::UnterminatedByteString => { - "Missing trailing `\"` symbol to terminate the byte string literal" - } - TokenizeError::UnterminatedRawString => { - "Missing trailing `\"` with `#` symbols to terminate the raw string literal" - } - TokenizeError::UnterminatedRawByteString => { - "Missing trailing `\"` with `#` symbols to terminate the raw byte string literal" - } - TokenizeError::UnstartedRawString => { - "Missing `\"` symbol after `#` symbols to begin the raw string literal" - } - TokenizeError::UnstartedRawByteString => { - "Missing `\"` symbol after `#` symbols to begin the raw byte string literal" - } - TokenizeError::LifetimeStartsWithNumber => { - "Lifetime name cannot start with a number" - } - }; - write!(f, "{}", msg) - } -} - -impl fmt::Display for EscapeError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let msg = match self { - EscapeError::ZeroChars => "Empty literal", - EscapeError::MoreThanOneChar => "Literal should be one character long", - EscapeError::LoneSlash => "Character must be escaped: '\\'", - EscapeError::InvalidEscape => "Invalid escape sequence", - EscapeError::BareCarriageReturn => "Character must be escaped: '\r'", - EscapeError::EscapeOnlyChar => "Character must be escaped", - EscapeError::TooShortHexEscape => "Escape sequence should have two digits", - EscapeError::InvalidCharInHexEscape => "Escape sequence should be a hexadecimal number", - EscapeError::OutOfRangeHexEscape => "Escape sequence should be ASCII", - EscapeError::NoBraceInUnicodeEscape => "Invalid escape sequence", - EscapeError::InvalidCharInUnicodeEscape => "Invalid escape sequence", - EscapeError::EmptyUnicodeEscape => "Invalid escape sequence", - EscapeError::UnclosedUnicodeEscape => "Missing '}'", - EscapeError::LeadingUnderscoreUnicodeEscape => "Invalid escape sequence", - EscapeError::OverlongUnicodeEscape => { - "Unicode escape sequence should have at most 6 digits" - } - EscapeError::LoneSurrogateUnicodeEscape => { - "Unicode escape code should not be a surrogate" - } - EscapeError::OutOfRangeUnicodeEscape => { - "Unicode escape code should be at most 0x10FFFF" - } - EscapeError::UnicodeEscapeInByte => "Unicode escapes are not allowed in bytes", - EscapeError::NonAsciiCharInByte => "Non ASCII characters are not allowed in bytes", - }; - write!(f, "{}", msg) - } -} - -impl From for SyntaxErrorKind { - fn from(err: EscapeError) -> Self { - SyntaxErrorKind::EscapeError(err) + self.0.fmt(f) } } diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index 7c2b18af3..251668996 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs @@ -6,15 +6,10 @@ //! The *real* implementation is in the (language-agnostic) `rowan` crate, this //! module just wraps its API. -use ra_parser::ParseError; +pub(crate) use rowan::{GreenNode, GreenToken}; use rowan::{GreenNodeBuilder, Language}; -use crate::{ - syntax_error::{SyntaxError, SyntaxErrorKind}, - Parse, SmolStr, SyntaxKind, TextUnit, -}; - -pub(crate) use rowan::{GreenNode, GreenToken}; +use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextUnit}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum RustLanguage {} @@ -73,8 +68,7 @@ impl SyntaxTreeBuilder { self.inner.finish_node() } - pub fn error(&mut self, error: ParseError, text_pos: TextUnit) { - let error = SyntaxError::new(SyntaxErrorKind::ParseError(error), text_pos); - self.errors.push(error) + pub fn error(&mut self, error: ra_parser::ParseError, text_pos: TextUnit) { + self.errors.push(SyntaxError::new_at_offset(error.0, text_pos)) } } diff --git a/crates/ra_syntax/src/tests.rs b/crates/ra_syntax/src/tests.rs index fb22b9e54..2533d0c44 100644 --- a/crates/ra_syntax/src/tests.rs +++ b/crates/ra_syntax/src/tests.rs @@ -5,7 +5,7 @@ use std::{ use test_utils::{collect_tests, dir_tests, project_dir, read_text}; -use crate::{fuzz, tokenize, Location, SourceFile, SyntaxError, TextRange, Token}; +use crate::{fuzz, tokenize, SourceFile, SyntaxError, Token}; #[test] fn lexer_tests() { @@ -128,25 +128,14 @@ fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) writeln!(acc, "{:?} {} {:?}", token.kind, token_len, token_text).unwrap(); } for err in errors { - let err_range = location_to_range(err.location()); writeln!( acc, "> error{:?} token({:?}) msg({})", - err.location(), - &text[err_range], - err.kind() + err.range(), + &text[*err.range()], + err.message() ) .unwrap(); } - return acc; - - // FIXME: copy-pasted this from `ra_ide/src/diagnostics.rs` - // `Location` will be refactored soon in new PR, see todos here: - // https://github.com/rust-analyzer/rust-analyzer/issues/223 - fn location_to_range(location: Location) -> TextRange { - match location { - Location::Offset(offset) => TextRange::offset_len(offset, 1.into()), - Location::Range(range) => range, - } - } + acc } 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; use rustc_lexer::unescape; use crate::{ - ast, match_ast, AstNode, SyntaxError, SyntaxErrorKind, + ast, match_ast, AstNode, SyntaxError, SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST_DEF, FN_DEF, INT_NUMBER, STRING, TYPE_ALIAS_DEF}, SyntaxNode, SyntaxToken, TextUnit, T, }; -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum EscapeError { - ZeroChars, - MoreThanOneChar, - LoneSlash, - InvalidEscape, - BareCarriageReturn, - EscapeOnlyChar, - TooShortHexEscape, - InvalidCharInHexEscape, - OutOfRangeHexEscape, - NoBraceInUnicodeEscape, - InvalidCharInUnicodeEscape, - EmptyUnicodeEscape, - UnclosedUnicodeEscape, - LeadingUnderscoreUnicodeEscape, - OverlongUnicodeEscape, - LoneSurrogateUnicodeEscape, - OutOfRangeUnicodeEscape, - UnicodeEscapeInByte, - NonAsciiCharInByte, -} +fn rustc_unescape_error_to_string(err: unescape::EscapeError) -> &'static str { + use unescape::EscapeError as EE; -impl From for EscapeError { - fn from(err: rustc_lexer::unescape::EscapeError) -> Self { - match err { - rustc_lexer::unescape::EscapeError::ZeroChars => EscapeError::ZeroChars, - rustc_lexer::unescape::EscapeError::MoreThanOneChar => EscapeError::MoreThanOneChar, - rustc_lexer::unescape::EscapeError::LoneSlash => EscapeError::LoneSlash, - rustc_lexer::unescape::EscapeError::InvalidEscape => EscapeError::InvalidEscape, - rustc_lexer::unescape::EscapeError::BareCarriageReturn - | rustc_lexer::unescape::EscapeError::BareCarriageReturnInRawString => { - EscapeError::BareCarriageReturn - } - rustc_lexer::unescape::EscapeError::EscapeOnlyChar => EscapeError::EscapeOnlyChar, - rustc_lexer::unescape::EscapeError::TooShortHexEscape => EscapeError::TooShortHexEscape, - rustc_lexer::unescape::EscapeError::InvalidCharInHexEscape => { - EscapeError::InvalidCharInHexEscape - } - rustc_lexer::unescape::EscapeError::OutOfRangeHexEscape => { - EscapeError::OutOfRangeHexEscape - } - rustc_lexer::unescape::EscapeError::NoBraceInUnicodeEscape => { - EscapeError::NoBraceInUnicodeEscape - } - rustc_lexer::unescape::EscapeError::InvalidCharInUnicodeEscape => { - EscapeError::InvalidCharInUnicodeEscape - } - rustc_lexer::unescape::EscapeError::EmptyUnicodeEscape => { - EscapeError::EmptyUnicodeEscape - } - rustc_lexer::unescape::EscapeError::UnclosedUnicodeEscape => { - EscapeError::UnclosedUnicodeEscape - } - rustc_lexer::unescape::EscapeError::LeadingUnderscoreUnicodeEscape => { - EscapeError::LeadingUnderscoreUnicodeEscape - } - rustc_lexer::unescape::EscapeError::OverlongUnicodeEscape => { - EscapeError::OverlongUnicodeEscape - } - rustc_lexer::unescape::EscapeError::LoneSurrogateUnicodeEscape => { - EscapeError::LoneSurrogateUnicodeEscape - } - rustc_lexer::unescape::EscapeError::OutOfRangeUnicodeEscape => { - EscapeError::OutOfRangeUnicodeEscape - } - rustc_lexer::unescape::EscapeError::UnicodeEscapeInByte => { - EscapeError::UnicodeEscapeInByte - } - rustc_lexer::unescape::EscapeError::NonAsciiCharInByte - | rustc_lexer::unescape::EscapeError::NonAsciiCharInByteString => { - EscapeError::NonAsciiCharInByte - } + #[rustfmt::skip] + let err_message = match err { + EE::ZeroChars => { + "Literal must not be empty" } - } -} + EE::MoreThanOneChar => { + "Literal must be one character long" + } + EE::LoneSlash => { + "Character must be escaped: `\\`" + } + EE::InvalidEscape => { + "Invalid escape" + } + EE::BareCarriageReturn | EE::BareCarriageReturnInRawString => { + "Character must be escaped: `\r`" + } + EE::EscapeOnlyChar => { + "Escape character `\\` must be escaped itself" + } + EE::TooShortHexEscape => { + "ASCII hex escape code must have exactly two digits" + } + EE::InvalidCharInHexEscape => { + "ASCII hex escape code must contain only hex characters" + } + EE::OutOfRangeHexEscape => { + "ASCII hex escape code must be at most 0x7F" + } + EE::NoBraceInUnicodeEscape => { + "Missing `{` to begin the unicode escape" + } + EE::InvalidCharInUnicodeEscape => { + "Unicode escape must contain only hex characters and underscores" + } + EE::EmptyUnicodeEscape => { + "Unicode escape must not be empty" + } + EE::UnclosedUnicodeEscape => { + "Missing '}' to terminate the unicode escape" + } + EE::LeadingUnderscoreUnicodeEscape => { + "Unicode escape code must not begin with an underscore" + } + EE::OverlongUnicodeEscape => { + "Unicode escape code must have at most 6 digits" + } + EE::LoneSurrogateUnicodeEscape => { + "Unicode escape code must not be a surrogate" + } + EE::OutOfRangeUnicodeEscape => { + "Unicode escape code must be at most 0x10FFFF" + } + EE::UnicodeEscapeInByte => { + "Byte literals must not contain unicode escapes" + } + EE::NonAsciiCharInByte | EE::NonAsciiCharInByteString => { + "Byte literals must not contain non-ASCII characters" + } + }; -impl From for SyntaxErrorKind { - fn from(err: rustc_lexer::unescape::EscapeError) -> Self { - SyntaxErrorKind::EscapeError(err.into()) - } + err_message } pub(crate) fn validate(root: &SyntaxNode) -> Vec { @@ -118,6 +102,7 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec { } fn validate_literal(literal: ast::Literal, acc: &mut Vec) { + // FIXME: move this function to outer scope (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366196658) fn unquote(text: &str, prefix_len: usize, end_delimiter: char) -> Option<&str> { text.rfind(end_delimiter).and_then(|end| text.get(prefix_len..end)) } @@ -125,9 +110,10 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec) { let token = literal.token(); let text = token.text().as_str(); + // FIXME: lift this lambda refactor to `fn` (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366199205) let mut push_err = |prefix_len, (off, err): (usize, unescape::EscapeError)| { let off = token.text_range().start() + TextUnit::from_usize(off + prefix_len); - acc.push(SyntaxError::new(err.into(), off)); + acc.push(SyntaxError::new_at_offset(rustc_unescape_error_to_string(err), off)); }; match token.kind() { @@ -195,7 +181,8 @@ fn validate_numeric_name(name_ref: Option, errors: &mut Vec) { FN_DEF | CONST_DEF | TYPE_ALIAS_DEF => (), _ => return, } + let impl_block = match parent.parent().and_then(|it| it.parent()).and_then(ast::ImplBlock::cast) { Some(it) => it, None => return, }; if impl_block.target_trait().is_some() { - errors - .push(SyntaxError::new(SyntaxErrorKind::VisibilityNotAllowed, vis.syntax.text_range())) + errors.push(SyntaxError::new("Unnecessary visibility qualifier", vis.syntax.text_range())); } } fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec) { if expr.op_kind() == Some(ast::RangeOp::Inclusive) && expr.end().is_none() { errors.push(SyntaxError::new( - SyntaxErrorKind::InclusiveRangeMissingEnd, + "An inclusive range must have an end expression", expr.syntax().text_range(), )); } 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 @@ -//! FIXME: write short doc here +//! Logic for validating block expressions i.e. `ast::BlockExpr`. use crate::{ ast::{self, AstNode, AttrsOwner}, SyntaxError, - SyntaxErrorKind::*, SyntaxKind::*, }; @@ -15,10 +14,11 @@ pub(crate) fn validate_block_expr(expr: ast::BlockExpr, errors: &mut Vec Date: Thu, 6 Feb 2020 13:00:39 +0200 Subject: Change semmantical analyzis to tree validation as per @matklad Co-Authored-By: Aleksey Kladov --- crates/ra_syntax/src/syntax_error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index 460552103..71b228ff6 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs @@ -5,7 +5,7 @@ use std::fmt; use crate::{TextRange, TextUnit}; /// Represents the result of unsuccessful tokenization, parsing -/// or semmantical analyzis. +/// or tree validation. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct SyntaxError(String, TextRange); -- cgit v1.2.3 From 6ae4850c897ce9539b15f67375ba1d5d8f647f37 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Thu, 6 Feb 2020 15:42:00 +0200 Subject: ra_syntax: Apply Aleksei Kladov suggestion about TextRange of TextUnit Co-Authored-By: Aleksey Kladov --- crates/ra_syntax/src/syntax_error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index 71b228ff6..eaa825cf0 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs @@ -24,7 +24,7 @@ impl SyntaxError { Self(message.into(), range) } pub fn new_at_offset(message: impl Into, offset: TextUnit) -> Self { - Self(message.into(), TextRange::offset_len(offset, 1.into())) + Self(message.into(), TextRange::offset_len(offset, 0.into())) } pub fn message(&self) -> &str { -- cgit v1.2.3 From acdab6f0f232913da44fca085e2f508d53982ab6 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 10 Feb 2020 01:19:37 +0200 Subject: ra_syntax: moved reexport declaration after imports as per matklad --- crates/ra_syntax/src/syntax_node.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index 251668996..4e3a1460d 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs @@ -6,11 +6,12 @@ //! The *real* implementation is in the (language-agnostic) `rowan` crate, this //! module just wraps its API. -pub(crate) use rowan::{GreenNode, GreenToken}; use rowan::{GreenNodeBuilder, Language}; use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextUnit}; +pub(crate) use rowan::{GreenNode, GreenToken}; + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum RustLanguage {} impl Language for RustLanguage { -- cgit v1.2.3 From e00922d113e5f998893419dedae511043890f9fa Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 10 Feb 2020 02:08:49 +0200 Subject: ra_syntax: SyntaxError::range() now returns by value --- crates/ra_syntax/src/parsing/reparsing.rs | 2 +- crates/ra_syntax/src/syntax_error.rs | 4 ++-- crates/ra_syntax/src/tests.rs | 10 ++-------- 3 files changed, 5 insertions(+), 11 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index 41a355ec7..4faeeab45 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs @@ -180,7 +180,7 @@ fn merge_errors( } res.extend(new_errors.into_iter().map(|new_err| { // fighting borrow checker with a variable ;) - let offseted_range = *new_err.range() + range_before_reparse.start(); + let offseted_range = new_err.range() + range_before_reparse.start(); new_err.with_range(offseted_range) })); res diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index eaa825cf0..af4584e66 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs @@ -30,8 +30,8 @@ impl SyntaxError { pub fn message(&self) -> &str { &self.0 } - pub fn range(&self) -> &TextRange { - &self.1 + pub fn range(&self) -> TextRange { + self.1 } pub fn with_range(mut self, range: TextRange) -> Self { diff --git a/crates/ra_syntax/src/tests.rs b/crates/ra_syntax/src/tests.rs index 2533d0c44..912e6aec0 100644 --- a/crates/ra_syntax/src/tests.rs +++ b/crates/ra_syntax/src/tests.rs @@ -128,14 +128,8 @@ fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) writeln!(acc, "{:?} {} {:?}", token.kind, token_len, token_text).unwrap(); } for err in errors { - writeln!( - acc, - "> error{:?} token({:?}) msg({})", - err.range(), - &text[*err.range()], - err.message() - ) - .unwrap(); + writeln!(acc, "> error{:?} token({:?}) msg({})", err.range(), &text[err.range()], err) + .unwrap(); } acc } -- cgit v1.2.3 From b510e77fbeca7d4691ddfdbb540d0975bdeef4b3 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 10 Feb 2020 02:10:56 +0200 Subject: ra_syntax: followup fix for making SyntaxError::range() to return by value --- crates/ra_syntax/src/parsing/reparsing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index 4faeeab45..57453e220 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs @@ -168,7 +168,7 @@ fn merge_errors( let mut res = Vec::new(); for old_err in old_errors { - let old_err_range = *old_err.range(); + let old_err_range = old_err.range(); // FIXME: make sure that .start() was here previously by a mistake if old_err_range.end() <= range_before_reparse.start() { res.push(old_err); -- cgit v1.2.3 From e05eb631d41a7743a16daa982edf1001a294783a Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 17 Feb 2020 22:50:58 +0200 Subject: ra_syntax: change module-level documentation for syntax_error to "see X" as per matklad --- crates/ra_syntax/src/syntax_error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index af4584e66..135301bf6 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs @@ -1,4 +1,4 @@ -//! Module that defines `SyntaxError`. +//! See docs for `SyntaxError`. use std::fmt; -- cgit v1.2.3 From cd8e56c580fd8e79eccd55790a23a4b554bbe161 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 17 Feb 2020 23:13:38 +0200 Subject: ra_syntax: remove message() method and use only Display trait in SyntaxError as per matklad --- crates/ra_syntax/src/lib.rs | 2 +- crates/ra_syntax/src/syntax_error.rs | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index cc02c4be5..e3f74da6d 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -115,7 +115,7 @@ impl Parse { pub fn debug_dump(&self) -> String { let mut buf = format!("{:#?}", self.tree().syntax()); for err in self.errors.iter() { - writeln!(buf, "error {:?}: {}", err.range(), err.message()).unwrap(); + writeln!(buf, "error {:?}: {}", err.range(), err).unwrap(); } buf } diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index 135301bf6..54acf7847 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs @@ -27,9 +27,6 @@ impl SyntaxError { Self(message.into(), TextRange::offset_len(offset, 0.into())) } - pub fn message(&self) -> &str { - &self.0 - } pub fn range(&self) -> TextRange { self.1 } -- cgit v1.2.3 From fc5e7b8807f6d438028389b030dfae00965a8cd5 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 17 Feb 2020 23:14:31 +0200 Subject: ra_syntax: migrate test data to 0-length text-range of SyntaxError when constructed from TextUnit --- .../parser/err/0000_struct_field_missing_comma.txt | 2 +- .../parser/err/0001_item_recovery_in_file.txt | 4 +- .../parser/err/0002_duplicate_shebang.txt | 22 ++++---- .../test_data/parser/err/0003_C++_semicolon.txt | 2 +- .../parser/err/0004_use_path_bad_segment.txt | 2 +- .../parser/err/0005_attribute_recover.txt | 6 +- .../parser/err/0006_named_field_recovery.txt | 16 +++--- .../parser/err/0007_stray_curly_in_file.txt | 6 +- .../parser/err/0008_item_block_recovery.txt | 6 +- .../err/0009_broken_struct_type_parameter.txt | 22 ++++---- .../parser/err/0010_unsafe_lambda_block.txt | 2 +- .../test_data/parser/err/0011_extern_struct.txt | 2 +- .../test_data/parser/err/0013_invalid_type.txt | 36 ++++++------ .../test_data/parser/err/0014_where_no_bounds.txt | 2 +- .../test_data/parser/err/0015_curly_in_params.txt | 12 ++-- .../test_data/parser/err/0016_missing_semi.txt | 2 +- .../parser/err/0017_incomplete_binexpr.txt | 2 +- .../test_data/parser/err/0018_incomplete_fn.txt | 10 ++-- .../test_data/parser/err/0019_let_recover.txt | 20 +++---- .../test_data/parser/err/0020_fn_recover.txt | 6 +- .../test_data/parser/err/0021_incomplete_param.txt | 4 +- .../test_data/parser/err/0022_bad_exprs.txt | 66 +++++++++++----------- .../test_data/parser/err/0023_mismatched_paren.txt | 4 +- .../test_data/parser/err/0024_many_type_parens.txt | 58 +++++++++---------- .../ra_syntax/test_data/parser/err/0025_nope.txt | 22 ++++---- .../test_data/parser/err/0026_imp_recovery.txt | 4 +- .../parser/err/0027_incomplere_where_for.txt | 4 +- .../test_data/parser/err/0029_field_completion.txt | 2 +- .../parser/err/0032_match_arms_inner_attrs.txt | 22 ++++---- .../parser/err/0033_match_arms_outer_attrs.txt | 6 +- .../test_data/parser/err/0034_bad_box_pattern.txt | 12 ++-- .../test_data/parser/err/0035_use_recover.txt | 8 +-- .../test_data/parser/err/0036_partial_use.txt | 20 +++---- .../test_data/parser/err/0039_lambda_recovery.txt | 2 +- .../inline/err/0001_array_type_missing_semi.txt | 10 ++-- .../parser/inline/err/0002_misplaced_label_err.txt | 8 +-- .../inline/err/0003_pointer_type_no_mutability.txt | 2 +- .../test_data/parser/inline/err/0004_impl_type.txt | 8 +-- .../inline/err/0005_fn_pointer_type_missing_fn.txt | 10 ++-- .../parser/inline/err/0006_unsafe_block_in_mod.txt | 4 +- .../inline/err/0007_async_without_semicolon.txt | 2 +- .../test_data/parser/inline/err/0008_pub_expr.txt | 2 +- .../inline/err/0009_attr_on_expr_not_allowed.txt | 4 +- .../parser/inline/err/0010_wrong_order_fns.txt | 4 +- .../parser/inline/err/0013_static_underscore.txt | 2 +- .../parser/inline/err/0014_default_fn_type.txt | 12 ++-- 46 files changed, 242 insertions(+), 242 deletions(-) (limited to 'crates/ra_syntax') 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 caf794ed2..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) IDENT@[29; 32) "u32" WHITESPACE@[32; 33) "\n" R_CURLY@[33; 34) "}" -error [21; 22): expected COMMA +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 01d71db8f..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) RECORD_FIELD_DEF_LIST@[19; 21) L_CURLY@[19; 20) "{" R_CURLY@[20; 21) "}" -error [0; 1): expected an item -error [3; 4): expected an item +error [0; 0): expected an item +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 d493d60d4..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) NAME@[36; 41) IDENT@[36; 41) "rusti" WHITESPACE@[41; 42) "\n" -error [23; 24): expected `[` -error [23; 24): expected an item -error [27; 28): expected one of `*`, `::`, `{`, `self`, `super` or an identifier -error [28; 29): expected SEMI -error [31; 32): expected EXCL -error [31; 32): expected `{`, `[`, `(` -error [31; 32): expected SEMI -error [31; 32): expected an item -error [35; 36): expected EXCL -error [41; 42): expected `{`, `[`, `(` -error [41; 42): expected SEMI +error [23; 23): expected `[` +error [23; 23): expected an item +error [27; 27): expected one of `*`, `::`, `{`, `self`, `super` or an identifier +error [28; 28): expected SEMI +error [31; 31): expected EXCL +error [31; 31): expected `{`, `[`, `(` +error [31; 31): expected SEMI +error [31; 31): expected an item +error [35; 35): expected EXCL +error [41; 41): expected `{`, `[`, `(` +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 b25010b50..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) R_CURLY@[38; 39) "}" ERROR@[39; 40) SEMI@[39; 40) ";" -error [39; 40): expected item, found `;` +error [39; 39): expected item, found `;` 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 16a542b95..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) ERROR@[9; 11) INT_NUMBER@[9; 11) "92" SEMI@[11; 12) ";" -error [9; 10): expected identifier +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 f20e6e911..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) WHITESPACE@[51; 52) "\n" R_CURLY@[52; 53) "}" WHITESPACE@[53; 54) "\n" -error [53; 54): expected R_PAREN -error [53; 54): expected `]` -error [53; 54): expected an item +error [53; 53): expected R_PAREN +error [53; 53): expected `]` +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 b9d7bbe45..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) WHITESPACE@[71; 72) "\n" R_CURLY@[72; 73) "}" WHITESPACE@[73; 74) "\n" -error [31; 32): expected field declaration -error [33; 34): expected COMMA -error [38; 39): expected field declaration -error [39; 40): expected COMMA -error [40; 41): expected field declaration -error [41; 42): expected COMMA -error [42; 43): expected field declaration -error [43; 44): expected COMMA +error [31; 31): expected field declaration +error [33; 33): expected COMMA +error [38; 38): expected field declaration +error [39; 39): expected COMMA +error [40; 40): expected field declaration +error [41; 41): expected COMMA +error [42; 42): expected field declaration +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 41b8e3890..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) ERROR@[29; 30) R_CURLY@[29; 30) "}" WHITESPACE@[30; 31) "\n" -error [0; 1): unmatched `}` -error [14; 15): unmatched `}` -error [29; 30): unmatched `}` +error [0; 0): unmatched `}` +error [14; 14): unmatched `}` +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 071786b3c..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) WHITESPACE@[92; 93) "\n" R_CURLY@[93; 94) "}" WHITESPACE@[94; 95) "\n" -error [17; 18): expected EXCL -error [19; 20): expected SEMI -error [20; 21): expected an item +error [17; 17): expected EXCL +error [19; 19): expected SEMI +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 04a091fb9..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) IDENT@[40; 41) "T" SEMI@[41; 42) ";" WHITESPACE@[42; 43) "\n" -error [9; 10): expected type parameter -error [11; 12): expected COMMA -error [11; 12): expected R_ANGLE -error [11; 12): expected `;`, `{`, or `(` -error [12; 13): expected an item -error [14; 15): expected an item -error [15; 16): expected an item -error [17; 18): expected an item -error [24; 25): expected SEMI -error [24; 25): expected expression -error [25; 26): expected SEMI +error [9; 9): expected type parameter +error [11; 11): expected COMMA +error [11; 11): expected R_ANGLE +error [11; 11): expected `;`, `{`, or `(` +error [12; 12): expected an item +error [14; 14): expected an item +error [15; 15): expected an item +error [17; 17): expected an item +error [24; 24): expected SEMI +error [24; 24): expected expression +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 e2316c52d..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) WHITESPACE@[39; 40) "\n" R_CURLY@[40; 41) "}" WHITESPACE@[41; 42) "\n" -error [24; 25): expected `{` +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 f082ed40d..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) IDENT@[14; 17) "Foo" SEMI@[17; 18) ";" WHITESPACE@[18; 19) "\n" -error [6; 7): expected existential, fn, trait or impl +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 06c9f7cf8..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) ERROR@[83; 84) SEMI@[83; 84) ";" WHITESPACE@[84; 86) "\n\n" -error [67; 68): expected type -error [68; 69): expected COMMA -error [68; 69): expected R_ANGLE -error [68; 69): expected COMMA -error [68; 69): expected R_ANGLE -error [68; 69): expected COMMA -error [68; 69): expected R_ANGLE -error [68; 69): expected COMMA -error [72; 73): expected COMMA -error [72; 73): expected a type -error [72; 73): expected R_PAREN -error [72; 73): expected SEMI -error [72; 73): expected an item -error [73; 74): expected an item -error [79; 80): expected an item -error [80; 81): expected an item -error [82; 83): expected an item -error [83; 84): expected an item +error [67; 67): expected type +error [68; 68): expected COMMA +error [68; 68): expected R_ANGLE +error [68; 68): expected COMMA +error [68; 68): expected R_ANGLE +error [68; 68): expected COMMA +error [68; 68): expected R_ANGLE +error [68; 68): expected COMMA +error [72; 72): expected COMMA +error [72; 72): expected a type +error [72; 72): expected R_PAREN +error [72; 72): expected SEMI +error [72; 72): expected an item +error [73; 73): expected an item +error [79; 79): expected an item +error [80; 80): expected an item +error [82; 82): expected an item +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 690fdd322..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) L_CURLY@[20; 21) "{" R_CURLY@[21; 22) "}" WHITESPACE@[22; 23) "\n" -error [19; 20): expected colon +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 583de5f00..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) WHITESPACE@[11; 12) "\n" R_CURLY@[12; 13) "}" WHITESPACE@[13; 14) "\n" -error [7; 8): expected value parameter -error [7; 8): expected R_PAREN -error [7; 8): expected a block -error [7; 8): unmatched `}` -error [8; 9): expected an item -error [10; 11): expected an item +error [7; 7): expected value parameter +error [7; 7): expected R_PAREN +error [7; 7): expected a block +error [7; 7): unmatched `}` +error [8; 8): expected an item +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 83bb0e0fe..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) WHITESPACE@[53; 54) "\n" R_CURLY@[54; 55) "}" WHITESPACE@[55; 56) "\n" -error [38; 39): expected SEMI +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 7423c2d61..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) WHITESPACE@[44; 45) "\n" R_CURLY@[45; 46) "}" WHITESPACE@[46; 47) "\n" -error [44; 45): expected expression +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 81d445254..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) WHITESPACE@[180; 181) "\n" R_CURLY@[181; 182) "}" WHITESPACE@[182; 183) "\n" -error [34; 35): expected pattern -error [34; 35): expected COLON -error [34; 35): expected type -error [180; 181): expected function arguments -error [180; 181): expected a block +error [34; 34): expected pattern +error [34; 34): expected COLON +error [34; 34): expected type +error [180; 180): expected function arguments +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 3e6f82dc4..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) WHITESPACE@[136; 137) "\n" R_CURLY@[137; 138) "}" WHITESPACE@[138; 139) "\n" -error [24; 25): expected expression -error [24; 25): expected SEMI -error [49; 50): expected pattern -error [49; 50): expected SEMI -error [75; 76): expected pattern -error [75; 76): expected SEMI -error [98; 99): expected pattern -error [98; 99): expected SEMI -error [124; 125): expected pattern -error [124; 125): expected SEMI +error [24; 24): expected expression +error [24; 24): expected SEMI +error [49; 49): expected pattern +error [49; 49): expected SEMI +error [75; 75): expected pattern +error [75; 75): expected SEMI +error [98; 98): expected pattern +error [98; 98): expected SEMI +error [124; 124): expected pattern +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 1ef36c9bd..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) L_CURLY@[13; 14) "{" R_CURLY@[14; 15) "}" WHITESPACE@[15; 16) "\n" -error [2; 3): expected a name -error [2; 3): expected function arguments -error [2; 3): expected a block +error [2; 2): expected a name +error [2; 2): expected function arguments +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 8035b8711..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) WHITESPACE@[19; 20) "\n" R_CURLY@[20; 21) "}" WHITESPACE@[21; 22) "\n" -error [16; 17): expected COLON -error [16; 17): expected type +error [16; 16): expected COLON +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 e4f318957..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) WHITESPACE@[109; 110) " " R_CURLY@[110; 111) "}" WHITESPACE@[111; 112) "\n" -error [16; 17): expected expression -error [17; 18): expected R_BRACK -error [17; 18): expected SEMI -error [17; 18): expected expression -error [18; 19): expected SEMI -error [25; 26): expected a name -error [26; 27): expected `;`, `{`, or `(` -error [30; 31): expected pattern -error [31; 32): expected SEMI -error [53; 54): expected expression -error [54; 55): expected SEMI -error [54; 55): expected expression -error [55; 56): expected SEMI -error [60; 61): expected type -error [60; 61): expected `{` -error [60; 61): expected expression -error [61; 62): expected SEMI -error [65; 66): expected pattern -error [65; 66): expected SEMI -error [65; 66): expected expression -error [92; 93): expected expression -error [93; 94): expected SEMI -error [93; 94): expected expression -error [94; 95): expected SEMI -error [95; 96): expected expression -error [96; 97): expected SEMI -error [96; 97): expected expression -error [97; 98): expected SEMI -error [103; 104): expected a name -error [104; 105): expected `{` -error [108; 109): expected pattern -error [108; 109): expected SEMI -error [108; 109): expected expression +error [16; 16): expected expression +error [17; 17): expected R_BRACK +error [17; 17): expected SEMI +error [17; 17): expected expression +error [18; 18): expected SEMI +error [25; 25): expected a name +error [26; 26): expected `;`, `{`, or `(` +error [30; 30): expected pattern +error [31; 31): expected SEMI +error [53; 53): expected expression +error [54; 54): expected SEMI +error [54; 54): expected expression +error [55; 55): expected SEMI +error [60; 60): expected type +error [60; 60): expected `{` +error [60; 60): expected expression +error [61; 61): expected SEMI +error [65; 65): expected pattern +error [65; 65): expected SEMI +error [65; 65): expected expression +error [92; 92): expected expression +error [93; 93): expected SEMI +error [93; 93): expected expression +error [94; 94): expected SEMI +error [95; 95): expected expression +error [96; 96): expected SEMI +error [96; 96): expected expression +error [97; 97): expected SEMI +error [103; 103): expected a name +error [104; 104): expected `{` +error [108; 108): expected pattern +error [108; 108): expected SEMI +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 7616ca59c..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) ERROR@[92; 93) R_CURLY@[92; 93) "}" WHITESPACE@[93; 94) "\n" -error [49; 50): unmatched `}` -error [92; 93): unmatched `}` +error [49; 49): unmatched `}` +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 c4170e9d8..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) WHITESPACE@[237; 238) "\n" R_CURLY@[238; 239) "}" WHITESPACE@[239; 240) "\n" -error [88; 89): expected COMMA -error [88; 89): expected R_ANGLE -error [121; 122): expected SEMI -error [121; 122): expected expression -error [140; 141): expected type -error [141; 142): expected R_PAREN -error [141; 142): expected COMMA -error [141; 142): expected R_ANGLE -error [141; 142): expected SEMI -error [146; 147): expected SEMI -error [146; 147): expected expression -error [147; 148): expected SEMI -error [148; 149): expected expression -error [149; 150): expected SEMI -error [154; 155): expected pattern -error [155; 156): expected IN_KW -error [155; 156): expected expression -error [157; 158): expected a block -error [165; 166): expected expression -error [168; 169): expected expression -error [179; 180): expected expression -error [180; 181): expected COMMA -error [180; 181): expected expression -error [180; 181): expected R_PAREN -error [180; 181): expected SEMI -error [215; 216): expected COMMA -error [215; 216): expected R_ANGLE -error [235; 236): expected SEMI -error [235; 236): expected expression +error [88; 88): expected COMMA +error [88; 88): expected R_ANGLE +error [121; 121): expected SEMI +error [121; 121): expected expression +error [140; 140): expected type +error [141; 141): expected R_PAREN +error [141; 141): expected COMMA +error [141; 141): expected R_ANGLE +error [141; 141): expected SEMI +error [146; 146): expected SEMI +error [146; 146): expected expression +error [147; 147): expected SEMI +error [148; 148): expected expression +error [149; 149): expected SEMI +error [154; 154): expected pattern +error [155; 155): expected IN_KW +error [155; 155): expected expression +error [157; 157): expected a block +error [165; 165): expected expression +error [168; 168): expected expression +error [179; 179): expected expression +error [180; 180): expected COMMA +error [180; 180): expected expression +error [180; 180): expected R_PAREN +error [180; 180): expected SEMI +error [215; 215): expected COMMA +error [215; 215): expected R_ANGLE +error [235; 235): expected SEMI +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 5ece9489b..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) WHITESPACE@[572; 573) "\n" R_CURLY@[573; 574) "}" WHITESPACE@[574; 575) "\n" -error [95; 96): expected type -error [95; 96): expected COMMA -error [96; 97): expected field -error [98; 99): expected field declaration -error [371; 372): expected COMMA -error [372; 373): expected a type -error [372; 373): expected R_PAREN -error [372; 373): expected COMMA -error [372; 373): expected enum variant -error [374; 375): expected enum variant -error [508; 509): expected expression +error [95; 95): expected type +error [95; 95): expected COMMA +error [96; 96): expected field +error [98; 98): expected field declaration +error [371; 371): expected COMMA +error [372; 372): expected a type +error [372; 372): expected R_PAREN +error [372; 372): expected COMMA +error [372; 372): expected enum variant +error [374; 374): expected enum variant +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 46985fc8e..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) L_CURLY@[35; 36) "{" R_CURLY@[36; 37) "}" WHITESPACE@[37; 38) "\n" -error [14; 15): expected trait or type -error [14; 15): expected `{` +error [14; 14): expected trait or type +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 26f10d426..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) L_CURLY@[27; 28) "{" R_CURLY@[28; 29) "}" WHITESPACE@[29; 30) "\n" -error [26; 27): expected a path -error [26; 27): expected colon +error [26; 26): expected a path +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 ab300283f..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) WHITESPACE@[21; 22) "\n" R_CURLY@[22; 23) "}" WHITESPACE@[23; 24) "\n" -error [21; 22): expected field name or number +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 eb9d632ad..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) WHITESPACE@[290; 291) "\n" R_CURLY@[291; 292) "}" WHITESPACE@[292; 293) "\n" -error [52; 53): expected `[` -error [52; 53): expected pattern -error [53; 54): expected FAT_ARROW -error [78; 79): expected COMMA -error [161; 162): expected `[` -error [161; 162): expected pattern -error [162; 163): expected FAT_ARROW -error [232; 233): expected `[` -error [232; 233): expected pattern -error [233; 234): expected FAT_ARROW -error [250; 251): expected COMMA +error [52; 52): expected `[` +error [52; 52): expected pattern +error [53; 53): expected FAT_ARROW +error [78; 78): expected COMMA +error [161; 161): expected `[` +error [161; 161): expected pattern +error [162; 162): expected FAT_ARROW +error [232; 232): expected `[` +error [232; 232): expected pattern +error [233; 233): expected FAT_ARROW +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 33eeee763..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) WHITESPACE@[86; 87) "\n" R_CURLY@[87; 88) "}" WHITESPACE@[88; 89) "\n" -error [80; 81): expected pattern -error [80; 81): expected FAT_ARROW -error [80; 81): expected expression +error [80; 80): expected pattern +error [80; 80): expected FAT_ARROW +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 301339244..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) WHITESPACE@[87; 88) "\n" R_CURLY@[88; 89) "}" WHITESPACE@[89; 91) "\n\n" -error [24; 25): expected a name -error [27; 28): expected SEMI -error [48; 49): expected a name -error [51; 52): expected SEMI -error [76; 77): expected a name -error [79; 80): expected SEMI +error [24; 24): expected a name +error [27; 27): expected SEMI +error [48; 48): expected a name +error [51; 51): expected SEMI +error [76; 76): expected a name +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 93365a532..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) L_CURLY@[45; 46) "{" R_CURLY@[46; 47) "}" WHITESPACE@[47; 48) "\n" -error [17; 18): expected one of `*`, `::`, `{`, `self`, `super` or an identifier -error [17; 18): expected SEMI -error [37; 38): expected one of `*`, `::`, `{`, `self`, `super` or an identifier -error [37; 38): expected SEMI +error [17; 17): expected one of `*`, `::`, `{`, `self`, `super` or an identifier +error [17; 17): expected SEMI +error [37; 37): expected one of `*`, `::`, `{`, `self`, `super` or an identifier +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 e7348f911..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) ERROR@[35; 36) SEMI@[35; 36) ";" WHITESPACE@[36; 37) "\n" -error [22; 23): expected COMMA -error [22; 23): expected one of `*`, `::`, `{`, `self`, `super` or an identifier -error [23; 24): expected COMMA -error [24; 25): expected one of `*`, `::`, `{`, `self`, `super` or an identifier -error [27; 28): expected COMMA -error [35; 36): expected COMMA -error [35; 36): expected one of `*`, `::`, `{`, `self`, `super` or an identifier -error [36; 37): expected COMMA -error [36; 37): expected R_CURLY -error [36; 37): expected SEMI +error [22; 22): expected COMMA +error [22; 22): expected one of `*`, `::`, `{`, `self`, `super` or an identifier +error [23; 23): expected COMMA +error [24; 24): expected one of `*`, `::`, `{`, `self`, `super` or an identifier +error [27; 27): expected COMMA +error [35; 35): expected COMMA +error [35; 35): expected one of `*`, `::`, `{`, `self`, `super` or an identifier +error [36; 36): expected COMMA +error [36; 36): expected R_CURLY +error [36; 36): expected SEMI 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 e0a95f0d3..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) WHITESPACE@[80; 81) "\n" R_CURLY@[81; 82) "}" WHITESPACE@[82; 83) "\n" -error [56; 57): expected expression +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 b3baee30d..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) ERROR@[16; 17) SEMI@[16; 17) ";" WHITESPACE@[17; 18) "\n" -error [12; 13): expected `;` or `]` -error [12; 13): expected SEMI -error [13; 14): expected an item -error [15; 16): expected an item -error [16; 17): expected an item +error [12; 12): expected `;` or `]` +error [12; 12): expected SEMI +error [13; 13): expected an item +error [15; 15): expected an item +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 50f37416e..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) WHITESPACE@[27; 28) "\n" R_CURLY@[28; 29) "}" WHITESPACE@[29; 30) "\n" -error [22; 23): expected a loop -error [22; 23): expected SEMI -error [27; 28): expected type -error [27; 28): expected `{` +error [22; 22): expected a loop +error [22; 22): expected SEMI +error [27; 27): expected type +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 c770166eb..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) R_PAREN@[11; 12) ")" SEMI@[12; 13) ";" WHITESPACE@[13; 14) "\n" -error [10; 11): expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate) +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 c1eac055a..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) L_CURLY@[84; 85) "{" R_CURLY@[85; 86) "}" WHITESPACE@[86; 87) "\n" -error [38; 39): expected trait or type -error [38; 39): expected `{` -error [70; 71): expected trait or type -error [70; 71): expected `{` +error [38; 38): expected trait or type +error [38; 38): expected `{` +error [70; 70): expected trait or type +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 961648a1d..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) ERROR@[18; 19) SEMI@[18; 19) ";" WHITESPACE@[19; 20) "\n" -error [15; 16): expected `fn` -error [15; 16): expected SEMI -error [16; 17): expected an item -error [17; 18): expected an item -error [18; 19): expected an item +error [15; 15): expected `fn` +error [15; 15): expected SEMI +error [16; 16): expected an item +error [17; 17): expected an item +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 3e5a36db8..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) L_CURLY@[30; 31) "{" R_CURLY@[31; 32) "}" WHITESPACE@[32; 33) "\n" -error [11; 12): expected an item -error [18; 19): expected an item +error [11; 11): expected an item +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 8b7fd43ae..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) WHITESPACE@[27; 28) " " R_CURLY@[28; 29) "}" WHITESPACE@[29; 30) "\n" -error [27; 28): expected SEMI +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 63362e74b..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) WHITESPACE@[18; 19) " " R_CURLY@[19; 20) "}" WHITESPACE@[20; 21) "\n" -error [14; 15): expected an item +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 736a2f40e..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) WHITESPACE@[45; 46) "\n" R_CURLY@[46; 47) "}" WHITESPACE@[47; 48) "\n" -error [24; 25): attributes are not allowed on BIN_EXPR -error [44; 45): attributes are not allowed on IF_EXPR +error [24; 24): attributes are not allowed on BIN_EXPR +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) L_CURLY@[47; 48) "{" R_CURLY@[48; 49) "}" WHITESPACE@[49; 50) "\n" -error 6: expected existential, fn, trait or impl -error 31: expected existential, fn, trait or impl +error [6; 6): expected existential, fn, trait or impl +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 58fafff13..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) INT_NUMBER@[16; 17) "5" SEMI@[17; 18) ";" WHITESPACE@[18; 19) "\n" -error [7; 8): expected a name +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 ff53f8f4c..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) WHITESPACE@[59; 60) "\n" R_CURLY@[60; 61) "}" WHITESPACE@[61; 62) "\n" -error [21; 22): expected EXCL -error [21; 22): expected `{`, `[`, `(` -error [21; 22): expected SEMI -error [47; 48): expected EXCL -error [47; 48): expected `{`, `[`, `(` -error [47; 48): expected SEMI +error [21; 21): expected EXCL +error [21; 21): expected `{`, `[`, `(` +error [21; 21): expected SEMI +error [47; 47): expected EXCL +error [47; 47): expected `{`, `[`, `(` +error [47; 47): expected SEMI -- cgit v1.2.3 From 053ccf4121797e4e559e3225d46d3f23cb1ad70b Mon Sep 17 00:00:00 2001 From: Veetaha Date: Tue, 18 Feb 2020 02:11:16 +0200 Subject: ra_syntax: fix reparsing merging errors, also now reparse_token() reports errors --- crates/ra_syntax/src/parsing/reparsing.rs | 57 +++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 7 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index 57453e220..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( edit: &AtomTextEdit, errors: Vec, ) -> Option<(GreenNode, Vec, TextRange)> { - if let Some((green, old_range)) = reparse_token(node, &edit) { - return Some((green, merge_errors(errors, Vec::new(), old_range, edit), old_range)); + if let Some((green, new_errors, old_range)) = reparse_token(node, &edit) { + return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range)); } if let Some((green, new_errors, old_range)) = reparse_block(node, &edit) { @@ -40,7 +40,7 @@ pub(crate) fn incremental_reparse( fn reparse_token<'node>( root: &'node SyntaxNode, edit: &AtomTextEdit, -) -> Option<(GreenNode, TextRange)> { +) -> Option<(GreenNode, Vec, TextRange)> { let prev_token = algo::find_covering_element(root, edit.delete).as_token()?.clone(); let prev_token_kind = prev_token.kind(); match prev_token_kind { @@ -54,7 +54,7 @@ fn reparse_token<'node>( } let mut new_text = get_text_after_edit(prev_token.clone().into(), &edit); - let (new_token_kind, _error) = lex_single_syntax_kind(&new_text)?; + let (new_token_kind, new_err) = lex_single_syntax_kind(&new_text)?; if new_token_kind != prev_token_kind || (new_token_kind == IDENT && is_contextual_kw(&new_text)) @@ -76,7 +76,11 @@ fn reparse_token<'node>( let new_token = GreenToken::new(rowan::SyntaxKind(prev_token_kind.into()), new_text.into()); - Some((prev_token.replace_with(new_token), prev_token.text_range())) + Some(( + prev_token.replace_with(new_token), + new_err.into_iter().collect(), + prev_token.text_range(), + )) } _ => None, } @@ -200,9 +204,9 @@ mod tests { let fully_reparsed = SourceFile::parse(&after); let incrementally_reparsed: Parse = { - let f = SourceFile::parse(&before); + let before = SourceFile::parse(&before); let (green, new_errors, range) = - incremental_reparse(f.tree().syntax(), &edit, f.errors.to_vec()).unwrap(); + incremental_reparse(before.tree().syntax(), &edit, before.errors.to_vec()).unwrap(); assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length"); Parse::new(green, new_errors) }; @@ -211,6 +215,7 @@ mod tests { &format!("{:#?}", fully_reparsed.tree().syntax()), &format!("{:#?}", incrementally_reparsed.tree().syntax()), ); + assert_eq!(fully_reparsed.errors(), incrementally_reparsed.errors()); } #[test] // FIXME: some test here actually test token reparsing @@ -409,4 +414,42 @@ enum Foo { 4, ); } + + #[test] + fn reparse_str_token_with_error_unchanged() { + do_check(r#""<|>Unclosed<|> string literal"#, "Still unclosed", 24); + } + + #[test] + fn reparse_str_token_with_error_fixed() { + do_check(r#""unterinated<|><|>"#, "\"", 12); + } + + #[test] + fn reparse_block_with_error_in_middle_unchanged() { + do_check( + r#"fn main() { + if {} + 32 + 4<|><|> + return + if {} + }"#, + "23", + 105, + ) + } + + #[test] + fn reparse_block_with_error_in_middle_fixed() { + do_check( + r#"fn main() { + if {} + 32 + 4<|><|> + return + if {} + }"#, + ";", + 105, + ) + } } -- cgit v1.2.3