cgen: fix generics method with sumtype arguments (#13166)

pull/13178/head
yuyi 2022-01-15 00:45:12 +08:00 committed by GitHub
parent 104e0c5692
commit 879d1d2f11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 1 deletions

View File

@ -1471,7 +1471,37 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
} else { } else {
node.args 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 // only v variadic, C variadic args will be appeneded like normal args
is_variadic := expected_types.len > 0 && expected_types.last().has_flag(.variadic) is_variadic := expected_types.len > 0 && expected_types.last().has_flag(.variadic)
&& node.language == .v && node.language == .v

View File

@ -0,0 +1,26 @@
module main
fn test_generics_method_with_sumtype_args() {
mut me := CatDad{}
ret := me.adopt<CatType, Cat>(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, T>(d D, t T) int {
return 22
}