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 {
|
if right.op == .amp && right.right is ast.StructInit {
|
||||||
right_type = c.expr(right)
|
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() {
|
if right.is_auto_deref_var() {
|
||||||
left_type = ast.mktyp(right_type.deref())
|
left_type = ast.mktyp(right_type.deref())
|
||||||
|
@ -3238,6 +3238,12 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
|||||||
return typ
|
return typ
|
||||||
} else if node.kind == .function {
|
} else if node.kind == .function {
|
||||||
info := node.info as ast.IdentFn
|
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
|
return info.typ
|
||||||
} else if node.kind == .unresolved {
|
} else if node.kind == .unresolved {
|
||||||
// first use
|
// 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,
|
mut fn_type := ast.new_type(c.table.find_or_register_fn_type(func, false,
|
||||||
true))
|
true))
|
||||||
if func.generic_names.len > 0 {
|
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,
|
if typ_ := c.table.resolve_generic_to_concrete(fn_type, func.generic_names,
|
||||||
node.concrete_types)
|
concrete_types)
|
||||||
{
|
{
|
||||||
fn_type = typ_
|
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
|
node.name = name
|
||||||
|
@ -2131,7 +2131,7 @@ fn (mut p Parser) is_following_concrete_types() bool {
|
|||||||
} else if cur_tok.kind == .rsbr {
|
} else if cur_tok.kind == .rsbr {
|
||||||
break
|
break
|
||||||
} else if cur_tok.kind == .name {
|
} 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
|
return false
|
||||||
}
|
}
|
||||||
} else if cur_tok.kind != .comma {
|
} 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