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 fn call (#15361)

This commit is contained in:
yuyi 2022-08-08 09:54:52 +08:00 committed by GitHub
parent ee9142a113
commit c7152a6ab6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 21 deletions

View File

@ -667,10 +667,6 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr
if param.typ.nr_muls() > 0 && to_set.nr_muls() > 0 {
to_set = to_set.set_nr_muls(0)
}
// If the parent fn param is a generic too
if to_set.has_flag(.generic) {
to_set = c.unwrap_generic(to_set)
}
} else if param.typ.has_flag(.generic) {
arg_sym := c.table.sym(arg.typ)
if param.typ.has_flag(.variadic) {
@ -759,21 +755,7 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr
}
}
if to_set != ast.void_type {
if typ != ast.void_type {
// try to promote
// only numbers so we don't promote pointers
if typ.is_number() && to_set.is_number() {
promoted := c.promote_num(typ, to_set)
if promoted != ast.void_type {
to_set = promoted
}
}
if !c.check_types(typ, to_set) {
c.error('inferred generic type `$gt_name` is ambiguous: got `${c.table.sym(to_set).name}`, expected `${c.table.sym(typ).name}`',
arg.pos)
}
}
if to_set != ast.void_type && typ == ast.void_type {
typ = to_set
}
}

View File

@ -1,5 +1,5 @@
vlib/v/checker/tests/generics_type_ambiguous.vv:7:19: error: inferred generic type `B` is ambiguous: got `int`, expected `string`
5 |
vlib/v/checker/tests/generics_type_ambiguous.vv:7:19: error: cannot use `int literal` as `string` in argument 4 to `test`
5 |
6 | fn main() {
7 | test(2, 2, "2", 2)
| ^

View File

@ -0,0 +1,26 @@
module main
pub struct Reptile {}
pub struct Insect {}
fn test_generics_with_nested_generic_fn_infer_call() {
mut r := Reptile{}
mut i := Insect{}
ret1 := node_search(mut r)
println(ret1)
assert ret1 == Reptile{}
ret2 := node_search(mut i)
println(ret2)
assert ret2 == Insect{}
}
pub fn node_search<T>(mut t T) T {
return hydrate(mut t)
}
fn hydrate<T>(mut t T) T {
return t
}