diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 1e7d9a364c..b91dfa1e26 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1471,7 +1471,37 @@ fn (mut g Gen) call_args(node ast.CallExpr) { } else { node.args } - expected_types := node.expected_arg_types + mut expected_types := node.expected_arg_types + // unwrap generics fn/method arguments to concretes + if node.concrete_types.len > 0 && node.concrete_types.all(!it.has_flag(.generic)) { + if node.is_method { + if func := g.table.find_method(g.table.sym(node.left_type), node.name) { + if func.generic_names.len > 0 { + for i in 0 .. expected_types.len { + mut muttable := unsafe { &ast.Table(g.table) } + if utyp := muttable.resolve_generic_to_concrete(node.expected_arg_types[i], + func.generic_names, node.concrete_types) + { + expected_types[i] = utyp + } + } + } + } + } else { + if func := g.table.find_fn(node.name) { + if func.generic_names.len > 0 { + for i in 0 .. expected_types.len { + mut muttable := unsafe { &ast.Table(g.table) } + if utyp := muttable.resolve_generic_to_concrete(node.expected_arg_types[i], + func.generic_names, node.concrete_types) + { + expected_types[i] = utyp + } + } + } + } + } + } // only v variadic, C variadic args will be appeneded like normal args is_variadic := expected_types.len > 0 && expected_types.last().has_flag(.variadic) && node.language == .v diff --git a/vlib/v/tests/generics_method_with_sumtype_args_test.v b/vlib/v/tests/generics_method_with_sumtype_args_test.v new file mode 100644 index 0000000000..3ff6fc0b79 --- /dev/null +++ b/vlib/v/tests/generics_method_with_sumtype_args_test.v @@ -0,0 +1,26 @@ +module main + +fn test_generics_method_with_sumtype_args() { + mut me := CatDad{} + ret := me.adopt(CatType.black, BlackCat{}) + println(ret) + assert ret == 22 +} + +[flag] +enum CatType { + black + white +} + +type Cat = BlackCat | WhiteCat + +struct BlackCat {} + +struct WhiteCat {} + +struct CatDad {} + +fn (mut foo CatDad) adopt(d D, t T) int { + return 22 +}