checker: fix sum type operator check (#6815)
							parent
							
								
									ee5ad2a653
								
							
						
					
					
						commit
						ed874ffc5b
					
				|  | @ -861,6 +861,12 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { | |||
| 		c.error('string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`', | ||||
| 			infix_expr.pos) | ||||
| 	} | ||||
| 	// sum types can't have any infix operation except of "is", is is checked before and doesn't reach this
 | ||||
| 	if c.table.type_kind(left_type) == .union_sum_type { | ||||
| 		c.error('cannot use operator `$infix_expr.op` with `$left.name`', infix_expr.pos) | ||||
| 	} else if c.table.type_kind(right_type) == .union_sum_type { | ||||
| 		c.error('cannot use operator `$infix_expr.op` with `$right.name`', infix_expr.pos) | ||||
| 	} | ||||
| 	// Dual sides check (compatibility check)
 | ||||
| 	if !c.symmetric_check(right_type, left_type) && !c.pref.translated { | ||||
| 		// for type-unresolved consts
 | ||||
|  |  | |||
|  | @ -0,0 +1,14 @@ | |||
| vlib/v/checker/tests/sum_type_infix_err.vv:5:9: error: cannot use operator `+` with `Abc` | ||||
|     3 | fn main() { | ||||
|     4 |     x := Abc(0) | ||||
|     5 |     _ := x + Abc(5) | ||||
|       |            ^ | ||||
|     6 |     _ := 'test' + x | ||||
|     7 |     _ = unsafe{&x + 5} | ||||
| vlib/v/checker/tests/sum_type_infix_err.vv:6:14: error: cannot use operator `+` with `Abc` | ||||
|     4 |     x := Abc(0) | ||||
|     5 |     _ := x + Abc(5) | ||||
|     6 |     _ := 'test' + x | ||||
|       |                 ^ | ||||
|     7 |     _ = unsafe{&x + 5} | ||||
|     8 | } | ||||
|  | @ -0,0 +1,8 @@ | |||
| __type Abc = int | string | ||||
| 
 | ||||
| fn main() { | ||||
| 	x := Abc(0) | ||||
| 	_ := x + Abc(5) | ||||
| 	_ := 'test' + x | ||||
| 	_ = unsafe{&x + 5} | ||||
| } | ||||
|  | @ -1,18 +1,18 @@ | |||
| vlib/v/checker/tests/sum_type_mutable_cast_err.vv:23:10: error: infix expr: cannot use `any_int` (right expression) as `Abc` | ||||
| vlib/v/checker/tests/sum_type_mutable_cast_err.vv:23:10: error: cannot use operator `+` with `Abc` | ||||
|    21 |     mut x := Abc(0) | ||||
|    22 |     if x is int { | ||||
|    23 |         _ := x + 5 | ||||
|       |                ^ | ||||
|    24 |     } | ||||
|    25 |     f := Foo{Bar{Abc(0)}} | ||||
| vlib/v/checker/tests/sum_type_mutable_cast_err.vv:27:14: error: infix expr: cannot use `any_int` (right expression) as `Abc` | ||||
| vlib/v/checker/tests/sum_type_mutable_cast_err.vv:27:14: error: cannot use operator `+` with `Abc` | ||||
|    25 |     f := Foo{Bar{Abc(0)}} | ||||
|    26 |     if f.b.a is int { | ||||
|    27 |         _ := f.b.a + 5 | ||||
|       |                    ^ | ||||
|    28 |     } | ||||
|    29 |     mut f2 := Foo2{Bar2{Abc(0)}} | ||||
| vlib/v/checker/tests/sum_type_mutable_cast_err.vv:31:14: error: infix expr: cannot use `any_int` (right expression) as `Abc` | ||||
| vlib/v/checker/tests/sum_type_mutable_cast_err.vv:31:14: error: cannot use operator `+` with `Abc` | ||||
|    29 |     mut f2 := Foo2{Bar2{Abc(0)}} | ||||
|    30 |     if f2.b.a is int { | ||||
|    31 |         _ := f.b.a + 5 | ||||
|  |  | |||
|  | @ -26,7 +26,9 @@ pub enum Language { | |||
| 
 | ||||
| // Represents a type that only needs an identifier, e.g. int, array_int.
 | ||||
| // A pointer type `&T` would have a TypeSymbol `T`.
 | ||||
| // Note: For a Type, use Table.type_to_str(typ) not TypeSymbol.name.
 | ||||
| // Note: For a Type, use:
 | ||||
| // * Table.type_to_str(typ) not TypeSymbol.name.
 | ||||
| // * Table.type_kind(typ) not TypeSymbol.kind.
 | ||||
| // Each TypeSymbol is entered into `Table.types`.
 | ||||
| // See also: Table.get_type_symbol.
 | ||||
| pub struct TypeSymbol { | ||||
|  | @ -363,6 +365,14 @@ pub: | |||
| 	func     Fn | ||||
| } | ||||
| 
 | ||||
| // returns TypeSymbol kind only if there are no type modifiers
 | ||||
| pub fn (table &Table) type_kind(typ Type) Kind { | ||||
| 	if typ.nr_muls() > 0 || typ.has_flag(.optional) { | ||||
| 		return Kind.placeholder | ||||
| 	} | ||||
| 	return table.get_type_symbol(typ).kind | ||||
| } | ||||
| 
 | ||||
| pub enum Kind { | ||||
| 	placeholder | ||||
| 	void | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue