From 8a2236d3f8ee6feee34bca2cd52b532fbadb3980 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 6 Jun 2022 17:30:48 +0800 Subject: [PATCH] cgen: fix generic interface with non-generic method (#14694) --- vlib/v/gen/c/cgen.v | 4 +- ...s_interface_with_non_generic_method_test.v | 45 +++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/generics_interface_with_non_generic_method_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index e8d177bd0e..b26ad28a6e 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5743,7 +5743,7 @@ static inline __shared__$interface_name ${shared_fn_name}(__shared__$cctype* x) for method in methods { mut name := method.name - if inter_info.parent_type.has_flag(.generic) { + if method.generic_names.len > 0 && inter_info.parent_type.has_flag(.generic) { parent_sym := g.table.sym(inter_info.parent_type) match parent_sym.info { ast.Struct, ast.Interface, ast.SumType { @@ -5760,7 +5760,7 @@ static inline __shared__$interface_name ${shared_fn_name}(__shared__$cctype* x) } // .speak = Cat_speak if st_sym.info is ast.Struct { - if st_sym.info.parent_type.has_flag(.generic) { + if method.generic_names.len > 0 && st_sym.info.parent_type.has_flag(.generic) { name = g.generic_fn_name(st_sym.info.concrete_types, method.name, false) } diff --git a/vlib/v/tests/generics_interface_with_non_generic_method_test.v b/vlib/v/tests/generics_interface_with_non_generic_method_test.v new file mode 100644 index 0000000000..3d95b533bf --- /dev/null +++ b/vlib/v/tests/generics_interface_with_non_generic_method_test.v @@ -0,0 +1,45 @@ +module main + +interface TypeFactory { + get_type(type_name string) T +} + +enum NodeType { + unknown + expression + statement + literal +} + +struct EnumTypeFactory {} + +fn (f EnumTypeFactory) get_type(type_name string) NodeType { + return match type_name { + 'expression' { NodeType.expression } + 'statement' { NodeType.statement } + 'literal' { NodeType.literal } + else { NodeType.unknown } + } +} + +struct Node { + factory TypeFactory + type_name NodeType +} + +fn new_node(type_name string, factory TypeFactory) Node { + return Node{ + factory: factory + type_name: factory.get_type(type_name) + } +} + +fn test_generic_interface_with_non_generic_method() { + root1 := new_node('literal', EnumTypeFactory{}) + println(root1) + assert root1.type_name == .literal + + root2 := new_node('expression', root1.factory) + println(root2) + assert root2.type_name == .expression +}