1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: fix generics with nested generic method call (#15390)

This commit is contained in:
yuyi 2022-08-10 16:29:19 +08:00 committed by GitHub
parent c752e5eb3e
commit 78d0255e6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 5 deletions

View File

@ -1526,12 +1526,12 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
if method.generic_names.len != node.concrete_types.len {
// no type arguments given in call, attempt implicit instantiation
c.infer_fn_generic_types(method, mut node)
concrete_types = node.concrete_types
} else {
if node.concrete_types.len > 0 && !node.concrete_types[0].has_flag(.generic) {
c.table.register_fn_concrete_types(method.fkey(), node.concrete_types)
}
concrete_types = node.concrete_types.map(c.unwrap_generic(it))
}
if concrete_types.len > 0 && !concrete_types[0].has_flag(.generic) {
c.table.register_fn_concrete_types(method.fkey(), concrete_types)
}
// resolve return generics struct to concrete type
if method.generic_names.len > 0 && method.return_type.has_flag(.generic)
&& !isnil(c.table.cur_fn) && c.table.cur_fn.generic_names.len == 0 {

View File

@ -0,0 +1,40 @@
struct Calc<S> {
mut:
typ S
}
struct TypeA {}
struct TypeB {}
fn (mut c Calc<S>) next<T>(input T) f64 {
$if S is TypeA || S is TypeB {
return c.typ.next(input)
} $else {
return 99.0
}
}
fn (mut t TypeA) next<T>(input T) f64 {
return 10.0
}
fn (mut t TypeB) next<T>(input T) f64 {
return 11.0
}
fn test_generics_with_nested_generic_method_call() {
{
mut c := Calc<TypeA>{
typ: TypeA{}
}
assert c.next(100) == 10.0
}
{
mut c := Calc<TypeB>{
typ: TypeB{}
}
assert c.next(100) == 11.0
}
println('OK!!')
}