diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 2b715e9af2b6f6..56283b67cab7bd 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3568,12 +3568,16 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { tt := c.table.type_to_str(to_type) c.error('cannot cast incompatible option ${final_to_sym.name} `${ft}` to `${tt}`', node.pos) - } - - if to_sym.kind == .rune && from_sym.is_string() { + } else if to_sym.kind == .rune && from_sym.is_string() { snexpr := node.expr.str() ft := c.table.type_to_str(from_type) c.error('cannot cast `${ft}` to rune, use `${snexpr}.runes()` instead.', node.pos) + } else if !from_type.is_ptr() && from_type != ast.string_type + && final_from_sym.info is ast.Struct && !final_from_sym.info.is_empty_struct() + && (final_to_sym.is_int() || final_to_sym.is_float()) { + ft := c.table.type_to_str(from_type) + tt := c.table.type_to_str(to_type) + c.error('cannot cast type `${ft}` to `${tt}`', node.pos) } if to_sym.kind == .enum && !(c.inside_unsafe || c.file.is_translated) && from_sym.is_int() { diff --git a/vlib/v/checker/tests/c_struct_cast.out b/vlib/v/checker/tests/c_struct_cast.out new file mode 100644 index 00000000000000..5fe6dad5c9a100 --- /dev/null +++ b/vlib/v/checker/tests/c_struct_cast.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/c_struct_cast.vv:18:7: error: cannot cast type `Vector3` to `int` + 16 | } + 17 | dump(v) + 18 | dump(int(v)) + | ~~~~~~ + 19 | } diff --git a/vlib/v/checker/tests/c_struct_cast.vv b/vlib/v/checker/tests/c_struct_cast.vv new file mode 100644 index 00000000000000..f59bf4e8203132 --- /dev/null +++ b/vlib/v/checker/tests/c_struct_cast.vv @@ -0,0 +1,19 @@ +module main + +pub struct C.Vector3 { + x f32 + y f32 + z f32 +} + +pub type Vector3 = C.Vector3 + +fn main() { + v := Vector3{ + x: 0.0 + y: 1.7 + z: 0.0 + } + dump(v) + dump(int(v)) +}