parser: parse func<T>() when T is a map or array type (#6765)
parent
1d706674f2
commit
62cae1ba00
|
@ -1030,13 +1030,28 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
||||||
p.expr_mod = mod
|
p.expr_mod = mod
|
||||||
}
|
}
|
||||||
lit0_is_capital := p.tok.lit[0].is_capital()
|
lit0_is_capital := p.tok.lit[0].is_capital()
|
||||||
|
// use heuristics to detect `func<T>()` from `var < expr`
|
||||||
|
is_generic_call := !lit0_is_capital && p.peek_tok.kind == .lt && (match p.peek_tok2.kind {
|
||||||
|
.name {
|
||||||
|
// maybe `f<int>`, `f<map[`
|
||||||
|
(p.peek_tok2.kind == .name &&
|
||||||
|
p.peek_tok3.kind == .gt) ||
|
||||||
|
(p.peek_tok2.lit == 'map' && p.peek_tok3.kind == .lsbr)
|
||||||
|
}
|
||||||
|
.lsbr {
|
||||||
|
// maybe `f<[]T>`, assume `var < []` is invalid
|
||||||
|
p.peek_tok3.kind == .rsbr
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
// p.warn('name expr $p.tok.lit $p.peek_tok.str()')
|
// p.warn('name expr $p.tok.lit $p.peek_tok.str()')
|
||||||
same_line := p.tok.line_nr == p.peek_tok.line_nr
|
same_line := p.tok.line_nr == p.peek_tok.line_nr
|
||||||
// `(` must be on same line as name token otherwise it's a ParExpr
|
// `(` must be on same line as name token otherwise it's a ParExpr
|
||||||
if !same_line && p.peek_tok.kind == .lpar {
|
if !same_line && p.peek_tok.kind == .lpar {
|
||||||
node = p.parse_ident(language)
|
node = p.parse_ident(language)
|
||||||
} else if p.peek_tok.kind == .lpar ||
|
} else if p.peek_tok.kind == .lpar || is_generic_call {
|
||||||
(p.peek_tok.kind == .lt && !lit0_is_capital && p.peek_tok2.kind == .name && p.peek_tok3.kind == .gt) {
|
|
||||||
// foo(), foo<int>() or type() cast
|
// foo(), foo<int>() or type() cast
|
||||||
mut name := p.tok.lit
|
mut name := p.tok.lit
|
||||||
if mod.len > 0 {
|
if mod.len > 0 {
|
||||||
|
|
|
@ -13,11 +13,17 @@ fn plus<T>(xxx T, b T) T {
|
||||||
return xxx + b
|
return xxx + b
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_generic_fn() {
|
fn test_identity() {
|
||||||
assert simple<int>(1) == 1
|
assert simple<int>(1) == 1
|
||||||
assert simple<int>(1 + 0) == 1
|
assert simple<int>(1 + 0) == 1
|
||||||
assert simple<string>('g') == 'g'
|
assert simple<string>('g') == 'g'
|
||||||
assert simple<string>('g') + 'h' == 'gh'
|
assert simple<string>('g') + 'h' == 'gh'
|
||||||
|
|
||||||
|
assert simple<[]int>([1])[0] == 1
|
||||||
|
assert simple<map[string]string>({'a':'b'})['a'] == 'b'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_plus() {
|
||||||
a := plus<int>(2, 3)
|
a := plus<int>(2, 3)
|
||||||
println(a)
|
println(a)
|
||||||
assert a == 5
|
assert a == 5
|
||||||
|
|
Loading…
Reference in New Issue