mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
parent
39ec1134fa
commit
a0a8b7e47a
|
@ -935,14 +935,15 @@ pub:
|
|||
mut_pos token.Pos
|
||||
comptime bool
|
||||
pub mut:
|
||||
scope &Scope = unsafe { nil }
|
||||
obj ScopeObject
|
||||
mod string
|
||||
name string
|
||||
kind IdentKind
|
||||
info IdentInfo
|
||||
is_mut bool // if mut *token* is before name. Use `is_mut()` to lookup mut variable
|
||||
or_expr OrExpr
|
||||
scope &Scope = unsafe { nil }
|
||||
obj ScopeObject
|
||||
mod string
|
||||
name string
|
||||
kind IdentKind
|
||||
info IdentInfo
|
||||
is_mut bool // if mut *token* is before name. Use `is_mut()` to lookup mut variable
|
||||
or_expr OrExpr
|
||||
concrete_types []Type
|
||||
}
|
||||
|
||||
pub fn (i &Ident) is_mut() bool {
|
||||
|
|
|
@ -744,7 +744,7 @@ pub fn (mut t Table) register_anon_struct(name string, sym_idx int) {
|
|||
}
|
||||
|
||||
pub fn (t &Table) known_type(name string) bool {
|
||||
return t.find_type_idx(name) != 0 || t.parsing_type == name
|
||||
return t.find_type_idx(name) != 0 || t.parsing_type == name || name in ['i32', 'byte']
|
||||
}
|
||||
|
||||
// start_parsing_type open the scope during the parsing of a type
|
||||
|
|
|
@ -3387,7 +3387,16 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
|||
}
|
||||
// Non-anon-function object (not a call), e.g. `onclick(my_click)`
|
||||
if func := c.table.find_fn(name) {
|
||||
fn_type := ast.new_type(c.table.find_or_register_fn_type(func, false, true))
|
||||
mut fn_type := ast.new_type(c.table.find_or_register_fn_type(func, false,
|
||||
true))
|
||||
if func.generic_names.len > 0 {
|
||||
if typ_ := c.table.resolve_generic_to_concrete(fn_type, func.generic_names,
|
||||
node.concrete_types)
|
||||
{
|
||||
fn_type = typ_
|
||||
c.table.register_fn_concrete_types(func.fkey(), node.concrete_types)
|
||||
}
|
||||
}
|
||||
node.name = name
|
||||
node.kind = .function
|
||||
node.info = ast.IdentFn{
|
||||
|
|
|
@ -2018,6 +2018,17 @@ pub fn (mut f Fmt) ident(node ast.Ident) {
|
|||
}
|
||||
name := f.short_module(node.name)
|
||||
f.write(name)
|
||||
if node.concrete_types.len > 0 {
|
||||
f.write('[')
|
||||
for i, concrete_type in node.concrete_types {
|
||||
typ_name := f.table.type_to_str_using_aliases(concrete_type, f.mod2alias)
|
||||
f.write(typ_name)
|
||||
if i != node.concrete_types.len - 1 {
|
||||
f.write(', ')
|
||||
}
|
||||
}
|
||||
f.write(']')
|
||||
}
|
||||
if node.or_expr.kind == .propagate_option {
|
||||
f.write('?')
|
||||
} else if node.or_expr.kind == .block {
|
||||
|
|
|
@ -4215,6 +4215,8 @@ fn (mut g Gen) ident(node ast.Ident) {
|
|||
if cattr := func.attrs.find_first('c') {
|
||||
name = cattr.arg
|
||||
}
|
||||
} else if node.concrete_types.len > 0 {
|
||||
name = g.generic_fn_name(node.concrete_types, name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2116,7 +2116,6 @@ fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
|
|||
}
|
||||
|
||||
pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
|
||||
// p.warn('name ')
|
||||
is_option := p.tok.kind == .question && p.peek_tok.kind == .lsbr
|
||||
if is_option {
|
||||
p.next()
|
||||
|
@ -2169,9 +2168,13 @@ pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
|
|||
scope: p.scope
|
||||
}
|
||||
}
|
||||
if p.inside_match_body && name == 'it' {
|
||||
// p.warn('it')
|
||||
mut is_known_generic_fn := false
|
||||
if func := p.table.find_fn(p.prepend_mod(name)) {
|
||||
if func.generic_names.len > 0 {
|
||||
is_known_generic_fn = true
|
||||
}
|
||||
}
|
||||
mut concrete_types := []ast.Type{}
|
||||
if p.expr_mod.len > 0 {
|
||||
name = '${p.expr_mod}.${name}'
|
||||
}
|
||||
|
@ -2188,6 +2191,9 @@ pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
|
|||
} else if allowed_cases && p.tok.kind == .key_orelse {
|
||||
or_kind = ast.OrKind.block
|
||||
or_stmts, or_pos = p.or_block(.no_err_var)
|
||||
} else if is_known_generic_fn && p.tok.kind == .lsbr {
|
||||
// `generic_fn[int]`
|
||||
concrete_types = p.parse_concrete_types()
|
||||
}
|
||||
return ast.Ident{
|
||||
tok_kind: p.tok.kind
|
||||
|
@ -2212,6 +2218,7 @@ pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
|
|||
stmts: or_stmts
|
||||
pos: or_pos
|
||||
}
|
||||
concrete_types: concrete_types
|
||||
}
|
||||
}
|
||||
|
||||
|
|
20
vlib/v/tests/generics_fn_variable_test.v
Normal file
20
vlib/v/tests/generics_fn_variable_test.v
Normal file
|
@ -0,0 +1,20 @@
|
|||
type Fn[T] = fn (x T, i int) T
|
||||
|
||||
fn func[T](x T, i int, f_ Fn[T]) T {
|
||||
return f_(x, i)
|
||||
}
|
||||
|
||||
fn f[T](x T, i int) T {
|
||||
return x
|
||||
}
|
||||
|
||||
fn test_generic_fn_variable() {
|
||||
ff := f[int]
|
||||
ret := ff(1, 11)
|
||||
println(ret)
|
||||
assert ret == 1
|
||||
|
||||
x := func[f64](2.0, 3, f[f64])
|
||||
println(x)
|
||||
assert x == 2.0
|
||||
}
|
Loading…
Reference in New Issue
Block a user