mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: fix sum type operator check (#6815)
This commit is contained in:
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 `+`',
|
c.error('string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`',
|
||||||
infix_expr.pos)
|
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)
|
// Dual sides check (compatibility check)
|
||||||
if !c.symmetric_check(right_type, left_type) && !c.pref.translated {
|
if !c.symmetric_check(right_type, left_type) && !c.pref.translated {
|
||||||
// for type-unresolved consts
|
// for type-unresolved consts
|
||||||
|
14
vlib/v/checker/tests/sum_type_infix_err.out
Normal file
14
vlib/v/checker/tests/sum_type_infix_err.out
Normal file
@ -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 | }
|
8
vlib/v/checker/tests/sum_type_infix_err.vv
Normal file
8
vlib/v/checker/tests/sum_type_infix_err.vv
Normal file
@ -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)
|
21 | mut x := Abc(0)
|
||||||
22 | if x is int {
|
22 | if x is int {
|
||||||
23 | _ := x + 5
|
23 | _ := x + 5
|
||||||
| ^
|
| ^
|
||||||
24 | }
|
24 | }
|
||||||
25 | f := Foo{Bar{Abc(0)}}
|
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)}}
|
25 | f := Foo{Bar{Abc(0)}}
|
||||||
26 | if f.b.a is int {
|
26 | if f.b.a is int {
|
||||||
27 | _ := f.b.a + 5
|
27 | _ := f.b.a + 5
|
||||||
| ^
|
| ^
|
||||||
28 | }
|
28 | }
|
||||||
29 | mut f2 := Foo2{Bar2{Abc(0)}}
|
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)}}
|
29 | mut f2 := Foo2{Bar2{Abc(0)}}
|
||||||
30 | if f2.b.a is int {
|
30 | if f2.b.a is int {
|
||||||
31 | _ := f.b.a + 5
|
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.
|
// Represents a type that only needs an identifier, e.g. int, array_int.
|
||||||
// A pointer type `&T` would have a TypeSymbol `T`.
|
// 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`.
|
// Each TypeSymbol is entered into `Table.types`.
|
||||||
// See also: Table.get_type_symbol.
|
// See also: Table.get_type_symbol.
|
||||||
pub struct TypeSymbol {
|
pub struct TypeSymbol {
|
||||||
@ -363,6 +365,14 @@ pub:
|
|||||||
func Fn
|
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 {
|
pub enum Kind {
|
||||||
placeholder
|
placeholder
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user