diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index af385b020c..3b081a6b33 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2278,9 +2278,17 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { method = m has_method = true } else { - if left_type_sym.info is ast.Struct { - if left_type_sym.info.parent_type != 0 { - type_sym := c.table.get_type_symbol(left_type_sym.info.parent_type) + if left_type_sym.kind in [.struct_, .sum_type, .interface_] { + mut parent_type := ast.void_type + if left_type_sym.info is ast.Struct { + parent_type = left_type_sym.info.parent_type + } else if left_type_sym.info is ast.SumType { + parent_type = left_type_sym.info.parent_type + } else if left_type_sym.info is ast.Interface { + parent_type = left_type_sym.info.parent_type + } + if parent_type != 0 { + type_sym := c.table.get_type_symbol(parent_type) if m := c.table.type_find_method(type_sym, method_name) { method = m has_method = true diff --git a/vlib/v/tests/generic_sumtype_method_test.v b/vlib/v/tests/generic_sumtype_method_test.v new file mode 100644 index 0000000000..1e564a1d76 --- /dev/null +++ b/vlib/v/tests/generic_sumtype_method_test.v @@ -0,0 +1,32 @@ +struct Empty {} + +struct Node { + value T + left Leaf + right Leaf +} + +type Leaf = Empty | Node + +// return size(number of nodes) of BST +fn (leaf Leaf) size() int { + return match leaf { + Empty { 0 } + Node { 1 + leaf.left.size() + leaf.right.size() } + } +} + +fn test_generic_sumtype_method() { + r := Node{ + value: 20 + left: Empty{} + right: Empty{} + } + tree := Leaf(Node{ + value: 10 + left: Empty{} + right: r + }) + println(tree.size()) + assert tree.size() == 2 +}