From bf904c2f823070ddda3adcf4b08a77eef29c6635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kr=C3=BCger?= <45282134+UweKrueger@users.noreply.github.com> Date: Mon, 4 Jan 2021 19:48:13 +0100 Subject: [PATCH] checker, cgen: allow using literals as `int` and `f64` for sum types (#7864) --- vlib/v/checker/check_types.v | 2 +- vlib/v/checker/tests/is_type_not_exist.out | 7 -- vlib/v/gen/cgen.v | 3 +- vlib/v/tests/sumtype_literal_test.v | 84 ++++++++++++++++++++++ 4 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 vlib/v/tests/sumtype_literal_test.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index c2653b38a2..7a1c06af51 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -123,7 +123,7 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool { return true } // sum type - if c.table.sumtype_has_variant(expected, got) { + if c.table.sumtype_has_variant(expected, c.table.mktyp(got)) { return true } // fn type diff --git a/vlib/v/checker/tests/is_type_not_exist.out b/vlib/v/checker/tests/is_type_not_exist.out index 881050431a..1c52d7ac11 100644 --- a/vlib/v/checker/tests/is_type_not_exist.out +++ b/vlib/v/checker/tests/is_type_not_exist.out @@ -1,10 +1,3 @@ -vlib/v/checker/tests/is_type_not_exist.vv:4:25: error: cannot use `int literal` as `Integer` in argument 1 to `fn_with_sum_type_param` - 2 | - 3 | fn main() { - 4 | fn_with_sum_type_param(1) - | ^ - 5 | } - 6 | vlib/v/checker/tests/is_type_not_exist.vv:8:10: error: is: type `SomethingThatDontExist` does not exist 6 | 7 | fn fn_with_sum_type_param(i Integer) { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 83b49bf036..c980844e5e 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1320,7 +1320,8 @@ fn (mut g Gen) for_in(it ast.ForInStmt) { } // use instead of expr() when you need to cast to union sum type (can add other casts also) -fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type table.Type, expected_type table.Type) { +fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw table.Type, expected_type table.Type) { + got_type := g.table.mktyp(got_type_raw) // cast to sum type if expected_type != table.void_type { expected_is_ptr := expected_type.is_ptr() diff --git a/vlib/v/tests/sumtype_literal_test.v b/vlib/v/tests/sumtype_literal_test.v new file mode 100644 index 0000000000..afcc9c29ce --- /dev/null +++ b/vlib/v/tests/sumtype_literal_test.v @@ -0,0 +1,84 @@ +type Foo = f32 | f64 | i16 | int | u64 + +fn test_assign_cast() { + a := Foo(3) + b := Foo(3.0) + c := Foo(-7.25) + d := Foo(i16(-4)) + e := Foo(f32(-0.0625)) + assert a is int + assert b is f64 + assert b !is int + assert c is f64 + assert d is i16 + assert e is f32 +} + +fn test_assign_mut() { + mut a := Foo(0) + mut b := Foo(i16(3)) + mut c := Foo(f32(1)) + a = 12.3 + b = -123456 + c = 33. + assert a is f64 + assert b is int + assert c is f64 +} + +fn test_call_arg() { + assert get_type_idx(0.25) == 1 + assert get_type_idx(-7) == 3 + assert get_type_idx(u64(0)) == 4 + assert get_type_idx(f32(-0.125e-7)) == 0 +} + +fn get_type_idx(x Foo) int { + match x { + f32 { + return 0 + } + f64 { + return 1 + } + i16 { + return 2 + } + int { + return 3 + } + u64 { + return 4 + } + } +} + +fn test_sumtype_return() { + a := gen_foo(0) + b := gen_foo(1) + c := gen_foo(2) + d := gen_foo(3) + e := gen_foo(4) + assert a is f32 + assert b is f64 + assert c is f64 + assert c !is int + assert d is i16 + assert e is int +} + +fn gen_foo(n int) Foo { + if n == 0 { + return f32(0.5) + } + if n == 1 { + return -17.3e23 + } + if n == 2 { + return 32. + } + if n == 3 { + return i16(13) + } + return 1 +}