checker: make sure negation is only used with numeric types (#9854)
							parent
							
								
									dd2002cc57
								
							
						
					
					
						commit
						b4e4d48bbd
					
				| 
						 | 
					@ -328,12 +328,6 @@ pub fn (typ Type) is_number() bool {
 | 
				
			||||||
	return typ.clear_flags() in ast.number_type_idxs
 | 
						return typ.clear_flags() in ast.number_type_idxs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn (typ Type) is_number_or_literal() bool {
 | 
					 | 
				
			||||||
	res := int(typ) in ast.number_type_idxs
 | 
					 | 
				
			||||||
	eprintln('> is_number_or_literal typ: $typ.debug() | res: $res')
 | 
					 | 
				
			||||||
	return res
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[inline]
 | 
					[inline]
 | 
				
			||||||
pub fn (typ Type) is_string() bool {
 | 
					pub fn (typ Type) is_string() bool {
 | 
				
			||||||
	return typ.idx() in ast.string_type_idxs
 | 
						return typ.idx() in ast.string_type_idxs
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5883,14 +5883,19 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
 | 
				
			||||||
	if node.op == .not && right_type != ast.bool_type_idx && !c.pref.translated {
 | 
						if node.op == .not && right_type != ast.bool_type_idx && !c.pref.translated {
 | 
				
			||||||
		c.error('! operator can only be used with bool types', node.pos)
 | 
							c.error('! operator can only be used with bool types', node.pos)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if node.op == .arrow {
 | 
						// FIXME
 | 
				
			||||||
		right := c.table.get_type_symbol(right_type)
 | 
						// there are currently other issues to investigate if right_type
 | 
				
			||||||
		if right.kind == .chan {
 | 
						// is unwraped directly as initialization, so do it here
 | 
				
			||||||
			c.stmts(node.or_block.stmts)
 | 
						right_sym := c.table.get_final_type_symbol(c.unwrap_generic(right_type))
 | 
				
			||||||
			return right.chan_info().elem_type
 | 
						if node.op == .minus && !right_sym.is_number() {
 | 
				
			||||||
		} else {
 | 
							c.error('- operator can only be used with numeric types', node.pos)
 | 
				
			||||||
			c.error('<- operator can only be used with `chan` types', node.pos)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if node.op == .arrow {
 | 
				
			||||||
 | 
							if right_sym.kind == .chan {
 | 
				
			||||||
 | 
								c.stmts(node.or_block.stmts)
 | 
				
			||||||
 | 
								return right_sym.chan_info().elem_type
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							c.error('<- operator can only be used with `chan` types', node.pos)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return right_type
 | 
						return right_type
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,42 +1,62 @@
 | 
				
			||||||
vlib/v/checker/tests/minus_op_wrong_type_err.vv:3:13: error: mismatched types `Aaa` and `int literal`
 | 
					vlib/v/checker/tests/minus_op_wrong_type_err.vv:10:10: error: mismatched types `Aaa` and `int literal`
 | 
				
			||||||
    1 | struct Aaa{}
 | 
					    8 |
 | 
				
			||||||
    2 | fn main() {
 | 
					    9 | fn main() {
 | 
				
			||||||
    3 |     println(Aaa{} - 10)
 | 
					   10 |     println(Aaa{} - 10)
 | 
				
			||||||
      |             ~~~~~~~~~~
 | 
					      |             ~~~~~~~~~~
 | 
				
			||||||
    4 |     println(10 - Aaa{})
 | 
					   11 |     println(10 - Aaa{})
 | 
				
			||||||
    5 |     println([1,2,3] - 10)
 | 
					   12 |     println([1, 2, 3] - 10)
 | 
				
			||||||
vlib/v/checker/tests/minus_op_wrong_type_err.vv:4:13: error: mismatched types `int literal` and `Aaa`
 | 
					vlib/v/checker/tests/minus_op_wrong_type_err.vv:11:10: error: mismatched types `int literal` and `Aaa`
 | 
				
			||||||
    2 | fn main() {
 | 
					    9 | fn main() {
 | 
				
			||||||
    3 |     println(Aaa{} - 10)
 | 
					   10 |     println(Aaa{} - 10)
 | 
				
			||||||
    4 |     println(10 - Aaa{})
 | 
					   11 |     println(10 - Aaa{})
 | 
				
			||||||
      |             ~~~~~~~~~~
 | 
					      |             ~~~~~~~~~~
 | 
				
			||||||
    5 |     println([1,2,3] - 10)
 | 
					   12 |     println([1, 2, 3] - 10)
 | 
				
			||||||
    6 |     println(10 - [1,2,3])
 | 
					   13 |     println(10 - [1, 2, 3])
 | 
				
			||||||
vlib/v/checker/tests/minus_op_wrong_type_err.vv:5:13: error: mismatched types `[]int` and `int literal`
 | 
					vlib/v/checker/tests/minus_op_wrong_type_err.vv:12:10: error: mismatched types `[]int` and `int literal`
 | 
				
			||||||
    3 |     println(Aaa{} - 10)
 | 
					   10 |     println(Aaa{} - 10)
 | 
				
			||||||
    4 |     println(10 - Aaa{})
 | 
					   11 |     println(10 - Aaa{})
 | 
				
			||||||
    5 |     println([1,2,3] - 10)
 | 
					   12 |     println([1, 2, 3] - 10)
 | 
				
			||||||
      |             ~~~~~~~~~~~~
 | 
					      |             ~~~~~~~~~~~~~~
 | 
				
			||||||
    6 |     println(10 - [1,2,3])
 | 
					   13 |     println(10 - [1, 2, 3])
 | 
				
			||||||
    7 |     a := map[string]int
 | 
					   14 |     a := map[string]int{}
 | 
				
			||||||
vlib/v/checker/tests/minus_op_wrong_type_err.vv:6:13: error: mismatched types `int literal` and `[]int`
 | 
					vlib/v/checker/tests/minus_op_wrong_type_err.vv:13:10: error: mismatched types `int literal` and `[]int`
 | 
				
			||||||
    4 |     println(10 - Aaa{})
 | 
					   11 |     println(10 - Aaa{})
 | 
				
			||||||
    5 |     println([1,2,3] - 10)
 | 
					   12 |     println([1, 2, 3] - 10)
 | 
				
			||||||
    6 |     println(10 - [1,2,3])
 | 
					   13 |     println(10 - [1, 2, 3])
 | 
				
			||||||
      |             ~~~~~~~~~~~~
 | 
					      |             ~~~~~~~~~~~~~~
 | 
				
			||||||
    7 |     a := map[string]int
 | 
					   14 |     a := map[string]int{}
 | 
				
			||||||
    8 |     println(a - 10)
 | 
					   15 |     println(a - 10)
 | 
				
			||||||
vlib/v/checker/tests/minus_op_wrong_type_err.vv:8:13: error: mismatched types `map[string]int` and `int literal`
 | 
					vlib/v/checker/tests/minus_op_wrong_type_err.vv:15:10: error: mismatched types `map[string]int` and `int literal`
 | 
				
			||||||
    6 |     println(10 - [1,2,3])
 | 
					   13 |     println(10 - [1, 2, 3])
 | 
				
			||||||
    7 |     a := map[string]int
 | 
					   14 |     a := map[string]int{}
 | 
				
			||||||
    8 |     println(a - 10)
 | 
					   15 |     println(a - 10)
 | 
				
			||||||
      |             ~~~~~~
 | 
					      |             ~~~~~~
 | 
				
			||||||
    9 |     println(10 - a)
 | 
					   16 |     println(10 - a)
 | 
				
			||||||
   10 | }
 | 
					   17 |     println(-Aaa{})
 | 
				
			||||||
vlib/v/checker/tests/minus_op_wrong_type_err.vv:9:13: error: mismatched types `int literal` and `map[string]int`
 | 
					vlib/v/checker/tests/minus_op_wrong_type_err.vv:16:10: error: mismatched types `int literal` and `map[string]int`
 | 
				
			||||||
    7 |     a := map[string]int
 | 
					   14 |     a := map[string]int{}
 | 
				
			||||||
    8 |     println(a - 10)
 | 
					   15 |     println(a - 10)
 | 
				
			||||||
    9 |     println(10 - a)
 | 
					   16 |     println(10 - a)
 | 
				
			||||||
      |             ~~~~~~
 | 
					      |             ~~~~~~
 | 
				
			||||||
   10 | }
 | 
					   17 |     println(-Aaa{})
 | 
				
			||||||
 | 
					   18 |     println(-a)
 | 
				
			||||||
 | 
					vlib/v/checker/tests/minus_op_wrong_type_err.vv:17:10: error: - operator can only be used with numeric types
 | 
				
			||||||
 | 
					   15 |     println(a - 10)
 | 
				
			||||||
 | 
					   16 |     println(10 - a)
 | 
				
			||||||
 | 
					   17 |     println(-Aaa{})
 | 
				
			||||||
 | 
					      |             ^
 | 
				
			||||||
 | 
					   18 |     println(-a)
 | 
				
			||||||
 | 
					   19 |     println(-Color.red)
 | 
				
			||||||
 | 
					vlib/v/checker/tests/minus_op_wrong_type_err.vv:18:10: error: - operator can only be used with numeric types
 | 
				
			||||||
 | 
					   16 |     println(10 - a)
 | 
				
			||||||
 | 
					   17 |     println(-Aaa{})
 | 
				
			||||||
 | 
					   18 |     println(-a)
 | 
				
			||||||
 | 
					      |             ^
 | 
				
			||||||
 | 
					   19 |     println(-Color.red)
 | 
				
			||||||
 | 
					   20 | }
 | 
				
			||||||
 | 
					vlib/v/checker/tests/minus_op_wrong_type_err.vv:19:10: error: - operator can only be used with numeric types
 | 
				
			||||||
 | 
					   17 |     println(-Aaa{})
 | 
				
			||||||
 | 
					   18 |     println(-a)
 | 
				
			||||||
 | 
					   19 |     println(-Color.red)
 | 
				
			||||||
 | 
					      |             ^
 | 
				
			||||||
 | 
					   20 | }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,20 @@
 | 
				
			||||||
struct Aaa{}
 | 
					struct Aaa {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum Color {
 | 
				
			||||||
 | 
						red
 | 
				
			||||||
 | 
						green
 | 
				
			||||||
 | 
						blue
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
	println(Aaa{} - 10)
 | 
						println(Aaa{} - 10)
 | 
				
			||||||
	println(10 - Aaa{})
 | 
						println(10 - Aaa{})
 | 
				
			||||||
    println([1,2,3] - 10)
 | 
						println([1, 2, 3] - 10)
 | 
				
			||||||
    println(10 - [1,2,3])
 | 
						println(10 - [1, 2, 3])
 | 
				
			||||||
	a := map[string]int
 | 
						a := map[string]int{}
 | 
				
			||||||
	println(a - 10)
 | 
						println(a - 10)
 | 
				
			||||||
	println(10 - a)
 | 
						println(10 - a)
 | 
				
			||||||
 | 
						println(-Aaa{})
 | 
				
			||||||
 | 
						println(-a)
 | 
				
			||||||
 | 
						println(-Color.red)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue