aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/assist_ctx.rs2
-rw-r--r--crates/ra_assists/src/ast_editor.rs6
-rw-r--r--crates/ra_cli/src/main.rs6
-rw-r--r--crates/ra_db/src/lib.rs6
-rw-r--r--crates/ra_hir/src/code_model.rs2
-rw-r--r--crates/ra_hir/src/expr/scope.rs4
-rw-r--r--crates/ra_hir/src/expr/validation.rs2
-rw-r--r--crates/ra_hir/src/ids.rs2
-rw-r--r--crates/ra_hir/src/source_binder.rs2
-rw-r--r--crates/ra_hir/src/ty/tests.rs240
-rw-r--r--crates/ra_ide_api/src/call_info.rs2
-rw-r--r--crates/ra_ide_api/src/change.rs2
-rw-r--r--crates/ra_ide_api/src/completion.rs4
-rw-r--r--crates/ra_ide_api/src/completion/completion_context.rs15
-rw-r--r--crates/ra_ide_api/src/diagnostics.rs38
-rw-r--r--crates/ra_ide_api/src/display/navigation_target.rs4
-rw-r--r--crates/ra_ide_api/src/display/structure.rs4
-rw-r--r--crates/ra_ide_api/src/extend_selection.rs4
-rw-r--r--crates/ra_ide_api/src/folding_ranges.rs2
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs2
-rw-r--r--crates/ra_ide_api/src/goto_type_definition.rs2
-rw-r--r--crates/ra_ide_api/src/hover.rs4
-rw-r--r--crates/ra_ide_api/src/impls.rs2
-rw-r--r--crates/ra_ide_api/src/join_lines.rs2
-rw-r--r--crates/ra_ide_api/src/lib.rs12
-rw-r--r--crates/ra_ide_api/src/matching_brace.rs2
-rw-r--r--crates/ra_ide_api/src/references.rs4
-rw-r--r--crates/ra_ide_api/src/runnables.rs2
-rw-r--r--crates/ra_ide_api/src/status.rs8
-rw-r--r--crates/ra_ide_api/src/symbol_index.rs2
-rw-r--r--crates/ra_ide_api/src/syntax_highlighting.rs4
-rw-r--r--crates/ra_ide_api/src/syntax_tree.rs8
-rw-r--r--crates/ra_ide_api/src/test_utils.rs2
-rw-r--r--crates/ra_ide_api/src/typing.rs6
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs4
-rw-r--r--crates/ra_mbe/src/mbe_parser.rs2
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs9
-rw-r--r--crates/ra_mbe/src/tests.rs163
-rw-r--r--crates/ra_syntax/src/ast.rs16
-rw-r--r--crates/ra_syntax/src/fuzz.rs21
-rw-r--r--crates/ra_syntax/src/lib.rs94
-rw-r--r--crates/ra_syntax/src/parsing/reparsing.rs12
-rw-r--r--crates/ra_syntax/src/ptr.rs2
-rw-r--r--crates/ra_syntax/src/syntax_node.rs55
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt4
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt4
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt6
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt16
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt6
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt6
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt22
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt36
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt12
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt10
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt20
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt6
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt4
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt78
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt4
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt62
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0025_nope.txt22
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt4
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0027_incomplere_where_for.txt4
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0028_macro_2.0.txt134
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0030_string_suffixes.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0031_block_inner_attrs.txt8
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt22
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0001_array_type_missing_semi.txt10
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0002_misplaced_label_err.txt8
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0003_pointer_type_no_mutability.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0004_impl_type.txt8
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt10
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0006_unsafe_block_in_mod.txt4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0007_async_without_semicolon.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.txt6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt4
-rw-r--r--crates/ra_syntax/tests/test.rs29
89 files changed, 705 insertions, 687 deletions
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs
index e744e82d0..1d58d9e71 100644
--- a/crates/ra_assists/src/assist_ctx.rs
+++ b/crates/ra_assists/src/assist_ctx.rs
@@ -71,7 +71,7 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> {
71 where 71 where
72 F: FnOnce(AssistCtx<DB>) -> T, 72 F: FnOnce(AssistCtx<DB>) -> T,
73 { 73 {
74 let source_file = &db.parse(frange.file_id); 74 let source_file = &db.parse(frange.file_id).tree;
75 let assist = 75 let assist =
76 if should_compute_edit { Assist::Resolved(vec![]) } else { Assist::Unresolved(vec![]) }; 76 if should_compute_edit { Assist::Resolved(vec![]) } else { Assist::Unresolved(vec![]) };
77 77
diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs
index 9afcac01a..cabb3d862 100644
--- a/crates/ra_assists/src/ast_editor.rs
+++ b/crates/ra_assists/src/ast_editor.rs
@@ -283,7 +283,7 @@ impl AstBuilder<ast::NameRef> {
283} 283}
284 284
285fn ast_node_from_file_text<N: AstNode>(text: &str) -> TreeArc<N> { 285fn ast_node_from_file_text<N: AstNode>(text: &str) -> TreeArc<N> {
286 let file = SourceFile::parse(text); 286 let file = SourceFile::parse(text).tree;
287 let res = file.syntax().descendants().find_map(N::cast).unwrap().to_owned(); 287 let res = file.syntax().descendants().find_map(N::cast).unwrap().to_owned();
288 res 288 res
289} 289}
@@ -292,7 +292,7 @@ mod tokens {
292 use once_cell::sync::Lazy; 292 use once_cell::sync::Lazy;
293 use ra_syntax::{AstNode, SourceFile, TreeArc, SyntaxToken, SyntaxKind::*, T}; 293 use ra_syntax::{AstNode, SourceFile, TreeArc, SyntaxToken, SyntaxKind::*, T};
294 294
295 static SOURCE_FILE: Lazy<TreeArc<SourceFile>> = Lazy::new(|| SourceFile::parse(",\n; ;")); 295 static SOURCE_FILE: Lazy<TreeArc<SourceFile>> = Lazy::new(|| SourceFile::parse(",\n; ;").tree);
296 296
297 pub(crate) fn comma() -> SyntaxToken<'static> { 297 pub(crate) fn comma() -> SyntaxToken<'static> {
298 SOURCE_FILE 298 SOURCE_FILE
@@ -326,7 +326,7 @@ mod tokens {
326 326
327 impl WsBuilder { 327 impl WsBuilder {
328 pub(crate) fn new(text: &str) -> WsBuilder { 328 pub(crate) fn new(text: &str) -> WsBuilder {
329 WsBuilder(SourceFile::parse(text)) 329 WsBuilder(SourceFile::parse(text).ok().unwrap())
330 } 330 }
331 pub(crate) fn ws(&self) -> SyntaxToken<'_> { 331 pub(crate) fn ws(&self) -> SyntaxToken<'_> {
332 self.0.syntax().first_child_or_token().unwrap().as_token().unwrap() 332 self.0.syntax().first_child_or_token().unwrap().as_token().unwrap()
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs
index 84a1564ce..c9ca13bbc 100644
--- a/crates/ra_cli/src/main.rs
+++ b/crates/ra_cli/src/main.rs
@@ -34,7 +34,7 @@ fn main() -> Result<()> {
34 if !matches.is_present("no-dump") { 34 if !matches.is_present("no-dump") {
35 println!("{}", file.syntax().debug_dump()); 35 println!("{}", file.syntax().debug_dump());
36 } 36 }
37 ::std::mem::forget(file); 37 std::mem::forget(file);
38 } 38 }
39 ("symbols", _) => { 39 ("symbols", _) => {
40 let file = file()?; 40 let file = file()?;
@@ -60,11 +60,11 @@ fn main() -> Result<()> {
60 60
61fn file() -> Result<TreeArc<SourceFile>> { 61fn file() -> Result<TreeArc<SourceFile>> {
62 let text = read_stdin()?; 62 let text = read_stdin()?;
63 Ok(SourceFile::parse(&text)) 63 Ok(SourceFile::parse(&text).tree)
64} 64}
65 65
66fn read_stdin() -> Result<String> { 66fn read_stdin() -> Result<String> {
67 let mut buff = String::new(); 67 let mut buff = String::new();
68 ::std::io::stdin().read_to_string(&mut buff)?; 68 std::io::stdin().read_to_string(&mut buff)?;
69 Ok(buff) 69 Ok(buff)
70} 70}
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs
index 68b9a7143..7c49c585b 100644
--- a/crates/ra_db/src/lib.rs
+++ b/crates/ra_db/src/lib.rs
@@ -4,7 +4,7 @@ mod input;
4 4
5use std::{panic, sync::Arc}; 5use std::{panic, sync::Arc};
6 6
7use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc}; 7use ra_syntax::{TextUnit, TextRange, SourceFile, Parse};
8use relative_path::RelativePathBuf; 8use relative_path::RelativePathBuf;
9use ra_prof::profile; 9use ra_prof::profile;
10 10
@@ -74,7 +74,7 @@ pub trait SourceDatabase: CheckCanceled + std::fmt::Debug {
74 fn file_text(&self, file_id: FileId) -> Arc<String>; 74 fn file_text(&self, file_id: FileId) -> Arc<String>;
75 // Parses the file into the syntax tree. 75 // Parses the file into the syntax tree.
76 #[salsa::invoke(parse_query)] 76 #[salsa::invoke(parse_query)]
77 fn parse(&self, file_id: FileId) -> TreeArc<SourceFile>; 77 fn parse(&self, file_id: FileId) -> Parse;
78 /// Path to a file, relative to the root of its source root. 78 /// Path to a file, relative to the root of its source root.
79 #[salsa::input] 79 #[salsa::input]
80 fn file_relative_path(&self, file_id: FileId) -> RelativePathBuf; 80 fn file_relative_path(&self, file_id: FileId) -> RelativePathBuf;
@@ -98,7 +98,7 @@ fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<Cra
98 Arc::new(res) 98 Arc::new(res)
99} 99}
100 100
101fn parse_query(db: &impl SourceDatabase, file_id: FileId) -> TreeArc<SourceFile> { 101fn parse_query(db: &impl SourceDatabase, file_id: FileId) -> Parse {
102 let _p = profile("parse_query"); 102 let _p = profile("parse_query");
103 let text = db.file_text(file_id); 103 let text = db.file_text(file_id);
104 SourceFile::parse(&*text) 104 SourceFile::parse(&*text)
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index a9ffc8782..69496b624 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -116,7 +116,7 @@ impl ModuleSource {
116 ) -> ModuleSource { 116 ) -> ModuleSource {
117 match (file_id, decl_id) { 117 match (file_id, decl_id) {
118 (Some(file_id), _) => { 118 (Some(file_id), _) => {
119 let source_file = db.parse(file_id); 119 let source_file = db.parse(file_id).tree;
120 ModuleSource::SourceFile(source_file) 120 ModuleSource::SourceFile(source_file)
121 } 121 }
122 (None, Some(item_id)) => { 122 (None, Some(item_id)) => {
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs
index 58f365128..83d226fc1 100644
--- a/crates/ra_hir/src/expr/scope.rs
+++ b/crates/ra_hir/src/expr/scope.rs
@@ -190,7 +190,7 @@ mod tests {
190 }; 190 };
191 191
192 let (db, _source_root, file_id) = MockDatabase::with_single_file(&code); 192 let (db, _source_root, file_id) = MockDatabase::with_single_file(&code);
193 let file = db.parse(file_id); 193 let file = db.parse(file_id).ok().unwrap();
194 let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); 194 let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap();
195 let analyzer = SourceAnalyzer::new(&db, file_id, marker.syntax(), None); 195 let analyzer = SourceAnalyzer::new(&db, file_id, marker.syntax(), None);
196 196
@@ -288,7 +288,7 @@ mod tests {
288 let (off, code) = extract_offset(code); 288 let (off, code) = extract_offset(code);
289 289
290 let (db, _source_root, file_id) = MockDatabase::with_single_file(&code); 290 let (db, _source_root, file_id) = MockDatabase::with_single_file(&code);
291 let file = db.parse(file_id); 291 let file = db.parse(file_id).ok().unwrap();
292 let expected_name = find_node_at_offset::<ast::Name>(file.syntax(), expected_offset.into()) 292 let expected_name = find_node_at_offset::<ast::Name>(file.syntax(), expected_offset.into())
293 .expect("failed to find a name at the target offset"); 293 .expect("failed to find a name at the target offset");
294 let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); 294 let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap();
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs
index 3f758f283..2816144a7 100644
--- a/crates/ra_hir/src/expr/validation.rs
+++ b/crates/ra_hir/src/expr/validation.rs
@@ -75,7 +75,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
75 } 75 }
76 let source_map = self.func.body_source_map(db); 76 let source_map = self.func.body_source_map(db);
77 let file_id = self.func.source(db).0; 77 let file_id = self.func.source(db).0;
78 let source_file = db.parse(file_id.original_file(db)); 78 let source_file = db.parse(file_id.original_file(db)).tree;
79 if let Some(field_list_node) = source_map 79 if let Some(field_list_node) = source_map
80 .expr_syntax(id) 80 .expr_syntax(id)
81 .map(|ptr| ptr.to_node(source_file.syntax())) 81 .map(|ptr| ptr.to_node(source_file.syntax()))
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 5c3799e95..06b6888f4 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -64,7 +64,7 @@ impl HirFileId {
64 db.check_canceled(); 64 db.check_canceled();
65 let _p = profile("parse_or_expand_query"); 65 let _p = profile("parse_or_expand_query");
66 match file_id.0 { 66 match file_id.0 {
67 HirFileIdRepr::File(file_id) => Some(db.parse(file_id).syntax().to_owned()), 67 HirFileIdRepr::File(file_id) => Some(db.parse(file_id).tree.syntax().to_owned()),
68 HirFileIdRepr::Macro(macro_file) => { 68 HirFileIdRepr::Macro(macro_file) => {
69 let macro_call_id = macro_file.macro_call_id; 69 let macro_call_id = macro_file.macro_call_id;
70 let tt = db 70 let tt = db
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 179faebfb..860e10069 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -46,7 +46,7 @@ pub fn module_from_declaration(
46 46
47/// Locates the module by position in the source code. 47/// Locates the module by position in the source code.
48pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> { 48pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> {
49 let file = db.parse(position.file_id); 49 let file = db.parse(position.file_id).tree;
50 match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { 50 match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) {
51 Some(m) if !m.has_semi() => module_from_inline(db, position.file_id.into(), m), 51 Some(m) if !m.has_semi() => module_from_inline(db, position.file_id.into(), m),
52 _ => module_from_file_id(db, position.file_id.into()), 52 _ => module_from_file_id(db, position.file_id.into()),
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index cd24faba5..da9aeec6d 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -59,7 +59,7 @@ fn test() {
59 let b: usize = 1; 59 let b: usize = 1;
60 let c = b; 60 let c = b;
61} 61}
62}"#), 62"#),
63 @r###" 63 @r###"
64[11; 71) '{ ...= b; }': () 64[11; 71) '{ ...= b; }': ()
65[21; 22) 'a': isize 65[21; 22) 'a': isize
@@ -85,7 +85,7 @@ fn test() {
85 a(); 85 a();
86 b::c(); 86 b::c();
87} 87}
88}"#), 88"#),
89 @r###" 89 @r###"
90[15; 20) '{ 1 }': u32 90[15; 20) '{ 1 }': u32
91[17; 18) '1': u32 91[17; 18) '1': u32
@@ -1004,7 +1004,7 @@ fn infer_tuple_struct_generics() {
1004 assert_snapshot_matches!( 1004 assert_snapshot_matches!(
1005 infer(r#" 1005 infer(r#"
1006struct A<T>(T); 1006struct A<T>(T);
1007enum Option<T> { Some(T), None }; 1007enum Option<T> { Some(T), None }
1008use Option::*; 1008use Option::*;
1009 1009
1010fn test() { 1010fn test() {
@@ -1017,22 +1017,24 @@ fn test() {
1017} 1017}
1018"#), 1018"#),
1019 @r###" 1019 @r###"
1020[77; 185) '{ ...one; }': () 1020 â‹®
1021[83; 84) 'A': A<i32>(T) -> A<T> 1021 â‹®[76; 184) '{ ...one; }': ()
1022[83; 88) 'A(42)': A<i32> 1022 â‹®[82; 83) 'A': A<i32>(T) -> A<T>
1023[85; 87) '42': i32 1023 â‹®[82; 87) 'A(42)': A<i32>
1024[94; 95) 'A': A<u128>(T) -> A<T> 1024 â‹®[84; 86) '42': i32
1025[94; 103) 'A(42u128)': A<u128> 1025 â‹®[93; 94) 'A': A<u128>(T) -> A<T>
1026[96; 102) '42u128': u128 1026 â‹®[93; 102) 'A(42u128)': A<u128>
1027[109; 113) 'Some': Some<&str>(T) -> Option<T> 1027 â‹®[95; 101) '42u128': u128
1028[109; 118) 'Some("x")': Option<&str> 1028 â‹®[108; 112) 'Some': Some<&str>(T) -> Option<T>
1029[114; 117) '"x"': &str 1029 â‹®[108; 117) 'Some("x")': Option<&str>
1030[124; 136) 'Option::Some': Some<&str>(T) -> Option<T> 1030 â‹®[113; 116) '"x"': &str
1031[124; 141) 'Option...e("x")': Option<&str> 1031 â‹®[123; 135) 'Option::Some': Some<&str>(T) -> Option<T>
1032[137; 140) '"x"': &str 1032 â‹®[123; 140) 'Option...e("x")': Option<&str>
1033[147; 151) 'None': Option<{unknown}> 1033 â‹®[136; 139) '"x"': &str
1034[161; 162) 'x': Option<i64> 1034 â‹®[146; 150) 'None': Option<{unknown}>
1035[178; 182) 'None': Option<i64>"### 1035 â‹®[160; 161) 'x': Option<i64>
1036 â‹®[177; 181) 'None': Option<i64>
1037 "###
1036 ); 1038 );
1037} 1039}
1038 1040
@@ -1268,7 +1270,7 @@ impl Struct {
1268 const FOO: u32 = 1; 1270 const FOO: u32 = 1;
1269} 1271}
1270 1272
1271enum Enum; 1273enum Enum {}
1272 1274
1273impl Enum { 1275impl Enum {
1274 const BAR: u32 = 2; 1276 const BAR: u32 = 2;
@@ -1291,16 +1293,18 @@ fn test() {
1291} 1293}
1292"#), 1294"#),
1293 @r###" 1295 @r###"
1294[52; 53) '1': u32 1296 â‹®
1295[103; 104) '2': u32 1297 â‹®[52; 53) '1': u32
1296[211; 212) '5': u32 1298 â‹®[105; 106) '2': u32
1297[227; 305) '{ ...:ID; }': () 1299 â‹®[213; 214) '5': u32
1298[237; 238) 'x': u32 1300 â‹®[229; 307) '{ ...:ID; }': ()
1299[241; 252) 'Struct::FOO': u32 1301 â‹®[239; 240) 'x': u32
1300[262; 263) 'y': u32 1302 â‹®[243; 254) 'Struct::FOO': u32
1301[266; 275) 'Enum::BAR': u32 1303 â‹®[264; 265) 'y': u32
1302[285; 286) 'z': {unknown} 1304 â‹®[268; 277) 'Enum::BAR': u32
1303[289; 302) 'TraitTest::ID': {unknown}"### 1305 â‹®[287; 288) 'z': {unknown}
1306 â‹®[291; 304) 'TraitTest::ID': {unknown}
1307 "###
1304 ); 1308 );
1305} 1309}
1306 1310
@@ -1308,7 +1312,7 @@ fn test() {
1308fn infer_associated_method_struct() { 1312fn infer_associated_method_struct() {
1309 assert_snapshot_matches!( 1313 assert_snapshot_matches!(
1310 infer(r#" 1314 infer(r#"
1311struct A { x: u32 }; 1315struct A { x: u32 }
1312 1316
1313impl A { 1317impl A {
1314 fn new() -> A { 1318 fn new() -> A {
@@ -1321,15 +1325,17 @@ fn test() {
1321} 1325}
1322"#), 1326"#),
1323 @r###" 1327 @r###"
1324[50; 76) '{ ... }': A 1328 â‹®
1325[60; 70) 'A { x: 0 }': A 1329 â‹®[49; 75) '{ ... }': A
1326[67; 68) '0': u32 1330 â‹®[59; 69) 'A { x: 0 }': A
1327[89; 123) '{ ...a.x; }': () 1331 â‹®[66; 67) '0': u32
1328[99; 100) 'a': A 1332 â‹®[88; 122) '{ ...a.x; }': ()
1329[103; 109) 'A::new': fn new() -> A 1333 â‹®[98; 99) 'a': A
1330[103; 111) 'A::new()': A 1334 â‹®[102; 108) 'A::new': fn new() -> A
1331[117; 118) 'a': A 1335 â‹®[102; 110) 'A::new()': A
1332[117; 120) 'a.x': u32"### 1336 â‹®[116; 117) 'a': A
1337 â‹®[116; 119) 'a.x': u32
1338 "###
1333 ); 1339 );
1334} 1340}
1335 1341
@@ -1337,7 +1343,7 @@ fn test() {
1337fn infer_associated_method_enum() { 1343fn infer_associated_method_enum() {
1338 assert_snapshot_matches!( 1344 assert_snapshot_matches!(
1339 infer(r#" 1345 infer(r#"
1340enum A { B, C }; 1346enum A { B, C }
1341 1347
1342impl A { 1348impl A {
1343 pub fn b() -> A { 1349 pub fn b() -> A {
@@ -1355,19 +1361,21 @@ fn test() {
1355} 1361}
1356"#), 1362"#),
1357 @r###" 1363 @r###"
1358[48; 68) '{ ... }': A 1364 â‹®
1359[58; 62) 'A::B': A 1365 â‹®[47; 67) '{ ... }': A
1360[89; 109) '{ ... }': A 1366 â‹®[57; 61) 'A::B': A
1361[99; 103) 'A::C': A 1367 â‹®[88; 108) '{ ... }': A
1362[122; 179) '{ ... c; }': () 1368 â‹®[98; 102) 'A::C': A
1363[132; 133) 'a': A 1369 â‹®[121; 178) '{ ... c; }': ()
1364[136; 140) 'A::b': fn b() -> A 1370 â‹®[131; 132) 'a': A
1365[136; 142) 'A::b()': A 1371 â‹®[135; 139) 'A::b': fn b() -> A
1366[148; 149) 'a': A 1372 â‹®[135; 141) 'A::b()': A
1367[159; 160) 'c': A 1373 â‹®[147; 148) 'a': A
1368[163; 167) 'A::c': fn c() -> A 1374 â‹®[158; 159) 'c': A
1369[163; 169) 'A::c()': A 1375 â‹®[162; 166) 'A::c': fn c() -> A
1370[175; 176) 'c': A"### 1376 â‹®[162; 168) 'A::c()': A
1377 â‹®[174; 175) 'c': A
1378 "###
1371 ); 1379 );
1372} 1380}
1373 1381
@@ -1540,7 +1548,7 @@ fn test() {
1540fn infer_type_alias() { 1548fn infer_type_alias() {
1541 assert_snapshot_matches!( 1549 assert_snapshot_matches!(
1542 infer(r#" 1550 infer(r#"
1543struct A<X, Y> { x: X, y: Y }; 1551struct A<X, Y> { x: X, y: Y }
1544type Foo = A<u32, i128>; 1552type Foo = A<u32, i128>;
1545type Bar<T> = A<T, u128>; 1553type Bar<T> = A<T, u128>;
1546type Baz<U, V> = A<V, U>; 1554type Baz<U, V> = A<V, U>;
@@ -1554,22 +1562,24 @@ fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) {
1554} 1562}
1555"#), 1563"#),
1556 @r###" 1564 @r###"
1557[117; 118) 'x': A<u32, i128> 1565 â‹®
1558[125; 126) 'y': A<&str, u128> 1566 â‹®[116; 117) 'x': A<u32, i128>
1559[139; 140) 'z': A<u8, i8> 1567 â‹®[124; 125) 'y': A<&str, u128>
1560[155; 212) '{ ...z.y; }': () 1568 â‹®[138; 139) 'z': A<u8, i8>
1561[161; 162) 'x': A<u32, i128> 1569 â‹®[154; 211) '{ ...z.y; }': ()
1562[161; 164) 'x.x': u32 1570 â‹®[160; 161) 'x': A<u32, i128>
1563[170; 171) 'x': A<u32, i128> 1571 â‹®[160; 163) 'x.x': u32
1564[170; 173) 'x.y': i128 1572 â‹®[169; 170) 'x': A<u32, i128>
1565[179; 180) 'y': A<&str, u128> 1573 â‹®[169; 172) 'x.y': i128
1566[179; 182) 'y.x': &str 1574 â‹®[178; 179) 'y': A<&str, u128>
1567[188; 189) 'y': A<&str, u128> 1575 â‹®[178; 181) 'y.x': &str
1568[188; 191) 'y.y': u128 1576 â‹®[187; 188) 'y': A<&str, u128>
1569[197; 198) 'z': A<u8, i8> 1577 â‹®[187; 190) 'y.y': u128
1570[197; 200) 'z.x': u8 1578 â‹®[196; 197) 'z': A<u8, i8>
1571[206; 207) 'z': A<u8, i8> 1579 â‹®[196; 199) 'z.x': u8
1572[206; 209) 'z.y': i8"### 1580 â‹®[205; 206) 'z': A<u8, i8>
1581 â‹®[205; 208) 'z.y': i8
1582 "###
1573 ) 1583 )
1574} 1584}
1575 1585
@@ -1578,7 +1588,7 @@ fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) {
1578fn recursive_type_alias() { 1588fn recursive_type_alias() {
1579 assert_snapshot_matches!( 1589 assert_snapshot_matches!(
1580 infer(r#" 1590 infer(r#"
1581struct A<X> {}; 1591struct A<X> {}
1582type Foo = Foo; 1592type Foo = Foo;
1583type Bar = A<Bar>; 1593type Bar = A<Bar>;
1584fn test(x: Foo) {} 1594fn test(x: Foo) {}
@@ -1795,18 +1805,21 @@ fn infer_std_crash_3() {
1795 assert_snapshot_matches!( 1805 assert_snapshot_matches!(
1796 infer(r#" 1806 infer(r#"
1797pub fn compute() { 1807pub fn compute() {
1798 match _ { 1808 match nope!() {
1799 SizeSkeleton::Pointer { non_zero: true, tail } => {} 1809 SizeSkeleton::Pointer { non_zero: true, tail } => {}
1800 } 1810 }
1801} 1811}
1802"#), 1812"#),
1803 @r###" 1813 @r###"
1804[18; 102) '{ ... } }': () 1814 â‹®
1805[24; 100) 'match ... }': () 1815 â‹®[18; 108) '{ ... } }': ()
1806[42; 88) 'SizeSk...tail }': {unknown} 1816 â‹®[24; 106) 'match ... }': ()
1807[76; 80) 'true': {unknown} 1817 â‹®[30; 37) 'nope!()': {unknown}
1808[82; 86) 'tail': {unknown} 1818 â‹®[48; 94) 'SizeSk...tail }': {unknown}
1809[92; 94) '{}': ()"### 1819 â‹®[82; 86) 'true': {unknown}
1820 â‹®[88; 92) 'tail': {unknown}
1821 â‹®[98; 100) '{}': ()
1822 "###
1810 ); 1823 );
1811} 1824}
1812 1825
@@ -1817,20 +1830,21 @@ fn infer_std_crash_4() {
1817 infer(r#" 1830 infer(r#"
1818pub fn primitive_type() { 1831pub fn primitive_type() {
1819 match *self { 1832 match *self {
1820 BorrowedRef { type_: box Primitive(p), ..} => {}, 1833 BorrowedRef { type_: Primitive(p), ..} => {},
1821 } 1834 }
1822} 1835}
1823"#), 1836"#),
1824 @r###" 1837 @r###"
1825[25; 110) '{ ... } }': () 1838 â‹®
1826[31; 108) 'match ... }': () 1839 â‹®[25; 106) '{ ... } }': ()
1827[37; 42) '*self': {unknown} 1840 â‹®[31; 104) 'match ... }': ()
1828[38; 42) 'self': {unknown} 1841 â‹®[37; 42) '*self': {unknown}
1829[53; 95) 'Borrow...), ..}': {unknown} 1842 â‹®[38; 42) 'self': {unknown}
1830[74; 77) 'box': {unknown} 1843 â‹®[53; 91) 'Borrow...), ..}': {unknown}
1831[78; 87) 'Primitive': {unknown} 1844 â‹®[74; 86) 'Primitive(p)': {unknown}
1832[88; 89) 'p': {unknown} 1845 â‹®[84; 85) 'p': {unknown}
1833[99; 101) '{}': ()"### 1846 â‹®[95; 97) '{}': ()
1847 "###
1834 ); 1848 );
1835} 1849}
1836 1850
@@ -2304,8 +2318,8 @@ trait Into<T> {
2304 fn into(self) -> T; 2318 fn into(self) -> T;
2305} 2319}
2306struct S; 2320struct S;
2307impl Into<u32> for S; 2321impl Into<u32> for S {}
2308impl Into<u64> for S; 2322impl Into<u64> for S {}
2309fn test() { 2323fn test() {
2310 let x: u32 = S.into(); 2324 let x: u32 = S.into();
2311 let y: u64 = S.into(); 2325 let y: u64 = S.into();
@@ -2313,18 +2327,20 @@ fn test() {
2313} 2327}
2314"#), 2328"#),
2315 @r###" 2329 @r###"
2316[29; 33) 'self': Self 2330 â‹®
2317[107; 198) '{ ...(S); }': () 2331 â‹®[29; 33) 'self': Self
2318[117; 118) 'x': u32 2332 â‹®[111; 202) '{ ...(S); }': ()
2319[126; 127) 'S': S 2333 â‹®[121; 122) 'x': u32
2320[126; 134) 'S.into()': u32 2334 â‹®[130; 131) 'S': S
2321[144; 145) 'y': u64 2335 â‹®[130; 138) 'S.into()': u32
2322[153; 154) 'S': S 2336 â‹®[148; 149) 'y': u64
2323[153; 161) 'S.into()': u64 2337 â‹®[157; 158) 'S': S
2324[171; 172) 'z': {unknown} 2338 â‹®[157; 165) 'S.into()': u64
2325[175; 192) 'Into::...::into': {unknown} 2339 â‹®[175; 176) 'z': {unknown}
2326[175; 195) 'Into::...nto(S)': {unknown} 2340 â‹®[179; 196) 'Into::...::into': {unknown}
2327[193; 194) 'S': S"### 2341 â‹®[179; 199) 'Into::...nto(S)': {unknown}
2342 â‹®[197; 198) 'S': S
2343 "###
2328 ); 2344 );
2329} 2345}
2330 2346
@@ -2617,7 +2633,7 @@ fn method_resolution_where_clause_1() {
2617trait Clone {} 2633trait Clone {}
2618trait Trait { fn foo(self) -> u128; } 2634trait Trait { fn foo(self) -> u128; }
2619struct S; 2635struct S;
2620impl Clone for S {}; 2636impl Clone for S {}
2621impl<T> Trait for T where T: Clone {} 2637impl<T> Trait for T where T: Clone {}
2622fn test() { S.foo()<|>; } 2638fn test() { S.foo()<|>; }
2623"#, 2639"#,
@@ -2634,7 +2650,7 @@ trait Into<T> { fn into(self) -> T; }
2634trait From<T> { fn from(other: T) -> Self; } 2650trait From<T> { fn from(other: T) -> Self; }
2635struct S1; 2651struct S1;
2636struct S2; 2652struct S2;
2637impl From<S2> for S1 {}; 2653impl From<S2> for S1 {}
2638impl<T, U> Into<U> for T where U: From<T> {} 2654impl<T, U> Into<U> for T where U: From<T> {}
2639fn test() { S2.into()<|>; } 2655fn test() { S2.into()<|>; }
2640"#, 2656"#,
@@ -2651,7 +2667,7 @@ trait Into<T> { fn into(self) -> T; }
2651trait From<T> { fn from(other: T) -> Self; } 2667trait From<T> { fn from(other: T) -> Self; }
2652struct S1; 2668struct S1;
2653struct S2; 2669struct S2;
2654impl From<S2> for S1 {}; 2670impl From<S2> for S1 {}
2655impl<T, U: From<T>> Into<U> for T {} 2671impl<T, U: From<T>> Into<U> for T {}
2656fn test() { S2.into()<|>; } 2672fn test() { S2.into()<|>; }
2657"#, 2673"#,
@@ -2680,8 +2696,8 @@ fn method_resolution_slow() {
2680//- /main.rs 2696//- /main.rs
2681trait SendX {} 2697trait SendX {}
2682 2698
2683struct S1; impl SendX for S1; 2699struct S1; impl SendX for S1 {}
2684struct S2; impl SendX for S2; 2700struct S2; impl SendX for S2 {}
2685struct U1; 2701struct U1;
2686 2702
2687trait Trait { fn method(self); } 2703trait Trait { fn method(self); }
@@ -2702,7 +2718,7 @@ fn test() { (S {}).method()<|>; }
2702} 2718}
2703 2719
2704fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 2720fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
2705 let file = db.parse(pos.file_id); 2721 let file = db.parse(pos.file_id).ok().unwrap();
2706 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); 2722 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap();
2707 let analyzer = SourceAnalyzer::new(db, pos.file_id, expr.syntax(), Some(pos.offset)); 2723 let analyzer = SourceAnalyzer::new(db, pos.file_id, expr.syntax(), Some(pos.offset));
2708 let ty = analyzer.type_of(db, expr).unwrap(); 2724 let ty = analyzer.type_of(db, expr).unwrap();
@@ -2716,7 +2732,7 @@ fn type_at(content: &str) -> String {
2716 2732
2717fn infer(content: &str) -> String { 2733fn infer(content: &str) -> String {
2718 let (db, _, file_id) = MockDatabase::with_single_file(content); 2734 let (db, _, file_id) = MockDatabase::with_single_file(content);
2719 let source_file = db.parse(file_id); 2735 let source_file = db.parse(file_id).ok().unwrap();
2720 2736
2721 let mut acc = String::new(); 2737 let mut acc = String::new();
2722 acc.push_str("\n"); 2738 acc.push_str("\n");
@@ -2794,7 +2810,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
2794 ", 2810 ",
2795 ); 2811 );
2796 { 2812 {
2797 let file = db.parse(pos.file_id); 2813 let file = db.parse(pos.file_id).ok().unwrap();
2798 let node = 2814 let node =
2799 algo::find_token_at_offset(file.syntax(), pos.offset).right_biased().unwrap().parent(); 2815 algo::find_token_at_offset(file.syntax(), pos.offset).right_biased().unwrap().parent();
2800 let events = db.log_executed(|| { 2816 let events = db.log_executed(|| {
@@ -2815,7 +2831,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
2815 db.query_mut(ra_db::FileTextQuery).set(pos.file_id, Arc::new(new_text)); 2831 db.query_mut(ra_db::FileTextQuery).set(pos.file_id, Arc::new(new_text));
2816 2832
2817 { 2833 {
2818 let file = db.parse(pos.file_id); 2834 let file = db.parse(pos.file_id).ok().unwrap();
2819 let node = 2835 let node =
2820 algo::find_token_at_offset(file.syntax(), pos.offset).right_biased().unwrap().parent(); 2836 algo::find_token_at_offset(file.syntax(), pos.offset).right_biased().unwrap().parent();
2821 let events = db.log_executed(|| { 2837 let events = db.log_executed(|| {
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs
index 4413aec73..5d43282fd 100644
--- a/crates/ra_ide_api/src/call_info.rs
+++ b/crates/ra_ide_api/src/call_info.rs
@@ -10,7 +10,7 @@ use crate::{FilePosition, CallInfo, FunctionSignature, db::RootDatabase};
10 10
11/// Computes parameter information for the given call expression. 11/// Computes parameter information for the given call expression.
12pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { 12pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> {
13 let file = db.parse(position.file_id); 13 let file = db.parse(position.file_id).tree;
14 let syntax = file.syntax(); 14 let syntax = file.syntax();
15 15
16 // Find the calling expression and it's NameRef 16 // Find the calling expression and it's NameRef
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs
index 0e64abdbd..4b597afc0 100644
--- a/crates/ra_ide_api/src/change.rs
+++ b/crates/ra_ide_api/src/change.rs
@@ -138,7 +138,7 @@ impl LibraryData {
138 files: Vec<(FileId, RelativePathBuf, Arc<String>)>, 138 files: Vec<(FileId, RelativePathBuf, Arc<String>)>,
139 ) -> LibraryData { 139 ) -> LibraryData {
140 let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, _, text)| { 140 let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, _, text)| {
141 let file = SourceFile::parse(text); 141 let file = SourceFile::parse(text).tree;
142 (*file_id, file) 142 (*file_id, file)
143 })); 143 }));
144 let mut root_change = RootChange::default(); 144 let mut root_change = RootChange::default();
diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs
index deff59cd3..3a75bbf92 100644
--- a/crates/ra_ide_api/src/completion.rs
+++ b/crates/ra_ide_api/src/completion.rs
@@ -51,8 +51,8 @@ pub use crate::completion::completion_item::{CompletionItem, CompletionItemKind,
51/// identifier prefix/fuzzy match should be done higher in the stack, together 51/// identifier prefix/fuzzy match should be done higher in the stack, together
52/// with ordering of completions (currently this is done by the client). 52/// with ordering of completions (currently this is done by the client).
53pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Option<Completions> { 53pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Option<Completions> {
54 let original_file = db.parse(position.file_id); 54 let original_parse = db.parse(position.file_id);
55 let ctx = CompletionContext::new(db, &original_file, position)?; 55 let ctx = CompletionContext::new(db, &original_parse, position)?;
56 56
57 let mut acc = Completions::default(); 57 let mut acc = Completions::default();
58 58
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs
index a8c8cc7b0..bda7d9bb2 100644
--- a/crates/ra_ide_api/src/completion/completion_context.rs
+++ b/crates/ra_ide_api/src/completion/completion_context.rs
@@ -1,6 +1,6 @@
1use ra_text_edit::AtomTextEdit; 1use ra_text_edit::AtomTextEdit;
2use ra_syntax::{ 2use ra_syntax::{
3 AstNode, SyntaxNode, SourceFile, TextUnit, TextRange, SyntaxToken, 3 AstNode, SyntaxNode, SourceFile, TextUnit, TextRange, SyntaxToken, Parse,
4 ast, 4 ast,
5 algo::{find_token_at_offset, find_covering_element, find_node_at_offset}, 5 algo::{find_token_at_offset, find_covering_element, find_node_at_offset},
6 SyntaxKind::*, 6 SyntaxKind::*,
@@ -43,11 +43,12 @@ pub(crate) struct CompletionContext<'a> {
43impl<'a> CompletionContext<'a> { 43impl<'a> CompletionContext<'a> {
44 pub(super) fn new( 44 pub(super) fn new(
45 db: &'a db::RootDatabase, 45 db: &'a db::RootDatabase,
46 original_file: &'a SourceFile, 46 original_parse: &'a Parse,
47 position: FilePosition, 47 position: FilePosition,
48 ) -> Option<CompletionContext<'a>> { 48 ) -> Option<CompletionContext<'a>> {
49 let module = source_binder::module_from_position(db, position); 49 let module = source_binder::module_from_position(db, position);
50 let token = find_token_at_offset(original_file.syntax(), position.offset).left_biased()?; 50 let token =
51 find_token_at_offset(original_parse.tree.syntax(), position.offset).left_biased()?;
51 let analyzer = 52 let analyzer =
52 hir::SourceAnalyzer::new(db, position.file_id, token.parent(), Some(position.offset)); 53 hir::SourceAnalyzer::new(db, position.file_id, token.parent(), Some(position.offset));
53 let mut ctx = CompletionContext { 54 let mut ctx = CompletionContext {
@@ -69,7 +70,7 @@ impl<'a> CompletionContext<'a> {
69 dot_receiver: None, 70 dot_receiver: None,
70 is_call: false, 71 is_call: false,
71 }; 72 };
72 ctx.fill(original_file, position.offset); 73 ctx.fill(&original_parse, position.offset);
73 Some(ctx) 74 Some(ctx)
74 } 75 }
75 76
@@ -82,13 +83,13 @@ impl<'a> CompletionContext<'a> {
82 } 83 }
83 } 84 }
84 85
85 fn fill(&mut self, original_file: &'a SourceFile, offset: TextUnit) { 86 fn fill(&mut self, original_parse: &'a Parse, offset: TextUnit) {
86 // Insert a fake ident to get a valid parse tree. We will use this file 87 // Insert a fake ident to get a valid parse tree. We will use this file
87 // to determine context, though the original_file will be used for 88 // to determine context, though the original_file will be used for
88 // actual completion. 89 // actual completion.
89 let file = { 90 let file = {
90 let edit = AtomTextEdit::insert(offset, "intellijRulezz".to_string()); 91 let edit = AtomTextEdit::insert(offset, "intellijRulezz".to_string());
91 original_file.reparse(&edit) 92 original_parse.reparse(&edit).tree
92 }; 93 };
93 94
94 // First, let's try to complete a reference to some declaration. 95 // First, let's try to complete a reference to some declaration.
@@ -99,7 +100,7 @@ impl<'a> CompletionContext<'a> {
99 self.is_param = true; 100 self.is_param = true;
100 return; 101 return;
101 } 102 }
102 self.classify_name_ref(original_file, name_ref); 103 self.classify_name_ref(&original_parse.tree, name_ref);
103 } 104 }
104 105
105 // Otherwise, see if this is a declaration. We can use heuristics to 106 // Otherwise, see if this is a declaration. We can use heuristics to
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs
index 923008708..a2a8c1e4f 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide_api/src/diagnostics.rs
@@ -4,7 +4,7 @@ use itertools::Itertools;
4use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}}; 4use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}};
5use ra_db::SourceDatabase; 5use ra_db::SourceDatabase;
6use ra_syntax::{ 6use ra_syntax::{
7 T, Location, SourceFile, TextRange, SyntaxNode, 7 T, Location, TextRange, SyntaxNode,
8 ast::{self, AstNode, NamedFieldList, NamedField}, 8 ast::{self, AstNode, NamedFieldList, NamedField},
9}; 9};
10use ra_assists::ast_editor::{AstEditor, AstBuilder}; 10use ra_assists::ast_editor::{AstEditor, AstBuilder};
@@ -21,10 +21,17 @@ pub enum Severity {
21 21
22pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> { 22pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> {
23 let _p = profile("diagnostics"); 23 let _p = profile("diagnostics");
24 let source_file = db.parse(file_id); 24 let parse = db.parse(file_id);
25 let mut res = Vec::new(); 25 let mut res = Vec::new();
26 26
27 syntax_errors(&mut res, &source_file); 27 res.extend(parse.errors.iter().map(|err| Diagnostic {
28 range: location_to_range(err.location()),
29 message: format!("Syntax Error: {}", err),
30 severity: Severity::Error,
31 fix: None,
32 }));
33
34 let source_file = parse.tree;
28 35
29 for node in source_file.syntax().descendants() { 36 for node in source_file.syntax().descendants() {
30 check_unnecessary_braces_in_use_statement(&mut res, file_id, node); 37 check_unnecessary_braces_in_use_statement(&mut res, file_id, node);
@@ -51,8 +58,6 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
51 }) 58 })
52 }) 59 })
53 .on::<hir::diagnostics::MissingFields, _>(|d| { 60 .on::<hir::diagnostics::MissingFields, _>(|d| {
54 let file_id = d.file().original_file(db);
55 let source_file = db.parse(file_id);
56 let syntax_node = d.syntax_node_ptr(); 61 let syntax_node = d.syntax_node_ptr();
57 let node = NamedFieldList::cast(syntax_node.to_node(source_file.syntax())).unwrap(); 62 let node = NamedFieldList::cast(syntax_node.to_node(source_file.syntax())).unwrap();
58 let mut ast_editor = AstEditor::new(node); 63 let mut ast_editor = AstEditor::new(node);
@@ -77,21 +82,11 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
77 drop(sink); 82 drop(sink);
78 res.into_inner() 83 res.into_inner()
79} 84}
80 85fn location_to_range(location: Location) -> TextRange {
81fn syntax_errors(acc: &mut Vec<Diagnostic>, source_file: &SourceFile) { 86 match location {
82 fn location_to_range(location: Location) -> TextRange { 87 Location::Offset(offset) => TextRange::offset_len(offset, 1.into()),
83 match location { 88 Location::Range(range) => range,
84 Location::Offset(offset) => TextRange::offset_len(offset, 1.into()),
85 Location::Range(range) => range,
86 }
87 } 89 }
88
89 acc.extend(source_file.errors().into_iter().map(|err| Diagnostic {
90 range: location_to_range(err.location()),
91 message: format!("Syntax Error: {}", err),
92 severity: Severity::Error,
93 fix: None,
94 }));
95} 90}
96 91
97fn check_unnecessary_braces_in_use_statement( 92fn check_unnecessary_braces_in_use_statement(
@@ -177,6 +172,7 @@ fn check_struct_shorthand_initialization(
177mod tests { 172mod tests {
178 use test_utils::assert_eq_text; 173 use test_utils::assert_eq_text;
179 use insta::assert_debug_snapshot_matches; 174 use insta::assert_debug_snapshot_matches;
175 use ra_syntax::SourceFile;
180 176
181 use crate::mock_analysis::single_file; 177 use crate::mock_analysis::single_file;
182 178
@@ -185,7 +181,7 @@ mod tests {
185 type DiagnosticChecker = fn(&mut Vec<Diagnostic>, FileId, &SyntaxNode) -> Option<()>; 181 type DiagnosticChecker = fn(&mut Vec<Diagnostic>, FileId, &SyntaxNode) -> Option<()>;
186 182
187 fn check_not_applicable(code: &str, func: DiagnosticChecker) { 183 fn check_not_applicable(code: &str, func: DiagnosticChecker) {
188 let file = SourceFile::parse(code); 184 let file = SourceFile::parse(code).tree;
189 let mut diagnostics = Vec::new(); 185 let mut diagnostics = Vec::new();
190 for node in file.syntax().descendants() { 186 for node in file.syntax().descendants() {
191 func(&mut diagnostics, FileId(0), node); 187 func(&mut diagnostics, FileId(0), node);
@@ -194,7 +190,7 @@ mod tests {
194 } 190 }
195 191
196 fn check_apply(before: &str, after: &str, func: DiagnosticChecker) { 192 fn check_apply(before: &str, after: &str, func: DiagnosticChecker) {
197 let file = SourceFile::parse(before); 193 let file = SourceFile::parse(before).tree;
198 let mut diagnostics = Vec::new(); 194 let mut diagnostics = Vec::new();
199 for node in file.syntax().descendants() { 195 for node in file.syntax().descendants() {
200 func(&mut diagnostics, FileId(0), node); 196 func(&mut diagnostics, FileId(0), node);
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs
index 7f81483f7..ae729614f 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide_api/src/display/navigation_target.rs
@@ -79,7 +79,7 @@ impl NavigationTarget {
79 file_id: FileId, 79 file_id: FileId,
80 pat: AstPtr<ast::Pat>, 80 pat: AstPtr<ast::Pat>,
81 ) -> NavigationTarget { 81 ) -> NavigationTarget {
82 let file = db.parse(file_id); 82 let file = db.parse(file_id).tree;
83 let (name, full_range) = match pat.to_node(file.syntax()).kind() { 83 let (name, full_range) = match pat.to_node(file.syntax()).kind() {
84 ast::PatKind::BindPat(pat) => return NavigationTarget::from_bind_pat(file_id, &pat), 84 ast::PatKind::BindPat(pat) => return NavigationTarget::from_bind_pat(file_id, &pat),
85 _ => ("_".into(), pat.syntax_node_ptr().range()), 85 _ => ("_".into(), pat.syntax_node_ptr().range()),
@@ -290,7 +290,7 @@ impl NavigationTarget {
290 } 290 }
291 291
292 pub(crate) fn node(&self, db: &RootDatabase) -> Option<TreeArc<SyntaxNode>> { 292 pub(crate) fn node(&self, db: &RootDatabase) -> Option<TreeArc<SyntaxNode>> {
293 let source_file = db.parse(self.file_id()); 293 let source_file = db.parse(self.file_id()).tree;
294 let source_file = source_file.syntax(); 294 let source_file = source_file.syntax();
295 let node = source_file 295 let node = source_file
296 .descendants() 296 .descendants()
diff --git a/crates/ra_ide_api/src/display/structure.rs b/crates/ra_ide_api/src/display/structure.rs
index ec2c9bbc6..24ab7b59c 100644
--- a/crates/ra_ide_api/src/display/structure.rs
+++ b/crates/ra_ide_api/src/display/structure.rs
@@ -183,7 +183,9 @@ fn obsolete() {}
183#[deprecated(note = "for awhile")] 183#[deprecated(note = "for awhile")]
184fn very_obsolete() {} 184fn very_obsolete() {}
185"#, 185"#,
186 ); 186 )
187 .ok()
188 .unwrap();
187 let structure = file_structure(&file); 189 let structure = file_structure(&file);
188 assert_debug_snapshot_matches!("file_structure", structure); 190 assert_debug_snapshot_matches!("file_structure", structure);
189 } 191 }
diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide_api/src/extend_selection.rs
index 4553faad0..00c445310 100644
--- a/crates/ra_ide_api/src/extend_selection.rs
+++ b/crates/ra_ide_api/src/extend_selection.rs
@@ -11,7 +11,7 @@ use crate::{FileRange, db::RootDatabase};
11 11
12// FIXME: restore macro support 12// FIXME: restore macro support
13pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { 13pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange {
14 let source_file = db.parse(frange.file_id); 14 let source_file = db.parse(frange.file_id).tree;
15 try_extend_selection(source_file.syntax(), frange.range).unwrap_or(frange.range) 15 try_extend_selection(source_file.syntax(), frange.range).unwrap_or(frange.range)
16} 16}
17 17
@@ -212,7 +212,7 @@ mod tests {
212 212
213 fn do_check(before: &str, afters: &[&str]) { 213 fn do_check(before: &str, afters: &[&str]) {
214 let (cursor, before) = extract_offset(before); 214 let (cursor, before) = extract_offset(before);
215 let file = SourceFile::parse(&before); 215 let file = SourceFile::parse(&before).tree;
216 let mut range = TextRange::offset_len(cursor, 0.into()); 216 let mut range = TextRange::offset_len(cursor, 0.into());
217 for &after in afters { 217 for &after in afters {
218 range = try_extend_selection(file.syntax(), range).unwrap(); 218 range = try_extend_selection(file.syntax(), range).unwrap();
diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide_api/src/folding_ranges.rs
index 6987fcc9e..b50bbee38 100644
--- a/crates/ra_ide_api/src/folding_ranges.rs
+++ b/crates/ra_ide_api/src/folding_ranges.rs
@@ -191,7 +191,7 @@ mod tests {
191 191
192 fn do_check(text: &str, fold_kinds: &[FoldKind]) { 192 fn do_check(text: &str, fold_kinds: &[FoldKind]) {
193 let (ranges, text) = extract_ranges(text, "fold"); 193 let (ranges, text) = extract_ranges(text, "fold");
194 let file = SourceFile::parse(&text); 194 let file = SourceFile::parse(&text).tree;
195 let folds = folding_ranges(&file); 195 let folds = folding_ranges(&file);
196 196
197 assert_eq!( 197 assert_eq!(
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index 9c56f17f2..4f8554625 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -19,7 +19,7 @@ pub(crate) fn goto_definition(
19 db: &RootDatabase, 19 db: &RootDatabase,
20 position: FilePosition, 20 position: FilePosition,
21) -> Option<RangeInfo<Vec<NavigationTarget>>> { 21) -> Option<RangeInfo<Vec<NavigationTarget>>> {
22 let file = db.parse(position.file_id); 22 let file = db.parse(position.file_id).tree;
23 let syntax = file.syntax(); 23 let syntax = file.syntax();
24 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { 24 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) {
25 let navs = reference_definition(db, position.file_id, name_ref).to_vec(); 25 let navs = reference_definition(db, position.file_id, name_ref).to_vec();
diff --git a/crates/ra_ide_api/src/goto_type_definition.rs b/crates/ra_ide_api/src/goto_type_definition.rs
index e456ec5d6..0f638b170 100644
--- a/crates/ra_ide_api/src/goto_type_definition.rs
+++ b/crates/ra_ide_api/src/goto_type_definition.rs
@@ -10,7 +10,7 @@ pub(crate) fn goto_type_definition(
10 db: &RootDatabase, 10 db: &RootDatabase,
11 position: FilePosition, 11 position: FilePosition,
12) -> Option<RangeInfo<Vec<NavigationTarget>>> { 12) -> Option<RangeInfo<Vec<NavigationTarget>>> {
13 let file = db.parse(position.file_id); 13 let file = db.parse(position.file_id).tree;
14 14
15 let node = find_token_at_offset(file.syntax(), position.offset).find_map(|token| { 15 let node = find_token_at_offset(file.syntax(), position.offset).find_map(|token| {
16 token 16 token
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index 6545a2581..a390dab65 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -68,7 +68,7 @@ impl HoverResult {
68} 68}
69 69
70pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> { 70pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> {
71 let file = db.parse(position.file_id); 71 let file = db.parse(position.file_id).tree;
72 let mut res = HoverResult::new(); 72 let mut res = HoverResult::new();
73 73
74 let mut range = None; 74 let mut range = None;
@@ -120,7 +120,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
120} 120}
121 121
122pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { 122pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
123 let file = db.parse(frange.file_id); 123 let file = db.parse(frange.file_id).tree;
124 let syntax = file.syntax(); 124 let syntax = file.syntax();
125 let leaf_node = find_covering_element(syntax, frange.range); 125 let leaf_node = find_covering_element(syntax, frange.range);
126 // if we picked identifier, expand to pattern/expression 126 // if we picked identifier, expand to pattern/expression
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs
index ee9220a15..b80238d9e 100644
--- a/crates/ra_ide_api/src/impls.rs
+++ b/crates/ra_ide_api/src/impls.rs
@@ -11,7 +11,7 @@ pub(crate) fn goto_implementation(
11 db: &RootDatabase, 11 db: &RootDatabase,
12 position: FilePosition, 12 position: FilePosition,
13) -> Option<RangeInfo<Vec<NavigationTarget>>> { 13) -> Option<RangeInfo<Vec<NavigationTarget>>> {
14 let file = db.parse(position.file_id); 14 let file = db.parse(position.file_id).tree;
15 let syntax = file.syntax(); 15 let syntax = file.syntax();
16 16
17 let module = source_binder::module_from_position(db, position)?; 17 let module = source_binder::module_from_position(db, position)?;
diff --git a/crates/ra_ide_api/src/join_lines.rs b/crates/ra_ide_api/src/join_lines.rs
index 4ca005466..3978e9635 100644
--- a/crates/ra_ide_api/src/join_lines.rs
+++ b/crates/ra_ide_api/src/join_lines.rs
@@ -506,7 +506,7 @@ fn foo() {
506 506
507 fn check_join_lines_sel(before: &str, after: &str) { 507 fn check_join_lines_sel(before: &str, after: &str) {
508 let (sel, before) = extract_range(before); 508 let (sel, before) = extract_range(before);
509 let file = SourceFile::parse(&before); 509 let file = SourceFile::parse(&before).tree;
510 let result = join_lines(&file, sel); 510 let result = join_lines(&file, sel);
511 let actual = result.apply(&before); 511 let actual = result.apply(&before);
512 assert_eq_text!(after, &actual); 512 assert_eq_text!(after, &actual);
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index 452407e8e..2fe46cd13 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -314,7 +314,7 @@ impl Analysis {
314 314
315 /// Gets the syntax tree of the file. 315 /// Gets the syntax tree of the file.
316 pub fn parse(&self, file_id: FileId) -> TreeArc<SourceFile> { 316 pub fn parse(&self, file_id: FileId) -> TreeArc<SourceFile> {
317 self.db.parse(file_id).clone() 317 self.db.parse(file_id).tree
318 } 318 }
319 319
320 /// Gets the file's `LineIndex`: data structure to convert between absolute 320 /// Gets the file's `LineIndex`: data structure to convert between absolute
@@ -331,7 +331,7 @@ impl Analysis {
331 /// Returns position of the matching brace (all types of braces are 331 /// Returns position of the matching brace (all types of braces are
332 /// supported). 332 /// supported).
333 pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> { 333 pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> {
334 let file = self.db.parse(position.file_id); 334 let file = self.db.parse(position.file_id).tree;
335 matching_brace::matching_brace(&file, position.offset) 335 matching_brace::matching_brace(&file, position.offset)
336 } 336 }
337 337
@@ -344,7 +344,7 @@ impl Analysis {
344 /// Returns an edit to remove all newlines in the range, cleaning up minor 344 /// Returns an edit to remove all newlines in the range, cleaning up minor
345 /// stuff like trailing commas. 345 /// stuff like trailing commas.
346 pub fn join_lines(&self, frange: FileRange) -> SourceChange { 346 pub fn join_lines(&self, frange: FileRange) -> SourceChange {
347 let file = self.db.parse(frange.file_id); 347 let file = self.db.parse(frange.file_id).tree;
348 let file_edit = SourceFileEdit { 348 let file_edit = SourceFileEdit {
349 file_id: frange.file_id, 349 file_id: frange.file_id,
350 edit: join_lines::join_lines(&file, frange.range), 350 edit: join_lines::join_lines(&file, frange.range),
@@ -362,7 +362,7 @@ impl Analysis {
362 /// this works when adding `let =`. 362 /// this works when adding `let =`.
363 // FIXME: use a snippet completion instead of this hack here. 363 // FIXME: use a snippet completion instead of this hack here.
364 pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { 364 pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> {
365 let file = self.db.parse(position.file_id); 365 let file = self.db.parse(position.file_id).tree;
366 let edit = typing::on_eq_typed(&file, position.offset)?; 366 let edit = typing::on_eq_typed(&file, position.offset)?;
367 Some(SourceChange::source_file_edit( 367 Some(SourceChange::source_file_edit(
368 "add semicolon", 368 "add semicolon",
@@ -378,13 +378,13 @@ impl Analysis {
378 /// Returns a tree representation of symbols in the file. Useful to draw a 378 /// Returns a tree representation of symbols in the file. Useful to draw a
379 /// file outline. 379 /// file outline.
380 pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> { 380 pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> {
381 let file = self.db.parse(file_id); 381 let file = self.db.parse(file_id).tree;
382 file_structure(&file) 382 file_structure(&file)
383 } 383 }
384 384
385 /// Returns the set of folding ranges. 385 /// Returns the set of folding ranges.
386 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { 386 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> {
387 let file = self.db.parse(file_id); 387 let file = self.db.parse(file_id).tree;
388 folding_ranges::folding_ranges(&file) 388 folding_ranges::folding_ranges(&file)
389 } 389 }
390 390
diff --git a/crates/ra_ide_api/src/matching_brace.rs b/crates/ra_ide_api/src/matching_brace.rs
index eaa4b620c..7f3e65b46 100644
--- a/crates/ra_ide_api/src/matching_brace.rs
+++ b/crates/ra_ide_api/src/matching_brace.rs
@@ -31,7 +31,7 @@ mod tests {
31 fn test_matching_brace() { 31 fn test_matching_brace() {
32 fn do_check(before: &str, after: &str) { 32 fn do_check(before: &str, after: &str) {
33 let (pos, before) = extract_offset(before); 33 let (pos, before) = extract_offset(before);
34 let file = SourceFile::parse(&before); 34 let file = SourceFile::parse(&before).tree;
35 let new_pos = match matching_brace(&file, pos) { 35 let new_pos = match matching_brace(&file, pos) {
36 None => pos, 36 None => pos,
37 Some(pos) => pos, 37 Some(pos) => pos,
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs
index d5c2b08ca..a75042b76 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide_api/src/references.rs
@@ -60,7 +60,7 @@ pub(crate) fn find_all_refs(
60 db: &RootDatabase, 60 db: &RootDatabase,
61 position: FilePosition, 61 position: FilePosition,
62) -> Option<ReferenceSearchResult> { 62) -> Option<ReferenceSearchResult> {
63 let file = db.parse(position.file_id); 63 let file = db.parse(position.file_id).tree;
64 let (binding, analyzer) = find_binding(db, &file, position)?; 64 let (binding, analyzer) = find_binding(db, &file, position)?;
65 let declaration = NavigationTarget::from_bind_pat(position.file_id, binding); 65 let declaration = NavigationTarget::from_bind_pat(position.file_id, binding);
66 66
@@ -99,7 +99,7 @@ pub(crate) fn rename(
99 position: FilePosition, 99 position: FilePosition,
100 new_name: &str, 100 new_name: &str,
101) -> Option<SourceChange> { 101) -> Option<SourceChange> {
102 let source_file = db.parse(position.file_id); 102 let source_file = db.parse(position.file_id).tree;
103 let syntax = source_file.syntax(); 103 let syntax = source_file.syntax();
104 104
105 if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(syntax, position) { 105 if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(syntax, position) {
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide_api/src/runnables.rs
index 3969076a8..afe629d50 100644
--- a/crates/ra_ide_api/src/runnables.rs
+++ b/crates/ra_ide_api/src/runnables.rs
@@ -22,7 +22,7 @@ pub enum RunnableKind {
22} 22}
23 23
24pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { 24pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
25 let source_file = db.parse(file_id); 25 let source_file = db.parse(file_id).tree;
26 source_file.syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect() 26 source_file.syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect()
27} 27}
28 28
diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide_api/src/status.rs
index d99a4e750..821106fea 100644
--- a/crates/ra_ide_api/src/status.rs
+++ b/crates/ra_ide_api/src/status.rs
@@ -4,7 +4,7 @@ use std::{
4 sync::Arc, 4 sync::Arc,
5}; 5};
6 6
7use ra_syntax::{AstNode, TreeArc, SourceFile}; 7use ra_syntax::{AstNode, Parse};
8use ra_db::{ 8use ra_db::{
9 ParseQuery, FileTextQuery, SourceRootId, 9 ParseQuery, FileTextQuery, SourceRootId,
10 salsa::{Database, debug::{DebugQueryTable, TableEntry}}, 10 salsa::{Database, debug::{DebugQueryTable, TableEntry}},
@@ -72,17 +72,17 @@ impl fmt::Display for SyntaxTreeStats {
72 } 72 }
73} 73}
74 74
75impl FromIterator<TableEntry<FileId, TreeArc<SourceFile>>> for SyntaxTreeStats { 75impl FromIterator<TableEntry<FileId, Parse>> for SyntaxTreeStats {
76 fn from_iter<T>(iter: T) -> SyntaxTreeStats 76 fn from_iter<T>(iter: T) -> SyntaxTreeStats
77 where 77 where
78 T: IntoIterator<Item = TableEntry<FileId, TreeArc<SourceFile>>>, 78 T: IntoIterator<Item = TableEntry<FileId, Parse>>,
79 { 79 {
80 let mut res = SyntaxTreeStats::default(); 80 let mut res = SyntaxTreeStats::default();
81 for entry in iter { 81 for entry in iter {
82 res.total += 1; 82 res.total += 1;
83 if let Some(value) = entry.value { 83 if let Some(value) = entry.value {
84 res.retained += 1; 84 res.retained += 1;
85 res.retained_size += value.syntax().memory_size_of_subtree(); 85 res.retained_size += value.tree.syntax().memory_size_of_subtree();
86 } 86 }
87 } 87 }
88 res 88 res
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs
index 1dcff8beb..a6cd7bf61 100644
--- a/crates/ra_ide_api/src/symbol_index.rs
+++ b/crates/ra_ide_api/src/symbol_index.rs
@@ -63,7 +63,7 @@ pub(crate) trait SymbolsDatabase: hir::db::HirDatabase {
63 63
64fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> { 64fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> {
65 db.check_canceled(); 65 db.check_canceled();
66 let source_file = db.parse(file_id); 66 let source_file = db.parse(file_id).tree;
67 67
68 let symbols = source_file_to_file_symbols(&source_file, file_id); 68 let symbols = source_file_to_file_symbols(&source_file, file_id);
69 69
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs
index 739b898d2..bf4e9c9d1 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide_api/src/syntax_highlighting.rs
@@ -32,7 +32,7 @@ fn is_control_keyword(kind: SyntaxKind) -> bool {
32 32
33pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { 33pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
34 let _p = profile("highlight"); 34 let _p = profile("highlight");
35 let source_file = db.parse(file_id); 35 let source_file = db.parse(file_id).tree;
36 36
37 fn calc_binding_hash(file_id: FileId, text: &SmolStr, shadow_count: u32) -> u64 { 37 fn calc_binding_hash(file_id: FileId, text: &SmolStr, shadow_count: u32) -> u64 {
38 fn hash<T: std::hash::Hash + std::fmt::Debug>(x: T) -> u64 { 38 fn hash<T: std::hash::Hash + std::fmt::Debug>(x: T) -> u64 {
@@ -177,7 +177,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
177} 177}
178 178
179pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String { 179pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String {
180 let source_file = db.parse(file_id); 180 let source_file = db.parse(file_id).tree;
181 181
182 fn rainbowify(seed: u64) -> String { 182 fn rainbowify(seed: u64) -> String {
183 use rand::prelude::*; 183 use rand::prelude::*;
diff --git a/crates/ra_ide_api/src/syntax_tree.rs b/crates/ra_ide_api/src/syntax_tree.rs
index c7288220c..7165fa97a 100644
--- a/crates/ra_ide_api/src/syntax_tree.rs
+++ b/crates/ra_ide_api/src/syntax_tree.rs
@@ -14,7 +14,7 @@ pub(crate) fn syntax_tree(
14 text_range: Option<TextRange>, 14 text_range: Option<TextRange>,
15) -> String { 15) -> String {
16 if let Some(text_range) = text_range { 16 if let Some(text_range) = text_range {
17 let file = db.parse(file_id); 17 let file = db.parse(file_id).tree;
18 let node = match algo::find_covering_element(file.syntax(), text_range) { 18 let node = match algo::find_covering_element(file.syntax(), text_range) {
19 SyntaxElement::Node(node) => node, 19 SyntaxElement::Node(node) => node,
20 SyntaxElement::Token(token) => { 20 SyntaxElement::Token(token) => {
@@ -27,7 +27,7 @@ pub(crate) fn syntax_tree(
27 27
28 node.debug_dump() 28 node.debug_dump()
29 } else { 29 } else {
30 db.parse(file_id).syntax().debug_dump() 30 db.parse(file_id).tree.syntax().debug_dump()
31 } 31 }
32} 32}
33 33
@@ -84,8 +84,8 @@ fn syntax_tree_for_token(node: SyntaxToken, text_range: TextRange) -> Option<Str
84 84
85 // If the "file" parsed without errors, 85 // If the "file" parsed without errors,
86 // return its syntax 86 // return its syntax
87 if parsed.errors().is_empty() { 87 if parsed.errors.is_empty() {
88 return Some(parsed.syntax().debug_dump()); 88 return Some(parsed.tree.syntax().debug_dump());
89 } 89 }
90 90
91 None 91 None
diff --git a/crates/ra_ide_api/src/test_utils.rs b/crates/ra_ide_api/src/test_utils.rs
index d0bd3a1e4..6e0d883b4 100644
--- a/crates/ra_ide_api/src/test_utils.rs
+++ b/crates/ra_ide_api/src/test_utils.rs
@@ -9,7 +9,7 @@ pub fn check_action<F: Fn(&SourceFile, TextUnit) -> Option<TextEdit>>(
9 f: F, 9 f: F,
10) { 10) {
11 let (before_cursor_pos, before) = extract_offset(before); 11 let (before_cursor_pos, before) = extract_offset(before);
12 let file = SourceFile::parse(&before); 12 let file = SourceFile::parse(&before).ok().unwrap();
13 let result = f(&file, before_cursor_pos).expect("code action is not applicable"); 13 let result = f(&file, before_cursor_pos).expect("code action is not applicable");
14 let actual = result.apply(&before); 14 let actual = result.apply(&before);
15 let actual_cursor_pos = 15 let actual_cursor_pos =
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs
index ae53bca77..63bc0cf88 100644
--- a/crates/ra_ide_api/src/typing.rs
+++ b/crates/ra_ide_api/src/typing.rs
@@ -10,7 +10,7 @@ use ra_db::{FilePosition, SourceDatabase};
10use crate::{db::RootDatabase, SourceChange, SourceFileEdit}; 10use crate::{db::RootDatabase, SourceChange, SourceFileEdit};
11 11
12pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> { 12pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> {
13 let file = db.parse(position.file_id); 13 let file = db.parse(position.file_id).tree;
14 let comment = find_token_at_offset(file.syntax(), position.offset) 14 let comment = find_token_at_offset(file.syntax(), position.offset)
15 .left_biased() 15 .left_biased()
16 .and_then(ast::Comment::cast)?; 16 .and_then(ast::Comment::cast)?;
@@ -85,7 +85,7 @@ pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<TextEdit> {
85} 85}
86 86
87pub(crate) fn on_dot_typed(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> { 87pub(crate) fn on_dot_typed(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> {
88 let file = db.parse(position.file_id); 88 let file = db.parse(position.file_id).tree;
89 assert_eq!(file.syntax().text().char_at(position.offset), Some('.')); 89 assert_eq!(file.syntax().text().char_at(position.offset), Some('.'));
90 90
91 let whitespace = find_token_at_offset(file.syntax(), position.offset) 91 let whitespace = find_token_at_offset(file.syntax(), position.offset)
@@ -138,7 +138,7 @@ mod tests {
138 let mut edit = TextEditBuilder::default(); 138 let mut edit = TextEditBuilder::default();
139 edit.insert(offset, "=".to_string()); 139 edit.insert(offset, "=".to_string());
140 let before = edit.finish().apply(&before); 140 let before = edit.finish().apply(&before);
141 let file = SourceFile::parse(&before); 141 let file = SourceFile::parse(&before).tree;
142 if let Some(result) = on_eq_typed(&file, offset) { 142 if let Some(result) = on_eq_typed(&file, offset) {
143 let actual = result.apply(&before); 143 let actual = result.apply(&before);
144 assert_eq_text!(after, &actual); 144 assert_eq_text!(after, &actual);
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index 7fff8deff..a0bd0c5f8 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -597,7 +597,7 @@ mod tests {
597 } 597 }
598 598
599 fn create_rules(macro_definition: &str) -> crate::MacroRules { 599 fn create_rules(macro_definition: &str) -> crate::MacroRules {
600 let source_file = ast::SourceFile::parse(macro_definition); 600 let source_file = ast::SourceFile::parse(macro_definition).ok().unwrap();
601 let macro_definition = 601 let macro_definition =
602 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); 602 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
603 603
@@ -609,7 +609,7 @@ mod tests {
609 rules: &crate::MacroRules, 609 rules: &crate::MacroRules,
610 invocation: &str, 610 invocation: &str,
611 ) -> Result<tt::Subtree, ExpandError> { 611 ) -> Result<tt::Subtree, ExpandError> {
612 let source_file = ast::SourceFile::parse(invocation); 612 let source_file = ast::SourceFile::parse(invocation).ok().unwrap();
613 let macro_invocation = 613 let macro_invocation =
614 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); 614 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
615 615
diff --git a/crates/ra_mbe/src/mbe_parser.rs b/crates/ra_mbe/src/mbe_parser.rs
index 797c70bc7..d8fe293c7 100644
--- a/crates/ra_mbe/src/mbe_parser.rs
+++ b/crates/ra_mbe/src/mbe_parser.rs
@@ -175,7 +175,7 @@ mod tests {
175 } 175 }
176 176
177 fn create_rules(macro_definition: &str) -> Result<crate::MacroRules, ParseError> { 177 fn create_rules(macro_definition: &str) -> Result<crate::MacroRules, ParseError> {
178 let source_file = ast::SourceFile::parse(macro_definition); 178 let source_file = ast::SourceFile::parse(macro_definition).ok().unwrap();
179 let macro_definition = 179 let macro_definition =
180 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); 180 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
181 181
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs
index c0a3fec35..dce82f33d 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/ra_mbe/src/syntax_bridge.rs
@@ -56,8 +56,9 @@ where
56 if tree_sink.roots.len() != 1 { 56 if tree_sink.roots.len() != 1 {
57 return Err(ExpandError::ConversionError); 57 return Err(ExpandError::ConversionError);
58 } 58 }
59 59 //FIXME: would be cool to report errors
60 Ok(tree_sink.inner.finish()) 60 let (tree, _errors) = tree_sink.inner.finish();
61 Ok(tree)
61} 62}
62 63
63/// Parses the token tree (result of macro expansion) to an expression 64/// Parses the token tree (result of macro expansion) to an expression
@@ -383,7 +384,7 @@ mod tests {
383 } 384 }
384 "#, 385 "#,
385 ); 386 );
386 let expansion = expand(&rules, "literals!(foo)"); 387 let expansion = expand(&rules, "literals!(foo);");
387 let buffer = tt::buffer::TokenBuffer::new(&[expansion.clone().into()]); 388 let buffer = tt::buffer::TokenBuffer::new(&[expansion.clone().into()]);
388 let mut tt_src = SubtreeTokenSource::new(&buffer); 389 let mut tt_src = SubtreeTokenSource::new(&buffer);
389 let mut tokens = vec![]; 390 let mut tokens = vec![];
@@ -422,7 +423,7 @@ mod tests {
422 } 423 }
423 "#, 424 "#,
424 ); 425 );
425 let expansion = expand(&rules, "stmts!()"); 426 let expansion = expand(&rules, "stmts!();");
426 assert!(token_tree_to_expr(&expansion).is_err()); 427 assert!(token_tree_to_expr(&expansion).is_err());
427 } 428 }
428} 429}
diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs
index e3a5ceecf..1db35cd8d 100644
--- a/crates/ra_mbe/src/tests.rs
+++ b/crates/ra_mbe/src/tests.rs
@@ -29,11 +29,11 @@ macro_rules! impl_froms {
29impl_froms!(TokenTree: Leaf, Subtree); 29impl_froms!(TokenTree: Leaf, Subtree);
30"#; 30"#;
31 31
32 let source_file = ast::SourceFile::parse(macro_definition); 32 let source_file = ast::SourceFile::parse(macro_definition).ok().unwrap();
33 let macro_definition = 33 let macro_definition =
34 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); 34 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
35 35
36 let source_file = ast::SourceFile::parse(macro_invocation); 36 let source_file = ast::SourceFile::parse(macro_invocation).ok().unwrap();
37 let macro_invocation = 37 let macro_invocation =
38 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); 38 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
39 39
@@ -49,7 +49,7 @@ impl_froms!(TokenTree: Leaf, Subtree);
49} 49}
50 50
51pub(crate) fn create_rules(macro_definition: &str) -> MacroRules { 51pub(crate) fn create_rules(macro_definition: &str) -> MacroRules {
52 let source_file = ast::SourceFile::parse(macro_definition); 52 let source_file = ast::SourceFile::parse(macro_definition).ok().unwrap();
53 let macro_definition = 53 let macro_definition =
54 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); 54 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
55 55
@@ -58,7 +58,7 @@ pub(crate) fn create_rules(macro_definition: &str) -> MacroRules {
58} 58}
59 59
60pub(crate) fn expand(rules: &MacroRules, invocation: &str) -> tt::Subtree { 60pub(crate) fn expand(rules: &MacroRules, invocation: &str) -> tt::Subtree {
61 let source_file = ast::SourceFile::parse(invocation); 61 let source_file = ast::SourceFile::parse(invocation).ok().unwrap();
62 let macro_invocation = 62 let macro_invocation =
63 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); 63 source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
64 64
@@ -95,7 +95,7 @@ pub(crate) fn expand_to_expr(
95pub(crate) fn text_to_tokentree(text: &str) -> tt::Subtree { 95pub(crate) fn text_to_tokentree(text: &str) -> tt::Subtree {
96 // wrap the given text to a macro call 96 // wrap the given text to a macro call
97 let wrapped = format!("wrap_macro!( {} )", text); 97 let wrapped = format!("wrap_macro!( {} )", text);
98 let wrapped = ast::SourceFile::parse(&wrapped); 98 let wrapped = ast::SourceFile::parse(&wrapped).tree;
99 let wrapped = wrapped.syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); 99 let wrapped = wrapped.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
100 let mut wrapped = ast_to_token_tree(wrapped).unwrap().0; 100 let mut wrapped = ast_to_token_tree(wrapped).unwrap().0;
101 wrapped.delimiter = tt::Delimiter::None; 101 wrapped.delimiter = tt::Delimiter::None;
@@ -294,7 +294,7 @@ fn test_match_group_pattern_with_multiple_defs() {
294 macro_rules! foo { 294 macro_rules! foo {
295 ($ ($ i:ident),*) => ( struct Bar { $ ( 295 ($ ($ i:ident),*) => ( struct Bar { $ (
296 fn $ i {} 296 fn $ i {}
297 )*} ); 297 )*} );
298 } 298 }
299"#, 299"#,
300 ); 300 );
@@ -314,7 +314,7 @@ fn test_match_group_pattern_with_multiple_statement() {
314 macro_rules! foo { 314 macro_rules! foo {
315 ($ ($ i:ident),*) => ( fn baz { $ ( 315 ($ ($ i:ident),*) => ( fn baz { $ (
316 $ i (); 316 $ i ();
317 )*} ); 317 )*} );
318 } 318 }
319"#, 319"#,
320 ); 320 );
@@ -329,7 +329,7 @@ fn test_match_group_pattern_with_multiple_statement_without_semi() {
329 macro_rules! foo { 329 macro_rules! foo {
330 ($ ($ i:ident),*) => ( fn baz { $ ( 330 ($ ($ i:ident),*) => ( fn baz { $ (
331 $i() 331 $i()
332 );*} ); 332 );*} );
333 } 333 }
334"#, 334"#,
335 ); 335 );
@@ -344,7 +344,7 @@ fn test_match_group_empty_fixed_token() {
344 macro_rules! foo { 344 macro_rules! foo {
345 ($ ($ i:ident)* #abc) => ( fn baz { $ ( 345 ($ ($ i:ident)* #abc) => ( fn baz { $ (
346 $ i (); 346 $ i ();
347 )*} ); 347 )*} );
348 } 348 }
349"#, 349"#,
350 ); 350 );
@@ -356,10 +356,10 @@ fn test_match_group_empty_fixed_token() {
356fn test_match_group_in_subtree() { 356fn test_match_group_in_subtree() {
357 let rules = create_rules( 357 let rules = create_rules(
358 r#" 358 r#"
359 macro_rules! foo { 359 macro_rules! foo {
360 (fn $name:ident {$($i:ident)*} ) => ( fn $name() { $ ( 360 (fn $name:ident {$($i:ident)*} ) => ( fn $name() { $ (
361 $ i (); 361 $ i ();
362 )*} ); 362 )*} );
363 }"#, 363 }"#,
364 ); 364 );
365 365
@@ -370,15 +370,15 @@ fn test_match_group_in_subtree() {
370fn test_match_group_with_multichar_sep() { 370fn test_match_group_with_multichar_sep() {
371 let rules = create_rules( 371 let rules = create_rules(
372 r#" 372 r#"
373 macro_rules! foo { 373 macro_rules! foo {
374 (fn $name:ident {$($i:literal)*} ) => ( fn $name() -> bool { $($i)&&*} ); 374 (fn $name:ident {$($i:literal)*} ) => ( fn $name() -> bool { $($i)&&*} );
375 }"#, 375 }"#,
376 ); 376 );
377 377
378 assert_expansion( 378 assert_expansion(
379 MacroKind::Items, 379 MacroKind::Items,
380 &rules, 380 &rules,
381 "foo! (fn baz {true true} )", 381 "foo! (fn baz {true true} );",
382 "fn baz () -> bool {true &&true}", 382 "fn baz () -> bool {true &&true}",
383 ); 383 );
384} 384}
@@ -387,24 +387,24 @@ fn test_match_group_with_multichar_sep() {
387fn test_match_group_zero_match() { 387fn test_match_group_zero_match() {
388 let rules = create_rules( 388 let rules = create_rules(
389 r#" 389 r#"
390 macro_rules! foo { 390 macro_rules! foo {
391 ( $($i:ident)* ) => (); 391 ( $($i:ident)* ) => ();
392 }"#, 392 }"#,
393 ); 393 );
394 394
395 assert_expansion(MacroKind::Items, &rules, "foo! ()", ""); 395 assert_expansion(MacroKind::Items, &rules, "foo! ();", "");
396} 396}
397 397
398#[test] 398#[test]
399fn test_match_group_in_group() { 399fn test_match_group_in_group() {
400 let rules = create_rules( 400 let rules = create_rules(
401 r#" 401 r#"
402 macro_rules! foo { 402 macro_rules! foo {
403 { $( ( $($i:ident)* ) )* } => ( $( ( $($i)* ) )* ); 403 { $( ( $($i:ident)* ) )* } => ( $( ( $($i)* ) )* );
404 }"#, 404 }"#,
405 ); 405 );
406 406
407 assert_expansion(MacroKind::Items, &rules, "foo! ( (a b) )", "(a b)"); 407 assert_expansion(MacroKind::Items, &rules, "foo! ( (a b) );", "(a b)");
408} 408}
409 409
410#[test] 410#[test]
@@ -418,7 +418,7 @@ fn test_expand_to_item_list() {
418 } 418 }
419 ", 419 ",
420 ); 420 );
421 let expansion = expand(&rules, "structs!(Foo, Bar)"); 421 let expansion = expand(&rules, "structs!(Foo, Bar);");
422 let tree = token_tree_to_macro_items(&expansion); 422 let tree = token_tree_to_macro_items(&expansion);
423 assert_eq!( 423 assert_eq!(
424 tree.unwrap().syntax().debug_dump().trim(), 424 tree.unwrap().syntax().debug_dump().trim(),
@@ -490,7 +490,7 @@ fn test_expand_literals_to_token_tree() {
490 } 490 }
491 "#, 491 "#,
492 ); 492 );
493 let expansion = expand(&rules, "literals!(foo)"); 493 let expansion = expand(&rules, "literals!(foo);");
494 let stm_tokens = &to_subtree(&expansion.token_trees[0]).token_trees; 494 let stm_tokens = &to_subtree(&expansion.token_trees[0]).token_trees;
495 495
496 // [let] [a] [=] ['c'] [;] 496 // [let] [a] [=] ['c'] [;]
@@ -586,7 +586,7 @@ fn test_match_literal() {
586 } 586 }
587"#, 587"#,
588 ); 588 );
589 assert_expansion(MacroKind::Items, &rules, "foo! ['(']", "fn foo () {}"); 589 assert_expansion(MacroKind::Items, &rules, "foo! ['('];", "fn foo () {}");
590} 590}
591 591
592// The following tests are port from intellij-rust directly 592// The following tests are port from intellij-rust directly
@@ -651,7 +651,7 @@ fn test_expr() {
651 r#" 651 r#"
652 macro_rules! foo { 652 macro_rules! foo {
653 ($ i:expr) => { 653 ($ i:expr) => {
654 fn bar() { $ i; } 654 fn bar() { $ i; }
655 } 655 }
656 } 656 }
657"#, 657"#,
@@ -671,7 +671,7 @@ fn test_expr_order() {
671 r#" 671 r#"
672 macro_rules! foo { 672 macro_rules! foo {
673 ($ i:expr) => { 673 ($ i:expr) => {
674 fn bar() { $ i * 2; } 674 fn bar() { $ i * 2; }
675 } 675 }
676 } 676 }
677"#, 677"#,
@@ -725,7 +725,7 @@ fn test_last_expr() {
725 assert_expansion( 725 assert_expansion(
726 MacroKind::Items, 726 MacroKind::Items,
727 &rules, 727 &rules,
728 "vec!(1,2,3)", 728 "vec!(1,2,3);",
729 "{let mut v = Vec :: new () ; v . push (1) ; v . push (2) ; v . push (3) ; v}", 729 "{let mut v = Vec :: new () ; v . push (1) ; v . push (2) ; v . push (3) ; v}",
730 ); 730 );
731} 731}
@@ -896,13 +896,13 @@ fn test_meta_doc_comments() {
896 assert_expansion( 896 assert_expansion(
897 MacroKind::Items, 897 MacroKind::Items,
898 &rules, 898 &rules,
899 r#"foo! { 899 r#"foo! {
900 /// Single Line Doc 1 900 /// Single Line Doc 1
901 /** 901 /**
902 MultiLines Doc 902 MultiLines Doc
903 */ 903 */
904 }"#, 904 }"#,
905 "# [doc = \" Single Line Doc 1\"] # [doc = \" \\\\n MultiLines Doc\\\\n \"] fn bar () {}", 905 "# [doc = \" Single Line Doc 1\"] # [doc = \"\\\\n MultiLines Doc\\\\n \"] fn bar () {}",
906 ); 906 );
907} 907}
908 908
@@ -950,7 +950,7 @@ fn test_literal() {
950 } 950 }
951"#, 951"#,
952 ); 952 );
953 assert_expansion(MacroKind::Items, &rules, r#"foo!(u8 0)"#, r#"const VALUE : u8 = 0 ;"#); 953 assert_expansion(MacroKind::Items, &rules, r#"foo!(u8 0);"#, r#"const VALUE : u8 = 0 ;"#);
954} 954}
955 955
956#[test] 956#[test]
@@ -984,7 +984,7 @@ macro_rules! foo {
984 bar!($a); 984 bar!($a);
985 fn $b() -> u8 {$c} 985 fn $b() -> u8 {$c}
986 } 986 }
987} 987}
988"#, 988"#,
989 ); 989 );
990 assert_expansion( 990 assert_expansion(
@@ -1017,12 +1017,12 @@ fn test_vec() {
1017 assert_expansion( 1017 assert_expansion(
1018 MacroKind::Items, 1018 MacroKind::Items,
1019 &rules, 1019 &rules,
1020 r#"vec![1u32,2]"#, 1020 r#"vec![1u32,2];"#,
1021 r#"{let mut v = Vec :: new () ; v . push (1u32) ; v . push (2) ; v}"#, 1021 r#"{let mut v = Vec :: new () ; v . push (1u32) ; v . push (2) ; v}"#,
1022 ); 1022 );
1023 1023
1024 assert_eq!( 1024 assert_eq!(
1025 expand_to_expr(&rules, r#"vec![1u32,2]"#).syntax().debug_dump().trim(), 1025 expand_to_expr(&rules, r#"vec![1u32,2];"#).syntax().debug_dump().trim(),
1026 r#"BLOCK_EXPR@[0; 45) 1026 r#"BLOCK_EXPR@[0; 45)
1027 BLOCK@[0; 45) 1027 BLOCK@[0; 45)
1028 L_CURLY@[0; 1) "{" 1028 L_CURLY@[0; 1) "{"
@@ -1119,7 +1119,7 @@ macro_rules! STRUCT {
1119 // from https://github.com/retep998/winapi-rs/blob/a7ef2bca086aae76cf6c4ce4c2552988ed9798ad/src/shared/d3d9caps.rs 1119 // from https://github.com/retep998/winapi-rs/blob/a7ef2bca086aae76cf6c4ce4c2552988ed9798ad/src/shared/d3d9caps.rs
1120 assert_expansion(MacroKind::Items, &rules, r#"STRUCT!{struct D3DVSHADERCAPS2_0 {Caps: u8,}}"#, 1120 assert_expansion(MacroKind::Items, &rules, r#"STRUCT!{struct D3DVSHADERCAPS2_0 {Caps: u8,}}"#,
1121 "# [repr (C)] # [derive (Copy)] pub struct D3DVSHADERCAPS2_0 {pub Caps : u8 ,} impl Clone for D3DVSHADERCAPS2_0 {# [inline] fn clone (& self) -> D3DVSHADERCAPS2_0 {* self}} # [cfg (feature = \"impl-default\")] impl Default for D3DVSHADERCAPS2_0 {# [inline] fn default () -> D3DVSHADERCAPS2_0 {unsafe {$crate :: _core :: mem :: zeroed ()}}}"); 1121 "# [repr (C)] # [derive (Copy)] pub struct D3DVSHADERCAPS2_0 {pub Caps : u8 ,} impl Clone for D3DVSHADERCAPS2_0 {# [inline] fn clone (& self) -> D3DVSHADERCAPS2_0 {* self}} # [cfg (feature = \"impl-default\")] impl Default for D3DVSHADERCAPS2_0 {# [inline] fn default () -> D3DVSHADERCAPS2_0 {unsafe {$crate :: _core :: mem :: zeroed ()}}}");
1122 assert_expansion(MacroKind::Items, &rules, r#"STRUCT!{#[cfg_attr(target_arch = "x86", repr(packed))] struct D3DCONTENTPROTECTIONCAPS {Caps : u8 ,}}"#, 1122 assert_expansion(MacroKind::Items, &rules, r#"STRUCT!{#[cfg_attr(target_arch = "x86", repr(packed))] struct D3DCONTENTPROTECTIONCAPS {Caps : u8 ,}}"#,
1123 "# [repr (C)] # [derive (Copy)] # [cfg_attr (target_arch = \"x86\" , repr (packed))] pub struct D3DCONTENTPROTECTIONCAPS {pub Caps : u8 ,} impl Clone for D3DCONTENTPROTECTIONCAPS {# [inline] fn clone (& self) -> D3DCONTENTPROTECTIONCAPS {* self}} # [cfg (feature = \"impl-default\")] impl Default for D3DCONTENTPROTECTIONCAPS {# [inline] fn default () -> D3DCONTENTPROTECTIONCAPS {unsafe {$crate :: _core :: mem :: zeroed ()}}}"); 1123 "# [repr (C)] # [derive (Copy)] # [cfg_attr (target_arch = \"x86\" , repr (packed))] pub struct D3DCONTENTPROTECTIONCAPS {pub Caps : u8 ,} impl Clone for D3DCONTENTPROTECTIONCAPS {# [inline] fn clone (& self) -> D3DCONTENTPROTECTIONCAPS {* self}} # [cfg (feature = \"impl-default\")] impl Default for D3DCONTENTPROTECTIONCAPS {# [inline] fn default () -> D3DCONTENTPROTECTIONCAPS {unsafe {$crate :: _core :: mem :: zeroed ()}}}");
1124} 1124}
1125 1125
@@ -1136,11 +1136,11 @@ macro_rules! int_base {
1136 } 1136 }
1137 } 1137 }
1138 } 1138 }
1139} 1139}
1140"#, 1140"#,
1141 ); 1141 );
1142 1142
1143 assert_expansion(MacroKind::Items, &rules, r#" int_base!{Binary for isize as usize -> Binary}"#, 1143 assert_expansion(MacroKind::Items, &rules, r#" int_base!{Binary for isize as usize -> Binary}"#,
1144 "# [stable (feature = \"rust1\" , since = \"1.0.0\")] impl fmt ::Binary for isize {fn fmt (& self , f : & mut fmt :: Formatter < \'_ >) -> fmt :: Result {Binary . fmt_int (* self as usize , f)}}" 1144 "# [stable (feature = \"rust1\" , since = \"1.0.0\")] impl fmt ::Binary for isize {fn fmt (& self , f : & mut fmt :: Formatter < \'_ >) -> fmt :: Result {Binary . fmt_int (* self as usize , f)}}"
1145 ); 1145 );
1146} 1146}
@@ -1150,7 +1150,7 @@ fn test_generate_pattern_iterators() {
1150 // from https://github.com/rust-lang/rust/blob/316a391dcb7d66dc25f1f9a4ec9d368ef7615005/src/libcore/str/mod.rs 1150 // from https://github.com/rust-lang/rust/blob/316a391dcb7d66dc25f1f9a4ec9d368ef7615005/src/libcore/str/mod.rs
1151 let rules = create_rules( 1151 let rules = create_rules(
1152 r#" 1152 r#"
1153macro_rules! generate_pattern_iterators { 1153macro_rules! generate_pattern_iterators {
1154 { double ended; with $(#[$common_stability_attribute:meta])*, 1154 { double ended; with $(#[$common_stability_attribute:meta])*,
1155 $forward_iterator:ident, 1155 $forward_iterator:ident,
1156 $reverse_iterator:ident, $iterty:ty 1156 $reverse_iterator:ident, $iterty:ty
@@ -1161,7 +1161,7 @@ macro_rules! generate_pattern_iterators {
1161"#, 1161"#,
1162 ); 1162 );
1163 1163
1164 assert_expansion(MacroKind::Items, &rules, r#"generate_pattern_iterators ! ( double ended ; with # [ stable ( feature = "rust1" , since = "1.0.0" ) ] , Split , RSplit , & 'a str )"#, 1164 assert_expansion(MacroKind::Items, &rules, r#"generate_pattern_iterators ! ( double ended ; with # [ stable ( feature = "rust1" , since = "1.0.0" ) ] , Split , RSplit , & 'a str );"#,
1165 "fn foo () {}"); 1165 "fn foo () {}");
1166} 1166}
1167 1167
@@ -1170,7 +1170,7 @@ fn test_impl_fn_for_zst() {
1170 // from https://github.com/rust-lang/rust/blob/5d20ff4d2718c820632b38c1e49d4de648a9810b/src/libcore/internal_macros.rs 1170 // from https://github.com/rust-lang/rust/blob/5d20ff4d2718c820632b38c1e49d4de648a9810b/src/libcore/internal_macros.rs
1171 let rules = create_rules( 1171 let rules = create_rules(
1172 r#" 1172 r#"
1173macro_rules! impl_fn_for_zst { 1173macro_rules! impl_fn_for_zst {
1174 { $( $( #[$attr: meta] )* 1174 { $( $( #[$attr: meta] )*
1175 struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn = 1175 struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
1176 |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty 1176 |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
@@ -1208,27 +1208,26 @@ $body: block; )+
1208 )+ 1208 )+
1209} 1209}
1210 } 1210 }
1211}
1212"#, 1211"#,
1213 ); 1212 );
1214 1213
1215 assert_expansion(MacroKind::Items, &rules, r#" 1214 assert_expansion(MacroKind::Items, &rules, r#"
1216impl_fn_for_zst ! { 1215impl_fn_for_zst ! {
1217 # [ derive ( Clone ) ] 1216 # [ derive ( Clone ) ]
1218 struct CharEscapeDebugContinue impl Fn = | c : char | -> char :: EscapeDebug { 1217 struct CharEscapeDebugContinue impl Fn = | c : char | -> char :: EscapeDebug {
1219 c . escape_debug_ext ( false ) 1218 c . escape_debug_ext ( false )
1220 } ; 1219 } ;
1221 1220
1222 # [ derive ( Clone ) ] 1221 # [ derive ( Clone ) ]
1223 struct CharEscapeUnicode impl Fn = | c : char | -> char :: EscapeUnicode { 1222 struct CharEscapeUnicode impl Fn = | c : char | -> char :: EscapeUnicode {
1224 c . escape_unicode ( ) 1223 c . escape_unicode ( )
1225 } ; 1224 } ;
1226 # [ derive ( Clone ) ] 1225 # [ derive ( Clone ) ]
1227 struct CharEscapeDefault impl Fn = | c : char | -> char :: EscapeDefault { 1226 struct CharEscapeDefault impl Fn = | c : char | -> char :: EscapeDefault {
1228 c . escape_default ( ) 1227 c . escape_default ( )
1229 } ; 1228 } ;
1230 } 1229 }
1231"#, 1230"#,
1232 "# [derive (Clone)] struct CharEscapeDebugContinue ; impl Fn < (char ,) > for CharEscapeDebugContinue {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeDebug {{c . escape_debug_ext (false)}}} impl FnMut < (char ,) > for CharEscapeDebugContinue {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeDebug {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeDebugContinue {type Output = char :: EscapeDebug ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeDebug {Fn :: call (& self , (c ,))}} # [derive (Clone)] struct CharEscapeUnicode ; impl Fn < (char ,) > for CharEscapeUnicode {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeUnicode {{c . escape_unicode ()}}} impl FnMut < (char ,) > for CharEscapeUnicode {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeUnicode {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeUnicode {type Output = char :: EscapeUnicode ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeUnicode {Fn :: call (& self , (c ,))}} # [derive (Clone)] struct CharEscapeDefault ; impl Fn < (char ,) > for CharEscapeDefault {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeDefault {{c . escape_default ()}}} impl FnMut < (char ,) > for CharEscapeDefault {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeDefault {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeDefault {type Output = char :: EscapeDefault ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeDefault {Fn :: call (& self , (c ,))}}"); 1231 "# [derive (Clone)] struct CharEscapeDebugContinue ; impl Fn < (char ,) > for CharEscapeDebugContinue {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeDebug {{c . escape_debug_ext (false)}}} impl FnMut < (char ,) > for CharEscapeDebugContinue {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeDebug {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeDebugContinue {type Output = char :: EscapeDebug ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeDebug {Fn :: call (& self , (c ,))}} # [derive (Clone)] struct CharEscapeUnicode ; impl Fn < (char ,) > for CharEscapeUnicode {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeUnicode {{c . escape_unicode ()}}} impl FnMut < (char ,) > for CharEscapeUnicode {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeUnicode {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeUnicode {type Output = char :: EscapeUnicode ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeUnicode {Fn :: call (& self , (c ,))}} # [derive (Clone)] struct CharEscapeDefault ; impl Fn < (char ,) > for CharEscapeDefault {# [inline] extern \"rust-call\" fn call (& self , (c ,) : (char ,)) -> char :: EscapeDefault {{c . escape_default ()}}} impl FnMut < (char ,) > for CharEscapeDefault {# [inline] extern \"rust-call\" fn call_mut (& mut self , (c ,) : (char ,)) -> char :: EscapeDefault {Fn :: call (&* self , (c ,))}} impl FnOnce < (char ,) > for CharEscapeDefault {type Output = char :: EscapeDefault ; # [inline] extern \"rust-call\" fn call_once (self , (c ,) : (char ,)) -> char :: EscapeDefault {Fn :: call (& self , (c ,))}}");
1233} 1232}
1234 1233
@@ -1263,7 +1262,7 @@ fn test_cfg_if_items() {
1263"#, 1262"#,
1264 ); 1263 );
1265 1264
1266 assert_expansion(MacroKind::Items, &rules, r#"__cfg_if_items ! { ( rustdoc , ) ; ( ( ) ( # [ cfg ( any ( target_os = "redox" , unix ) ) ] # [ stable ( feature = "rust1" , since = "1.0.0" ) ] pub use sys :: ext as unix ; # [ cfg ( windows ) ] # [ stable ( feature = "rust1" , since = "1.0.0" ) ] pub use sys :: ext as windows ; # [ cfg ( any ( target_os = "linux" , target_os = "l4re" ) ) ] pub mod linux ; ) ) , }"#, 1265 assert_expansion(MacroKind::Items, &rules, r#"__cfg_if_items ! { ( rustdoc , ) ; ( ( ) ( # [ cfg ( any ( target_os = "redox" , unix ) ) ] # [ stable ( feature = "rust1" , since = "1.0.0" ) ] pub use sys :: ext as unix ; # [ cfg ( windows ) ] # [ stable ( feature = "rust1" , since = "1.0.0" ) ] pub use sys :: ext as windows ; # [ cfg ( any ( target_os = "linux" , target_os = "l4re" ) ) ] pub mod linux ; ) ) , }"#,
1267 "__cfg_if_items ! {(rustdoc ,) ;}"); 1266 "__cfg_if_items ! {(rustdoc ,) ;}");
1268} 1267}
1269 1268
@@ -1294,23 +1293,23 @@ fn test_cfg_if_main() {
1294 ); 1293 );
1295 1294
1296 assert_expansion(MacroKind::Items, &rules, r#" 1295 assert_expansion(MacroKind::Items, &rules, r#"
1297cfg_if ! { 1296cfg_if ! {
1298 if # [ cfg ( target_env = "msvc" ) ] { 1297 if # [ cfg ( target_env = "msvc" ) ] {
1299 // no extra unwinder support needed 1298 // no extra unwinder support needed
1300 } else if # [ cfg ( all ( target_arch = "wasm32" , not ( target_os = "emscripten" ) ) ) ] { 1299 } else if # [ cfg ( all ( target_arch = "wasm32" , not ( target_os = "emscripten" ) ) ) ] {
1301 // no unwinder on the system! 1300 // no unwinder on the system!
1302 } else { 1301 } else {
1303 mod libunwind ; 1302 mod libunwind ;
1304 pub use libunwind :: * ; 1303 pub use libunwind :: * ;
1305 } 1304 }
1306 } 1305 }
1307"#, 1306"#,
1308 "__cfg_if_items ! {() ; ((target_env = \"msvc\") ()) , ((all (target_arch = \"wasm32\" , not (target_os = \"emscripten\"))) ()) , (() (mod libunwind ; pub use libunwind :: * ;)) ,}"); 1307 "__cfg_if_items ! {() ; ((target_env = \"msvc\") ()) , ((all (target_arch = \"wasm32\" , not (target_os = \"emscripten\"))) ()) , (() (mod libunwind ; pub use libunwind :: * ;)) ,}");
1309 1308
1310 assert_expansion(MacroKind::Items, &rules, r#" 1309 assert_expansion(MacroKind::Items, &rules, r#"
1311cfg_if ! { @ __apply cfg ( all ( not ( any ( not ( any ( target_os = "solaris" , target_os = "illumos" ) ) ) ) ) ) , } 1310cfg_if ! { @ __apply cfg ( all ( not ( any ( not ( any ( target_os = "solaris" , target_os = "illumos" ) ) ) ) ) ) , }
1312"#, 1311"#,
1313 "" 1312 ""
1314 ); 1313 );
1315} 1314}
1316 1315
@@ -1329,16 +1328,16 @@ macro_rules! arbitrary {
1329 $logic 1328 $logic
1330 } 1329 }
1331 } 1330 }
1332 }; 1331 };
1333 1332
1334}"#, 1333}"#,
1335 ); 1334 );
1336 1335
1337 assert_expansion(MacroKind::Items, &rules, r#"arbitrary ! ( [ A : Arbitrary ] 1336 assert_expansion(MacroKind::Items, &rules, r#"arbitrary ! ( [ A : Arbitrary ]
1338 Vec < A > , 1337 Vec < A > ,
1339 VecStrategy < A :: Strategy > , 1338 VecStrategy < A :: Strategy > ,
1340 RangedParams1 < A :: Parameters > ; 1339 RangedParams1 < A :: Parameters > ;
1341 args => { let product_unpack ! [ range , a ] = args ; vec ( any_with :: < A > ( a ) , range ) } 1340 args => { let product_unpack ! [ range , a ] = args ; vec ( any_with :: < A > ( a ) , range ) }
1342 ) ;"#, 1341 ) ;"#,
1343 "impl <A : Arbitrary > $crate :: arbitrary :: Arbitrary for Vec < A > {type Parameters = RangedParams1 < A :: Parameters > ; type Strategy = VecStrategy < A :: Strategy > ; fn arbitrary_with (args : Self :: Parameters) -> Self :: Strategy {{let product_unpack ! [range , a] = args ; vec (any_with :: < A > (a) , range)}}}"); 1342 "impl <A : Arbitrary > $crate :: arbitrary :: Arbitrary for Vec < A > {type Parameters = RangedParams1 < A :: Parameters > ; type Strategy = VecStrategy < A :: Strategy > ; fn arbitrary_with (args : Self :: Parameters) -> Self :: Strategy {{let product_unpack ! [range , a] = args ; vec (any_with :: < A > (a) , range)}}}");
1344} 1343}
@@ -1350,7 +1349,7 @@ fn test_old_ridl() {
1350 let rules = create_rules( 1349 let rules = create_rules(
1351 r#" 1350 r#"
1352#[macro_export] 1351#[macro_export]
1353macro_rules! RIDL { 1352macro_rules! RIDL {
1354 (interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) 1353 (interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident)
1355 {$( 1354 {$(
1356 fn $method:ident(&mut self $(,$p:ident : $t:ty)*) -> $rtr:ty 1355 fn $method:ident(&mut self $(,$p:ident : $t:ty)*) -> $rtr:ty
@@ -1360,7 +1359,7 @@ macro_rules! RIDL {
1360 $(pub unsafe fn $method(&mut self) -> $rtr { 1359 $(pub unsafe fn $method(&mut self) -> $rtr {
1361 ((*self.lpVtbl).$method)(self $(,$p)*) 1360 ((*self.lpVtbl).$method)(self $(,$p)*)
1362 })+ 1361 })+
1363 } 1362 }
1364 }; 1363 };
1365}"#, 1364}"#,
1366 ); 1365 );
@@ -1388,11 +1387,11 @@ macro_rules! quick_error {
1388 quick_error!(ENUM_DEFINITION [enum $name $( #[$meta] )*] 1387 quick_error!(ENUM_DEFINITION [enum $name $( #[$meta] )*]
1389 body [] 1388 body []
1390 queue [$( 1389 queue [$(
1391 $( #[$imeta] )* 1390 $( #[$imeta] )*
1392 => 1391 =>
1393 $iitem: $imode [$( $ivar: $ityp ),*] 1392 $iitem: $imode [$( $ivar: $ityp ),*]
1394 )*] 1393 )*]
1395 ); 1394 );
1396}; 1395};
1397 1396
1398} 1397}
@@ -1403,7 +1402,7 @@ macro_rules! quick_error {
1403 &rules, 1402 &rules,
1404 r#" 1403 r#"
1405quick_error ! (SORT [enum Wrapped # [derive (Debug)]] items [ 1404quick_error ! (SORT [enum Wrapped # [derive (Debug)]] items [
1406 => One : UNIT [] {} 1405 => One : UNIT [] {}
1407 => Two : TUPLE [s :String] {display ("two: {}" , s) from ()} 1406 => Two : TUPLE [s :String] {display ("two: {}" , s) from ()}
1408 ] buf [] queue []) ; 1407 ] buf [] queue []) ;
1409"#, 1408"#,
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index f7e33366e..319110b6a 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -80,7 +80,9 @@ fn test_doc_comment_none() {
80 // non-doc 80 // non-doc
81 mod foo {} 81 mod foo {}
82 "#, 82 "#,
83 ); 83 )
84 .ok()
85 .unwrap();
84 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 86 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
85 assert!(module.doc_comment_text().is_none()); 87 assert!(module.doc_comment_text().is_none());
86} 88}
@@ -93,7 +95,9 @@ fn test_doc_comment_of_items() {
93 // non-doc 95 // non-doc
94 mod foo {} 96 mod foo {}
95 "#, 97 "#,
96 ); 98 )
99 .ok()
100 .unwrap();
97 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 101 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
98 assert_eq!("doc", module.doc_comment_text().unwrap()); 102 assert_eq!("doc", module.doc_comment_text().unwrap());
99} 103}
@@ -110,7 +114,9 @@ fn test_doc_comment_preserves_indents() {
110 /// ``` 114 /// ```
111 mod foo {} 115 mod foo {}
112 "#, 116 "#,
113 ); 117 )
118 .ok()
119 .unwrap();
114 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 120 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
115 assert_eq!("doc1\n```\nfn foo() {\n // ...\n}\n```", module.doc_comment_text().unwrap()); 121 assert_eq!("doc1\n```\nfn foo() {\n // ...\n}\n```", module.doc_comment_text().unwrap());
116} 122}
@@ -133,7 +139,9 @@ where
133 for<'a> F: Fn(&'a str) 139 for<'a> F: Fn(&'a str)
134{} 140{}
135 "#, 141 "#,
136 ); 142 )
143 .ok()
144 .unwrap();
137 let where_clause = file.syntax().descendants().find_map(WhereClause::cast).unwrap(); 145 let where_clause = file.syntax().descendants().find_map(WhereClause::cast).unwrap();
138 146
139 let mut predicates = where_clause.predicates(); 147 let mut predicates = where_clause.predicates();
diff --git a/crates/ra_syntax/src/fuzz.rs b/crates/ra_syntax/src/fuzz.rs
index af11b2e1a..6a9905bd1 100644
--- a/crates/ra_syntax/src/fuzz.rs
+++ b/crates/ra_syntax/src/fuzz.rs
@@ -5,12 +5,11 @@ use std::str::{self, FromStr};
5fn check_file_invariants(file: &SourceFile) { 5fn check_file_invariants(file: &SourceFile) {
6 let root = file.syntax(); 6 let root = file.syntax();
7 validation::validate_block_structure(root); 7 validation::validate_block_structure(root);
8 let _ = file.errors();
9} 8}
10 9
11pub fn check_parser(text: &str) { 10pub fn check_parser(text: &str) {
12 let file = SourceFile::parse(text); 11 let file = SourceFile::parse(text);
13 check_file_invariants(&file); 12 check_file_invariants(&file.tree);
14} 13}
15 14
16#[derive(Debug, Clone)] 15#[derive(Debug, Clone)]
@@ -44,16 +43,18 @@ impl CheckReparse {
44 } 43 }
45 44
46 pub fn run(&self) { 45 pub fn run(&self) {
47 let file = SourceFile::parse(&self.text); 46 let parse = SourceFile::parse(&self.text);
48 let new_file = file.reparse(&self.edit); 47 let new_parse = parse.reparse(&self.edit);
49 check_file_invariants(&new_file); 48 check_file_invariants(&new_parse.tree);
50 assert_eq!(&new_file.syntax().text().to_string(), &self.edited_text); 49 assert_eq!(&new_parse.tree.syntax().text().to_string(), &self.edited_text);
51 let full_reparse = SourceFile::parse(&self.edited_text); 50 let full_reparse = SourceFile::parse(&self.edited_text);
52 for (a, b) in new_file.syntax().descendants().zip(full_reparse.syntax().descendants()) { 51 for (a, b) in
52 new_parse.tree.syntax().descendants().zip(full_reparse.tree.syntax().descendants())
53 {
53 if (a.kind(), a.range()) != (b.kind(), b.range()) { 54 if (a.kind(), a.range()) != (b.kind(), b.range()) {
54 eprint!("original:\n{}", file.syntax().debug_dump()); 55 eprint!("original:\n{}", parse.tree.syntax().debug_dump());
55 eprint!("reparsed:\n{}", new_file.syntax().debug_dump()); 56 eprint!("reparsed:\n{}", new_parse.tree.syntax().debug_dump());
56 eprint!("full reparse:\n{}", full_reparse.syntax().debug_dump()); 57 eprint!("full reparse:\n{}", full_reparse.tree.syntax().debug_dump());
57 assert_eq!( 58 assert_eq!(
58 format!("{:?}", a), 59 format!("{:?}", a),
59 format!("{:?}", b), 60 format!("{:?}", b),
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index 0ceabc203..930a643b7 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -31,6 +31,12 @@ pub mod ast;
31#[doc(hidden)] 31#[doc(hidden)]
32pub mod fuzz; 32pub mod fuzz;
33 33
34use std::{sync::Arc, fmt::Write};
35
36use ra_text_edit::AtomTextEdit;
37
38use crate::syntax_node::GreenNode;
39
34pub use rowan::{SmolStr, TextRange, TextUnit}; 40pub use rowan::{SmolStr, TextRange, TextUnit};
35pub use ra_parser::SyntaxKind; 41pub use ra_parser::SyntaxKind;
36pub use ra_parser::T; 42pub use ra_parser::T;
@@ -43,45 +49,72 @@ pub use crate::{
43 parsing::{tokenize, classify_literal, Token}, 49 parsing::{tokenize, classify_literal, Token},
44}; 50};
45 51
46use ra_text_edit::AtomTextEdit; 52/// `Parse` is the result of the parsing: a syntax tree and a collection of
47use crate::syntax_node::GreenNode; 53/// errors.
48 54///
49/// `SourceFile` represents a parse tree for a single Rust file. 55/// Note that we always produce a syntax tree, even for completely invalid
50pub use crate::ast::SourceFile; 56/// files.
57#[derive(Debug, Clone, PartialEq, Eq)]
58pub struct Parse {
59 pub tree: TreeArc<SourceFile>,
60 pub errors: Arc<Vec<SyntaxError>>,
61}
51 62
52impl SourceFile { 63impl Parse {
53 fn new(green: GreenNode, errors: Vec<SyntaxError>) -> TreeArc<SourceFile> { 64 pub fn ok(self) -> Result<TreeArc<SourceFile>, Arc<Vec<SyntaxError>>> {
54 let root = SyntaxNode::new(green, errors); 65 if self.errors.is_empty() {
55 if cfg!(debug_assertions) { 66 Ok(self.tree)
56 validation::validate_block_structure(&root); 67 } else {
68 Err(self.errors)
57 } 69 }
58 assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
59 TreeArc::cast(root)
60 } 70 }
61 71
62 pub fn parse(text: &str) -> TreeArc<SourceFile> { 72 pub fn reparse(&self, edit: &AtomTextEdit) -> Parse {
63 let (green, errors) = parsing::parse_text(text); 73 self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
64 SourceFile::new(green, errors)
65 } 74 }
66 75
67 pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> { 76 pub fn debug_dump(&self) -> String {
68 self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) 77 let mut buf = self.tree.syntax().debug_dump();
78 for err in self.errors.iter() {
79 writeln!(buf, "err: `{}`", err).unwrap();
80 }
81 buf
69 } 82 }
70 83
71 pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreeArc<SourceFile>> { 84 fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<Parse> {
72 parsing::incremental_reparse(self.syntax(), edit, self.errors()) 85 // FIXME: validation errors are not handled here
73 .map(|(green_node, errors, _reparsed_range)| SourceFile::new(green_node, errors)) 86 parsing::incremental_reparse(self.tree.syntax(), edit, self.errors.to_vec()).map(
87 |(green_node, errors, _reparsed_range)| Parse {
88 tree: SourceFile::new(green_node),
89 errors: Arc::new(errors),
90 },
91 )
74 } 92 }
75 93
76 fn full_reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> { 94 fn full_reparse(&self, edit: &AtomTextEdit) -> Parse {
77 let text = edit.apply(self.syntax().text().to_string()); 95 let text = edit.apply(self.tree.syntax().text().to_string());
78 SourceFile::parse(&text) 96 SourceFile::parse(&text)
79 } 97 }
98}
99
100/// `SourceFile` represents a parse tree for a single Rust file.
101pub use crate::ast::SourceFile;
102
103impl SourceFile {
104 fn new(green: GreenNode) -> TreeArc<SourceFile> {
105 let root = SyntaxNode::new(green);
106 if cfg!(debug_assertions) {
107 validation::validate_block_structure(&root);
108 }
109 assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
110 TreeArc::cast(root)
111 }
80 112
81 pub fn errors(&self) -> Vec<SyntaxError> { 113 pub fn parse(text: &str) -> Parse {
82 let mut errors = self.syntax.root_data().to_vec(); 114 let (green, mut errors) = parsing::parse_text(text);
83 errors.extend(validation::validate(self)); 115 let tree = SourceFile::new(green);
84 errors 116 errors.extend(validation::validate(&tree));
117 Parse { tree, errors: Arc::new(errors) }
85 } 118 }
86} 119}
87 120
@@ -98,14 +131,15 @@ fn api_walkthrough() {
98 "; 131 ";
99 // `SourceFile` is the main entry point. 132 // `SourceFile` is the main entry point.
100 // 133 //
101 // Note how `parse` does not return a `Result`: even completely invalid 134 // The `parse` method returns a `Parse` -- a pair of syntax tree and a list
102 // source code might be parsed. 135 // of errors. That is, syntax tree is constructed even in presence of errors.
103 let file = SourceFile::parse(source_code); 136 let parse = SourceFile::parse(source_code);
137 assert!(parse.errors.is_empty());
104 138
105 // Due to the way ownership is set up, owned syntax Nodes always live behind 139 // Due to the way ownership is set up, owned syntax Nodes always live behind
106 // a `TreeArc` smart pointer. `TreeArc` is roughly an `std::sync::Arc` which 140 // a `TreeArc` smart pointer. `TreeArc` is roughly an `std::sync::Arc` which
107 // points to the whole file instead of an individual node. 141 // points to the whole file instead of an individual node.
108 let file: TreeArc<SourceFile> = file; 142 let file: TreeArc<SourceFile> = parse.tree;
109 143
110 // `SourceFile` is the root of the syntax tree. We can iterate file's items: 144 // `SourceFile` is the root of the syntax tree. We can iterate file's items:
111 let mut func = None; 145 let mut func = None;
diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs
index 3b6687f61..cf27a3393 100644
--- a/crates/ra_syntax/src/parsing/reparsing.rs
+++ b/crates/ra_syntax/src/parsing/reparsing.rs
@@ -166,9 +166,11 @@ fn merge_errors(
166 166
167#[cfg(test)] 167#[cfg(test)]
168mod tests { 168mod tests {
169 use std::sync::Arc;
170
169 use test_utils::{extract_range, assert_eq_text}; 171 use test_utils::{extract_range, assert_eq_text};
170 172
171 use crate::{SourceFile, AstNode}; 173 use crate::{SourceFile, AstNode, Parse};
172 use super::*; 174 use super::*;
173 175
174 fn do_check(before: &str, replace_with: &str, reparsed_len: u32) { 176 fn do_check(before: &str, replace_with: &str, reparsed_len: u32) {
@@ -181,14 +183,14 @@ mod tests {
181 let f = SourceFile::parse(&before); 183 let f = SourceFile::parse(&before);
182 let edit = AtomTextEdit { delete: range, insert: replace_with.to_string() }; 184 let edit = AtomTextEdit { delete: range, insert: replace_with.to_string() };
183 let (green, new_errors, range) = 185 let (green, new_errors, range) =
184 incremental_reparse(f.syntax(), &edit, f.errors()).unwrap(); 186 incremental_reparse(f.tree.syntax(), &edit, f.errors.to_vec()).unwrap();
185 assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length"); 187 assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length");
186 SourceFile::new(green, new_errors) 188 Parse { tree: SourceFile::new(green), errors: Arc::new(new_errors) }
187 }; 189 };
188 190
189 assert_eq_text!( 191 assert_eq_text!(
190 &fully_reparsed.syntax().debug_dump(), 192 &fully_reparsed.tree.syntax().debug_dump(),
191 &incrementally_reparsed.syntax().debug_dump(), 193 &incrementally_reparsed.tree.syntax().debug_dump(),
192 ); 194 );
193 } 195 }
194 196
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs
index cee9503ca..10cddb852 100644
--- a/crates/ra_syntax/src/ptr.rs
+++ b/crates/ra_syntax/src/ptr.rs
@@ -76,7 +76,7 @@ impl<N: AstNode> From<AstPtr<N>> for SyntaxNodePtr {
76fn test_local_syntax_ptr() { 76fn test_local_syntax_ptr() {
77 use crate::{ast, AstNode, SourceFile}; 77 use crate::{ast, AstNode, SourceFile};
78 78
79 let file = SourceFile::parse("struct Foo { f: u32, }"); 79 let file = SourceFile::parse("struct Foo { f: u32, }").ok().unwrap();
80 let field = file.syntax().descendants().find_map(ast::NamedFieldDef::cast).unwrap(); 80 let field = file.syntax().descendants().find_map(ast::NamedFieldDef::cast).unwrap();
81 let ptr = SyntaxNodePtr::new(field.syntax()); 81 let ptr = SyntaxNodePtr::new(field.syntax());
82 let field_syntax = ptr.to_node(file.syntax()); 82 let field_syntax = ptr.to_node(file.syntax());
diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs
index 80054f529..4105b5220 100644
--- a/crates/ra_syntax/src/syntax_node.rs
+++ b/crates/ra_syntax/src/syntax_node.rs
@@ -9,7 +9,6 @@
9use std::{ 9use std::{
10 ops::RangeInclusive, 10 ops::RangeInclusive,
11 fmt::{self, Write}, 11 fmt::{self, Write},
12 any::Any,
13 borrow::Borrow, 12 borrow::Borrow,
14 iter::successors, 13 iter::successors,
15}; 14};
@@ -133,10 +132,8 @@ pub enum Direction {
133} 132}
134 133
135impl SyntaxNode { 134impl SyntaxNode {
136 pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> TreeArc<SyntaxNode> { 135 pub(crate) fn new(green: GreenNode) -> TreeArc<SyntaxNode> {
137 let errors: Option<Box<Any + Send + Sync>> = 136 let ptr = TreeArc(rowan::SyntaxNode::new(green, None));
138 if errors.is_empty() { None } else { Some(Box::new(errors)) };
139 let ptr = TreeArc(rowan::SyntaxNode::new(green, errors));
140 TreeArc::cast(ptr) 137 TreeArc::cast(ptr)
141 } 138 }
142 139
@@ -259,37 +256,18 @@ impl SyntaxNode {
259 } 256 }
260 257
261 pub fn debug_dump(&self) -> String { 258 pub fn debug_dump(&self) -> String {
262 let mut errors: Vec<_> = match self.ancestors().find_map(SourceFile::cast) {
263 Some(file) => file.errors(),
264 None => self.root_data().to_vec(),
265 };
266 errors.sort_by_key(|e| e.offset());
267 let mut err_pos = 0;
268 let mut level = 0; 259 let mut level = 0;
269 let mut buf = String::new(); 260 let mut buf = String::new();
270 macro_rules! indent {
271 () => {
272 for _ in 0..level {
273 buf.push_str(" ");
274 }
275 };
276 }
277 261
278 for event in self.preorder_with_tokens() { 262 for event in self.preorder_with_tokens() {
279 match event { 263 match event {
280 WalkEvent::Enter(element) => { 264 WalkEvent::Enter(element) => {
281 indent!(); 265 for _ in 0..level {
266 buf.push_str(" ");
267 }
282 match element { 268 match element {
283 SyntaxElement::Node(node) => writeln!(buf, "{:?}", node).unwrap(), 269 SyntaxElement::Node(node) => writeln!(buf, "{:?}", node).unwrap(),
284 SyntaxElement::Token(token) => { 270 SyntaxElement::Token(token) => writeln!(buf, "{:?}", token).unwrap(),
285 writeln!(buf, "{:?}", token).unwrap();
286 let off = token.range().end();
287 while err_pos < errors.len() && errors[err_pos].offset() <= off {
288 indent!();
289 writeln!(buf, "err: `{}`", errors[err_pos]).unwrap();
290 err_pos += 1;
291 }
292 }
293 } 271 }
294 level += 1; 272 level += 1;
295 } 273 }
@@ -298,23 +276,10 @@ impl SyntaxNode {
298 } 276 }
299 277
300 assert_eq!(level, 0); 278 assert_eq!(level, 0);
301 for err in errors[err_pos..].iter() {
302 writeln!(buf, "err: `{}`", err).unwrap();
303 }
304 279
305 buf 280 buf
306 } 281 }
307 282
308 pub(crate) fn root_data(&self) -> &[SyntaxError] {
309 match self.0.root_data() {
310 None => &[],
311 Some(data) => {
312 let data: &Vec<SyntaxError> = std::any::Any::downcast_ref(data).unwrap();
313 data.as_slice()
314 }
315 }
316 }
317
318 pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode { 283 pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode {
319 self.0.replace_with(replacement) 284 self.0.replace_with(replacement)
320 } 285 }
@@ -386,7 +351,7 @@ impl SyntaxNode {
386 let len = new_children.iter().map(|it| it.text_len()).sum::<TextUnit>(); 351 let len = new_children.iter().map(|it| it.text_len()).sum::<TextUnit>();
387 let new_node = GreenNode::new(rowan::SyntaxKind(self.kind() as u16), new_children); 352 let new_node = GreenNode::new(rowan::SyntaxKind(self.kind() as u16), new_children);
388 let new_file_node = self.replace_with(new_node); 353 let new_file_node = self.replace_with(new_node);
389 let file = SourceFile::new(new_file_node, Vec::new()); 354 let file = SourceFile::new(new_file_node);
390 355
391 // FIXME: use a more elegant way to re-fetch the node (#1185), make 356 // FIXME: use a more elegant way to re-fetch the node (#1185), make
392 // `range` private afterwards 357 // `range` private afterwards
@@ -629,13 +594,13 @@ impl SyntaxTreeBuilder {
629 (green, self.errors) 594 (green, self.errors)
630 } 595 }
631 596
632 pub fn finish(self) -> TreeArc<SyntaxNode> { 597 pub fn finish(self) -> (TreeArc<SyntaxNode>, Vec<SyntaxError>) {
633 let (green, errors) = self.finish_raw(); 598 let (green, errors) = self.finish_raw();
634 let node = SyntaxNode::new(green, errors); 599 let node = SyntaxNode::new(green);
635 if cfg!(debug_assertions) { 600 if cfg!(debug_assertions) {
636 crate::validation::validate_block_structure(&node); 601 crate::validation::validate_block_structure(&node);
637 } 602 }
638 node 603 (node, errors)
639 } 604 }
640 605
641 pub fn token(&mut self, kind: SyntaxKind, text: SmolStr) { 606 pub fn token(&mut self, kind: SyntaxKind, text: SmolStr) {
diff --git a/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt b/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt
index 21ef31ba8..0662052c5 100644
--- a/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt
@@ -18,7 +18,6 @@ SOURCE_FILE@[0; 34)
18 PATH_SEGMENT@[18; 21) 18 PATH_SEGMENT@[18; 21)
19 NAME_REF@[18; 21) 19 NAME_REF@[18; 21)
20 IDENT@[18; 21) "u32" 20 IDENT@[18; 21) "u32"
21 err: `expected COMMA`
22 WHITESPACE@[21; 26) "\n " 21 WHITESPACE@[21; 26) "\n "
23 NAMED_FIELD_DEF@[26; 32) 22 NAMED_FIELD_DEF@[26; 32)
24 NAME@[26; 27) 23 NAME@[26; 27)
@@ -32,3 +31,4 @@ SOURCE_FILE@[0; 34)
32 IDENT@[29; 32) "u32" 31 IDENT@[29; 32) "u32"
33 WHITESPACE@[32; 33) "\n" 32 WHITESPACE@[32; 33) "\n"
34 R_CURLY@[33; 34) "}" 33 R_CURLY@[33; 34) "}"
34err: `expected COMMA`
diff --git a/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt b/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt
index d7762c089..45044fe0a 100644
--- a/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt
@@ -1,9 +1,7 @@
1SOURCE_FILE@[0; 21) 1SOURCE_FILE@[0; 21)
2 ERROR@[0; 2) 2 ERROR@[0; 2)
3 IF_KW@[0; 2) "if" 3 IF_KW@[0; 2) "if"
4 err: `expected an item`
5 WHITESPACE@[2; 3) " " 4 WHITESPACE@[2; 3) " "
6 err: `expected an item`
7 ERROR@[3; 8) 5 ERROR@[3; 8)
8 MATCH_KW@[3; 8) "match" 6 MATCH_KW@[3; 8) "match"
9 WHITESPACE@[8; 10) "\n\n" 7 WHITESPACE@[8; 10) "\n\n"
@@ -16,3 +14,5 @@ SOURCE_FILE@[0; 21)
16 NAMED_FIELD_DEF_LIST@[19; 21) 14 NAMED_FIELD_DEF_LIST@[19; 21)
17 L_CURLY@[19; 20) "{" 15 L_CURLY@[19; 20) "{"
18 R_CURLY@[20; 21) "}" 16 R_CURLY@[20; 21) "}"
17err: `expected an item`
18err: `expected an item`
diff --git a/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt b/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt
index 76642f43b..1506acdfd 100644
--- a/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt
@@ -1,7 +1,7 @@
1SOURCE_FILE@[0; 42) 1SOURCE_FILE@[0; 42)
2 SHEBANG@[0; 20) "#!/use/bin/env rusti" 2 SHEBANG@[0; 20) "#!/use/bin/env rusti"
3 WHITESPACE@[20; 21) "\n" 3 WHITESPACE@[20; 21) "\n"
4 err: `expected an item`
5 ERROR@[21; 41) 4 ERROR@[21; 41)
6 SHEBANG@[21; 41) "#!/use/bin/env rusti" 5 SHEBANG@[21; 41) "#!/use/bin/env rusti"
7 WHITESPACE@[41; 42) "\n" 6 WHITESPACE@[41; 42) "\n"
7err: `expected an item`
diff --git a/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt
index b52aaa368..586baf1bb 100644
--- a/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt
@@ -33,7 +33,7 @@ SOURCE_FILE@[0; 40)
33 COMMA@[36; 37) "," 33 COMMA@[36; 37) ","
34 WHITESPACE@[37; 38) "\n" 34 WHITESPACE@[37; 38) "\n"
35 R_CURLY@[38; 39) "}" 35 R_CURLY@[38; 39) "}"
36 err: `expected item, found `;`
37consider removing this semicolon`
38 ERROR@[39; 40) 36 ERROR@[39; 40)
39 SEMI@[39; 40) ";" 37 SEMI@[39; 40) ";"
38err: `expected item, found `;`
39consider removing this semicolon`
diff --git a/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt b/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt
index fb44f21ea..a70223912 100644
--- a/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt
@@ -9,8 +9,8 @@ SOURCE_FILE@[0; 12)
9 NAME_REF@[4; 7) 9 NAME_REF@[4; 7)
10 IDENT@[4; 7) "foo" 10 IDENT@[4; 7) "foo"
11 COLONCOLON@[7; 9) "::" 11 COLONCOLON@[7; 9) "::"
12 err: `expected identifier`
13 PATH_SEGMENT@[9; 11) 12 PATH_SEGMENT@[9; 11)
14 ERROR@[9; 11) 13 ERROR@[9; 11)
15 INT_NUMBER@[9; 11) "92" 14 INT_NUMBER@[9; 11) "92"
16 SEMI@[11; 12) ";" 15 SEMI@[11; 12) ";"
16err: `expected identifier`
diff --git a/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt b/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt
index 1e27522bf..9a6da88fe 100644
--- a/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt
@@ -49,7 +49,7 @@ SOURCE_FILE@[0; 54)
49 L_CURLY@[50; 51) "{" 49 L_CURLY@[50; 51) "{"
50 WHITESPACE@[51; 52) "\n" 50 WHITESPACE@[51; 52) "\n"
51 R_CURLY@[52; 53) "}" 51 R_CURLY@[52; 53) "}"
52 err: `expected R_PAREN`
53 err: `expected R_BRACK`
54 err: `expected an item`
55 WHITESPACE@[53; 54) "\n" 52 WHITESPACE@[53; 54) "\n"
53err: `expected R_PAREN`
54err: `expected R_BRACK`
55err: `expected an item`
diff --git a/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt b/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt
index d47b98ed4..5effbb60f 100644
--- a/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt
@@ -23,25 +23,17 @@ SOURCE_FILE@[0; 74)
23 VISIBILITY@[27; 30) 23 VISIBILITY@[27; 30)
24 PUB_KW@[27; 30) "pub" 24 PUB_KW@[27; 30) "pub"
25 WHITESPACE@[30; 31) " " 25 WHITESPACE@[30; 31) " "
26 err: `expected field declaration`
27 ERROR@[31; 33) 26 ERROR@[31; 33)
28 INT_NUMBER@[31; 33) "92" 27 INT_NUMBER@[31; 33) "92"
29 err: `expected COMMA`
30 WHITESPACE@[33; 38) "\n " 28 WHITESPACE@[33; 38) "\n "
31 err: `expected field declaration`
32 ERROR@[38; 39) 29 ERROR@[38; 39)
33 PLUS@[38; 39) "+" 30 PLUS@[38; 39) "+"
34 err: `expected COMMA`
35 WHITESPACE@[39; 40) " " 31 WHITESPACE@[39; 40) " "
36 err: `expected field declaration`
37 ERROR@[40; 41) 32 ERROR@[40; 41)
38 MINUS@[40; 41) "-" 33 MINUS@[40; 41) "-"
39 err: `expected COMMA`
40 WHITESPACE@[41; 42) " " 34 WHITESPACE@[41; 42) " "
41 err: `expected field declaration`
42 ERROR@[42; 43) 35 ERROR@[42; 43)
43 STAR@[42; 43) "*" 36 STAR@[42; 43) "*"
44 err: `expected COMMA`
45 WHITESPACE@[43; 48) "\n " 37 WHITESPACE@[43; 48) "\n "
46 NAMED_FIELD_DEF@[48; 58) 38 NAMED_FIELD_DEF@[48; 58)
47 VISIBILITY@[48; 51) 39 VISIBILITY@[48; 51)
@@ -72,3 +64,11 @@ SOURCE_FILE@[0; 74)
72 WHITESPACE@[71; 72) "\n" 64 WHITESPACE@[71; 72) "\n"
73 R_CURLY@[72; 73) "}" 65 R_CURLY@[72; 73) "}"
74 WHITESPACE@[73; 74) "\n" 66 WHITESPACE@[73; 74) "\n"
67err: `expected field declaration`
68err: `expected COMMA`
69err: `expected field declaration`
70err: `expected COMMA`
71err: `expected field declaration`
72err: `expected COMMA`
73err: `expected field declaration`
74err: `expected COMMA`
diff --git a/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt b/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt
index 94066ed05..ff59f5d71 100644
--- a/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt
@@ -1,7 +1,6 @@
1SOURCE_FILE@[0; 31) 1SOURCE_FILE@[0; 31)
2 ERROR@[0; 1) 2 ERROR@[0; 1)
3 R_CURLY@[0; 1) "}" 3 R_CURLY@[0; 1) "}"
4 err: `unmatched `}``
5 WHITESPACE@[1; 3) "\n\n" 4 WHITESPACE@[1; 3) "\n\n"
6 STRUCT_DEF@[3; 12) 5 STRUCT_DEF@[3; 12)
7 STRUCT_KW@[3; 9) "struct" 6 STRUCT_KW@[3; 9) "struct"
@@ -10,7 +9,6 @@ SOURCE_FILE@[0; 31)
10 IDENT@[10; 11) "S" 9 IDENT@[10; 11) "S"
11 SEMI@[11; 12) ";" 10 SEMI@[11; 12) ";"
12 WHITESPACE@[12; 14) "\n\n" 11 WHITESPACE@[12; 14) "\n\n"
13 err: `unmatched `}``
14 ERROR@[14; 15) 12 ERROR@[14; 15)
15 R_CURLY@[14; 15) "}" 13 R_CURLY@[14; 15) "}"
16 WHITESPACE@[15; 17) "\n\n" 14 WHITESPACE@[15; 17) "\n\n"
@@ -26,7 +24,9 @@ SOURCE_FILE@[0; 31)
26 L_CURLY@[25; 26) "{" 24 L_CURLY@[25; 26) "{"
27 R_CURLY@[26; 27) "}" 25 R_CURLY@[26; 27) "}"
28 WHITESPACE@[27; 29) "\n\n" 26 WHITESPACE@[27; 29) "\n\n"
29 err: `unmatched `}``
30 ERROR@[29; 30) 27 ERROR@[29; 30)
31 R_CURLY@[29; 30) "}" 28 R_CURLY@[29; 30) "}"
32 WHITESPACE@[30; 31) "\n" 29 WHITESPACE@[30; 31) "\n"
30err: `unmatched `}``
31err: `unmatched `}``
32err: `unmatched `}``
diff --git a/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt b/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt
index 6f5a27856..75f6b3b9c 100644
--- a/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt
@@ -18,13 +18,10 @@ SOURCE_FILE@[0; 95)
18 PATH_SEGMENT@[14; 17) 18 PATH_SEGMENT@[14; 17)
19 NAME_REF@[14; 17) 19 NAME_REF@[14; 17)
20 IDENT@[14; 17) "bar" 20 IDENT@[14; 17) "bar"
21 err: `expected EXCL`
22 TOKEN_TREE@[17; 19) 21 TOKEN_TREE@[17; 19)
23 L_PAREN@[17; 18) "(" 22 L_PAREN@[17; 18) "("
24 R_PAREN@[18; 19) ")" 23 R_PAREN@[18; 19) ")"
25 err: `expected SEMI`
26 WHITESPACE@[19; 20) " " 24 WHITESPACE@[19; 20) " "
27 err: `expected an item`
28 ERROR@[20; 80) 25 ERROR@[20; 80)
29 L_CURLY@[20; 21) "{" 26 L_CURLY@[20; 21) "{"
30 WHITESPACE@[21; 26) "\n " 27 WHITESPACE@[21; 26) "\n "
@@ -75,3 +72,6 @@ SOURCE_FILE@[0; 95)
75 WHITESPACE@[92; 93) "\n" 72 WHITESPACE@[92; 93) "\n"
76 R_CURLY@[93; 94) "}" 73 R_CURLY@[93; 94) "}"
77 WHITESPACE@[94; 95) "\n" 74 WHITESPACE@[94; 95) "\n"
75err: `expected EXCL`
76err: `expected SEMI`
77err: `expected an item`
diff --git a/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt b/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt
index 80568b5bd..8aa8c3ef4 100644
--- a/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt
@@ -6,25 +6,17 @@ SOURCE_FILE@[0; 43)
6 IDENT@[7; 8) "S" 6 IDENT@[7; 8) "S"
7 TYPE_PARAM_LIST@[8; 11) 7 TYPE_PARAM_LIST@[8; 11)
8 L_ANGLE@[8; 9) "<" 8 L_ANGLE@[8; 9) "<"
9 err: `expected type parameter`
10 ERROR@[9; 11) 9 ERROR@[9; 11)
11 INT_NUMBER@[9; 11) "90" 10 INT_NUMBER@[9; 11) "90"
12 err: `expected COMMA`
13 err: `expected R_ANGLE`
14 err: `expected `;`, `{`, or `(``
15 WHITESPACE@[11; 12) " " 11 WHITESPACE@[11; 12) " "
16 err: `expected an item`
17 ERROR@[12; 13) 12 ERROR@[12; 13)
18 PLUS@[12; 13) "+" 13 PLUS@[12; 13) "+"
19 WHITESPACE@[13; 14) " " 14 WHITESPACE@[13; 14) " "
20 err: `expected an item`
21 ERROR@[14; 15) 15 ERROR@[14; 15)
22 INT_NUMBER@[14; 15) "2" 16 INT_NUMBER@[14; 15) "2"
23 err: `expected an item`
24 ERROR@[15; 16) 17 ERROR@[15; 16)
25 R_ANGLE@[15; 16) ">" 18 R_ANGLE@[15; 16) ">"
26 WHITESPACE@[16; 17) " " 19 WHITESPACE@[16; 17) " "
27 err: `expected an item`
28 ERROR@[17; 31) 20 ERROR@[17; 31)
29 L_CURLY@[17; 18) "{" 21 L_CURLY@[17; 18) "{"
30 WHITESPACE@[18; 23) "\n " 22 WHITESPACE@[18; 23) "\n "
@@ -34,12 +26,9 @@ SOURCE_FILE@[0; 43)
34 PATH_SEGMENT@[23; 24) 26 PATH_SEGMENT@[23; 24)
35 NAME_REF@[23; 24) 27 NAME_REF@[23; 24)
36 IDENT@[23; 24) "f" 28 IDENT@[23; 24) "f"
37 err: `expected SEMI`
38 err: `expected expression`
39 EXPR_STMT@[24; 25) 29 EXPR_STMT@[24; 25)
40 ERROR@[24; 25) 30 ERROR@[24; 25)
41 COLON@[24; 25) ":" 31 COLON@[24; 25) ":"
42 err: `expected SEMI`
43 WHITESPACE@[25; 26) " " 32 WHITESPACE@[25; 26) " "
44 PATH_EXPR@[26; 29) 33 PATH_EXPR@[26; 29)
45 PATH@[26; 29) 34 PATH@[26; 29)
@@ -56,3 +45,14 @@ SOURCE_FILE@[0; 43)
56 IDENT@[40; 41) "T" 45 IDENT@[40; 41) "T"
57 SEMI@[41; 42) ";" 46 SEMI@[41; 42) ";"
58 WHITESPACE@[42; 43) "\n" 47 WHITESPACE@[42; 43) "\n"
48err: `expected type parameter`
49err: `expected COMMA`
50err: `expected R_ANGLE`
51err: `expected `;`, `{`, or `(``
52err: `expected an item`
53err: `expected an item`
54err: `expected an item`
55err: `expected an item`
56err: `expected SEMI`
57err: `expected expression`
58err: `expected SEMI`
diff --git a/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt b/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt
index 36982085a..22a1727f0 100644
--- a/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt
@@ -23,7 +23,6 @@ SOURCE_FILE@[0; 42)
23 TUPLE_TYPE@[22; 24) 23 TUPLE_TYPE@[22; 24)
24 L_PAREN@[22; 23) "(" 24 L_PAREN@[22; 23) "("
25 R_PAREN@[23; 24) ")" 25 R_PAREN@[23; 24) ")"
26 err: `expected `{``
27 WHITESPACE@[24; 25) " " 26 WHITESPACE@[24; 25) " "
28 BLOCK_EXPR@[25; 38) 27 BLOCK_EXPR@[25; 38)
29 UNSAFE_KW@[25; 31) "unsafe" 28 UNSAFE_KW@[25; 31) "unsafe"
@@ -40,3 +39,4 @@ SOURCE_FILE@[0; 42)
40 WHITESPACE@[39; 40) "\n" 39 WHITESPACE@[39; 40) "\n"
41 R_CURLY@[40; 41) "}" 40 R_CURLY@[40; 41) "}"
42 WHITESPACE@[41; 42) "\n" 41 WHITESPACE@[41; 42) "\n"
42err: `expected `{``
diff --git a/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt
index 3fb0a77ef..ee2a29d9f 100644
--- a/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt
@@ -2,7 +2,6 @@ SOURCE_FILE@[0; 19)
2 ERROR@[0; 6) 2 ERROR@[0; 6)
3 ABI@[0; 6) 3 ABI@[0; 6)
4 EXTERN_KW@[0; 6) "extern" 4 EXTERN_KW@[0; 6) "extern"
5 err: `expected fn, trait or impl`
6 WHITESPACE@[6; 7) " " 5 WHITESPACE@[6; 7) " "
7 STRUCT_DEF@[7; 18) 6 STRUCT_DEF@[7; 18)
8 STRUCT_KW@[7; 13) "struct" 7 STRUCT_KW@[7; 13) "struct"
@@ -11,3 +10,4 @@ SOURCE_FILE@[0; 19)
11 IDENT@[14; 17) "Foo" 10 IDENT@[14; 17) "Foo"
12 SEMI@[17; 18) ";" 11 SEMI@[17; 18) ";"
13 WHITESPACE@[18; 19) "\n" 12 WHITESPACE@[18; 19) "\n"
13err: `expected fn, trait or impl`
diff --git a/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt b/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt
index 47b992b0a..1f5cc55c0 100644
--- a/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt
@@ -43,17 +43,9 @@ SOURCE_FILE@[0; 86)
43 IDENT@[63; 66) "Box" 43 IDENT@[63; 66) "Box"
44 TYPE_ARG_LIST@[66; 68) 44 TYPE_ARG_LIST@[66; 68)
45 L_ANGLE@[66; 67) "<" 45 L_ANGLE@[66; 67) "<"
46 err: `expected type`
47 TYPE_ARG@[67; 68) 46 TYPE_ARG@[67; 68)
48 ERROR@[67; 68) 47 ERROR@[67; 68)
49 AT@[67; 68) "@" 48 AT@[67; 68) "@"
50 err: `expected COMMA`
51 err: `expected R_ANGLE`
52 err: `expected COMMA`
53 err: `expected R_ANGLE`
54 err: `expected COMMA`
55 err: `expected R_ANGLE`
56 err: `expected COMMA`
57 WHITESPACE@[68; 69) " " 49 WHITESPACE@[68; 69) " "
58 POS_FIELD_DEF@[69; 72) 50 POS_FIELD_DEF@[69; 72)
59 PATH_TYPE@[69; 72) 51 PATH_TYPE@[69; 72)
@@ -61,29 +53,37 @@ SOURCE_FILE@[0; 86)
61 PATH_SEGMENT@[69; 72) 53 PATH_SEGMENT@[69; 72)
62 NAME_REF@[69; 72) 54 NAME_REF@[69; 72)
63 IDENT@[69; 72) "Any" 55 IDENT@[69; 72) "Any"
64 err: `expected COMMA`
65 err: `expected a type`
66 err: `expected R_PAREN`
67 err: `expected SEMI`
68 err: `expected an item`
69 ERROR@[72; 72) 56 ERROR@[72; 72)
70 ERROR@[72; 73) 57 ERROR@[72; 73)
71 R_ANGLE@[72; 73) ">" 58 R_ANGLE@[72; 73) ">"
72 err: `expected an item`
73 ERROR@[73; 74) 59 ERROR@[73; 74)
74 COMMA@[73; 74) "," 60 COMMA@[73; 74) ","
75 WHITESPACE@[74; 79) "\n " 61 WHITESPACE@[74; 79) "\n "
76 err: `expected an item`
77 ERROR@[79; 80) 62 ERROR@[79; 80)
78 R_ANGLE@[79; 80) ">" 63 R_ANGLE@[79; 80) ">"
79 err: `expected an item`
80 ERROR@[80; 81) 64 ERROR@[80; 81)
81 R_ANGLE@[80; 81) ">" 65 R_ANGLE@[80; 81) ">"
82 WHITESPACE@[81; 82) "\n" 66 WHITESPACE@[81; 82) "\n"
83 err: `expected an item`
84 ERROR@[82; 83) 67 ERROR@[82; 83)
85 R_PAREN@[82; 83) ")" 68 R_PAREN@[82; 83) ")"
86 err: `expected an item`
87 ERROR@[83; 84) 69 ERROR@[83; 84)
88 SEMI@[83; 84) ";" 70 SEMI@[83; 84) ";"
89 WHITESPACE@[84; 86) "\n\n" 71 WHITESPACE@[84; 86) "\n\n"
72err: `expected type`
73err: `expected COMMA`
74err: `expected R_ANGLE`
75err: `expected COMMA`
76err: `expected R_ANGLE`
77err: `expected COMMA`
78err: `expected R_ANGLE`
79err: `expected COMMA`
80err: `expected COMMA`
81err: `expected a type`
82err: `expected R_PAREN`
83err: `expected SEMI`
84err: `expected an item`
85err: `expected an item`
86err: `expected an item`
87err: `expected an item`
88err: `expected an item`
89err: `expected an item`
diff --git a/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt b/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt
index 52ad7bef7..276a58b69 100644
--- a/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt
@@ -23,9 +23,9 @@ SOURCE_FILE@[0; 23)
23 PATH_SEGMENT@[18; 19) 23 PATH_SEGMENT@[18; 19)
24 NAME_REF@[18; 19) 24 NAME_REF@[18; 19)
25 IDENT@[18; 19) "T" 25 IDENT@[18; 19) "T"
26 err: `expected colon`
27 WHITESPACE@[19; 20) " " 26 WHITESPACE@[19; 20) " "
28 BLOCK@[20; 22) 27 BLOCK@[20; 22)
29 L_CURLY@[20; 21) "{" 28 L_CURLY@[20; 21) "{"
30 R_CURLY@[21; 22) "}" 29 R_CURLY@[21; 22) "}"
31 WHITESPACE@[22; 23) "\n" 30 WHITESPACE@[22; 23) "\n"
31err: `expected colon`
diff --git a/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt b/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt
index 1350980f2..8f93b832d 100644
--- a/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt
@@ -6,19 +6,19 @@ SOURCE_FILE@[0; 14)
6 IDENT@[3; 6) "foo" 6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 7) 7 PARAM_LIST@[6; 7)
8 L_PAREN@[6; 7) "(" 8 L_PAREN@[6; 7) "("
9 err: `expected value parameter`
10 err: `expected R_PAREN`
11 err: `expected a block`
12 err: `unmatched `}``
13 ERROR@[7; 8) 9 ERROR@[7; 8)
14 R_CURLY@[7; 8) "}" 10 R_CURLY@[7; 8) "}"
15 err: `expected an item`
16 ERROR@[8; 9) 11 ERROR@[8; 9)
17 R_PAREN@[8; 9) ")" 12 R_PAREN@[8; 9) ")"
18 WHITESPACE@[9; 10) " " 13 WHITESPACE@[9; 10) " "
19 err: `expected an item`
20 ERROR@[10; 13) 14 ERROR@[10; 13)
21 L_CURLY@[10; 11) "{" 15 L_CURLY@[10; 11) "{"
22 WHITESPACE@[11; 12) "\n" 16 WHITESPACE@[11; 12) "\n"
23 R_CURLY@[12; 13) "}" 17 R_CURLY@[12; 13) "}"
24 WHITESPACE@[13; 14) "\n" 18 WHITESPACE@[13; 14) "\n"
19err: `expected value parameter`
20err: `expected R_PAREN`
21err: `expected a block`
22err: `unmatched `}``
23err: `expected an item`
24err: `expected an item`
diff --git a/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt b/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt
index dd60814a0..105e45a35 100644
--- a/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt
@@ -29,7 +29,6 @@ SOURCE_FILE@[0; 56)
29 INT_NUMBER@[31; 32) "2" 29 INT_NUMBER@[31; 32) "2"
30 WHITESPACE@[32; 37) "\n " 30 WHITESPACE@[32; 37) "\n "
31 R_PAREN@[37; 38) ")" 31 R_PAREN@[37; 38) ")"
32 err: `expected SEMI`
33 WHITESPACE@[38; 43) "\n " 32 WHITESPACE@[38; 43) "\n "
34 EXPR_STMT@[43; 53) 33 EXPR_STMT@[43; 53)
35 RETURN_EXPR@[43; 52) 34 RETURN_EXPR@[43; 52)
@@ -41,3 +40,4 @@ SOURCE_FILE@[0; 56)
41 WHITESPACE@[53; 54) "\n" 40 WHITESPACE@[53; 54) "\n"
42 R_CURLY@[54; 55) "}" 41 R_CURLY@[54; 55) "}"
43 WHITESPACE@[55; 56) "\n" 42 WHITESPACE@[55; 56) "\n"
43err: `expected SEMI`
diff --git a/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt b/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt
index f115eb1dd..751740620 100644
--- a/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt
@@ -40,7 +40,7 @@ SOURCE_FILE@[0; 47)
40 INT_NUMBER@[41; 42) "1" 40 INT_NUMBER@[41; 42) "1"
41 WHITESPACE@[42; 43) " " 41 WHITESPACE@[42; 43) " "
42 PLUS@[43; 44) "+" 42 PLUS@[43; 44) "+"
43 err: `expected expression`
44 WHITESPACE@[44; 45) "\n" 43 WHITESPACE@[44; 45) "\n"
45 R_CURLY@[45; 46) "}" 44 R_CURLY@[45; 46) "}"
46 WHITESPACE@[46; 47) "\n" 45 WHITESPACE@[46; 47) "\n"
46err: `expected expression`
diff --git a/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt
index 9996cf824..82908b8f2 100644
--- a/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt
@@ -21,9 +21,6 @@ SOURCE_FILE@[0; 183)
21 PARAM@[33; 34) 21 PARAM@[33; 34)
22 REF_PAT@[33; 34) 22 REF_PAT@[33; 34)
23 AMP@[33; 34) "&" 23 AMP@[33; 34) "&"
24 err: `expected pattern`
25 err: `expected COLON`
26 err: `expected type`
27 R_PAREN@[34; 35) ")" 24 R_PAREN@[34; 35) ")"
28 WHITESPACE@[35; 36) " " 25 WHITESPACE@[35; 36) " "
29 RET_TYPE@[36; 46) 26 RET_TYPE@[36; 46)
@@ -124,8 +121,11 @@ SOURCE_FILE@[0; 183)
124 WHITESPACE@[169; 170) " " 121 WHITESPACE@[169; 170) " "
125 NAME@[170; 180) 122 NAME@[170; 180)
126 IDENT@[170; 180) "set_parent" 123 IDENT@[170; 180) "set_parent"
127 err: `expected function arguments`
128 err: `expected a block`
129 WHITESPACE@[180; 181) "\n" 124 WHITESPACE@[180; 181) "\n"
130 R_CURLY@[181; 182) "}" 125 R_CURLY@[181; 182) "}"
131 WHITESPACE@[182; 183) "\n" 126 WHITESPACE@[182; 183) "\n"
127err: `expected pattern`
128err: `expected COLON`
129err: `expected type`
130err: `expected function arguments`
131err: `expected a block`
diff --git a/crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt b/crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt
index c12649d5e..4a1b84ee5 100644
--- a/crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt
@@ -19,8 +19,6 @@ SOURCE_FILE@[0; 139)
19 IDENT@[19; 22) "foo" 19 IDENT@[19; 22) "foo"
20 WHITESPACE@[22; 23) " " 20 WHITESPACE@[22; 23) " "
21 EQ@[23; 24) "=" 21 EQ@[23; 24) "="
22 err: `expected expression`
23 err: `expected SEMI`
24 WHITESPACE@[24; 29) "\n " 22 WHITESPACE@[24; 29) "\n "
25 LET_STMT@[29; 41) 23 LET_STMT@[29; 41)
26 LET_KW@[29; 32) "let" 24 LET_KW@[29; 32) "let"
@@ -37,8 +35,6 @@ SOURCE_FILE@[0; 139)
37 WHITESPACE@[41; 46) "\n " 35 WHITESPACE@[41; 46) "\n "
38 LET_STMT@[46; 49) 36 LET_STMT@[46; 49)
39 LET_KW@[46; 49) "let" 37 LET_KW@[46; 49) "let"
40 err: `expected pattern`
41 err: `expected SEMI`
42 WHITESPACE@[49; 54) "\n " 38 WHITESPACE@[49; 54) "\n "
43 LET_STMT@[54; 67) 39 LET_STMT@[54; 67)
44 LET_KW@[54; 57) "let" 40 LET_KW@[54; 57) "let"
@@ -55,8 +51,6 @@ SOURCE_FILE@[0; 139)
55 WHITESPACE@[67; 72) "\n " 51 WHITESPACE@[67; 72) "\n "
56 LET_STMT@[72; 75) 52 LET_STMT@[72; 75)
57 LET_KW@[72; 75) "let" 53 LET_KW@[72; 75) "let"
58 err: `expected pattern`
59 err: `expected SEMI`
60 WHITESPACE@[75; 80) "\n " 54 WHITESPACE@[75; 80) "\n "
61 EXPR_STMT@[80; 90) 55 EXPR_STMT@[80; 90)
62 IF_EXPR@[80; 90) 56 IF_EXPR@[80; 90)
@@ -72,8 +66,6 @@ SOURCE_FILE@[0; 139)
72 WHITESPACE@[90; 95) "\n " 66 WHITESPACE@[90; 95) "\n "
73 LET_STMT@[95; 98) 67 LET_STMT@[95; 98)
74 LET_KW@[95; 98) "let" 68 LET_KW@[95; 98) "let"
75 err: `expected pattern`
76 err: `expected SEMI`
77 WHITESPACE@[98; 103) "\n " 69 WHITESPACE@[98; 103) "\n "
78 EXPR_STMT@[103; 116) 70 EXPR_STMT@[103; 116)
79 WHILE_EXPR@[103; 116) 71 WHILE_EXPR@[103; 116)
@@ -89,8 +81,6 @@ SOURCE_FILE@[0; 139)
89 WHITESPACE@[116; 121) "\n " 81 WHITESPACE@[116; 121) "\n "
90 LET_STMT@[121; 124) 82 LET_STMT@[121; 124)
91 LET_KW@[121; 124) "let" 83 LET_KW@[121; 124) "let"
92 err: `expected pattern`
93 err: `expected SEMI`
94 WHITESPACE@[124; 129) "\n " 84 WHITESPACE@[124; 129) "\n "
95 LOOP_EXPR@[129; 136) 85 LOOP_EXPR@[129; 136)
96 LOOP_KW@[129; 133) "loop" 86 LOOP_KW@[129; 133) "loop"
@@ -101,3 +91,13 @@ SOURCE_FILE@[0; 139)
101 WHITESPACE@[136; 137) "\n" 91 WHITESPACE@[136; 137) "\n"
102 R_CURLY@[137; 138) "}" 92 R_CURLY@[137; 138) "}"
103 WHITESPACE@[138; 139) "\n" 93 WHITESPACE@[138; 139) "\n"
94err: `expected expression`
95err: `expected SEMI`
96err: `expected pattern`
97err: `expected SEMI`
98err: `expected pattern`
99err: `expected SEMI`
100err: `expected pattern`
101err: `expected SEMI`
102err: `expected pattern`
103err: `expected SEMI`
diff --git a/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt b/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt
index b48bd5dee..d7ac73afa 100644
--- a/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt
@@ -1,9 +1,6 @@
1SOURCE_FILE@[0; 16) 1SOURCE_FILE@[0; 16)
2 FN_DEF@[0; 2) 2 FN_DEF@[0; 2)
3 FN_KW@[0; 2) "fn" 3 FN_KW@[0; 2) "fn"
4 err: `expected a name`
5 err: `expected function arguments`
6 err: `expected a block`
7 WHITESPACE@[2; 4) "\n\n" 4 WHITESPACE@[2; 4) "\n\n"
8 FN_DEF@[4; 15) 5 FN_DEF@[4; 15)
9 FN_KW@[4; 6) "fn" 6 FN_KW@[4; 6) "fn"
@@ -18,3 +15,6 @@ SOURCE_FILE@[0; 16)
18 L_CURLY@[13; 14) "{" 15 L_CURLY@[13; 14) "{"
19 R_CURLY@[14; 15) "}" 16 R_CURLY@[14; 15) "}"
20 WHITESPACE@[15; 16) "\n" 17 WHITESPACE@[15; 16) "\n"
18err: `expected a name`
19err: `expected function arguments`
20err: `expected a block`
diff --git a/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt b/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt
index 81b52c8ce..086224eee 100644
--- a/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt
@@ -23,8 +23,6 @@ SOURCE_FILE@[0; 22)
23 BIND_PAT@[15; 16) 23 BIND_PAT@[15; 16)
24 NAME@[15; 16) 24 NAME@[15; 16)
25 IDENT@[15; 16) "y" 25 IDENT@[15; 16) "y"
26 err: `expected COLON`
27 err: `expected type`
28 R_PAREN@[16; 17) ")" 26 R_PAREN@[16; 17) ")"
29 WHITESPACE@[17; 18) " " 27 WHITESPACE@[17; 18) " "
30 BLOCK@[18; 21) 28 BLOCK@[18; 21)
@@ -32,3 +30,5 @@ SOURCE_FILE@[0; 22)
32 WHITESPACE@[19; 20) "\n" 30 WHITESPACE@[19; 20) "\n"
33 R_CURLY@[20; 21) "}" 31 R_CURLY@[20; 21) "}"
34 WHITESPACE@[21; 22) "\n" 32 WHITESPACE@[21; 22) "\n"
33err: `expected COLON`
34err: `expected type`
diff --git a/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt
index 6dfdfc343..d7a5fa1d2 100644
--- a/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt
@@ -21,34 +21,23 @@ SOURCE_FILE@[0; 112)
21 LITERAL@[13; 14) 21 LITERAL@[13; 14)
22 INT_NUMBER@[13; 14) "2" 22 INT_NUMBER@[13; 14) "2"
23 COMMA@[14; 15) "," 23 COMMA@[14; 15) ","
24 err: `expected expression`
25 err: `expected R_BRACK`
26 err: `expected SEMI`
27 WHITESPACE@[15; 16) " " 24 WHITESPACE@[15; 16) " "
28 err: `expected expression`
29 EXPR_STMT@[16; 17) 25 EXPR_STMT@[16; 17)
30 ERROR@[16; 17) 26 ERROR@[16; 17)
31 AT@[16; 17) "@" 27 AT@[16; 17) "@"
32 err: `expected SEMI`
33 err: `expected expression`
34 EXPR_STMT@[17; 18) 28 EXPR_STMT@[17; 18)
35 ERROR@[17; 18) 29 ERROR@[17; 18)
36 COMMA@[17; 18) "," 30 COMMA@[17; 18) ","
37 err: `expected SEMI`
38 WHITESPACE@[18; 19) " " 31 WHITESPACE@[18; 19) " "
39 STRUCT_DEF@[19; 26) 32 STRUCT_DEF@[19; 26)
40 STRUCT_KW@[19; 25) "struct" 33 STRUCT_KW@[19; 25) "struct"
41 err: `expected a name`
42 ERROR@[25; 26) 34 ERROR@[25; 26)
43 COMMA@[25; 26) "," 35 COMMA@[25; 26) ","
44 err: `expected `;`, `{`, or `(``
45 WHITESPACE@[26; 27) " " 36 WHITESPACE@[26; 27) " "
46 LET_STMT@[27; 31) 37 LET_STMT@[27; 31)
47 LET_KW@[27; 30) "let" 38 LET_KW@[27; 30) "let"
48 err: `expected pattern`
49 ERROR@[30; 31) 39 ERROR@[30; 31)
50 R_BRACK@[30; 31) "]" 40 R_BRACK@[30; 31) "]"
51 err: `expected SEMI`
52 WHITESPACE@[31; 32) " " 41 WHITESPACE@[31; 32) " "
53 R_CURLY@[32; 33) "}" 42 R_CURLY@[32; 33) "}"
54 WHITESPACE@[33; 34) "\n" 43 WHITESPACE@[33; 34) "\n"
@@ -80,35 +69,22 @@ SOURCE_FILE@[0; 112)
80 LITERAL@[50; 51) 69 LITERAL@[50; 51)
81 INT_NUMBER@[50; 51) "2" 70 INT_NUMBER@[50; 51) "2"
82 COMMA@[51; 52) "," 71 COMMA@[51; 52) ","
83 err: `expected expression`
84 err: `expected SEMI`
85 WHITESPACE@[52; 53) " " 72 WHITESPACE@[52; 53) " "
86 err: `expected expression`
87 EXPR_STMT@[53; 54) 73 EXPR_STMT@[53; 54)
88 ERROR@[53; 54) 74 ERROR@[53; 54)
89 AT@[53; 54) "@" 75 AT@[53; 54) "@"
90 err: `expected SEMI`
91 err: `expected expression`
92 EXPR_STMT@[54; 55) 76 EXPR_STMT@[54; 55)
93 ERROR@[54; 55) 77 ERROR@[54; 55)
94 COMMA@[54; 55) "," 78 COMMA@[54; 55) ","
95 err: `expected SEMI`
96 WHITESPACE@[55; 56) " " 79 WHITESPACE@[55; 56) " "
97 IMPL_BLOCK@[56; 60) 80 IMPL_BLOCK@[56; 60)
98 IMPL_KW@[56; 60) "impl" 81 IMPL_KW@[56; 60) "impl"
99 err: `expected type`
100 err: `expected `{``
101 err: `expected expression`
102 EXPR_STMT@[60; 61) 82 EXPR_STMT@[60; 61)
103 ERROR@[60; 61) 83 ERROR@[60; 61)
104 COMMA@[60; 61) "," 84 COMMA@[60; 61) ","
105 err: `expected SEMI`
106 WHITESPACE@[61; 62) " " 85 WHITESPACE@[61; 62) " "
107 LET_STMT@[62; 65) 86 LET_STMT@[62; 65)
108 LET_KW@[62; 65) "let" 87 LET_KW@[62; 65) "let"
109 err: `expected pattern`
110 err: `expected SEMI`
111 err: `expected expression`
112 ERROR@[65; 66) 88 ERROR@[65; 66)
113 R_PAREN@[65; 66) ")" 89 R_PAREN@[65; 66) ")"
114 WHITESPACE@[66; 67) " " 90 WHITESPACE@[66; 67) " "
@@ -145,45 +121,69 @@ SOURCE_FILE@[0; 112)
145 LITERAL@[89; 90) 121 LITERAL@[89; 90)
146 INT_NUMBER@[89; 90) "2" 122 INT_NUMBER@[89; 90) "2"
147 COMMA@[90; 91) "," 123 COMMA@[90; 91) ","
148 err: `expected expression`
149 err: `expected SEMI`
150 WHITESPACE@[91; 92) " " 124 WHITESPACE@[91; 92) " "
151 err: `expected expression`
152 EXPR_STMT@[92; 93) 125 EXPR_STMT@[92; 93)
153 ERROR@[92; 93) 126 ERROR@[92; 93)
154 AT@[92; 93) "@" 127 AT@[92; 93) "@"
155 err: `expected SEMI`
156 err: `expected expression`
157 EXPR_STMT@[93; 94) 128 EXPR_STMT@[93; 94)
158 ERROR@[93; 94) 129 ERROR@[93; 94)
159 COMMA@[93; 94) "," 130 COMMA@[93; 94) ","
160 err: `expected SEMI`
161 WHITESPACE@[94; 95) " " 131 WHITESPACE@[94; 95) " "
162 err: `expected expression`
163 EXPR_STMT@[95; 96) 132 EXPR_STMT@[95; 96)
164 ERROR@[95; 96) 133 ERROR@[95; 96)
165 R_BRACK@[95; 96) "]" 134 R_BRACK@[95; 96) "]"
166 err: `expected SEMI`
167 err: `expected expression`
168 EXPR_STMT@[96; 97) 135 EXPR_STMT@[96; 97)
169 ERROR@[96; 97) 136 ERROR@[96; 97)
170 COMMA@[96; 97) "," 137 COMMA@[96; 97) ","
171 err: `expected SEMI`
172 WHITESPACE@[97; 98) " " 138 WHITESPACE@[97; 98) " "
173 TRAIT_DEF@[98; 104) 139 TRAIT_DEF@[98; 104)
174 TRAIT_KW@[98; 103) "trait" 140 TRAIT_KW@[98; 103) "trait"
175 err: `expected a name`
176 ERROR@[103; 104) 141 ERROR@[103; 104)
177 COMMA@[103; 104) "," 142 COMMA@[103; 104) ","
178 err: `expected `{``
179 WHITESPACE@[104; 105) " " 143 WHITESPACE@[104; 105) " "
180 LET_STMT@[105; 108) 144 LET_STMT@[105; 108)
181 LET_KW@[105; 108) "let" 145 LET_KW@[105; 108) "let"
182 err: `expected pattern`
183 err: `expected SEMI`
184 err: `expected expression`
185 ERROR@[108; 109) 146 ERROR@[108; 109)
186 R_PAREN@[108; 109) ")" 147 R_PAREN@[108; 109) ")"
187 WHITESPACE@[109; 110) " " 148 WHITESPACE@[109; 110) " "
188 R_CURLY@[110; 111) "}" 149 R_CURLY@[110; 111) "}"
189 WHITESPACE@[111; 112) "\n" 150 WHITESPACE@[111; 112) "\n"
151err: `expected expression`
152err: `expected R_BRACK`
153err: `expected SEMI`
154err: `expected expression`
155err: `expected SEMI`
156err: `expected expression`
157err: `expected SEMI`
158err: `expected a name`
159err: `expected `;`, `{`, or `(``
160err: `expected pattern`
161err: `expected SEMI`
162err: `expected expression`
163err: `expected SEMI`
164err: `expected expression`
165err: `expected SEMI`
166err: `expected expression`
167err: `expected SEMI`
168err: `expected type`
169err: `expected `{``
170err: `expected expression`
171err: `expected SEMI`
172err: `expected pattern`
173err: `expected SEMI`
174err: `expected expression`
175err: `expected expression`
176err: `expected SEMI`
177err: `expected expression`
178err: `expected SEMI`
179err: `expected expression`
180err: `expected SEMI`
181err: `expected expression`
182err: `expected SEMI`
183err: `expected expression`
184err: `expected SEMI`
185err: `expected a name`
186err: `expected `{``
187err: `expected pattern`
188err: `expected SEMI`
189err: `expected expression`
diff --git a/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt b/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt
index 469d35082..143600e67 100644
--- a/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt
@@ -31,13 +31,13 @@ SOURCE_FILE@[0; 94)
31 COMMA@[44; 45) "," 31 COMMA@[44; 45) ","
32 WHITESPACE@[45; 46) " " 32 WHITESPACE@[45; 46) " "
33 FLOAT_NUMBER@[46; 49) "2.0" 33 FLOAT_NUMBER@[46; 49) "2.0"
34 err: `unmatched `}``
35 WHITESPACE@[49; 54) "\n " 34 WHITESPACE@[49; 54) "\n "
36 R_CURLY@[54; 55) "}" 35 R_CURLY@[54; 55) "}"
37 WHITESPACE@[55; 56) " " 36 WHITESPACE@[55; 56) " "
38 COMMENT@[56; 91) "//~ ERROR incorrect c ..." 37 COMMENT@[56; 91) "//~ ERROR incorrect c ..."
39 WHITESPACE@[91; 92) "\n" 38 WHITESPACE@[91; 92) "\n"
40 err: `unmatched `}``
41 ERROR@[92; 93) 39 ERROR@[92; 93)
42 R_CURLY@[92; 93) "}" 40 R_CURLY@[92; 93) "}"
43 WHITESPACE@[93; 94) "\n" 41 WHITESPACE@[93; 94) "\n"
42err: `unmatched `}``
43err: `unmatched `}``
diff --git a/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt b/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt
index 0fb73d838..4f505fa76 100644
--- a/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt
@@ -103,8 +103,6 @@ SOURCE_FILE@[0; 240)
103 NAME_REF@[83; 87) 103 NAME_REF@[83; 87)
104 IDENT@[83; 87) "Copy" 104 IDENT@[83; 87) "Copy"
105 R_PAREN@[87; 88) ")" 105 R_PAREN@[87; 88) ")"
106 err: `expected COMMA`
107 err: `expected R_ANGLE`
108 WHITESPACE@[88; 89) " " 106 WHITESPACE@[88; 89) " "
109 PLUS@[89; 90) "+" 107 PLUS@[89; 90) "+"
110 WHITESPACE@[90; 91) " " 108 WHITESPACE@[90; 91) " "
@@ -141,8 +139,6 @@ SOURCE_FILE@[0; 240)
141 LIFETIME@[117; 119) "\'a" 139 LIFETIME@[117; 119) "\'a"
142 R_ANGLE@[119; 120) ">" 140 R_ANGLE@[119; 120) ">"
143 R_PAREN@[120; 121) ")" 141 R_PAREN@[120; 121) ")"
144 err: `expected SEMI`
145 err: `expected expression`
146 EXPR_STMT@[121; 123) 142 EXPR_STMT@[121; 123)
147 ERROR@[121; 122) 143 ERROR@[121; 122)
148 R_ANGLE@[121; 122) ">" 144 R_ANGLE@[121; 122) ">"
@@ -165,54 +161,35 @@ SOURCE_FILE@[0; 240)
165 TYPE_ARG@[139; 141) 161 TYPE_ARG@[139; 141)
166 PAREN_TYPE@[139; 141) 162 PAREN_TYPE@[139; 141)
167 L_PAREN@[139; 140) "(" 163 L_PAREN@[139; 140) "("
168 err: `expected type`
169 ERROR@[140; 141) 164 ERROR@[140; 141)
170 QUESTION@[140; 141) "?" 165 QUESTION@[140; 141) "?"
171 err: `expected R_PAREN`
172 err: `expected COMMA`
173 err: `expected R_ANGLE`
174 err: `expected SEMI`
175 EXPR_STMT@[141; 146) 166 EXPR_STMT@[141; 146)
176 PATH_EXPR@[141; 146) 167 PATH_EXPR@[141; 146)
177 PATH@[141; 146) 168 PATH@[141; 146)
178 PATH_SEGMENT@[141; 146) 169 PATH_SEGMENT@[141; 146)
179 NAME_REF@[141; 146) 170 NAME_REF@[141; 146)
180 IDENT@[141; 146) "Sized" 171 IDENT@[141; 146) "Sized"
181 err: `expected SEMI`
182 err: `expected expression`
183 EXPR_STMT@[146; 147) 172 EXPR_STMT@[146; 147)
184 ERROR@[146; 147) 173 ERROR@[146; 147)
185 R_PAREN@[146; 147) ")" 174 R_PAREN@[146; 147) ")"
186 err: `expected SEMI`
187 WHITESPACE@[147; 148) " " 175 WHITESPACE@[147; 148) " "
188 err: `expected expression`
189 EXPR_STMT@[148; 149) 176 EXPR_STMT@[148; 149)
190 ERROR@[148; 149) 177 ERROR@[148; 149)
191 PLUS@[148; 149) "+" 178 PLUS@[148; 149) "+"
192 err: `expected SEMI`
193 WHITESPACE@[149; 150) " " 179 WHITESPACE@[149; 150) " "
194 EXPR_STMT@[150; 151) 180 EXPR_STMT@[150; 151)
195 PAREN_EXPR@[150; 151) 181 PAREN_EXPR@[150; 151)
196 L_PAREN@[150; 151) "(" 182 L_PAREN@[150; 151) "("
197 err: `expected expression`
198 err: `expected R_PAREN`
199 err: `expected SEMI`
200 EXPR_STMT@[151; 157) 183 EXPR_STMT@[151; 157)
201 FOR_EXPR@[151; 157) 184 FOR_EXPR@[151; 157)
202 FOR_KW@[151; 154) "for" 185 FOR_KW@[151; 154) "for"
203 err: `expected pattern`
204 ERROR@[154; 155) 186 ERROR@[154; 155)
205 L_ANGLE@[154; 155) "<" 187 L_ANGLE@[154; 155) "<"
206 err: `expected IN_KW`
207 err: `expected expression`
208 ERROR@[155; 157) 188 ERROR@[155; 157)
209 LIFETIME@[155; 157) "\'a" 189 LIFETIME@[155; 157) "\'a"
210 err: `expected a block`
211 err: `expected expression`
212 EXPR_STMT@[157; 158) 190 EXPR_STMT@[157; 158)
213 ERROR@[157; 158) 191 ERROR@[157; 158)
214 R_ANGLE@[157; 158) ">" 192 R_ANGLE@[157; 158) ">"
215 err: `expected SEMI`
216 WHITESPACE@[158; 159) " " 193 WHITESPACE@[158; 159) " "
217 EXPR_STMT@[159; 180) 194 EXPR_STMT@[159; 180)
218 BIN_EXPR@[159; 180) 195 BIN_EXPR@[159; 180)
@@ -225,11 +202,9 @@ SOURCE_FILE@[0; 240)
225 NAME_REF@[159; 164) 202 NAME_REF@[159; 164)
226 IDENT@[159; 164) "Trait" 203 IDENT@[159; 164) "Trait"
227 L_ANGLE@[164; 165) "<" 204 L_ANGLE@[164; 165) "<"
228 err: `expected expression`
229 ERROR@[165; 167) 205 ERROR@[165; 167)
230 LIFETIME@[165; 167) "\'a" 206 LIFETIME@[165; 167) "\'a"
231 R_ANGLE@[167; 168) ">" 207 R_ANGLE@[167; 168) ">"
232 err: `expected expression`
233 ERROR@[168; 169) 208 ERROR@[168; 169)
234 R_PAREN@[168; 169) ")" 209 R_PAREN@[168; 169) ")"
235 WHITESPACE@[169; 170) " " 210 WHITESPACE@[169; 170) " "
@@ -244,10 +219,8 @@ SOURCE_FILE@[0; 240)
244 IDENT@[173; 177) "Copy" 219 IDENT@[173; 177) "Copy"
245 R_PAREN@[177; 178) ")" 220 R_PAREN@[177; 178) ")"
246 R_ANGLE@[178; 179) ">" 221 R_ANGLE@[178; 179) ">"
247 err: `expected expression`
248 ERROR@[179; 180) 222 ERROR@[179; 180)
249 SEMI@[179; 180) ";" 223 SEMI@[179; 180) ";"
250 err: `expected SEMI`
251 WHITESPACE@[180; 185) "\n " 224 WHITESPACE@[180; 185) "\n "
252 LET_STMT@[185; 235) 225 LET_STMT@[185; 235)
253 LET_KW@[185; 188) "let" 226 LET_KW@[185; 188) "let"
@@ -288,8 +261,6 @@ SOURCE_FILE@[0; 240)
288 LIFETIME@[211; 213) "\'a" 261 LIFETIME@[211; 213) "\'a"
289 R_ANGLE@[213; 214) ">" 262 R_ANGLE@[213; 214) ">"
290 R_PAREN@[214; 215) ")" 263 R_PAREN@[214; 215) ")"
291 err: `expected COMMA`
292 err: `expected R_ANGLE`
293 WHITESPACE@[215; 216) " " 264 WHITESPACE@[215; 216) " "
294 PLUS@[216; 217) "+" 265 PLUS@[216; 217) "+"
295 WHITESPACE@[217; 218) " " 266 WHITESPACE@[217; 218) " "
@@ -313,8 +284,6 @@ SOURCE_FILE@[0; 240)
313 NAME_REF@[229; 234) 284 NAME_REF@[229; 234)
314 IDENT@[229; 234) "Sized" 285 IDENT@[229; 234) "Sized"
315 R_PAREN@[234; 235) ")" 286 R_PAREN@[234; 235) ")"
316 err: `expected SEMI`
317 err: `expected expression`
318 EXPR_STMT@[235; 237) 287 EXPR_STMT@[235; 237)
319 ERROR@[235; 236) 288 ERROR@[235; 236)
320 R_ANGLE@[235; 236) ">" 289 R_ANGLE@[235; 236) ">"
@@ -322,3 +291,34 @@ SOURCE_FILE@[0; 240)
322 WHITESPACE@[237; 238) "\n" 291 WHITESPACE@[237; 238) "\n"
323 R_CURLY@[238; 239) "}" 292 R_CURLY@[238; 239) "}"
324 WHITESPACE@[239; 240) "\n" 293 WHITESPACE@[239; 240) "\n"
294err: `expected COMMA`
295err: `expected R_ANGLE`
296err: `expected SEMI`
297err: `expected expression`
298err: `expected type`
299err: `expected R_PAREN`
300err: `expected COMMA`
301err: `expected R_ANGLE`
302err: `expected SEMI`
303err: `expected SEMI`
304err: `expected expression`
305err: `expected SEMI`
306err: `expected expression`
307err: `expected SEMI`
308err: `expected expression`
309err: `expected R_PAREN`
310err: `expected SEMI`
311err: `expected pattern`
312err: `expected IN_KW`
313err: `expected expression`
314err: `expected a block`
315err: `expected expression`
316err: `expected SEMI`
317err: `expected expression`
318err: `expected expression`
319err: `expected expression`
320err: `expected SEMI`
321err: `expected COMMA`
322err: `expected R_ANGLE`
323err: `expected SEMI`
324err: `expected expression`
diff --git a/crates/ra_syntax/tests/data/parser/err/0025_nope.txt b/crates/ra_syntax/tests/data/parser/err/0025_nope.txt
index b8d769947..a1bd8647a 100644
--- a/crates/ra_syntax/tests/data/parser/err/0025_nope.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0025_nope.txt
@@ -50,14 +50,10 @@ SOURCE_FILE@[0; 575)
50 NAME@[91; 94) 50 NAME@[91; 94)
51 IDENT@[91; 94) "abc" 51 IDENT@[91; 94) "abc"
52 COLON@[94; 95) ":" 52 COLON@[94; 95) ":"
53 err: `expected type`
54 err: `expected COMMA`
55 WHITESPACE@[95; 96) " " 53 WHITESPACE@[95; 96) " "
56 err: `expected field`
57 ERROR@[96; 98) 54 ERROR@[96; 98)
58 L_CURLY@[96; 97) "{" 55 L_CURLY@[96; 97) "{"
59 R_CURLY@[97; 98) "}" 56 R_CURLY@[97; 98) "}"
60 err: `expected field declaration`
61 ERROR@[98; 99) 57 ERROR@[98; 99)
62 COMMA@[98; 99) "," 58 COMMA@[98; 99) ","
63 WHITESPACE@[99; 100) " " 59 WHITESPACE@[99; 100) " "
@@ -159,17 +155,11 @@ SOURCE_FILE@[0; 575)
159 PATH_SEGMENT@[368; 371) 155 PATH_SEGMENT@[368; 371)
160 NAME_REF@[368; 371) 156 NAME_REF@[368; 371)
161 IDENT@[368; 371) "i32" 157 IDENT@[368; 371) "i32"
162 err: `expected COMMA`
163 WHITESPACE@[371; 372) " " 158 WHITESPACE@[371; 372) " "
164 err: `expected a type`
165 err: `expected R_PAREN`
166 err: `expected COMMA`
167 err: `expected enum variant`
168 ERROR@[372; 372) 159 ERROR@[372; 372)
169 ERROR@[372; 374) 160 ERROR@[372; 374)
170 L_CURLY@[372; 373) "{" 161 L_CURLY@[372; 373) "{"
171 R_CURLY@[373; 374) "}" 162 R_CURLY@[373; 374) "}"
172 err: `expected enum variant`
173 ERROR@[374; 375) 163 ERROR@[374; 375)
174 R_PAREN@[374; 375) ")" 164 R_PAREN@[374; 375) ")"
175 WHITESPACE@[375; 376) " " 165 WHITESPACE@[375; 376) " "
@@ -192,7 +182,6 @@ SOURCE_FILE@[0; 575)
192 WHITESPACE@[505; 506) " " 182 WHITESPACE@[505; 506) " "
193 EQ@[506; 507) "=" 183 EQ@[506; 507) "="
194 WHITESPACE@[507; 508) " " 184 WHITESPACE@[507; 508) " "
195 err: `expected expression`
196 ERROR@[508; 509) 185 ERROR@[508; 509)
197 UNDERSCORE@[508; 509) "_" 186 UNDERSCORE@[508; 509) "_"
198 SEMI@[509; 510) ";" 187 SEMI@[509; 510) ";"
@@ -201,3 +190,14 @@ SOURCE_FILE@[0; 575)
201 WHITESPACE@[572; 573) "\n" 190 WHITESPACE@[572; 573) "\n"
202 R_CURLY@[573; 574) "}" 191 R_CURLY@[573; 574) "}"
203 WHITESPACE@[574; 575) "\n" 192 WHITESPACE@[574; 575) "\n"
193err: `expected type`
194err: `expected COMMA`
195err: `expected field`
196err: `expected field declaration`
197err: `expected COMMA`
198err: `expected a type`
199err: `expected R_PAREN`
200err: `expected COMMA`
201err: `expected enum variant`
202err: `expected enum variant`
203err: `expected expression`
diff --git a/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt b/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt
index cfd06c9c9..f473718dc 100644
--- a/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt
@@ -16,8 +16,6 @@ SOURCE_FILE@[0; 38)
16 NAME_REF@[8; 13) 16 NAME_REF@[8; 13)
17 IDENT@[8; 13) "Clone" 17 IDENT@[8; 13) "Clone"
18 R_ANGLE@[13; 14) ">" 18 R_ANGLE@[13; 14) ">"
19 err: `expected trait or type`
20 err: `expected `{``
21 WHITESPACE@[14; 15) "\n" 19 WHITESPACE@[14; 15) "\n"
22 IMPL_BLOCK@[15; 37) 20 IMPL_BLOCK@[15; 37)
23 IMPL_KW@[15; 19) "impl" 21 IMPL_KW@[15; 19) "impl"
@@ -47,3 +45,5 @@ SOURCE_FILE@[0; 38)
47 L_CURLY@[35; 36) "{" 45 L_CURLY@[35; 36) "{"
48 R_CURLY@[36; 37) "}" 46 R_CURLY@[36; 37) "}"
49 WHITESPACE@[37; 38) "\n" 47 WHITESPACE@[37; 38) "\n"
48err: `expected trait or type`
49err: `expected `{``
diff --git a/crates/ra_syntax/tests/data/parser/err/0027_incomplere_where_for.txt b/crates/ra_syntax/tests/data/parser/err/0027_incomplere_where_for.txt
index c87c2c936..5a2b52d05 100644
--- a/crates/ra_syntax/tests/data/parser/err/0027_incomplere_where_for.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0027_incomplere_where_for.txt
@@ -19,10 +19,10 @@ SOURCE_FILE@[0; 30)
19 LIFETIME_PARAM@[23; 25) 19 LIFETIME_PARAM@[23; 25)
20 LIFETIME@[23; 25) "\'a" 20 LIFETIME@[23; 25) "\'a"
21 R_ANGLE@[25; 26) ">" 21 R_ANGLE@[25; 26) ">"
22 err: `expected a path`
23 err: `expected colon`
24 WHITESPACE@[26; 27) "\n" 22 WHITESPACE@[26; 27) "\n"
25 BLOCK@[27; 29) 23 BLOCK@[27; 29)
26 L_CURLY@[27; 28) "{" 24 L_CURLY@[27; 28) "{"
27 R_CURLY@[28; 29) "}" 25 R_CURLY@[28; 29) "}"
28 WHITESPACE@[29; 30) "\n" 26 WHITESPACE@[29; 30) "\n"
27err: `expected a path`
28err: `expected colon`
diff --git a/crates/ra_syntax/tests/data/parser/err/0028_macro_2.0.txt b/crates/ra_syntax/tests/data/parser/err/0028_macro_2.0.txt
index 97ec4a5ab..8a59a5ac3 100644
--- a/crates/ra_syntax/tests/data/parser/err/0028_macro_2.0.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0028_macro_2.0.txt
@@ -4,7 +4,6 @@ SOURCE_FILE@[0; 349)
4 PATH_SEGMENT@[0; 5) 4 PATH_SEGMENT@[0; 5)
5 NAME_REF@[0; 5) 5 NAME_REF@[0; 5)
6 IDENT@[0; 5) "macro" 6 IDENT@[0; 5) "macro"
7 err: `expected EXCL`
8 WHITESPACE@[5; 6) " " 7 WHITESPACE@[5; 6) " "
9 NAME@[6; 21) 8 NAME@[6; 21)
10 IDENT@[6; 21) "parse_use_trees" 9 IDENT@[6; 21) "parse_use_trees"
@@ -28,9 +27,7 @@ SOURCE_FILE@[0; 349)
28 R_PAREN@[38; 39) ")" 27 R_PAREN@[38; 39) ")"
29 STAR@[39; 40) "*" 28 STAR@[39; 40) "*"
30 R_PAREN@[40; 41) ")" 29 R_PAREN@[40; 41) ")"
31 err: `expected SEMI`
32 WHITESPACE@[41; 42) " " 30 WHITESPACE@[41; 42) " "
33 err: `expected an item`
34 ERROR@[42; 93) 31 ERROR@[42; 93)
35 L_CURLY@[42; 43) "{" 32 L_CURLY@[42; 43) "{"
36 WHITESPACE@[43; 48) "\n " 33 WHITESPACE@[43; 48) "\n "
@@ -85,7 +82,6 @@ SOURCE_FILE@[0; 349)
85 PATH_SEGMENT@[134; 139) 82 PATH_SEGMENT@[134; 139)
86 NAME_REF@[134; 139) 83 NAME_REF@[134; 139)
87 IDENT@[134; 139) "macro" 84 IDENT@[134; 139) "macro"
88 err: `expected SEMI`
89 WHITESPACE@[139; 140) " " 85 WHITESPACE@[139; 140) " "
90 EXPR_STMT@[140; 154) 86 EXPR_STMT@[140; 154)
91 CALL_EXPR@[140; 154) 87 CALL_EXPR@[140; 154)
@@ -98,175 +94,112 @@ SOURCE_FILE@[0; 349)
98 L_PAREN@[150; 151) "(" 94 L_PAREN@[150; 151) "("
99 ARRAY_EXPR@[151; 154) 95 ARRAY_EXPR@[151; 154)
100 L_BRACK@[151; 152) "[" 96 L_BRACK@[151; 152) "["
101 err: `expected expression`
102 ERROR@[152; 153) 97 ERROR@[152; 153)
103 DOLLAR@[152; 153) "$" 98 DOLLAR@[152; 153) "$"
104 err: `expected COMMA`
105 PAREN_EXPR@[153; 154) 99 PAREN_EXPR@[153; 154)
106 L_PAREN@[153; 154) "(" 100 L_PAREN@[153; 154) "("
107 err: `expected expression`
108 err: `expected R_PAREN`
109 err: `expected COMMA`
110 err: `expected expression`
111 err: `expected R_BRACK`
112 err: `expected COMMA`
113 err: `expected SEMI`
114 err: `expected expression`
115 EXPR_STMT@[154; 155) 101 EXPR_STMT@[154; 155)
116 ERROR@[154; 155) 102 ERROR@[154; 155)
117 DOLLAR@[154; 155) "$" 103 DOLLAR@[154; 155) "$"
118 err: `expected SEMI`
119 EXPR_STMT@[155; 160) 104 EXPR_STMT@[155; 160)
120 PATH_EXPR@[155; 160) 105 PATH_EXPR@[155; 160)
121 PATH@[155; 160) 106 PATH@[155; 160)
122 PATH_SEGMENT@[155; 160) 107 PATH_SEGMENT@[155; 160)
123 NAME_REF@[155; 160) 108 NAME_REF@[155; 160)
124 IDENT@[155; 160) "input" 109 IDENT@[155; 160) "input"
125 err: `expected SEMI`
126 err: `expected expression`
127 EXPR_STMT@[160; 161) 110 EXPR_STMT@[160; 161)
128 ERROR@[160; 161) 111 ERROR@[160; 161)
129 COLON@[160; 161) ":" 112 COLON@[160; 161) ":"
130 err: `expected SEMI`
131 EXPR_STMT@[161; 165) 113 EXPR_STMT@[161; 165)
132 PATH_EXPR@[161; 165) 114 PATH_EXPR@[161; 165)
133 PATH@[161; 165) 115 PATH@[161; 165)
134 PATH_SEGMENT@[161; 165) 116 PATH_SEGMENT@[161; 165)
135 NAME_REF@[161; 165) 117 NAME_REF@[161; 165)
136 IDENT@[161; 165) "expr" 118 IDENT@[161; 165) "expr"
137 err: `expected SEMI`
138 err: `expected expression`
139 EXPR_STMT@[165; 166) 119 EXPR_STMT@[165; 166)
140 ERROR@[165; 166) 120 ERROR@[165; 166)
141 R_PAREN@[165; 166) ")" 121 R_PAREN@[165; 166) ")"
142 err: `expected SEMI`
143 err: `expected expression`
144 EXPR_STMT@[166; 167) 122 EXPR_STMT@[166; 167)
145 ERROR@[166; 167) 123 ERROR@[166; 167)
146 COMMA@[166; 167) "," 124 COMMA@[166; 167) ","
147 err: `expected SEMI`
148 EXPR_STMT@[167; 170) 125 EXPR_STMT@[167; 170)
149 PREFIX_EXPR@[167; 170) 126 PREFIX_EXPR@[167; 170)
150 STAR@[167; 168) "*" 127 STAR@[167; 168) "*"
151 WHITESPACE@[168; 169) " " 128 WHITESPACE@[168; 169) " "
152 err: `expected expression`
153 ERROR@[169; 170) 129 ERROR@[169; 170)
154 DOLLAR@[169; 170) "$" 130 DOLLAR@[169; 170) "$"
155 err: `expected SEMI`
156 EXPR_STMT@[170; 171) 131 EXPR_STMT@[170; 171)
157 PAREN_EXPR@[170; 171) 132 PAREN_EXPR@[170; 171)
158 L_PAREN@[170; 171) "(" 133 L_PAREN@[170; 171) "("
159 err: `expected expression`
160 err: `expected R_PAREN`
161 err: `expected SEMI`
162 err: `expected expression`
163 EXPR_STMT@[171; 172) 134 EXPR_STMT@[171; 172)
164 ERROR@[171; 172) 135 ERROR@[171; 172)
165 COMMA@[171; 172) "," 136 COMMA@[171; 172) ","
166 err: `expected SEMI`
167 err: `expected expression`
168 EXPR_STMT@[172; 173) 137 EXPR_STMT@[172; 173)
169 ERROR@[172; 173) 138 ERROR@[172; 173)
170 R_PAREN@[172; 173) ")" 139 R_PAREN@[172; 173) ")"
171 err: `expected SEMI`
172 EXPR_STMT@[173; 175) 140 EXPR_STMT@[173; 175)
173 PREFIX_EXPR@[173; 175) 141 PREFIX_EXPR@[173; 175)
174 STAR@[173; 174) "*" 142 STAR@[173; 174) "*"
175 err: `expected expression`
176 ERROR@[174; 175) 143 ERROR@[174; 175)
177 R_BRACK@[174; 175) "]" 144 R_BRACK@[174; 175) "]"
178 err: `expected SEMI`
179 err: `expected expression`
180 EXPR_STMT@[175; 176) 145 EXPR_STMT@[175; 176)
181 ERROR@[175; 176) 146 ERROR@[175; 176)
182 COMMA@[175; 176) "," 147 COMMA@[175; 176) ","
183 err: `expected SEMI`
184 WHITESPACE@[176; 177) " " 148 WHITESPACE@[176; 177) " "
185 EXPR_STMT@[177; 180) 149 EXPR_STMT@[177; 180)
186 ARRAY_EXPR@[177; 180) 150 ARRAY_EXPR@[177; 180)
187 L_BRACK@[177; 178) "[" 151 L_BRACK@[177; 178) "["
188 err: `expected expression`
189 ERROR@[178; 179) 152 ERROR@[178; 179)
190 DOLLAR@[178; 179) "$" 153 DOLLAR@[178; 179) "$"
191 err: `expected COMMA`
192 PAREN_EXPR@[179; 180) 154 PAREN_EXPR@[179; 180)
193 L_PAREN@[179; 180) "(" 155 L_PAREN@[179; 180) "("
194 err: `expected expression`
195 err: `expected R_PAREN`
196 err: `expected COMMA`
197 err: `expected expression`
198 err: `expected R_BRACK`
199 err: `expected SEMI`
200 err: `expected expression`
201 EXPR_STMT@[180; 181) 156 EXPR_STMT@[180; 181)
202 ERROR@[180; 181) 157 ERROR@[180; 181)
203 DOLLAR@[180; 181) "$" 158 DOLLAR@[180; 181) "$"
204 err: `expected SEMI`
205 EXPR_STMT@[181; 187) 159 EXPR_STMT@[181; 187)
206 PATH_EXPR@[181; 187) 160 PATH_EXPR@[181; 187)
207 PATH@[181; 187) 161 PATH@[181; 187)
208 PATH_SEGMENT@[181; 187) 162 PATH_SEGMENT@[181; 187)
209 NAME_REF@[181; 187) 163 NAME_REF@[181; 187)
210 IDENT@[181; 187) "output" 164 IDENT@[181; 187) "output"
211 err: `expected SEMI`
212 err: `expected expression`
213 EXPR_STMT@[187; 188) 165 EXPR_STMT@[187; 188)
214 ERROR@[187; 188) 166 ERROR@[187; 188)
215 COLON@[187; 188) ":" 167 COLON@[187; 188) ":"
216 err: `expected SEMI`
217 EXPR_STMT@[188; 192) 168 EXPR_STMT@[188; 192)
218 PATH_EXPR@[188; 192) 169 PATH_EXPR@[188; 192)
219 PATH@[188; 192) 170 PATH@[188; 192)
220 PATH_SEGMENT@[188; 192) 171 PATH_SEGMENT@[188; 192)
221 NAME_REF@[188; 192) 172 NAME_REF@[188; 192)
222 IDENT@[188; 192) "expr" 173 IDENT@[188; 192) "expr"
223 err: `expected SEMI`
224 err: `expected expression`
225 EXPR_STMT@[192; 193) 174 EXPR_STMT@[192; 193)
226 ERROR@[192; 193) 175 ERROR@[192; 193)
227 R_PAREN@[192; 193) ")" 176 R_PAREN@[192; 193) ")"
228 err: `expected SEMI`
229 err: `expected expression`
230 EXPR_STMT@[193; 194) 177 EXPR_STMT@[193; 194)
231 ERROR@[193; 194) 178 ERROR@[193; 194)
232 COMMA@[193; 194) "," 179 COMMA@[193; 194) ","
233 err: `expected SEMI`
234 EXPR_STMT@[194; 197) 180 EXPR_STMT@[194; 197)
235 PREFIX_EXPR@[194; 197) 181 PREFIX_EXPR@[194; 197)
236 STAR@[194; 195) "*" 182 STAR@[194; 195) "*"
237 WHITESPACE@[195; 196) " " 183 WHITESPACE@[195; 196) " "
238 err: `expected expression`
239 ERROR@[196; 197) 184 ERROR@[196; 197)
240 DOLLAR@[196; 197) "$" 185 DOLLAR@[196; 197) "$"
241 err: `expected SEMI`
242 EXPR_STMT@[197; 198) 186 EXPR_STMT@[197; 198)
243 PAREN_EXPR@[197; 198) 187 PAREN_EXPR@[197; 198)
244 L_PAREN@[197; 198) "(" 188 L_PAREN@[197; 198) "("
245 err: `expected expression`
246 err: `expected R_PAREN`
247 err: `expected SEMI`
248 err: `expected expression`
249 EXPR_STMT@[198; 199) 189 EXPR_STMT@[198; 199)
250 ERROR@[198; 199) 190 ERROR@[198; 199)
251 COMMA@[198; 199) "," 191 COMMA@[198; 199) ","
252 err: `expected SEMI`
253 err: `expected expression`
254 EXPR_STMT@[199; 200) 192 EXPR_STMT@[199; 200)
255 ERROR@[199; 200) 193 ERROR@[199; 200)
256 R_PAREN@[199; 200) ")" 194 R_PAREN@[199; 200) ")"
257 err: `expected SEMI`
258 EXPR_STMT@[200; 202) 195 EXPR_STMT@[200; 202)
259 PREFIX_EXPR@[200; 202) 196 PREFIX_EXPR@[200; 202)
260 STAR@[200; 201) "*" 197 STAR@[200; 201) "*"
261 err: `expected expression`
262 ERROR@[201; 202) 198 ERROR@[201; 202)
263 R_BRACK@[201; 202) "]" 199 R_BRACK@[201; 202) "]"
264 err: `expected SEMI`
265 err: `expected expression`
266 EXPR_STMT@[202; 203) 200 EXPR_STMT@[202; 203)
267 ERROR@[202; 203) 201 ERROR@[202; 203)
268 R_PAREN@[202; 203) ")" 202 R_PAREN@[202; 203) ")"
269 err: `expected SEMI`
270 WHITESPACE@[203; 204) " " 203 WHITESPACE@[203; 204) " "
271 BLOCK_EXPR@[204; 346) 204 BLOCK_EXPR@[204; 346)
272 BLOCK@[204; 346) 205 BLOCK@[204; 346)
@@ -323,3 +256,70 @@ SOURCE_FILE@[0; 349)
323 WHITESPACE@[346; 347) "\n" 256 WHITESPACE@[346; 347) "\n"
324 R_CURLY@[347; 348) "}" 257 R_CURLY@[347; 348) "}"
325 WHITESPACE@[348; 349) "\n" 258 WHITESPACE@[348; 349) "\n"
259err: `expected EXCL`
260err: `expected SEMI`
261err: `expected an item`
262err: `expected SEMI`
263err: `expected expression`
264err: `expected COMMA`
265err: `expected expression`
266err: `expected R_PAREN`
267err: `expected COMMA`
268err: `expected expression`
269err: `expected R_BRACK`
270err: `expected COMMA`
271err: `expected SEMI`
272err: `expected expression`
273err: `expected SEMI`
274err: `expected SEMI`
275err: `expected expression`
276err: `expected SEMI`
277err: `expected SEMI`
278err: `expected expression`
279err: `expected SEMI`
280err: `expected expression`
281err: `expected SEMI`
282err: `expected expression`
283err: `expected SEMI`
284err: `expected expression`
285err: `expected R_PAREN`
286err: `expected SEMI`
287err: `expected expression`
288err: `expected SEMI`
289err: `expected expression`
290err: `expected SEMI`
291err: `expected expression`
292err: `expected SEMI`
293err: `expected expression`
294err: `expected SEMI`
295err: `expected expression`
296err: `expected COMMA`
297err: `expected expression`
298err: `expected R_PAREN`
299err: `expected COMMA`
300err: `expected expression`
301err: `expected R_BRACK`
302err: `expected SEMI`
303err: `expected expression`
304err: `expected SEMI`
305err: `expected SEMI`
306err: `expected expression`
307err: `expected SEMI`
308err: `expected SEMI`
309err: `expected expression`
310err: `expected SEMI`
311err: `expected expression`
312err: `expected SEMI`
313err: `expected expression`
314err: `expected SEMI`
315err: `expected expression`
316err: `expected R_PAREN`
317err: `expected SEMI`
318err: `expected expression`
319err: `expected SEMI`
320err: `expected expression`
321err: `expected SEMI`
322err: `expected expression`
323err: `expected SEMI`
324err: `expected expression`
325err: `expected SEMI`
diff --git a/crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt b/crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt
index 27a0884f9..fa92f0845 100644
--- a/crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt
@@ -29,7 +29,7 @@ SOURCE_FILE@[0; 24)
29 NAME_REF@[19; 20) 29 NAME_REF@[19; 20)
30 IDENT@[19; 20) "a" 30 IDENT@[19; 20) "a"
31 DOT@[20; 21) "." 31 DOT@[20; 21) "."
32 err: `expected field name or number`
33 WHITESPACE@[21; 22) "\n" 32 WHITESPACE@[21; 22) "\n"
34 R_CURLY@[22; 23) "}" 33 R_CURLY@[22; 23) "}"
35 WHITESPACE@[23; 24) "\n" 34 WHITESPACE@[23; 24) "\n"
35err: `expected field name or number`
diff --git a/crates/ra_syntax/tests/data/parser/err/0030_string_suffixes.txt b/crates/ra_syntax/tests/data/parser/err/0030_string_suffixes.txt
index e0e38d37d..fb6d3c9c7 100644
--- a/crates/ra_syntax/tests/data/parser/err/0030_string_suffixes.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0030_string_suffixes.txt
@@ -21,7 +21,6 @@ SOURCE_FILE@[0; 112)
21 WHITESPACE@[23; 24) " " 21 WHITESPACE@[23; 24) " "
22 LITERAL@[24; 27) 22 LITERAL@[24; 27)
23 CHAR@[24; 27) "\'c\'" 23 CHAR@[24; 27) "\'c\'"
24 err: `expected SEMI`
25 EXPR_STMT@[27; 31) 24 EXPR_STMT@[27; 31)
26 PATH_EXPR@[27; 30) 25 PATH_EXPR@[27; 30)
27 PATH@[27; 30) 26 PATH@[27; 30)
@@ -68,3 +67,4 @@ SOURCE_FILE@[0; 112)
68 WHITESPACE@[109; 110) "\n" 67 WHITESPACE@[109; 110) "\n"
69 R_CURLY@[110; 111) "}" 68 R_CURLY@[110; 111) "}"
70 WHITESPACE@[111; 112) "\n" 69 WHITESPACE@[111; 112) "\n"
70err: `expected SEMI`
diff --git a/crates/ra_syntax/tests/data/parser/err/0031_block_inner_attrs.txt b/crates/ra_syntax/tests/data/parser/err/0031_block_inner_attrs.txt
index 80a973d4d..b4ec999b1 100644
--- a/crates/ra_syntax/tests/data/parser/err/0031_block_inner_attrs.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0031_block_inner_attrs.txt
@@ -24,7 +24,6 @@ SOURCE_FILE@[0; 350)
24 BLOCK@[29; 128) 24 BLOCK@[29; 128)
25 L_CURLY@[29; 30) "{" 25 L_CURLY@[29; 30) "{"
26 WHITESPACE@[30; 39) "\n " 26 WHITESPACE@[30; 39) "\n "
27 err: `A block in this position cannot accept inner attributes`
28 ATTR@[39; 83) 27 ATTR@[39; 83)
29 POUND@[39; 40) "#" 28 POUND@[39; 40) "#"
30 EXCL@[40; 41) "!" 29 EXCL@[40; 41) "!"
@@ -53,7 +52,6 @@ SOURCE_FILE@[0; 350)
53 BLOCK@[142; 257) 52 BLOCK@[142; 257)
54 L_CURLY@[142; 143) "{" 53 L_CURLY@[142; 143) "{"
55 WHITESPACE@[143; 152) "\n " 54 WHITESPACE@[143; 152) "\n "
56 err: `A block in this position cannot accept inner attributes`
57 ATTR@[152; 171) 55 ATTR@[152; 171)
58 POUND@[152; 153) "#" 56 POUND@[152; 153) "#"
59 EXCL@[153; 154) "!" 57 EXCL@[153; 154) "!"
@@ -66,7 +64,6 @@ SOURCE_FILE@[0; 350)
66 R_PAREN@[169; 170) ")" 64 R_PAREN@[169; 170) ")"
67 R_BRACK@[170; 171) "]" 65 R_BRACK@[170; 171) "]"
68 WHITESPACE@[171; 180) "\n " 66 WHITESPACE@[171; 180) "\n "
69 err: `A block in this position cannot accept inner attributes`
70 ATTR@[180; 212) 67 ATTR@[180; 212)
71 POUND@[180; 181) "#" 68 POUND@[180; 181) "#"
72 EXCL@[181; 182) "!" 69 EXCL@[181; 182) "!"
@@ -93,7 +90,6 @@ SOURCE_FILE@[0; 350)
93 BLOCK@[273; 347) 90 BLOCK@[273; 347)
94 L_CURLY@[273; 274) "{" 91 L_CURLY@[273; 274) "{"
95 WHITESPACE@[274; 283) "\n " 92 WHITESPACE@[274; 283) "\n "
96 err: `A block in this position cannot accept inner attributes`
97 ATTR@[283; 302) 93 ATTR@[283; 302)
98 POUND@[283; 284) "#" 94 POUND@[283; 284) "#"
99 EXCL@[284; 285) "!" 95 EXCL@[284; 285) "!"
@@ -112,3 +108,7 @@ SOURCE_FILE@[0; 350)
112 WHITESPACE@[347; 348) "\n" 108 WHITESPACE@[347; 348) "\n"
113 R_CURLY@[348; 349) "}" 109 R_CURLY@[348; 349) "}"
114 WHITESPACE@[349; 350) "\n" 110 WHITESPACE@[349; 350) "\n"
111err: `A block in this position cannot accept inner attributes`
112err: `A block in this position cannot accept inner attributes`
113err: `A block in this position cannot accept inner attributes`
114err: `A block in this position cannot accept inner attributes`
diff --git a/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt
index 92e3a1ee8..a3c53f353 100644
--- a/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt
@@ -36,11 +36,8 @@ SOURCE_FILE@[0; 293)
36 MATCH_ARM@[51; 78) 36 MATCH_ARM@[51; 78)
37 ATTR@[51; 52) 37 ATTR@[51; 52)
38 POUND@[51; 52) "#" 38 POUND@[51; 52) "#"
39 err: `expected `[``
40 err: `expected pattern`
41 ERROR@[52; 53) 39 ERROR@[52; 53)
42 EXCL@[52; 53) "!" 40 EXCL@[52; 53) "!"
43 err: `expected FAT_ARROW`
44 ARRAY_EXPR@[53; 78) 41 ARRAY_EXPR@[53; 78)
45 L_BRACK@[53; 54) "[" 42 L_BRACK@[53; 54) "["
46 CALL_EXPR@[54; 77) 43 CALL_EXPR@[54; 77)
@@ -55,7 +52,6 @@ SOURCE_FILE@[0; 293)
55 STRING@[58; 76) "\"Not allowed here\"" 52 STRING@[58; 76) "\"Not allowed here\""
56 R_PAREN@[76; 77) ")" 53 R_PAREN@[76; 77) ")"
57 R_BRACK@[77; 78) "]" 54 R_BRACK@[77; 78) "]"
58 err: `expected COMMA`
59 WHITESPACE@[78; 87) "\n " 55 WHITESPACE@[78; 87) "\n "
60 MATCH_ARM@[87; 94) 56 MATCH_ARM@[87; 94)
61 PLACEHOLDER_PAT@[87; 88) 57 PLACEHOLDER_PAT@[87; 88)
@@ -106,11 +102,8 @@ SOURCE_FILE@[0; 293)
106 MATCH_ARM@[160; 179) 102 MATCH_ARM@[160; 179)
107 ATTR@[160; 161) 103 ATTR@[160; 161)
108 POUND@[160; 161) "#" 104 POUND@[160; 161) "#"
109 err: `expected `[``
110 err: `expected pattern`
111 ERROR@[161; 162) 105 ERROR@[161; 162)
112 EXCL@[161; 162) "!" 106 EXCL@[161; 162) "!"
113 err: `expected FAT_ARROW`
114 ARRAY_EXPR@[162; 179) 107 ARRAY_EXPR@[162; 179)
115 L_BRACK@[162; 163) "[" 108 L_BRACK@[162; 163) "["
116 CALL_EXPR@[163; 178) 109 CALL_EXPR@[163; 178)
@@ -152,11 +145,8 @@ SOURCE_FILE@[0; 293)
152 WHITESPACE@[222; 231) "\n " 145 WHITESPACE@[222; 231) "\n "
153 ATTR@[231; 232) 146 ATTR@[231; 232)
154 POUND@[231; 232) "#" 147 POUND@[231; 232) "#"
155 err: `expected `[``
156 err: `expected pattern`
157 ERROR@[232; 233) 148 ERROR@[232; 233)
158 EXCL@[232; 233) "!" 149 EXCL@[232; 233) "!"
159 err: `expected FAT_ARROW`
160 ARRAY_EXPR@[233; 250) 150 ARRAY_EXPR@[233; 250)
161 L_BRACK@[233; 234) "[" 151 L_BRACK@[233; 234) "["
162 CALL_EXPR@[234; 249) 152 CALL_EXPR@[234; 249)
@@ -171,7 +161,6 @@ SOURCE_FILE@[0; 293)
171 STRING@[238; 248) "\"Nor here\"" 161 STRING@[238; 248) "\"Nor here\""
172 R_PAREN@[248; 249) ")" 162 R_PAREN@[248; 249) ")"
173 R_BRACK@[249; 250) "]" 163 R_BRACK@[249; 250) "]"
174 err: `expected COMMA`
175 WHITESPACE@[250; 259) "\n " 164 WHITESPACE@[250; 259) "\n "
176 MATCH_ARM@[259; 266) 165 MATCH_ARM@[259; 266)
177 PLACEHOLDER_PAT@[259; 260) 166 PLACEHOLDER_PAT@[259; 260)
@@ -199,3 +188,14 @@ SOURCE_FILE@[0; 293)
199 WHITESPACE@[290; 291) "\n" 188 WHITESPACE@[290; 291) "\n"
200 R_CURLY@[291; 292) "}" 189 R_CURLY@[291; 292) "}"
201 WHITESPACE@[292; 293) "\n" 190 WHITESPACE@[292; 293) "\n"
191err: `expected `[``
192err: `expected pattern`
193err: `expected FAT_ARROW`
194err: `expected COMMA`
195err: `expected `[``
196err: `expected pattern`
197err: `expected FAT_ARROW`
198err: `expected `[``
199err: `expected pattern`
200err: `expected FAT_ARROW`
201err: `expected COMMA`
diff --git a/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt
index ac9cb63f7..7bcf5ec81 100644
--- a/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt
@@ -54,11 +54,11 @@ SOURCE_FILE@[0; 89)
54 IDENT@[74; 78) "test" 54 IDENT@[74; 78) "test"
55 R_PAREN@[78; 79) ")" 55 R_PAREN@[78; 79) ")"
56 R_BRACK@[79; 80) "]" 56 R_BRACK@[79; 80) "]"
57 err: `expected pattern`
58 err: `expected FAT_ARROW`
59 err: `expected expression`
60 WHITESPACE@[80; 85) "\n " 57 WHITESPACE@[80; 85) "\n "
61 R_CURLY@[85; 86) "}" 58 R_CURLY@[85; 86) "}"
62 WHITESPACE@[86; 87) "\n" 59 WHITESPACE@[86; 87) "\n"
63 R_CURLY@[87; 88) "}" 60 R_CURLY@[87; 88) "}"
64 WHITESPACE@[88; 89) "\n" 61 WHITESPACE@[88; 89) "\n"
62err: `expected pattern`
63err: `expected FAT_ARROW`
64err: `expected expression`
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0001_array_type_missing_semi.txt b/crates/ra_syntax/tests/data/parser/inline/err/0001_array_type_missing_semi.txt
index 3020f9086..eb6d98fcd 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0001_array_type_missing_semi.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0001_array_type_missing_semi.txt
@@ -12,16 +12,16 @@ SOURCE_FILE@[0; 18)
12 TUPLE_TYPE@[10; 12) 12 TUPLE_TYPE@[10; 12)
13 L_PAREN@[10; 11) "(" 13 L_PAREN@[10; 11) "("
14 R_PAREN@[11; 12) ")" 14 R_PAREN@[11; 12) ")"
15 err: `expected `;` or `]``
16 err: `expected SEMI`
17 WHITESPACE@[12; 13) " " 15 WHITESPACE@[12; 13) " "
18 err: `expected an item`
19 ERROR@[13; 15) 16 ERROR@[13; 15)
20 INT_NUMBER@[13; 15) "92" 17 INT_NUMBER@[13; 15) "92"
21 err: `expected an item`
22 ERROR@[15; 16) 18 ERROR@[15; 16)
23 R_BRACK@[15; 16) "]" 19 R_BRACK@[15; 16) "]"
24 err: `expected an item`
25 ERROR@[16; 17) 20 ERROR@[16; 17)
26 SEMI@[16; 17) ";" 21 SEMI@[16; 17) ";"
27 WHITESPACE@[17; 18) "\n" 22 WHITESPACE@[17; 18) "\n"
23err: `expected `;` or `]``
24err: `expected SEMI`
25err: `expected an item`
26err: `expected an item`
27err: `expected an item`
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0002_misplaced_label_err.txt b/crates/ra_syntax/tests/data/parser/inline/err/0002_misplaced_label_err.txt
index d61d8e73e..b1d104bd4 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0002_misplaced_label_err.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0002_misplaced_label_err.txt
@@ -16,13 +16,13 @@ SOURCE_FILE@[0; 30)
16 LABEL@[16; 22) 16 LABEL@[16; 22)
17 LIFETIME@[16; 21) "\'loop" 17 LIFETIME@[16; 21) "\'loop"
18 COLON@[21; 22) ":" 18 COLON@[21; 22) ":"
19 err: `expected a loop`
20 err: `expected SEMI`
21 WHITESPACE@[22; 23) " " 19 WHITESPACE@[22; 23) " "
22 IMPL_BLOCK@[23; 27) 20 IMPL_BLOCK@[23; 27)
23 IMPL_KW@[23; 27) "impl" 21 IMPL_KW@[23; 27) "impl"
24 err: `expected type`
25 err: `expected `{``
26 WHITESPACE@[27; 28) "\n" 22 WHITESPACE@[27; 28) "\n"
27 R_CURLY@[28; 29) "}" 23 R_CURLY@[28; 29) "}"
28 WHITESPACE@[29; 30) "\n" 24 WHITESPACE@[29; 30) "\n"
25err: `expected a loop`
26err: `expected SEMI`
27err: `expected type`
28err: `expected `{``
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0003_pointer_type_no_mutability.txt b/crates/ra_syntax/tests/data/parser/inline/err/0003_pointer_type_no_mutability.txt
index 3d7a6a745..b470d9ad1 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0003_pointer_type_no_mutability.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0003_pointer_type_no_mutability.txt
@@ -9,9 +9,9 @@ SOURCE_FILE@[0; 14)
9 WHITESPACE@[8; 9) " " 9 WHITESPACE@[8; 9) " "
10 POINTER_TYPE@[9; 12) 10 POINTER_TYPE@[9; 12)
11 STAR@[9; 10) "*" 11 STAR@[9; 10) "*"
12 err: `expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate)`
13 TUPLE_TYPE@[10; 12) 12 TUPLE_TYPE@[10; 12)
14 L_PAREN@[10; 11) "(" 13 L_PAREN@[10; 11) "("
15 R_PAREN@[11; 12) ")" 14 R_PAREN@[11; 12) ")"
16 SEMI@[12; 13) ";" 15 SEMI@[12; 13) ";"
17 WHITESPACE@[13; 14) "\n" 16 WHITESPACE@[13; 14) "\n"
17err: `expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate)`
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0004_impl_type.txt b/crates/ra_syntax/tests/data/parser/inline/err/0004_impl_type.txt
index 86f84459a..ef4e0d5dd 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0004_impl_type.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0004_impl_type.txt
@@ -35,8 +35,6 @@ SOURCE_FILE@[0; 87)
35 WHITESPACE@[33; 34) "\n" 35 WHITESPACE@[33; 34) "\n"
36 IMPL_BLOCK@[34; 38) 36 IMPL_BLOCK@[34; 38)
37 IMPL_KW@[34; 38) "impl" 37 IMPL_KW@[34; 38) "impl"
38 err: `expected trait or type`
39 err: `expected `{``
40 WHITESPACE@[38; 39) " " 38 WHITESPACE@[38; 39) " "
41 IMPL_BLOCK@[39; 54) 39 IMPL_BLOCK@[39; 54)
42 IMPL_KW@[39; 43) "impl" 40 IMPL_KW@[39; 43) "impl"
@@ -61,8 +59,6 @@ SOURCE_FILE@[0; 87)
61 IDENT@[60; 66) "Trait2" 59 IDENT@[60; 66) "Trait2"
62 WHITESPACE@[66; 67) " " 60 WHITESPACE@[66; 67) " "
63 FOR_KW@[67; 70) "for" 61 FOR_KW@[67; 70) "for"
64 err: `expected trait or type`
65 err: `expected `{``
66 WHITESPACE@[70; 71) " " 62 WHITESPACE@[70; 71) " "
67 IMPL_BLOCK@[71; 86) 63 IMPL_BLOCK@[71; 86)
68 IMPL_KW@[71; 75) "impl" 64 IMPL_KW@[71; 75) "impl"
@@ -77,3 +73,7 @@ SOURCE_FILE@[0; 87)
77 L_CURLY@[84; 85) "{" 73 L_CURLY@[84; 85) "{"
78 R_CURLY@[85; 86) "}" 74 R_CURLY@[85; 86) "}"
79 WHITESPACE@[86; 87) "\n" 75 WHITESPACE@[86; 87) "\n"
76err: `expected trait or type`
77err: `expected `{``
78err: `expected trait or type`
79err: `expected `{``
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt b/crates/ra_syntax/tests/data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt
index 4587525aa..41e623b41 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt
@@ -8,16 +8,16 @@ SOURCE_FILE@[0; 20)
8 EQ@[7; 8) "=" 8 EQ@[7; 8) "="
9 WHITESPACE@[8; 9) " " 9 WHITESPACE@[8; 9) " "
10 UNSAFE_KW@[9; 15) "unsafe" 10 UNSAFE_KW@[9; 15) "unsafe"
11 err: `expected `fn``
12 err: `expected SEMI`
13 WHITESPACE@[15; 16) " " 11 WHITESPACE@[15; 16) " "
14 err: `expected an item`
15 ERROR@[16; 17) 12 ERROR@[16; 17)
16 L_PAREN@[16; 17) "(" 13 L_PAREN@[16; 17) "("
17 err: `expected an item`
18 ERROR@[17; 18) 14 ERROR@[17; 18)
19 R_PAREN@[17; 18) ")" 15 R_PAREN@[17; 18) ")"
20 err: `expected an item`
21 ERROR@[18; 19) 16 ERROR@[18; 19)
22 SEMI@[18; 19) ";" 17 SEMI@[18; 19) ";"
23 WHITESPACE@[19; 20) "\n" 18 WHITESPACE@[19; 20) "\n"
19err: `expected `fn``
20err: `expected SEMI`
21err: `expected an item`
22err: `expected an item`
23err: `expected an item`
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0006_unsafe_block_in_mod.txt b/crates/ra_syntax/tests/data/parser/inline/err/0006_unsafe_block_in_mod.txt
index fefa35c20..f1d0dd5c6 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0006_unsafe_block_in_mod.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0006_unsafe_block_in_mod.txt
@@ -11,11 +11,9 @@ SOURCE_FILE@[0; 33)
11 L_CURLY@[8; 9) "{" 11 L_CURLY@[8; 9) "{"
12 R_CURLY@[9; 10) "}" 12 R_CURLY@[9; 10) "}"
13 WHITESPACE@[10; 11) " " 13 WHITESPACE@[10; 11) " "
14 err: `expected an item`
15 ERROR@[11; 17) 14 ERROR@[11; 17)
16 UNSAFE_KW@[11; 17) "unsafe" 15 UNSAFE_KW@[11; 17) "unsafe"
17 WHITESPACE@[17; 18) " " 16 WHITESPACE@[17; 18) " "
18 err: `expected an item`
19 ERROR@[18; 21) 17 ERROR@[18; 21)
20 L_CURLY@[18; 19) "{" 18 L_CURLY@[18; 19) "{"
21 WHITESPACE@[19; 20) " " 19 WHITESPACE@[19; 20) " "
@@ -33,3 +31,5 @@ SOURCE_FILE@[0; 33)
33 L_CURLY@[30; 31) "{" 31 L_CURLY@[30; 31) "{"
34 R_CURLY@[31; 32) "}" 32 R_CURLY@[31; 32) "}"
35 WHITESPACE@[32; 33) "\n" 33 WHITESPACE@[32; 33) "\n"
34err: `expected an item`
35err: `expected an item`
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0007_async_without_semicolon.txt b/crates/ra_syntax/tests/data/parser/inline/err/0007_async_without_semicolon.txt
index 8afcd5429..1a8fa029c 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0007_async_without_semicolon.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0007_async_without_semicolon.txt
@@ -25,7 +25,7 @@ SOURCE_FILE@[0; 30)
25 BLOCK@[25; 27) 25 BLOCK@[25; 27)
26 L_CURLY@[25; 26) "{" 26 L_CURLY@[25; 26) "{"
27 R_CURLY@[26; 27) "}" 27 R_CURLY@[26; 27) "}"
28 err: `expected SEMI`
29 WHITESPACE@[27; 28) " " 28 WHITESPACE@[27; 28) " "
30 R_CURLY@[28; 29) "}" 29 R_CURLY@[28; 29) "}"
31 WHITESPACE@[29; 30) "\n" 30 WHITESPACE@[29; 30) "\n"
31err: `expected SEMI`
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.txt b/crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.txt
index 1af31c48b..cadbbc078 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.txt
@@ -14,7 +14,6 @@ SOURCE_FILE@[0; 21)
14 ERROR@[11; 14) 14 ERROR@[11; 14)
15 VISIBILITY@[11; 14) 15 VISIBILITY@[11; 14)
16 PUB_KW@[11; 14) "pub" 16 PUB_KW@[11; 14) "pub"
17 err: `expected an item`
18 WHITESPACE@[14; 15) " " 17 WHITESPACE@[14; 15) " "
19 EXPR_STMT@[15; 18) 18 EXPR_STMT@[15; 18)
20 LITERAL@[15; 17) 19 LITERAL@[15; 17)
@@ -23,3 +22,4 @@ SOURCE_FILE@[0; 21)
23 WHITESPACE@[18; 19) " " 22 WHITESPACE@[18; 19) " "
24 R_CURLY@[19; 20) "}" 23 R_CURLY@[19; 20) "}"
25 WHITESPACE@[20; 21) "\n" 24 WHITESPACE@[20; 21) "\n"
25err: `expected an item`
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt b/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt
index 9d50a520f..8e7d7d241 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt
@@ -27,7 +27,6 @@ SOURCE_FILE@[0; 48)
27 WHITESPACE@[22; 23) " " 27 WHITESPACE@[22; 23) " "
28 LITERAL@[23; 24) 28 LITERAL@[23; 24)
29 INT_NUMBER@[23; 24) "2" 29 INT_NUMBER@[23; 24) "2"
30 err: `attributes are not allowed on BIN_EXPR`
31 SEMI@[24; 25) ";" 30 SEMI@[24; 25) ";"
32 WHITESPACE@[25; 29) "\n " 31 WHITESPACE@[25; 29) "\n "
33 EXPR_STMT@[29; 45) 32 EXPR_STMT@[29; 45)
@@ -48,8 +47,9 @@ SOURCE_FILE@[0; 48)
48 BLOCK@[42; 44) 47 BLOCK@[42; 44)
49 L_CURLY@[42; 43) "{" 48 L_CURLY@[42; 43) "{"
50 R_CURLY@[43; 44) "}" 49 R_CURLY@[43; 44) "}"
51 err: `attributes are not allowed on IF_EXPR`
52 SEMI@[44; 45) ";" 50 SEMI@[44; 45) ";"
53 WHITESPACE@[45; 46) "\n" 51 WHITESPACE@[45; 46) "\n"
54 R_CURLY@[46; 47) "}" 52 R_CURLY@[46; 47) "}"
55 WHITESPACE@[47; 48) "\n" 53 WHITESPACE@[47; 48) "\n"
54err: `attributes are not allowed on BIN_EXPR`
55err: `attributes are not allowed on IF_EXPR`
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.txt b/crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.txt
index c111f60ea..36717439e 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.txt
@@ -19,7 +19,6 @@ SOURCE_FILE@[0; 47)
19 NAME_REF@[15; 16) 19 NAME_REF@[15; 16)
20 IDENT@[15; 16) "x" 20 IDENT@[15; 16) "x"
21 DOT@[16; 17) "." 21 DOT@[16; 17) "."
22 err: `Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix`
23 FLOAT_NUMBER@[17; 19) "0." 22 FLOAT_NUMBER@[17; 19) "0."
24 SEMI@[19; 20) ";" 23 SEMI@[19; 20) ";"
25 WHITESPACE@[20; 25) "\n " 24 WHITESPACE@[20; 25) "\n "
@@ -31,7 +30,6 @@ SOURCE_FILE@[0; 47)
31 NAME_REF@[25; 26) 30 NAME_REF@[25; 26)
32 IDENT@[25; 26) "x" 31 IDENT@[25; 26) "x"
33 DOT@[26; 27) "." 32 DOT@[26; 27) "."
34 err: `Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix`
35 INT_NUMBER@[27; 31) "1i32" 33 INT_NUMBER@[27; 31) "1i32"
36 SEMI@[31; 32) ";" 34 SEMI@[31; 32) ";"
37 WHITESPACE@[32; 37) "\n " 35 WHITESPACE@[32; 37) "\n "
@@ -43,9 +41,11 @@ SOURCE_FILE@[0; 47)
43 NAME_REF@[37; 38) 41 NAME_REF@[37; 38)
44 IDENT@[37; 38) "x" 42 IDENT@[37; 38) "x"
45 DOT@[38; 39) "." 43 DOT@[38; 39) "."
46 err: `Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix`
47 INT_NUMBER@[39; 43) "0x01" 44 INT_NUMBER@[39; 43) "0x01"
48 SEMI@[43; 44) ";" 45 SEMI@[43; 44) ";"
49 WHITESPACE@[44; 45) "\n" 46 WHITESPACE@[44; 45) "\n"
50 R_CURLY@[45; 46) "}" 47 R_CURLY@[45; 46) "}"
51 WHITESPACE@[46; 47) "\n" 48 WHITESPACE@[46; 47) "\n"
49err: `Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix`
50err: `Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix`
51err: `Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix`
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt b/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt
index 220191ffa..5f39e7238 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt
@@ -1,7 +1,6 @@
1SOURCE_FILE@[0; 50) 1SOURCE_FILE@[0; 50)
2 ERROR@[0; 5) 2 ERROR@[0; 5)
3 ASYNC_KW@[0; 5) "async" 3 ASYNC_KW@[0; 5) "async"
4 err: `expected fn, trait or impl`
5 WHITESPACE@[5; 6) " " 4 WHITESPACE@[5; 6) " "
6 FN_DEF@[6; 24) 5 FN_DEF@[6; 24)
7 UNSAFE_KW@[6; 12) "unsafe" 6 UNSAFE_KW@[6; 12) "unsafe"
@@ -20,7 +19,6 @@ SOURCE_FILE@[0; 50)
20 WHITESPACE@[24; 25) "\n" 19 WHITESPACE@[24; 25) "\n"
21 ERROR@[25; 31) 20 ERROR@[25; 31)
22 UNSAFE_KW@[25; 31) "unsafe" 21 UNSAFE_KW@[25; 31) "unsafe"
23 err: `expected fn, trait or impl`
24 WHITESPACE@[31; 32) " " 22 WHITESPACE@[31; 32) " "
25 FN_DEF@[32; 49) 23 FN_DEF@[32; 49)
26 CONST_KW@[32; 37) "const" 24 CONST_KW@[32; 37) "const"
@@ -37,3 +35,5 @@ SOURCE_FILE@[0; 50)
37 L_CURLY@[47; 48) "{" 35 L_CURLY@[47; 48) "{"
38 R_CURLY@[48; 49) "}" 36 R_CURLY@[48; 49) "}"
39 WHITESPACE@[49; 50) "\n" 37 WHITESPACE@[49; 50) "\n"
38err: `expected fn, trait or impl`
39err: `expected fn, trait or impl`
diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs
index 91799f8b5..f31e12588 100644
--- a/crates/ra_syntax/tests/test.rs
+++ b/crates/ra_syntax/tests/test.rs
@@ -8,7 +8,7 @@ use std::{
8}; 8};
9 9
10use test_utils::{project_dir, dir_tests, read_text, collect_tests}; 10use test_utils::{project_dir, dir_tests, read_text, collect_tests};
11use ra_syntax::{SourceFile, AstNode, fuzz}; 11use ra_syntax::{SourceFile, fuzz};
12 12
13#[test] 13#[test]
14fn lexer_tests() { 14fn lexer_tests() {
@@ -21,26 +21,21 @@ fn lexer_tests() {
21#[test] 21#[test]
22fn parser_tests() { 22fn parser_tests() {
23 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| { 23 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| {
24 let file = SourceFile::parse(text); 24 let parse = SourceFile::parse(text);
25 let errors = file.errors(); 25 let errors = parse.errors.as_slice();
26 assert_eq!( 26 assert_eq!(
27 &*errors, 27 errors,
28 &[] as &[ra_syntax::SyntaxError], 28 &[] as &[ra_syntax::SyntaxError],
29 "There should be no errors in the file {:?}", 29 "There should be no errors in the file {:?}",
30 path.display() 30 path.display(),
31 ); 31 );
32 file.syntax().debug_dump() 32 parse.debug_dump()
33 }); 33 });
34 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| { 34 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| {
35 let file = SourceFile::parse(text); 35 let parse = SourceFile::parse(text);
36 let errors = file.errors(); 36 let errors = parse.errors.as_slice();
37 assert_ne!( 37 assert!(!errors.is_empty(), "There should be errors in the file {:?}", path.display());
38 &*errors, 38 parse.debug_dump()
39 &[] as &[ra_syntax::SyntaxError],
40 "There should be errors in the file {:?}",
41 path.display()
42 );
43 file.syntax().debug_dump()
44 }); 39 });
45} 40}
46 41
@@ -83,9 +78,7 @@ fn self_hosting_parsing() {
83 { 78 {
84 count += 1; 79 count += 1;
85 let text = read_text(entry.path()); 80 let text = read_text(entry.path());
86 let node = SourceFile::parse(&text); 81 SourceFile::parse(&text).ok().expect("There should be no errors in the file");
87 let errors = node.errors();
88 assert_eq!(&*errors, &[], "There should be no errors in the file {:?}", entry);
89 } 82 }
90 assert!( 83 assert!(
91 count > 30, 84 count > 30,