diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index bbdaa4c8e38962..5906de76ee3c49 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -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()) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index eee5bf59bec385..11dfe2d599f493 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3234,6 +3234,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 @@ -3390,11 +3396,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 diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 4bdd4bbcf889a4..e26d0ad91e5bed 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -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 { diff --git a/vlib/v/tests/generics_fn_variable_test.v b/vlib/v/tests/generics_fn_variable_1_test.v similarity index 100% rename from vlib/v/tests/generics_fn_variable_test.v rename to vlib/v/tests/generics_fn_variable_1_test.v diff --git a/vlib/v/tests/generics_fn_variable_2_test.v b/vlib/v/tests/generics_fn_variable_2_test.v new file mode 100644 index 00000000000000..c92cd6b96789a7 --- /dev/null +++ b/vlib/v/tests/generics_fn_variable_2_test.v @@ -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 +}