checker: add a check for `x := math.sin<f64>(0)`
parent
1ead130eed
commit
f995aa35ea
|
@ -306,6 +306,7 @@ pub mut:
|
||||||
return_type table.Type
|
return_type table.Type
|
||||||
should_be_skipped bool
|
should_be_skipped bool
|
||||||
generic_type table.Type // TODO array, to support multiple types
|
generic_type table.Type // TODO array, to support multiple types
|
||||||
|
generic_list_pos token.Position
|
||||||
free_receiver bool // true if the receiver expression needs to be freed
|
free_receiver bool // true if the receiver expression needs to be freed
|
||||||
// autofree_pregen string
|
// autofree_pregen string
|
||||||
// autofree_vars []AutofreeArgVar
|
// autofree_vars []AutofreeArgVar
|
||||||
|
|
|
@ -1595,6 +1595,9 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if call_expr.generic_type.is_full() && !f.is_generic {
|
||||||
|
c.error('a non generic function called like a generic one', call_expr.generic_list_pos)
|
||||||
|
}
|
||||||
if f.is_generic {
|
if f.is_generic {
|
||||||
return call_expr.return_type
|
return call_expr.return_type
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
vlib/v/checker/tests/generics_non_generic_fn_called_like_a_generic_one.vv:4:15: error: a non generic function called like a generic one
|
||||||
|
2 |
|
||||||
|
3 | fn main() {
|
||||||
|
4 | x := math.sin<f64>(1.0)
|
||||||
|
| ~~~~~
|
||||||
|
5 | println(x)
|
||||||
|
6 | }
|
|
@ -0,0 +1,6 @@
|
||||||
|
import math
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
x := math.sin<f64>(1.0)
|
||||||
|
println(x)
|
||||||
|
}
|
|
@ -27,12 +27,14 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
|
||||||
or_kind = .block
|
or_kind = .block
|
||||||
}
|
}
|
||||||
mut generic_type := table.void_type
|
mut generic_type := table.void_type
|
||||||
|
mut generic_list_pos := p.tok.position()
|
||||||
if p.tok.kind == .lt {
|
if p.tok.kind == .lt {
|
||||||
// `foo<int>(10)`
|
// `foo<int>(10)`
|
||||||
p.next() // `<`
|
p.next() // `<`
|
||||||
p.expr_mod = ''
|
p.expr_mod = ''
|
||||||
generic_type = p.parse_type()
|
generic_type = p.parse_type()
|
||||||
p.check(.gt) // `>`
|
p.check(.gt) // `>`
|
||||||
|
generic_list_pos = generic_list_pos.extend(p.prev_tok.position())
|
||||||
// In case of `foo<T>()`
|
// In case of `foo<T>()`
|
||||||
// T is unwrapped and registered in the checker.
|
// T is unwrapped and registered in the checker.
|
||||||
if !generic_type.has_flag(.generic) {
|
if !generic_type.has_flag(.generic) {
|
||||||
|
@ -98,6 +100,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
|
||||||
pos: pos
|
pos: pos
|
||||||
language: language
|
language: language
|
||||||
generic_type: generic_type
|
generic_type: generic_type
|
||||||
|
generic_list_pos: generic_list_pos
|
||||||
or_block: ast.OrExpr{
|
or_block: ast.OrExpr{
|
||||||
stmts: or_stmts
|
stmts: or_stmts
|
||||||
kind: or_kind
|
kind: or_kind
|
||||||
|
|
|
@ -106,6 +106,16 @@ pub fn (t Type) idx() int {
|
||||||
return u16(t) & 0xffff
|
return u16(t) & 0xffff
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[inline]
|
||||||
|
pub fn (t Type) is_void() bool {
|
||||||
|
return t == void_type
|
||||||
|
}
|
||||||
|
|
||||||
|
[inline]
|
||||||
|
pub fn (t Type) is_full() bool {
|
||||||
|
return t != 0 && t != void_type
|
||||||
|
}
|
||||||
|
|
||||||
// return nr_muls for `t`
|
// return nr_muls for `t`
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (t Type) nr_muls() int {
|
pub fn (t Type) nr_muls() int {
|
||||||
|
|
Loading…
Reference in New Issue