1
0
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:
yuyi 2023-05-17 08:06:33 +08:00 committed by GitHub
parent 35f2a0fb66
commit ddb8e09fec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 3 deletions

View File

@ -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())

View File

@ -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

View File

@ -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 {

View 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
}