From 3a86f27b9f639e5fd18da533bde0b09bda0d4d1f Mon Sep 17 00:00:00 2001 From: Ned Palacios Date: Sat, 19 Dec 2020 16:43:50 +0800 Subject: [PATCH] cgen: fix optional struct const field access (#7405) --- vlib/v/gen/cgen.v | 9 +++++++++ vlib/v/tests/const_test.v | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index cc88eab10e..4709e46ae5 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2637,6 +2637,12 @@ fn (mut g Gen) expr(node ast.Expr) { g.checker_bug('unexpected SelectorExpr.expr_type = 0', node.pos) } sym := g.table.get_type_symbol(node.expr_type) + // if node expr is a root ident and an optional + mut is_optional := node.expr is ast.Ident && node.expr_type.has_flag(.optional) + if is_optional { + opt_base_typ := g.base_type(node.expr_type) + g.writeln('(*($opt_base_typ*)') + } if sym.kind == .array_fixed { assert node.field_name == 'len' info := sym.info as table.ArrayFixed @@ -2678,6 +2684,9 @@ fn (mut g Gen) expr(node ast.Expr) { } } g.expr(node.expr) + if is_optional { + g.write('.data)') + } // struct embedding if sym.kind == .struct_ { sym_info := sym.info as table.Struct diff --git a/vlib/v/tests/const_test.v b/vlib/v/tests/const_test.v index 6dbd787206..e55e279081 100644 --- a/vlib/v/tests/const_test.v +++ b/vlib/v/tests/const_test.v @@ -11,3 +11,26 @@ fn test_const() { assert d == 11 assert c == 1 } + +// const optional test +struct Foo { + name string = 'foo' +} + +fn foo_decode(name string) ?Foo { + if name == 'baz' { + return error('baz is not allowed') + } + + return Foo{name} +} + +pub const ( + def = foo_decode('baz') or { Foo{} } + bar = foo_decode('bar')? +) + +fn test_opt_const() { + assert def.name == 'foo' + assert bar.name == 'bar' +}