about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates/syntax
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@dend.ro>2024-03-10 08:47:38 +0200
committerLaurențiu Nicola <lnicola@dend.ro>2024-03-10 08:47:38 +0200
commit56493e4cbd6262adae03e73aefb8a9e618a9fc2d (patch)
tree404d4a38aff53e1c880c2708478fdcaf0b2f6e61 /src/tools/rust-analyzer/crates/syntax
parent5bc7b9ac8ace5312e1d2cdc2722715cf58d4f926 (diff)
parent574e23ec508064613783cba3d1833a95fd9a5080 (diff)
downloadrust-56493e4cbd6262adae03e73aefb8a9e618a9fc2d.tar.gz
rust-56493e4cbd6262adae03e73aefb8a9e618a9fc2d.zip
Merge commit '574e23ec508064613783cba3d1833a95fd9a5080' into sync-from-ra
Diffstat (limited to 'src/tools/rust-analyzer/crates/syntax')
-rw-r--r--src/tools/rust-analyzer/crates/syntax/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs5
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/lib.rs22
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/parsing.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/tests.rs4
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/validation.rs31
6 files changed, 35 insertions, 30 deletions
diff --git a/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
index a0fd73ee13f..9a8d73cf7ff 100644
--- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
@@ -27,7 +27,6 @@ tracing.workspace = true
 ra-ap-rustc_lexer.workspace = true
 
 parser.workspace = true
-profile.workspace = true
 stdx.workspace = true
 text-edit.workspace = true
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
index f299dda4f0f..ff18fee9bab 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -724,7 +724,10 @@ pub fn record_pat_field_list(
 ) -> ast::RecordPatFieldList {
     let mut fields = fields.into_iter().join(", ");
     if let Some(rest_pat) = rest_pat {
-        format_to!(fields, ", {rest_pat}");
+        if !fields.is_empty() {
+            fields.push_str(", ");
+        }
+        format_to!(fields, "{rest_pat}");
     }
     ast_from_text(&format!("fn f(S {{ {fields} }}: ()))"))
 }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs
index b755de86d32..1bb82cc191f 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs
@@ -97,8 +97,11 @@ impl<T> Parse<T> {
     pub fn syntax_node(&self) -> SyntaxNode {
         SyntaxNode::new_root(self.green.clone())
     }
-    pub fn errors(&self) -> &[SyntaxError] {
-        self.errors.as_deref().unwrap_or_default()
+
+    pub fn errors(&self) -> Vec<SyntaxError> {
+        let mut errors = if let Some(e) = self.errors.as_deref() { e.to_vec() } else { vec![] };
+        validation::validate(&self.syntax_node(), &mut errors);
+        errors
     }
 }
 
@@ -111,10 +114,10 @@ impl<T: AstNode> Parse<T> {
         T::cast(self.syntax_node()).unwrap()
     }
 
-    pub fn ok(self) -> Result<T, Arc<[SyntaxError]>> {
-        match self.errors {
-            Some(e) => Err(e),
-            None => Ok(self.tree()),
+    pub fn ok(self) -> Result<T, Vec<SyntaxError>> {
+        match self.errors() {
+            errors if !errors.is_empty() => Err(errors),
+            _ => Ok(self.tree()),
         }
     }
 }
@@ -132,7 +135,7 @@ impl Parse<SyntaxNode> {
 impl Parse<SourceFile> {
     pub fn debug_dump(&self) -> String {
         let mut buf = format!("{:#?}", self.tree().syntax());
-        for err in self.errors.as_deref().into_iter().flat_map(<[_]>::iter) {
+        for err in self.errors() {
             format_to!(buf, "error {:?}: {}\n", err.range(), err);
         }
         buf
@@ -168,11 +171,10 @@ pub use crate::ast::SourceFile;
 
 impl SourceFile {
     pub fn parse(text: &str) -> Parse<SourceFile> {
-        let (green, mut errors) = parsing::parse_text(text);
+        let _p = tracing::span!(tracing::Level::INFO, "SourceFile::parse").entered();
+        let (green, errors) = parsing::parse_text(text);
         let root = SyntaxNode::new_root(green.clone());
 
-        errors.extend(validation::validate(&root));
-
         assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
         Parse {
             green,
diff --git a/src/tools/rust-analyzer/crates/syntax/src/parsing.rs b/src/tools/rust-analyzer/crates/syntax/src/parsing.rs
index 1250b5274c1..d750476f63c 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/parsing.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/parsing.rs
@@ -10,6 +10,7 @@ use crate::{syntax_node::GreenNode, SyntaxError, SyntaxTreeBuilder};
 pub(crate) use crate::parsing::reparsing::incremental_reparse;
 
 pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) {
+    let _p = tracing::span!(tracing::Level::INFO, "parse_text").entered();
     let lexed = parser::LexedStr::new(text);
     let parser_input = lexed.to_input();
     let parser_output = parser::TopEntryPoint::SourceFile.parse(&parser_input);
@@ -21,6 +22,7 @@ pub(crate) fn build_tree(
     lexed: parser::LexedStr<'_>,
     parser_output: parser::Output,
 ) -> (GreenNode, Vec<SyntaxError>, bool) {
+    let _p = tracing::span!(tracing::Level::INFO, "build_tree").entered();
     let mut builder = SyntaxTreeBuilder::default();
 
     let is_eof = lexed.intersperse_trivia(&parser_output, &mut |step| match step {
diff --git a/src/tools/rust-analyzer/crates/syntax/src/tests.rs b/src/tools/rust-analyzer/crates/syntax/src/tests.rs
index 4c0a538f712..5400071c4b6 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/tests.rs
@@ -39,7 +39,7 @@ fn benchmark_parser() {
     let tree = {
         let _b = bench("parsing");
         let p = SourceFile::parse(&data);
-        assert!(p.errors.is_none());
+        assert!(p.errors().is_empty());
         assert_eq!(p.tree().syntax.text_range().len(), 352474.into());
         p.tree()
     };
@@ -57,7 +57,7 @@ fn validation_tests() {
     dir_tests(&test_data_dir(), &["parser/validation"], "rast", |text, path| {
         let parse = SourceFile::parse(text);
         let errors = parse.errors();
-        assert_errors_are_present(errors, path);
+        assert_errors_are_present(&errors, path);
         parse.debug_dump()
     });
 }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/validation.rs b/src/tools/rust-analyzer/crates/syntax/src/validation.rs
index 5c5b26f525f..dbfab537fe5 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/validation.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/validation.rs
@@ -15,33 +15,32 @@ use crate::{
     SyntaxNode, SyntaxToken, TextSize, T,
 };
 
-pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
+pub(crate) fn validate(root: &SyntaxNode, errors: &mut Vec<SyntaxError>) {
+    let _p = tracing::span!(tracing::Level::INFO, "parser::validate").entered();
     // FIXME:
     // * Add unescape validation of raw string literals and raw byte string literals
     // * Add validation of doc comments are being attached to nodes
 
-    let mut errors = Vec::new();
     for node in root.descendants() {
         match_ast! {
             match node {
-                ast::Literal(it) => validate_literal(it, &mut errors),
-                ast::Const(it) => validate_const(it, &mut errors),
-                ast::BlockExpr(it) => block::validate_block_expr(it, &mut errors),
-                ast::FieldExpr(it) => validate_numeric_name(it.name_ref(), &mut errors),
-                ast::RecordExprField(it) => validate_numeric_name(it.name_ref(), &mut errors),
-                ast::Visibility(it) => validate_visibility(it, &mut errors),
-                ast::RangeExpr(it) => validate_range_expr(it, &mut errors),
-                ast::PathSegment(it) => validate_path_keywords(it, &mut errors),
-                ast::RefType(it) => validate_trait_object_ref_ty(it, &mut errors),
-                ast::PtrType(it) => validate_trait_object_ptr_ty(it, &mut errors),
-                ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, &mut errors),
-                ast::MacroRules(it) => validate_macro_rules(it, &mut errors),
-                ast::LetExpr(it) => validate_let_expr(it, &mut errors),
+                ast::Literal(it) => validate_literal(it, errors),
+                ast::Const(it) => validate_const(it, errors),
+                ast::BlockExpr(it) => block::validate_block_expr(it, errors),
+                ast::FieldExpr(it) => validate_numeric_name(it.name_ref(), errors),
+                ast::RecordExprField(it) => validate_numeric_name(it.name_ref(), errors),
+                ast::Visibility(it) => validate_visibility(it, errors),
+                ast::RangeExpr(it) => validate_range_expr(it, errors),
+                ast::PathSegment(it) => validate_path_keywords(it, errors),
+                ast::RefType(it) => validate_trait_object_ref_ty(it, errors),
+                ast::PtrType(it) => validate_trait_object_ptr_ty(it, errors),
+                ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, errors),
+                ast::MacroRules(it) => validate_macro_rules(it, errors),
+                ast::LetExpr(it) => validate_let_expr(it, errors),
                 _ => (),
             }
         }
     }
-    errors
 }
 
 fn rustc_unescape_error_to_string(err: unescape::EscapeError) -> (&'static str, bool) {