checker,cgen: check sort_with_compare_context parameters too

pull/13721/head
Delyan Angelov 2022-03-12 16:25:16 +02:00
parent 509367b293
commit eb772cfcf9
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
5 changed files with 35 additions and 26 deletions

View File

@ -1297,26 +1297,12 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
c.fail_if_unreadable(arg.expr, got_arg_typ, 'argument')
}
}
if left_sym.kind == .array && method_name == 'sort_with_compare' {
array_info := left_sym.info as ast.Array
elem_typ := array_info.elem_type
arg_sym := c.table.sym(arg.typ)
if arg_sym.kind == .function {
func_info := arg_sym.info as ast.FnType
if func_info.func.params.len == 2 {
if func_info.func.params[0].typ.nr_muls() != elem_typ.nr_muls() + 1 {
arg_typ_str := c.table.type_to_str(func_info.func.params[0].typ)
expected_typ_str := c.table.type_to_str(elem_typ.ref())
c.error('sort_with_compare callback function parameter `${func_info.func.params[0].name}` with type `$arg_typ_str` should be `$expected_typ_str`',
func_info.func.params[0].type_pos)
}
if func_info.func.params[1].typ.nr_muls() != elem_typ.nr_muls() + 1 {
arg_typ_str := c.table.type_to_str(func_info.func.params[1].typ)
expected_typ_str := c.table.type_to_str(elem_typ.ref())
c.error('sort_with_compare callback function parameter `${func_info.func.params[1].name}` with type `$arg_typ_str` should be `$expected_typ_str`',
func_info.func.params[1].type_pos)
}
}
if left_sym.kind == .array {
if method_name == 'sort_with_compare' {
c.check_sort_cb_args(2, 'sort_with_compare', left_sym, arg)
}
if method_name == 'sort_with_compare_context' {
c.check_sort_cb_args(3, 'sort_with_compare_context', left_sym, arg)
}
}
// Handle expected interface
@ -1844,3 +1830,26 @@ fn scope_register_a_b(mut s ast.Scope, pos token.Pos, typ ast.Type) {
is_used: true
})
}
fn (mut c Checker) check_sort_cb_args(howmany int, fname string, left_sym &ast.TypeSymbol, arg &ast.CallArg) {
array_info := left_sym.info as ast.Array
elem_typ := array_info.elem_type
arg_sym := c.table.sym(arg.typ)
if arg_sym.kind != .function {
return
}
func_info := arg_sym.info as ast.FnType
if func_info.func.params.len != howmany {
c.error('$fname callback should have exactly $howmany parameters', arg.expr.pos())
return
}
desired_et_muls := elem_typ.nr_muls() + 1
expected_typ_str := c.table.type_to_str(elem_typ.ref())
for k in 0 .. 2 {
if func_info.func.params[k].typ.nr_muls() != desired_et_muls {
arg_typ_str := c.table.type_to_str(func_info.func.params[k].typ)
c.error('$fname callback function parameter `${func_info.func.params[k].name}` with type `$arg_typ_str` should be `$expected_typ_str`',
func_info.func.params[k].type_pos)
}
}
}

View File

@ -1,13 +1,13 @@
vlib/v/checker/tests/array_sort_with_compare_err.vv:11:24: error: sort_with_compare callback function parameter `a` with type `string` should be `&string`
9 | }
10 |
10 |
11 | fn sort_by_file_base(a string, b string) int {
| ~~~~~~
12 | return int(a > b)
13 | }
vlib/v/checker/tests/array_sort_with_compare_err.vv:4:26: error: cannot use `fn (string, string) int` as `fn (voidptr, voidptr) int` in argument 1 to `[]string.sort_with_compare`
2 | mut names := ['aaa', 'bbb', 'ccc']
3 |
3 |
4 | names.sort_with_compare(sort_by_file_base)
| ~~~~~~~~~~~~~~~~~
5 | println(names)
@ -15,7 +15,7 @@ vlib/v/checker/tests/array_sort_with_compare_err.vv:4:26: error: cannot use `fn
Details: ``'s expected fn argument: `` is a pointer, but the passed fn argument: `a` is NOT a pointer
vlib/v/checker/tests/array_sort_with_compare_err.vv:7:26: error: cannot use `int literal` as `fn (voidptr, voidptr) int` in argument 1 to `[]string.sort_with_compare`
5 | println(names)
6 |
6 |
7 | names.sort_with_compare(22)
| ~~
8 | println(names)

View File

@ -1,6 +1,6 @@
vlib/v/checker/tests/array_sort_with_compare_ref_elem_err.vv:21:23: error: sort_with_compare callback function parameter `a` with type `&Cell` should be `&&Cell`
19 | }
20 |
20 |
21 | fn sort_cells_by_yx(a &Cell, b &Cell) int {
| ^
22 | if a.pos.y == b.pos.y {

View File

@ -952,7 +952,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
receiver_type_name = 'map'
}
if final_left_sym.kind == .array
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
&& node.name in ['repeat', 'sort_with_compare', 'sort_with_compare_context', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
if !(left_sym.info is ast.Alias && typ_sym.has_method(node.name)) {
// `array_Xyz_clone` => `array_clone`
receiver_type_name = 'array'

View File

@ -318,7 +318,7 @@ fn (mut g JsGen) method_call(node ast.CallExpr) {
}
}
if final_left_sym.kind == .array
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
&& node.name in ['repeat', 'sort_with_compare', 'sort_with_compare_context', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
if !(left_sym.info is ast.Alias && typ_sym.has_method(node.name)) {
// `array_Xyz_clone` => `array_clone`
receiver_type_name = 'array'