From af334e320ce69eb95b430fb2dd2a41ae5100f336 Mon Sep 17 00:00:00 2001 From: Tanel Liiv <204019+dkull@users.noreply.github.com> Date: Wed, 13 May 2020 02:01:34 +0300 Subject: [PATCH] cgen: dereference in one place and fix --- vlib/v/gen/cgen.v | 18 ++++++++++++++---- vlib/v/gen/fn.v | 3 --- vlib/v/tests/sum_type_test.v | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 12e9068c5a..5054675cec 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -796,6 +796,20 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type, expected_type table.Type) } } } + // Generic dereferencing logic + expected_sym := g.table.get_type_symbol(expected_type) + got_is_ptr := got_type.is_ptr() + expected_is_ptr := expected_type.is_ptr() + neither_void := table.voidptr_type !in [got_type, expected_type] + if got_is_ptr && !expected_is_ptr && neither_void && expected_sym.kind !in [.interface_, .placeholder] { + got_deref_type := got_type.deref() + deref_sym := g.table.get_type_symbol(got_deref_type) + deref_will_match := expected_type in [got_type, got_deref_type, deref_sym.parent_idx] + got_is_opt := got_type.flag_is(.optional) + if deref_will_match || got_is_opt { + g.write('*') + } + } // no cast g.expr(expr) } @@ -2070,10 +2084,6 @@ fn (mut g Gen) return_statement(node ast.Return) { g.writeln(' }, sizeof($styp));') return } - if !g.fn_decl.return_type.is_ptr() && node.types[0].is_ptr() { - // Automatic Dereference - g.write('*') - } g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type) } g.writeln(';') diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index b1bbbdda42..3b8d78e091 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -618,9 +618,6 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) { if !g.is_json_fn { g.write('&/*qq*/') } - } else if !arg_is_ptr && expr_is_ptr && exp_sym.kind != .interface_ { - // Dereference a pointer if a value is required - g.write('*/*d*/') } g.expr_with_cast(arg.expr, arg.typ, expected_type) } diff --git a/vlib/v/tests/sum_type_test.v b/vlib/v/tests/sum_type_test.v index da856b2a64..d9ee2c1402 100644 --- a/vlib/v/tests/sum_type_test.v +++ b/vlib/v/tests/sum_type_test.v @@ -51,3 +51,37 @@ fn test_assignment_and_push() { else {} } } + +// Test moving structs between master/sub arrays + +type Master = Sub1 | Sub2 +struct Sub1 { +mut: + val int + name string +} +struct Sub2 { + name string + val int +} + +fn test_converting_down() { + mut out := []Master{} + out << Sub1 { val: 1, name: 'one' } + out << Sub2 { val: 2, name: 'two'} + out << Sub2 { val: 3, name: 'three'} + + mut res := []Sub2{cap: out.len} + for d in out { + match d { + Sub2 { res << it } + else {} + } + } + + assert res[0].val == 2 + assert res[0].name == 'two' + assert res[1].val == 3 + assert res[1].name == 'three' +} +