Skip to content

Commit

Permalink
parser, checker: fix sorting compare fn with mut reference parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 committed Jun 20, 2024
1 parent 72a3fd6 commit 0dc8fc1
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
6 changes: 6 additions & 0 deletions vlib/v/checker/infix.v
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
.array {
if left_sym.kind !in [.sum_type, .interface_] {
elem_type := right_final_sym.array_info().elem_type
if node.left.is_auto_deref_var() {
left_type = left_type.deref()
}
c.check_expected(left_type, elem_type) or {
c.error('left operand to `${node.op}` does not match the array element type: ${err.msg()}',
left_right_pos)
Expand All @@ -214,6 +217,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
}
} else {
elem_type := right_final_sym.array_info().elem_type
if node.left.is_auto_deref_var() {
left_type = left_type.deref()
}
c.check_expected(left_type, elem_type) or {
c.error('left operand to `${node.op}` does not match the array element type: ${err.msg()}',
left_right_pos)
Expand Down
16 changes: 10 additions & 6 deletions vlib/v/parser/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -943,11 +943,11 @@ fn (mut p Parser) fn_params() ([]ast.Param, bool, bool) {
p.error_with_pos('generic object cannot be `atomic`or `shared`', pos)
return []ast.Param{}, false, false
}
// if arg_type.is_ptr() {
// p.error('cannot mut')
// }
// arg_type = arg_type.ref()
param_type = param_type.set_nr_muls(1)
if param_type.is_int_valptr() || param_type.has_flag(.option) {
param_type = param_type.set_nr_muls(1)
} else {
param_type = param_type.ref()
}
if is_shared {
param_type = param_type.set_flag(.shared_f)
}
Expand Down Expand Up @@ -1063,7 +1063,11 @@ fn (mut p Parser) fn_params() ([]ast.Param, bool, bool) {
pos)
return []ast.Param{}, false, false
}
typ = typ.set_nr_muls(1)
if typ.is_int_valptr() || typ.has_flag(.option) {
typ = typ.set_nr_muls(1)
} else {
typ = typ.ref()
}
if is_shared {
typ = typ.set_flag(.shared_f)
}
Expand Down
40 changes: 40 additions & 0 deletions vlib/v/tests/sorting_compare_fn_with_mut_reference_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
struct Thing {
mut:
a int = 2
b int = 4
av int
}

fn (mut t Thing) average() int {
t.av = (t.a + t.b) / 2
return t.av
}

struct Things {
mut:
items []&Thing
}

fn (mut t Things) sort() {
t.items.sort_with_compare(fn (mut a &Thing, mut b &Thing) int {
if a.average() > b.average() {
return 1
} else if a.average() < b.average() {
return -1
}
return 0
})
}

fn test_sort_compare_fn_with_mut_ref_param() {
mut t := Things{}
t.items << &Thing{2, 4, 0}
t.items << &Thing{5, 7, 0}
t.items << &Thing{1, 2, 0}
t.sort()
println(t)
assert t.items.len == 3
assert t.items[0] == &Thing{1, 2, 1}
assert t.items[1] == &Thing{2, 4, 3}
assert t.items[2] == &Thing{5, 7, 6}
}

0 comments on commit 0dc8fc1

Please sign in to comment.