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
|
mut_pos token.Pos
|
||||||
comptime bool
|
comptime bool
|
||||||
pub mut:
|
pub mut:
|
||||||
scope &Scope = unsafe { nil }
|
scope &Scope = unsafe { nil }
|
||||||
obj ScopeObject
|
obj ScopeObject
|
||||||
mod string
|
mod string
|
||||||
name string
|
name string
|
||||||
kind IdentKind
|
kind IdentKind
|
||||||
info IdentInfo
|
info IdentInfo
|
||||||
is_mut bool // if mut *token* is before name. Use `is_mut()` to lookup mut variable
|
is_mut bool // if mut *token* is before name. Use `is_mut()` to lookup mut variable
|
||||||
or_expr OrExpr
|
or_expr OrExpr
|
||||||
|
concrete_types []Type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (i &Ident) is_mut() bool {
|
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 {
|
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
|
// 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)`
|
// Non-anon-function object (not a call), e.g. `onclick(my_click)`
|
||||||
if func := c.table.find_fn(name) {
|
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.name = name
|
||||||
node.kind = .function
|
node.kind = .function
|
||||||
node.info = ast.IdentFn{
|
node.info = ast.IdentFn{
|
||||||
|
@ -2018,6 +2018,17 @@ pub fn (mut f Fmt) ident(node ast.Ident) {
|
|||||||
}
|
}
|
||||||
name := f.short_module(node.name)
|
name := f.short_module(node.name)
|
||||||
f.write(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 {
|
if node.or_expr.kind == .propagate_option {
|
||||||
f.write('?')
|
f.write('?')
|
||||||
} else if node.or_expr.kind == .block {
|
} 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') {
|
if cattr := func.attrs.find_first('c') {
|
||||||
name = cattr.arg
|
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 {
|
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
|
is_option := p.tok.kind == .question && p.peek_tok.kind == .lsbr
|
||||||
if is_option {
|
if is_option {
|
||||||
p.next()
|
p.next()
|
||||||
@ -2169,9 +2168,13 @@ pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
|
|||||||
scope: p.scope
|
scope: p.scope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if p.inside_match_body && name == 'it' {
|
mut is_known_generic_fn := false
|
||||||
// p.warn('it')
|
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 {
|
if p.expr_mod.len > 0 {
|
||||||
name = '${p.expr_mod}.${name}'
|
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 {
|
} else if allowed_cases && p.tok.kind == .key_orelse {
|
||||||
or_kind = ast.OrKind.block
|
or_kind = ast.OrKind.block
|
||||||
or_stmts, or_pos = p.or_block(.no_err_var)
|
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{
|
return ast.Ident{
|
||||||
tok_kind: p.tok.kind
|
tok_kind: p.tok.kind
|
||||||
@ -2212,6 +2218,7 @@ pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
|
|||||||
stmts: or_stmts
|
stmts: or_stmts
|
||||||
pos: or_pos
|
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…
x
Reference in New Issue
Block a user