From da9588c1a551bc8d3031a3854f9e0cf674d110a6 Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Tue, 15 Dec 2020 09:00:51 +0530 Subject: [PATCH] checker: fix struct cast (#7308) --- vlib/v/checker/checker.v | 4 ++ vlib/v/checker/tests/struct_type_cast_err.out | 63 +++++++++++++++++++ vlib/v/checker/tests/struct_type_cast_err.vv | 15 +++++ 3 files changed, 82 insertions(+) create mode 100644 vlib/v/checker/tests/struct_type_cast_err.out create mode 100644 vlib/v/checker/tests/struct_type_cast_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 26d7eb3453..0e03464f5d 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3182,6 +3182,10 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type { } else if node.expr_type == table.none_type { type_name := c.table.type_to_str(node.typ) c.error('cannot cast `none` to `$type_name`', node.pos) + } else if from_type_sym.kind == .struct_ && !node.expr_type.is_ptr() && to_type_sym.kind !in + [.sum_type, .interface_] && !c.is_builtin_mod { + type_name := c.table.type_to_str(node.typ) + c.error('cannot cast `struct` to `$type_name`', node.pos) } if node.has_arg { c.expr(node.arg) diff --git a/vlib/v/checker/tests/struct_type_cast_err.out b/vlib/v/checker/tests/struct_type_cast_err.out new file mode 100644 index 0000000000..cdf9f0c6b1 --- /dev/null +++ b/vlib/v/checker/tests/struct_type_cast_err.out @@ -0,0 +1,63 @@ +vlib/v/checker/tests/struct_type_cast_err.vv:5:10: error: cannot cast `struct` 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` 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` 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` 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` 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 type `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` 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` to `i64` + 10 | _ := byte(foo) + 11 | _ := i8(foo) + 12 | _ := i64(foo) + | ~~~~~~~~ + 13 | _ := int(foo) + 14 | } +vlib/v/checker/tests/struct_type_cast_err.vv:13:10: error: cannot cast `struct` to `int` + 11 | _ := i8(foo) + 12 | _ := i64(foo) + 13 | _ := int(foo) + | ~~~~~~~~ + 14 | } + 15 | diff --git a/vlib/v/checker/tests/struct_type_cast_err.vv b/vlib/v/checker/tests/struct_type_cast_err.vv new file mode 100644 index 0000000000..e800a5662b --- /dev/null +++ b/vlib/v/checker/tests/struct_type_cast_err.vv @@ -0,0 +1,15 @@ +struct Foo{} + +fn main() { + foo := Foo{} + _ := string(foo) + _ := int(foo) + _ := u64(foo) + _ := u32(foo) + _ := rune(foo) + _ := byte(foo) + _ := i8(foo) + _ := i64(foo) + _ := int(foo) +} +