checker: make sure that the operator check is made on the concrete type (#13360)
							parent
							
								
									a054f868a0
								
							
						
					
					
						commit
						b9fce4ef09
					
				| 
						 | 
				
			
			@ -541,10 +541,10 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
 | 
			
		|||
	defer {
 | 
			
		||||
		c.expected_type = former_expected_type
 | 
			
		||||
	}
 | 
			
		||||
	left_type := c.expr(node.left)
 | 
			
		||||
	mut left_type := c.expr(node.left)
 | 
			
		||||
	node.left_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
 | 
			
		||||
	if left_type.is_number() && !left_type.is_ptr()
 | 
			
		||||
		&& 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 {
 | 
			
		||||
					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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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