From 919741d931bda41137b7dc97cb3a234784d2f333 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 17 Nov 2024 17:22:51 -0300 Subject: [PATCH] add test --- vlib/v/checker/checker.v | 3 +- vlib/v/gen/c/cgen.v | 4 +- .../options/option_selector_unwrap_test.v | 31 ++++++++++++ .../option_selector_unwrap_types_test.v | 47 +++++++++++++++++++ 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/options/option_selector_unwrap_test.v create mode 100644 vlib/v/tests/options/option_selector_unwrap_types_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 35d4c358fe204f..9fcadefba49685 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4204,7 +4204,8 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast. smartcasts << field.smartcasts } // smartcast either if the value is immutable or if the mut argument is explicitly given - if !is_mut || expr.is_mut { + if !is_mut || expr.is_mut + || (cur_type.has_flag(.option) && cur_type.clear_flag(.option) == to_type_) { smartcasts << to_type scope.register_struct_field(expr.expr.str(), ast.ScopeStructField{ struct_type: expr.expr_type diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index d79ccc40a73c66..4ba9edccbf4775 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4043,7 +4043,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { } for i, typ in field.smartcasts { if i == 0 && is_option_unwrap { - g.write('*(${g.styp(typ)}*)') + g.write('(*(${g.styp(typ)}*)') } g.write('(') if field_sym.kind == .sum_type && !is_option { @@ -4203,7 +4203,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { } g.write(field_name) if is_option_unwrap { - g.write('.data)') + g.write('.data))') } if sum_type_deref_field != '' { g.write('${sum_type_dot}${sum_type_deref_field})') diff --git a/vlib/v/tests/options/option_selector_unwrap_test.v b/vlib/v/tests/options/option_selector_unwrap_test.v new file mode 100644 index 00000000000000..78cd0b407c343b --- /dev/null +++ b/vlib/v/tests/options/option_selector_unwrap_test.v @@ -0,0 +1,31 @@ +import datatypes { DoublyLinkedList } + +pub type LayoutBoxId = usize + +pub struct LayoutBox { +} + +pub struct LayoutTree { +mut: + root ?LayoutBoxId + boxes []LayoutBox +} + +pub fn LayoutTree.new() LayoutTree { + return LayoutTree{ + root: ?LayoutBoxId(none) + boxes: []LayoutBox{} + } +} + +fn test_main() { + mut tree := LayoutTree.new() + tree.root = 1 + if tree.root != none { + mut parents := DoublyLinkedList[LayoutBoxId]{} + parents.push_back(tree.root) + assert parents.len == 1 + } else { + assert false + } +} diff --git a/vlib/v/tests/options/option_selector_unwrap_types_test.v b/vlib/v/tests/options/option_selector_unwrap_types_test.v new file mode 100644 index 00000000000000..f7a8f71c6b62bf --- /dev/null +++ b/vlib/v/tests/options/option_selector_unwrap_types_test.v @@ -0,0 +1,47 @@ +type SumType = int | string + +struct Struct { + a int +} + +struct Foo { + a ?int + b ?string + c ?SumType + d ?Struct +} + +fn test_main() { + w := Foo{ + a: 123 + b: 'foo' + c: SumType(123) + d: Struct{ + a: 123 + } + } + if w.a != none { + dump(w.a) + assert w.a == 123 + } else { + assert false + } + if w.b != none { + dump(w.b) + assert w.b == 'foo' + } else { + assert false + } + if w.c != none { + dump(w.c) + assert w.c is int + } else { + assert false + } + if w.d != none { + dump(w.d) + assert w.d.a == 123 + } else { + assert false + } +}