Skip to content

Incorrect handling of generic function calls #186

Description

@IlyasYOY

I found a problem in parsing code like this:

package main

func test[T any](t T) *T {
	return &t
}

func main() {
	val := test[int](123)
}

I get test[int](a) recognised as a type cast not as a function call.

Here are some tree-sitter tests patch:

diff --git a/test/corpus/expressions.txt b/test/corpus/expressions.txt
index 1b86acf..fd49e71 100644
--- a/test/corpus/expressions.txt
+++ b/test/corpus/expressions.txt
@@ -485,3 +485,104 @@ func main() {
               (call_expression
                 (identifier)
                 (argument_list)))))))))
+
+================================================================================
+Call function with generic parameter
+================================================================================
+
+package main
+
+func test[T any](t T) *T {
+	return &t
+}
+
+func main() {
+	val := test[int](123)
+}
+
+--------------------------------------------------------------------------------
+
+(source_file
+  (package_clause
+    (package_identifier))
+  (function_declaration
+    name: (identifier)
+    type_parameters: (type_parameter_list
+      (type_parameter_declaration
+        name: (identifier)
+        type: (type_constraint
+          (type_identifier))))
+    parameters: (parameter_list
+      (parameter_declaration
+        name: (identifier)
+        type: (type_identifier)))
+    result: (pointer_type
+      (type_identifier))
+    body: (block
+      (statement_list
+        (return_statement
+          (expression_list
+            (unary_expression
+              operand: (identifier)))))))
+  (function_declaration
+    name: (identifier)
+    parameters: (parameter_list)
+    body: (block
+      (statement_list
+        (short_var_declaration
+          left: (expression_list
+            (identifier))
+          right: (expression_list
+            (type_conversion_expression
+              type: (generic_type
+                type: (type_identifier)
+                type_arguments: (type_arguments
+                  (type_elem
+                    (type_identifier))))
+              operand: (int_literal))))))))
+
+================================================================================
+Call function without generic parameter
+================================================================================
+
+package main
+
+func test(t any) any {
+	return &t
+}
+
+func main() {
+	val := test(123)
+}
+
+--------------------------------------------------------------------------------
+
+(source_file
+  (package_clause
+    (package_identifier))
+  (function_declaration
+    name: (identifier)
+    parameters: (parameter_list
+      (parameter_declaration
+        name: (identifier)
+        type: (type_identifier)))
+    result: (type_identifier)
+    body: (block
+      (statement_list
+        (return_statement
+          (expression_list
+            (unary_expression
+              operand: (identifier)))))))
+  (function_declaration
+    name: (identifier)
+    parameters: (parameter_list)
+    body: (block
+      (statement_list
+        (short_var_declaration
+          left: (expression_list
+            (identifier))
+          right: (expression_list
+            (call_expression
+              function: (identifier)
+              arguments: (argument_list
+                (int_literal)))))))))

Both tests pass and the first one shows that expression is not recognized correctly: type_conversion_expression.

Here is the snippet from go doc:

When using a generic function, type arguments may be provided explicitly, or they may be partially or completely inferred from the context in which the function is used. Provided that they can be inferred, type argument lists may be omitted entirely


I found issue during neovim usage. Function wasn't colored correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions