From f8f7c99e2df5d258af89b679a863d0e14bc3c595 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 6 May 2024 05:02:37 -0300 Subject: [PATCH] cgen: fix option ptr unwrapping (#21415) --- vlib/v/gen/c/cgen.v | 4 +- vlib/v/tests/option_ptr_unwrap_test.v | 89 +++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/option_ptr_unwrap_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 076aec56d7..a0b10f767e 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4901,7 +4901,7 @@ fn (mut g Gen) ident(node ast.Ident) { g.write(g.get_ternary_name(name)) if is_auto_heap { g.write('))') - if is_option { + if is_option && node.or_expr.kind != .absent { g.write('.data') } } @@ -6992,7 +6992,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty if g.fn_decl.return_type == ast.void_type { g.writeln('\treturn;') } else { - styp := g.typ(g.fn_decl.return_type) + styp := g.typ(g.fn_decl.return_type).replace('*', '_ptr') err_obj := g.new_tmp_var() g.writeln('\t${styp} ${err_obj};') g.writeln('\tmemcpy(&${err_obj}, &${cvar_name}, sizeof(_option));') diff --git a/vlib/v/tests/option_ptr_unwrap_test.v b/vlib/v/tests/option_ptr_unwrap_test.v new file mode 100644 index 0000000000..cf1a589976 --- /dev/null +++ b/vlib/v/tests/option_ptr_unwrap_test.v @@ -0,0 +1,89 @@ +import time +// 41s. + +struct Node[T] { +mut: + data T + prev ?&Node[T] + next ?&Node[T] +} + +struct LinkedList[T] { +mut: + size usize + head ?&Node[T] +} + +fn new_linked_list[T]() &LinkedList[T] { + return &LinkedList[T]{} +} + +fn (mut li LinkedList[T]) add[T](data T) { + mut node := &Node[T]{data, none, none} + + if li.head == none { + li.head = node + node.next = node + node.prev = node + } else { + node.next = li.head + node.prev = li.head?.prev + node.prev?.next = node + li.head?.prev = node + } + + li.size += 1 +} + +fn (mut li LinkedList[T]) pop[T]() ?T { + if li.head == none { + return none + } + if li.size == 1 { + data := li.head?.data + li.head?.next = none + li.head?.prev = none + li.head = none + li.size -= 1 + return data + } + + mut tail := li.head?.prev? + mut curr := tail.prev? + curr.next = li.head + li.head?.prev = curr + + tail.next = none + tail.prev = none + li.size -= 1 + + return tail.data +} + +@[heap] +struct Integer { + value int +} + +fn test_main() { + max_itr := 2 + t := time.now() + for itr in 0 .. max_itr { + mut list := new_linked_list[&Integer]() + println('Itr#${itr} list size: ${list.size}') + + list.add(&Integer{10}) + println('Itr#${itr} list size: ${list.size}') + list.add(&Integer{20}) + println('Itr#${itr} list size: ${list.size}') + + mut n := list.pop() + println('Itr#${itr} list size: ${list.size}, data: ${n?}') + n = list.pop() + println('Itr#${itr} list size: ${list.size}, data: ${n?}') + n = list.pop() + println('Itr#${itr} list size: ${list.size}, data: ${n}') + } + d := time.since(t) + println('Bye(time ${d})!') +}