mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
ast, parser: fix generic fntype to concrete types with later generic fn definition (fix #18156) (#18157)
This commit is contained in:
parent
2351856fc3
commit
8482bc4626
@ -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 || name in ['i32', 'byte']
|
return t.type_idxs[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
|
||||||
|
@ -2119,6 +2119,29 @@ fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut p Parser) is_following_concrete_types() bool {
|
||||||
|
if !(p.tok.kind == .lsbr && p.tok.pos - p.prev_tok.pos == p.prev_tok.len) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
mut i := 1
|
||||||
|
for {
|
||||||
|
cur_tok := p.peek_token(i)
|
||||||
|
if cur_tok.kind == .eof {
|
||||||
|
return false
|
||||||
|
} else if cur_tok.kind == .rsbr {
|
||||||
|
break
|
||||||
|
} else if cur_tok.kind == .name {
|
||||||
|
if !(cur_tok.lit.len > 1 && p.is_typename(cur_tok)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else if cur_tok.kind != .comma {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut p Parser) ident(language ast.Language) ast.Ident {
|
pub fn (mut p Parser) ident(language ast.Language) ast.Ident {
|
||||||
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 {
|
||||||
@ -2172,12 +2195,7 @@ pub fn (mut p Parser) ident(language ast.Language) ast.Ident {
|
|||||||
scope: p.scope
|
scope: p.scope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mut is_known_generic_fn := false
|
is_following_concrete_types := p.is_following_concrete_types()
|
||||||
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{}
|
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}'
|
||||||
@ -2195,7 +2213,7 @@ pub fn (mut p Parser) 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 {
|
} else if is_following_concrete_types {
|
||||||
// `generic_fn[int]`
|
// `generic_fn[int]`
|
||||||
concrete_types = p.parse_concrete_types()
|
concrete_types = p.parse_concrete_types()
|
||||||
}
|
}
|
||||||
|
@ -4,17 +4,30 @@ fn func[T](x T, i int, f_ Fn[T]) T {
|
|||||||
return f_(x, i)
|
return f_(x, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn f[T](x T, i int) T {
|
fn f1[T](x T, i int) T {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_generic_fn_variable() {
|
fn test_generic_fn_variable() {
|
||||||
ff := f[int]
|
ff1 := f1[int]
|
||||||
ret := ff(1, 11)
|
ret1 := ff1(1, 11)
|
||||||
println(ret)
|
println(ret1)
|
||||||
assert ret == 1
|
assert ret1 == 1
|
||||||
|
|
||||||
x := func[f64](2.0, 3, f[f64])
|
ff2 := f2[int]
|
||||||
println(x)
|
ret2 := ff2(1, 11)
|
||||||
assert x == 2.0
|
println(ret2)
|
||||||
|
assert ret2 == 1
|
||||||
|
|
||||||
|
x1 := func[f64](2.0, 3, f1[f64])
|
||||||
|
println(x1)
|
||||||
|
assert x1 == 2.0
|
||||||
|
|
||||||
|
x2 := func[f64](2.0, 3, f2[f64])
|
||||||
|
println(x2)
|
||||||
|
assert x2 == 2.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f2[T](x T, i int) T {
|
||||||
|
return x
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user