mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parser, checker: fix generic fn variable assignment in generic fn (#18180)
This commit is contained in:
parent
35f2a0fb66
commit
ddb8e09fec
@ -182,6 +182,10 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||
if right.op == .amp && right.right is ast.StructInit {
|
||||
right_type = c.expr(right)
|
||||
}
|
||||
} else if mut right is ast.Ident {
|
||||
if right.kind == .function {
|
||||
c.expr(right)
|
||||
}
|
||||
}
|
||||
if right.is_auto_deref_var() {
|
||||
left_type = ast.mktyp(right_type.deref())
|
||||
|
@ -3238,6 +3238,12 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
||||
return typ
|
||||
} else if node.kind == .function {
|
||||
info := node.info as ast.IdentFn
|
||||
if func := c.table.find_fn(node.name) {
|
||||
if func.generic_names.len > 0 {
|
||||
concrete_types := node.concrete_types.map(c.unwrap_generic(it))
|
||||
c.table.register_fn_concrete_types(func.fkey(), concrete_types)
|
||||
}
|
||||
}
|
||||
return info.typ
|
||||
} else if node.kind == .unresolved {
|
||||
// first use
|
||||
@ -3394,11 +3400,12 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
||||
mut fn_type := ast.new_type(c.table.find_or_register_fn_type(func, false,
|
||||
true))
|
||||
if func.generic_names.len > 0 {
|
||||
concrete_types := node.concrete_types.map(c.unwrap_generic(it))
|
||||
if typ_ := c.table.resolve_generic_to_concrete(fn_type, func.generic_names,
|
||||
node.concrete_types)
|
||||
concrete_types)
|
||||
{
|
||||
fn_type = typ_
|
||||
c.table.register_fn_concrete_types(func.fkey(), node.concrete_types)
|
||||
c.table.register_fn_concrete_types(func.fkey(), concrete_types)
|
||||
}
|
||||
}
|
||||
node.name = name
|
||||
|
@ -2131,7 +2131,7 @@ fn (mut p Parser) is_following_concrete_types() bool {
|
||||
} else if cur_tok.kind == .rsbr {
|
||||
break
|
||||
} else if cur_tok.kind == .name {
|
||||
if !(cur_tok.lit.len > 1 && p.is_typename(cur_tok)) {
|
||||
if !(p.is_typename(cur_tok) && !(cur_tok.lit.len == 1 && !cur_tok.lit[0].is_capital())) {
|
||||
return false
|
||||
}
|
||||
} else if cur_tok.kind != .comma {
|
||||
|
26
vlib/v/tests/generics_fn_variable_2_test.v
Normal file
26
vlib/v/tests/generics_fn_variable_2_test.v
Normal file
@ -0,0 +1,26 @@
|
||||
fn g[T]() u32 {
|
||||
return sizeof(T)
|
||||
}
|
||||
|
||||
fn f[T]() u32 {
|
||||
p := g[T]
|
||||
return p()
|
||||
}
|
||||
|
||||
fn test_generic_fn_variable() {
|
||||
r1 := f[int]()
|
||||
println(r1)
|
||||
assert r1 == 4
|
||||
|
||||
r2 := f[string]()
|
||||
println(r2)
|
||||
assert r2 == 16
|
||||
|
||||
r3 := f[f64]()
|
||||
println(r3)
|
||||
assert r3 == 8
|
||||
|
||||
r4 := f[bool]()
|
||||
println(r4)
|
||||
assert r4 == 1
|
||||
}
|
Loading…
Reference in New Issue
Block a user