diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index ee7dad41fa..9c4a4412d2 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -187,7 +187,7 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) { .alias { // optimize simple eq/ne operation on numbers if left.unaliased_sym.is_int() { - if left.typ.is_ptr() { + if left.typ.is_ptr() && node.left.is_auto_deref_var() && !right.typ.is_pointer() { g.write('*'.repeat(left.typ.nr_muls())) } g.expr(node.left) diff --git a/vlib/v/gen/c/str.v b/vlib/v/gen/c/str.v index 0b3bd06759..13a493e8bc 100644 --- a/vlib/v/gen/c/str.v +++ b/vlib/v/gen/c/str.v @@ -64,6 +64,8 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) { if is_shared { typ = typ.clear_flag(.shared_f).set_nr_muls(0) } + // original is_ptr for the typ (aliased type could overwrite it) + is_ptr := typ.is_ptr() mut sym := g.table.sym(typ) // when type is non-option alias and doesn't has `str()`, print the aliased value if mut sym.info is ast.Alias && !sym.has_method('str') && !etype.has_flag(.option) { @@ -113,7 +115,6 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) { || sym.kind in [.array, .array_fixed, .map, .struct, .multi_return, .sum_type, .interface] { unwrap_option := expr is ast.Ident && expr.or_expr.kind == .propagate_option exp_typ := if unwrap_option { typ.clear_flag(.option) } else { typ } - is_ptr := exp_typ.is_ptr() is_dump_expr := expr is ast.DumpExpr is_var_mut := expr.is_auto_deref_var() str_fn_name := g.get_str_fn(exp_typ) @@ -170,7 +171,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) { if sym.is_c_struct() { g.write(c_struct_ptr(sym, typ, str_method_expects_ptr)) } else { - g.write('*'.repeat(typ.nr_muls())) + g.write('*'.repeat(etype.nr_muls())) } } else if sym.is_c_struct() { g.write(c_struct_ptr(sym, typ, str_method_expects_ptr)) @@ -201,7 +202,6 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) { g.write('}}}))') } } else { - is_ptr := typ.is_ptr() is_var_mut := expr.is_auto_deref_var() str_fn_name := g.get_str_fn(typ) g.write('${str_fn_name}(') diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index ef75939cb8..3bb5f03b70 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -37,9 +37,16 @@ fn (mut g Gen) struct_init(node ast.StructInit) { g.go_back(3) return } - mut sym := g.table.final_sym(g.unwrap_generic(node.typ)) + unwrapped_typ := g.unwrap_generic(node.typ) + mut sym := g.table.final_sym(unwrapped_typ) if sym.kind == .sum_type { - g.write(g.type_default_sumtype(g.unwrap_generic(node.typ), sym)) + if node.typ.has_flag(.generic) && unwrapped_typ.is_ptr() { + g.write('&(') + g.write(g.type_default_sumtype(unwrapped_typ.set_nr_muls(0), sym)) + g.write(')') + } else { + g.write(g.type_default_sumtype(unwrapped_typ, sym)) + } return } is_amp := g.is_amp @@ -120,7 +127,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) { } else { // alias to pointer type if (g.table.sym(node.typ).kind == .alias && g.table.unaliased_type(node.typ).is_ptr()) - || (node.typ.has_flag(.generic) && g.unwrap_generic(node.typ).is_ptr()) { + || (!sym.is_int() && node.typ.has_flag(.generic) && unwrapped_typ.is_ptr()) { g.write('&') } if is_array || const_msvc_init { @@ -349,10 +356,10 @@ fn (mut g Gen) struct_init(node ast.StructInit) { g.fixed_array_init(ast.ArrayInit{ pos: node.pos is_fixed: true - typ: g.unwrap_generic(node.typ) + typ: unwrapped_typ exprs: [ast.empty_expr] elem_type: arr_info.elem_type - }, g.unwrap(g.unwrap_generic(node.typ)), '', g.is_amp) + }, g.unwrap(unwrapped_typ), '', g.is_amp) initialized = true } if is_multiline { diff --git a/vlib/v/tests/generics/default_type_with_ref_test.v b/vlib/v/tests/generics/default_type_with_ref_test.v new file mode 100644 index 0000000000..d5d3e69219 --- /dev/null +++ b/vlib/v/tests/generics/default_type_with_ref_test.v @@ -0,0 +1,21 @@ +struct Struct {} + +type StructAlias = Struct + +type SumType = Struct | int + +type AliasInt = int + +fn (d Struct) a[T]() T { + return T{} +} + +fn test_main() { + s := Struct{} + assert s.a[&int]() == 0 + assert s.a[&int]() == unsafe { nil } + assert s.a[&Struct]() == Struct{} + assert s.a[&SumType]() is Struct + assert s.a[&StructAlias]() == StructAlias{} + assert s.a[&AliasInt]() == AliasInt(0) +}