diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 43a863eea9..1a8dd1dbc3 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3487,10 +3487,6 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { c.error('cannot convert type `$from_type_sym.name` to `$to_type_sym.name` (alias to `$to_type_sym_final.name`)', node.pos) } - } else if to_type_sym.kind == .byte && from_type_sym.kind == .alias - && from_type_sym_final.kind != .byte && !from_type.is_ptr() { - type_name := c.table.type_to_str(from_type) - c.error('cannot cast type `$type_name` to `byte`', node.pos) } else if to_type_sym.kind == .struct_ && !to_type.is_ptr() && !(to_type_sym.info as ast.Struct).is_typedef { // For now we ignore C typedef because of `C.Window(C.None)` in vlib/clipboard @@ -3523,10 +3519,13 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { if (to_type.is_ptr() || to_type_sym.kind !in [.sum_type, .interface_]) && !c.is_builtin_mod { from_type_name := c.table.type_to_str(from_type) type_name := c.table.type_to_str(to_type) - snexpr := node.expr.str() - c.error('cannot cast struct `$from_type_name` to `$type_name`, use `${snexpr}.str()` instead.', - node.pos) + c.error('cannot cast struct `$from_type_name` to `$type_name`', node.pos) } + } else if to_type_sym.kind == .byte && !from_type_sym_final.is_number() + && !from_type_sym_final.is_pointer() && !from_type.is_ptr() + && from_type_sym_final.kind !in [.char, .enum_, .bool] { + type_name := c.table.type_to_str(from_type) + c.error('cannot cast type `$type_name` to `byte`', node.pos) } else if from_type.has_flag(.optional) || from_type.has_flag(.variadic) { // variadic case can happen when arrays are converted into variadic msg := if from_type.has_flag(.optional) { 'an optional' } else { 'a variadic' } diff --git a/vlib/v/checker/tests/cast_alias_to_byte_err.out b/vlib/v/checker/tests/cast_alias_to_byte_err.out deleted file mode 100644 index e9404d5da3..0000000000 --- a/vlib/v/checker/tests/cast_alias_to_byte_err.out +++ /dev/null @@ -1,7 +0,0 @@ -vlib/v/checker/tests/cast_alias_to_byte_err.vv:5:7: error: cannot cast type `Foo` to `byte` - 3 | fn main() { - 4 | a := Foo('hello') - 5 | b := byte(a) - | ~~~~~~~ - 6 | println(b) - 7 | } diff --git a/vlib/v/checker/tests/cast_alias_to_byte_err.vv b/vlib/v/checker/tests/cast_alias_to_byte_err.vv deleted file mode 100644 index 29d837e84c..0000000000 --- a/vlib/v/checker/tests/cast_alias_to_byte_err.vv +++ /dev/null @@ -1,7 +0,0 @@ -type Foo = string - -fn main() { - a := Foo('hello') - b := byte(a) - println(b) -} diff --git a/vlib/v/checker/tests/cast_string_err.out b/vlib/v/checker/tests/cast_string_err.out index 7303f52447..2488e62de7 100644 --- a/vlib/v/checker/tests/cast_string_err.out +++ b/vlib/v/checker/tests/cast_string_err.out @@ -12,7 +12,7 @@ vlib/v/checker/tests/cast_string_err.vv:18:9: error: cannot cast sumtype `Sumtyp | ~~~~~~~~~~ 19 | println(sst) 20 | // -vlib/v/checker/tests/cast_string_err.vv:22:10: error: cannot cast struct `Abc` to `string`, use `abc.str()` instead. +vlib/v/checker/tests/cast_string_err.vv:22:10: error: cannot cast struct `Abc` to `string` 20 | // 21 | abc := Abc{} 22 | sabc := string(abc) diff --git a/vlib/v/checker/tests/cast_to_byte_err.out b/vlib/v/checker/tests/cast_to_byte_err.out new file mode 100644 index 0000000000..efbe57b6d7 --- /dev/null +++ b/vlib/v/checker/tests/cast_to_byte_err.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/cast_to_byte_err.vv:10:7: error: cannot cast type `string` to `byte` + 8 | fn main() { + 9 | // should be errors: + 10 | _ := byte('hello') + | ~~~~~~~~~~~~~ + 11 | _ := byte(SAlias('hello')) + 12 | +vlib/v/checker/tests/cast_to_byte_err.vv:11:7: error: cannot cast type `SAlias` to `byte` + 9 | // should be errors: + 10 | _ := byte('hello') + 11 | _ := byte(SAlias('hello')) + | ~~~~~~~~~~~~~~~~~~~~~ + 12 | + 13 | // should be allowed: diff --git a/vlib/v/checker/tests/cast_to_byte_err.vv b/vlib/v/checker/tests/cast_to_byte_err.vv new file mode 100644 index 0000000000..21919ddad3 --- /dev/null +++ b/vlib/v/checker/tests/cast_to_byte_err.vv @@ -0,0 +1,23 @@ +type SAlias = string + +type CAlias = char +type IAlias = int +type UAlias = u32 +type FAlias = f32 + +fn main() { + // should be errors: + _ := byte('hello') + _ := byte(SAlias('hello')) + + // should be allowed: + _ := byte(char(1)) + _ := byte(int(1)) + _ := byte(u32(1)) + _ := byte(f32(1.0)) + + _ := byte(CAlias(1)) + _ := byte(IAlias(1)) + _ := byte(UAlias(1)) + _ := byte(FAlias(1)) +} diff --git a/vlib/v/checker/tests/struct_type_cast_err.out b/vlib/v/checker/tests/struct_type_cast_err.out index 7678002a2a..c693bedbb0 100644 --- a/vlib/v/checker/tests/struct_type_cast_err.out +++ b/vlib/v/checker/tests/struct_type_cast_err.out @@ -1,60 +1,60 @@ -vlib/v/checker/tests/struct_type_cast_err.vv:5:10: error: cannot cast struct `Foo` to `string`, use `foo.str()` instead. +vlib/v/checker/tests/struct_type_cast_err.vv:5:10: error: cannot cast struct `Foo` to `string` 3 | fn main() { 4 | foo := Foo{} 5 | _ := string(foo) | ~~~~~~~~~~~ 6 | _ := int(foo) 7 | _ := u64(foo) -vlib/v/checker/tests/struct_type_cast_err.vv:6:10: error: cannot cast struct `Foo` to `int`, use `foo.str()` instead. +vlib/v/checker/tests/struct_type_cast_err.vv:6:10: error: cannot cast struct `Foo` to `int` 4 | foo := Foo{} 5 | _ := string(foo) 6 | _ := int(foo) | ~~~~~~~~ 7 | _ := u64(foo) 8 | _ := u32(foo) -vlib/v/checker/tests/struct_type_cast_err.vv:7:10: error: cannot cast struct `Foo` to `u64`, use `foo.str()` instead. +vlib/v/checker/tests/struct_type_cast_err.vv:7:10: error: cannot cast struct `Foo` to `u64` 5 | _ := string(foo) 6 | _ := int(foo) 7 | _ := u64(foo) | ~~~~~~~~ 8 | _ := u32(foo) 9 | _ := rune(foo) -vlib/v/checker/tests/struct_type_cast_err.vv:8:10: error: cannot cast struct `Foo` to `u32`, use `foo.str()` instead. +vlib/v/checker/tests/struct_type_cast_err.vv:8:10: error: cannot cast struct `Foo` to `u32` 6 | _ := int(foo) 7 | _ := u64(foo) 8 | _ := u32(foo) | ~~~~~~~~ 9 | _ := rune(foo) 10 | _ := byte(foo) -vlib/v/checker/tests/struct_type_cast_err.vv:9:10: error: cannot cast struct `Foo` to `rune`, use `foo.str()` instead. +vlib/v/checker/tests/struct_type_cast_err.vv:9:10: error: cannot cast struct `Foo` to `rune` 7 | _ := u64(foo) 8 | _ := u32(foo) 9 | _ := rune(foo) | ~~~~~~~~~ 10 | _ := byte(foo) 11 | _ := i8(foo) -vlib/v/checker/tests/struct_type_cast_err.vv:10:10: error: cannot cast struct `Foo` to `byte`, use `foo.str()` instead. +vlib/v/checker/tests/struct_type_cast_err.vv:10:10: error: cannot cast struct `Foo` to `byte` 8 | _ := u32(foo) 9 | _ := rune(foo) 10 | _ := byte(foo) | ~~~~~~~~~ 11 | _ := i8(foo) 12 | _ := i64(foo) -vlib/v/checker/tests/struct_type_cast_err.vv:11:10: error: cannot cast struct `Foo` to `i8`, use `foo.str()` instead. +vlib/v/checker/tests/struct_type_cast_err.vv:11:10: error: cannot cast struct `Foo` to `i8` 9 | _ := rune(foo) 10 | _ := byte(foo) 11 | _ := i8(foo) | ~~~~~~~ 12 | _ := i64(foo) 13 | _ := int(foo) -vlib/v/checker/tests/struct_type_cast_err.vv:12:10: error: cannot cast struct `Foo` to `i64`, use `foo.str()` instead. +vlib/v/checker/tests/struct_type_cast_err.vv:12:10: error: cannot cast struct `Foo` to `i64` 10 | _ := byte(foo) 11 | _ := i8(foo) 12 | _ := i64(foo) | ~~~~~~~~ 13 | _ := int(foo) 14 | _ = &I1(foo) -vlib/v/checker/tests/struct_type_cast_err.vv:13:10: error: cannot cast struct `Foo` to `int`, use `foo.str()` instead. +vlib/v/checker/tests/struct_type_cast_err.vv:13:10: error: cannot cast struct `Foo` to `int` 11 | _ := i8(foo) 12 | _ := i64(foo) 13 | _ := int(foo)