mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: make sure that the operator check is made on the concrete type (#13360)
This commit is contained in:
parent
a054f868a0
commit
b9fce4ef09
@ -541,10 +541,10 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
|||||||
defer {
|
defer {
|
||||||
c.expected_type = former_expected_type
|
c.expected_type = former_expected_type
|
||||||
}
|
}
|
||||||
left_type := c.expr(node.left)
|
mut left_type := c.expr(node.left)
|
||||||
node.left_type = left_type
|
node.left_type = left_type
|
||||||
c.expected_type = left_type
|
c.expected_type = left_type
|
||||||
right_type := c.expr(node.right)
|
mut right_type := c.expr(node.right)
|
||||||
node.right_type = right_type
|
node.right_type = right_type
|
||||||
if left_type.is_number() && !left_type.is_ptr()
|
if left_type.is_number() && !left_type.is_ptr()
|
||||||
&& right_type in [ast.int_literal_type, ast.float_literal_type] {
|
&& right_type in [ast.int_literal_type, ast.float_literal_type] {
|
||||||
@ -796,6 +796,18 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
|||||||
} else if !left_sym.has_method('<') && node.op == .gt {
|
} else if !left_sym.has_method('<') && node.op == .gt {
|
||||||
c.error('cannot use `>` as `<=` operator method is not defined', left_right_pos)
|
c.error('cannot use `>` as `<=` operator method is not defined', left_right_pos)
|
||||||
}
|
}
|
||||||
|
} else if left_type.has_flag(.generic) && right_type.has_flag(.generic) {
|
||||||
|
// Try to unwrap the generic type to make sure that
|
||||||
|
// the below check works as expected
|
||||||
|
left_gen_type := c.unwrap_generic(left_type)
|
||||||
|
gen_sym := c.table.sym(left_gen_type)
|
||||||
|
need_overload := gen_sym.kind in [.struct_, .interface_]
|
||||||
|
if need_overload && !gen_sym.has_method('<') && node.op in [.ge, .le] {
|
||||||
|
c.error('cannot use `$node.op` as `<` operator method is not defined',
|
||||||
|
left_right_pos)
|
||||||
|
} else if need_overload && !gen_sym.has_method('<') && node.op == .gt {
|
||||||
|
c.error('cannot use `>` as `<=` operator method is not defined', left_right_pos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.left_shift {
|
.left_shift {
|
||||||
|
21
vlib/v/checker/tests/cmp_between_struct.out
Normal file
21
vlib/v/checker/tests/cmp_between_struct.out
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
vlib/datatypes/heap.v:16:15: error: cannot use `>` as `<=` operator method is not defined
|
||||||
|
14 | mut child := heap.data.len - 1
|
||||||
|
15 | mut parent := heap.parent(child)
|
||||||
|
16 | for heap.data[parent] > heap.data[child] {
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
17 | heap.data[parent], heap.data[child] = heap.data[child], heap.data[parent]
|
||||||
|
18 | child = parent
|
||||||
|
vlib/datatypes/heap.v:37:15: error: cannot use `>` as `<=` operator method is not defined
|
||||||
|
35 | mut left := heap.left_child(parent) or { return item }
|
||||||
|
36 | mut right := heap.right_child(parent) or { left }
|
||||||
|
37 | for heap.data[parent] > heap.data[left] || heap.data[parent] > heap.data[right] {
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
38 | // choose min for min heap
|
||||||
|
39 | swap := if heap.data[left] <= heap.data[right] { left } else { right }
|
||||||
|
vlib/datatypes/heap.v:39:23: error: cannot use `<=` as `<` operator method is not defined
|
||||||
|
37 | for heap.data[parent] > heap.data[left] || heap.data[parent] > heap.data[right] {
|
||||||
|
38 | // choose min for min heap
|
||||||
|
39 | swap := if heap.data[left] <= heap.data[right] { left } else { right }
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
40 | heap.data[parent], heap.data[swap] = heap.data[swap], heap.data[parent]
|
||||||
|
41 | parent = swap
|
31
vlib/v/checker/tests/cmp_between_struct.vv
Normal file
31
vlib/v/checker/tests/cmp_between_struct.vv
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
import datatypes
|
||||||
|
|
||||||
|
struct Item {
|
||||||
|
priority int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue https://github.com/vlang/v/issues/13318
|
||||||
|
|
||||||
|
/*
|
||||||
|
fn (a Item) < (b Item) bool {
|
||||||
|
return a.priority < b.priority
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (a Item) == (b Item) bool {
|
||||||
|
return a.priority == b.priority
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
min_heap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min_heap() {
|
||||||
|
mut heap := datatypes.MinHeap<Item>{}
|
||||||
|
|
||||||
|
heap.insert(Item{10})
|
||||||
|
|
||||||
|
println(heap)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user