From 0232f074a8574e8ec87c4b7e61845c4fa414521d Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Tue, 20 Jun 2023 05:52:59 -0300 Subject: [PATCH] cgen: fix alias eq method + map init with option (#18483) --- vlib/v/gen/c/auto_eq_methods.v | 16 +++++++++++----- vlib/v/gen/c/cgen.v | 2 +- vlib/v/tests/option_alias_eq_test.v | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 vlib/v/tests/option_alias_eq_test.v diff --git a/vlib/v/gen/c/auto_eq_methods.v b/vlib/v/gen/c/auto_eq_methods.v index f69e36e561..bcb619eb11 100644 --- a/vlib/v/gen/c/auto_eq_methods.v +++ b/vlib/v/gen/c/auto_eq_methods.v @@ -230,14 +230,16 @@ fn (mut g Gen) gen_alias_equality_fn(left_type ast.Type) string { mut fn_builder := strings.new_builder(512) fn_builder.writeln('static bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b) {') - is_option := info.parent_type.has_flag(.option) || left.typ.has_flag(.option) + is_option := left.typ.has_flag(.option) - left_var := if is_option { '*' + g.read_opt(info.parent_type, 'a') } else { 'a' } - right_var := if is_option { '*' + g.read_opt(info.parent_type, 'b') } else { 'b' } + mut left_var := if is_option { '*' + g.read_opt(info.parent_type, 'a') } else { 'a' } + mut right_var := if is_option { '*' + g.read_opt(info.parent_type, 'b') } else { 'b' } sym := g.table.sym(info.parent_type) if sym.kind == .string { - if is_option { + if info.parent_type.has_flag(.option) { + left_var = '*' + g.read_opt(info.parent_type, 'a') + right_var = '*' + g.read_opt(info.parent_type, 'b') fn_builder.writeln('\treturn ((${left_var}).len == (${right_var}).len && (${left_var}).len == 0) || string__eq(${left_var}, ${right_var});') } else { fn_builder.writeln('\treturn string__eq(a, b);') @@ -462,7 +464,11 @@ fn (mut g Gen) gen_map_equality_fn(left_type ast.Type) string { fn_builder.writeln('\t\tif (*(voidptr*)map_get(&b, k, &(voidptr[]){ 0 }) != v) {') } else { - fn_builder.writeln('\t\tif (*(${ptr_value_styp}*)map_get(&b, k, &(${ptr_value_styp}[]){ 0 }) != v) {') + if value.typ.has_flag(.option) { + fn_builder.writeln('\t\tif (memcmp(v.data, ((${ptr_value_styp}*)map_get(&b, k, &(${ptr_value_styp}[]){ 0 }))->data, sizeof(${g.base_type(value.typ)})) != 0) {') + } else { + fn_builder.writeln('\t\tif (*(${ptr_value_styp}*)map_get(&b, k, &(${ptr_value_styp}[]){ 0 }) != v) {') + } } } fn_builder.writeln('\t\t\treturn false;') diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 28fc3f5642..28b33f9695 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3924,7 +3924,7 @@ fn (mut g Gen) unlock_locks() { fn (mut g Gen) map_init(node ast.MapInit) { unwrap_key_typ := g.unwrap_generic(node.key_type) - unwrap_val_typ := g.unwrap_generic(node.value_type).clear_flags(.option, .result) + unwrap_val_typ := g.unwrap_generic(node.value_type).clear_flags(.result) key_typ_str := g.typ(unwrap_key_typ) value_typ_str := g.typ(unwrap_val_typ) value_sym := g.table.sym(unwrap_val_typ) diff --git a/vlib/v/tests/option_alias_eq_test.v b/vlib/v/tests/option_alias_eq_test.v new file mode 100644 index 0000000000..0e12c8df29 --- /dev/null +++ b/vlib/v/tests/option_alias_eq_test.v @@ -0,0 +1,18 @@ +struct MyStruct { + field int +} + +pub type MyOpt = ?MyStruct + +fn empty() map[string]MyOpt { + return {} +} + +fn test_empty() { + expected := { + 'key': ?MyOpt(none) + } + assert dump(expected) == { + 'key': ?MyOpt(none) + } +}