checker: check s.$method(arg) argument is []string (#8455)

pull/8479/head
Nick Treleaven 2021-01-31 14:28:23 +00:00 committed by GitHub
parent 3be5795724
commit f992099726
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 2 deletions

View File

@ -3699,7 +3699,21 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) table.Type {
node.result_type = rtyp
return rtyp
}
if node.is_vweb || node.method_name == 'method' {
if node.method_name == 'method' {
if node.args_var.len > 0 {
v := node.scope.find_var(node.args_var) or {
c.error('unknown identifier `$node.args_var`', node.method_pos)
return table.void_type
}
s := c.table.type_to_str(c.expr(v.expr))
if s != '[]string' {
c.error('expected `[]string`, not s', node.method_pos)
}
}
// assume string for now
return table.string_type
}
if node.is_vweb {
return table.string_type
}
// s.$my_str()

View File

@ -0,0 +1,14 @@
vlib/v/checker/tests/comptime_call_method.vv:10:7: error: unknown identifier `wrong`
8 | s1 := S1{}
9 | $for method in S1.methods {
10 | s1.$method(wrong)
| ~~~~~~
11 | arg := 7
12 | s1.$method(arg)
vlib/v/checker/tests/comptime_call_method.vv:12:7: error: expected `[]string`, not s
10 | s1.$method(wrong)
11 | arg := 7
12 | s1.$method(arg)
| ~~~~~~
13 | }
14 | }

View File

@ -0,0 +1,14 @@
struct S1 {}
fn (t S1) m(s string) int {
return 7
}
fn test_methods_arg() {
s1 := S1{}
$for method in S1.methods {
s1.$method(wrong)
arg := 7
s1.$method(arg)
}
}

View File

@ -269,6 +269,7 @@ fn (mut p Parser) comptime_selector(left ast.Expr) ast.Expr {
mut args_var := ''
if p.tok.kind == .name {
args_var = p.tok.lit
p.mark_var_as_used(args_var)
p.next()
}
p.check(.rpar)

View File

@ -31,7 +31,6 @@ fn test_for_methods() {
$for method in Test.methods {
// currently the checker thinks all $method calls return string
$if method.return_type is string {
//~ $if method.name == 's' {println('yes')}
v := test.$method()
r += v.str()
}
@ -50,3 +49,19 @@ fn test_for_methods() {
}
assert r == '?testTwo'
}
struct S1 {}
fn (t S1) rep(s string, i int) string {
return s.repeat(i)
}
fn test_methods_arg() {
s1 := S1{}
$for method in S1.methods {
arr := ['!', '3']
r := s1.$method(arr)
assert r == '!!!'
}
}