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>2023-02-13 13:55:14 +0200
committerLaurențiu Nicola <lnicola@dend.ro>2023-02-13 13:55:14 +0200
commitc4a2f065854f85fcee397d0b9e8e535e6770e1da (patch)
tree8c1bd3d231f9cc21a955d7a2a31551a279fd49fa /src/tools/rust-analyzer/crates/syntax
parent20081880ad2a98bbc8c8293f96c5b284d1584d86 (diff)
parentc97aae38f20f64daede9877212aff83c259a4faa (diff)
:arrow_up: rust-analyzer
Diffstat (limited to 'src/tools/rust-analyzer/crates/syntax')
-rw-r--r--src/tools/rust-analyzer/crates/syntax/Cargo.toml26
-rw-r--r--src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml7
-rw-r--r--src/tools/rust-analyzer/crates/syntax/rust.ungram2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast.rs30
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs1
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs21
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_node.rs1
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/utils.rs7
8 files changed, 73 insertions, 22 deletions
diff --git a/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
index 00743cca559..8fc493a23f5 100644
--- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
@@ -2,10 +2,12 @@
 name = "syntax"
 version = "0.0.0"
 description = "Comment and whitespace preserving parser for the Rust language"
-license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust-analyzer"
-edition = "2021"
-rust-version = "1.65"
+
+authors.workspace = true
+edition.workspace = true
+license.workspace = true
+rust-version.workspace = true
 
 [lib]
 doctest = false
@@ -14,26 +16,26 @@ doctest = false
 cov-mark = "2.0.0-pre.1"
 itertools = "0.10.5"
 rowan = "0.15.10"
-rustc_lexer = { version = "725.0.0", package = "rustc-ap-rustc_lexer" }
+rustc_lexer = { version = "727.0.0", package = "rustc-ap-rustc_lexer" }
 rustc-hash = "1.1.0"
-once_cell = "1.15.0"
+once_cell = "1.17.0"
 indexmap = "1.9.1"
 smol_str = "0.1.23"
 
-stdx = { path = "../stdx", version = "0.0.0" }
-text-edit = { path = "../text-edit", version = "0.0.0" }
-parser = { path = "../parser", version = "0.0.0" }
-profile = { path = "../profile", version = "0.0.0" }
+parser.workspace = true
+profile.workspace = true
+stdx.workspace = true
+text-edit.workspace = true
 
 [dev-dependencies]
-rayon = "1.5.3"
+rayon = "1.6.1"
 expect-test = "1.4.0"
 proc-macro2 = "1.0.47"
 quote = "1.0.20"
 ungrammar = "1.16.1"
 
-test-utils = { path = "../test-utils" }
-sourcegen = { path = "../sourcegen" }
+test-utils.workspace = true
+sourcegen.workspace = true
 
 [features]
 in-rust-tree = []
diff --git a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml
index f295c40065d..6070222f1f1 100644
--- a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml
@@ -1,18 +1,17 @@
-
 [package]
 name = "syntax-fuzz"
 version = "0.0.1"
 publish = false
 edition = "2021"
-rust-version = "1.65"
+rust-version = "1.66.1"
 
 [package.metadata]
 cargo-fuzz = true
 
 [dependencies]
 syntax = { path = "..", version = "0.0.0" }
-text_edit = { path = "../../text_edit", version = "0.0.0" }
-libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git" }
+text-edit = { path = "../../text-edit", version = "0.0.0" }
+libfuzzer-sys = "0.4.5"
 
 # Prevent this from interfering with workspaces
 [workspace]
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram
index 2c67586a390..36ad5fddfd0 100644
--- a/src/tools/rust-analyzer/crates/syntax/rust.ungram
+++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -452,7 +452,7 @@ FieldExpr =
   Attr* Expr '.' NameRef
 
 ClosureExpr =
-  Attr* ('for' GenericParamList)? 'static'? 'async'? 'move'?  ParamList RetType?
+  Attr* ('for' GenericParamList)? 'const'? 'static'? 'async'? 'move'?  ParamList RetType?
   body:Expr
 
 IfExpr =
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast.rs b/src/tools/rust-analyzer/crates/syntax/src/ast.rs
index 10c04575833..385a4e0a3ce 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast.rs
@@ -13,6 +13,8 @@ pub mod prec;
 
 use std::marker::PhantomData;
 
+use itertools::Either;
+
 use crate::{
     syntax_node::{SyntaxNode, SyntaxNodeChildren, SyntaxToken},
     SyntaxKind,
@@ -98,6 +100,34 @@ impl<N: AstNode> Iterator for AstChildren<N> {
     }
 }
 
+impl<L, R> AstNode for Either<L, R>
+where
+    L: AstNode,
+    R: AstNode,
+{
+    fn can_cast(kind: SyntaxKind) -> bool
+    where
+        Self: Sized,
+    {
+        L::can_cast(kind) || R::can_cast(kind)
+    }
+
+    fn cast(syntax: SyntaxNode) -> Option<Self>
+    where
+        Self: Sized,
+    {
+        if L::can_cast(syntax.kind()) {
+            L::cast(syntax).map(Either::Left)
+        } else {
+            R::cast(syntax).map(Either::Right)
+        }
+    }
+
+    fn syntax(&self) -> &SyntaxNode {
+        self.as_ref().either(L::syntax, R::syntax)
+    }
+}
+
 mod support {
     use super::{AstChildren, AstNode, SyntaxKind, SyntaxNode, SyntaxToken};
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
index a214a5e4462..642a3bfc35d 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
@@ -842,6 +842,7 @@ impl ast::HasAttrs for ClosureExpr {}
 impl ClosureExpr {
     pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
     pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
+    pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
     pub fn static_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![static]) }
     pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
     pub fn move_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![move]) }
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 d5b3296980c..5aebe4cd9f5 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -12,7 +12,7 @@
 use itertools::Itertools;
 use stdx::{format_to, never};
 
-use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxToken};
+use crate::{ast, utils::is_raw_identifier, AstNode, SourceFile, SyntaxKind, SyntaxToken};
 
 /// While the parent module defines basic atomic "constructors", the `ext`
 /// module defines shortcuts for common things.
@@ -111,8 +111,7 @@ pub fn name_ref(name_ref: &str) -> ast::NameRef {
     ast_from_text(&format!("fn f() {{ {raw_escape}{name_ref}; }}"))
 }
 fn raw_ident_esc(ident: &str) -> &'static str {
-    let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some();
-    if is_keyword && !matches!(ident, "self" | "crate" | "super" | "Self") {
+    if is_raw_identifier(ident) {
         "r#"
     } else {
         ""
@@ -520,6 +519,15 @@ pub fn literal_pat(lit: &str) -> ast::LiteralPat {
     }
 }
 
+pub fn slice_pat(pats: impl IntoIterator<Item = ast::Pat>) -> ast::SlicePat {
+    let pats_str = pats.into_iter().join(", ");
+    return from_text(&format!("[{pats_str}]"));
+
+    fn from_text(text: &str) -> ast::SlicePat {
+        ast_from_text(&format!("fn f() {{ match () {{{text} => ()}} }}"))
+    }
+}
+
 /// Creates a tuple of patterns from an iterator of patterns.
 ///
 /// Invariant: `pats` must be length > 0
@@ -814,6 +822,7 @@ pub fn fn_(
     visibility: Option<ast::Visibility>,
     fn_name: ast::Name,
     type_params: Option<ast::GenericParamList>,
+    where_clause: Option<ast::WhereClause>,
     params: ast::ParamList,
     body: ast::BlockExpr,
     ret_type: Option<ast::RetType>,
@@ -823,6 +832,10 @@ pub fn fn_(
         Some(type_params) => format!("{type_params}"),
         None => "".into(),
     };
+    let where_clause = match where_clause {
+        Some(it) => format!("{it} "),
+        None => "".into(),
+    };
     let ret_type = match ret_type {
         Some(ret_type) => format!("{ret_type} "),
         None => "".into(),
@@ -835,7 +848,7 @@ pub fn fn_(
     let async_literal = if is_async { "async " } else { "" };
 
     ast_from_text(&format!(
-        "{visibility}{async_literal}fn {fn_name}{type_params}{params} {ret_type}{body}",
+        "{visibility}{async_literal}fn {fn_name}{type_params}{params} {ret_type}{where_clause}{body}",
     ))
 }
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_node.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_node.rs
index a08c01597d3..2e9e0bc226b 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_node.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_node.rs
@@ -48,6 +48,7 @@ impl SyntaxTreeBuilder {
     pub fn finish(self) -> Parse<SyntaxNode> {
         let (green, errors) = self.finish_raw();
         // Disable block validation, see https://github.com/rust-lang/rust-analyzer/pull/10357
+        #[allow(clippy::overly_complex_bool_expr)]
         if cfg!(debug_assertions) && false {
             let node = SyntaxNode::new_root(green.clone());
             crate::validation::validate_block_structure(&node);
diff --git a/src/tools/rust-analyzer/crates/syntax/src/utils.rs b/src/tools/rust-analyzer/crates/syntax/src/utils.rs
index f4c02518b4c..25f34ea9d39 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/utils.rs
@@ -2,7 +2,7 @@
 
 use itertools::Itertools;
 
-use crate::{ast, match_ast, AstNode};
+use crate::{ast, match_ast, AstNode, SyntaxKind};
 
 pub fn path_to_string_stripping_turbo_fish(path: &ast::Path) -> String {
     path.syntax()
@@ -23,6 +23,11 @@ pub fn path_to_string_stripping_turbo_fish(path: &ast::Path) -> String {
         .join("::")
 }
 
+pub fn is_raw_identifier(name: &str) -> bool {
+    let is_keyword = SyntaxKind::from_keyword(name).is_some();
+    is_keyword && !matches!(name, "self" | "crate" | "super" | "Self")
+}
+
 #[cfg(test)]
 mod tests {
     use super::path_to_string_stripping_turbo_fish;