From b10b65e134608491b72631618e111ed2661f5464 Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 2 Feb 2022 15:11:29 +0800 Subject: [PATCH] cgen: fix error for interface with multi-nested embed struct (#13345) --- vlib/v/gen/c/cgen.v | 10 +++- ...nterface_with_multi_nested_embed_1_test.v} | 2 +- ...interface_with_multi_nested_embed_2_test.v | 57 +++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) rename vlib/v/tests/{interface_struct_with_multi_nested_embed_test.v => interface_with_multi_nested_embed_1_test.v} (95%) create mode 100644 vlib/v/tests/interface_with_multi_nested_embed_2_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 75ca27bedb..82182f53e1 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3604,10 +3604,15 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { } // struct embedding if sym.info in [ast.Struct, ast.Aggregate] { - for embed in node.from_embed_types { + for i, embed in node.from_embed_types { embed_sym := g.table.sym(embed) embed_name := embed_sym.embed_name() - if node.expr_type.is_ptr() { + is_left_ptr := if i == 0 { + node.expr_type.is_ptr() + } else { + node.from_embed_types[i - 1].is_ptr() + } + if is_left_ptr { g.write('->') } else { g.write('.') @@ -6831,6 +6836,7 @@ static inline __shared__$interface_name ${shared_fn_name}(__shared__$cctype* x) styp := g.cc_type(method.params[0].typ, true) mut method_call := '${styp}_$name' if !method.params[0].typ.is_ptr() { + method_call = '${cctype}_$name' // inline void Cat_speak_Interface_Animal_method_wrapper(Cat c) { return Cat_speak(*c); } iwpostfix := '_Interface_${interface_name}_method_wrapper' methods_wrapper.write_string('static inline ${g.typ(method.return_type)} ${cctype}_$name${iwpostfix}(') diff --git a/vlib/v/tests/interface_struct_with_multi_nested_embed_test.v b/vlib/v/tests/interface_with_multi_nested_embed_1_test.v similarity index 95% rename from vlib/v/tests/interface_struct_with_multi_nested_embed_test.v rename to vlib/v/tests/interface_with_multi_nested_embed_1_test.v index 794ee09143..3f9d9168ac 100644 --- a/vlib/v/tests/interface_struct_with_multi_nested_embed_test.v +++ b/vlib/v/tests/interface_with_multi_nested_embed_1_test.v @@ -1,4 +1,4 @@ -fn test_interface_struct_with_multi_nested_embed() { +fn test_interface_with_multi_nested_embed() { mut win := &Window{} mut ll := &LinearLayout{} mut lbl := &Label{ diff --git a/vlib/v/tests/interface_with_multi_nested_embed_2_test.v b/vlib/v/tests/interface_with_multi_nested_embed_2_test.v new file mode 100644 index 0000000000..540d8fdef3 --- /dev/null +++ b/vlib/v/tests/interface_with_multi_nested_embed_2_test.v @@ -0,0 +1,57 @@ +fn test_interface_with_multi_nested_embed() { + mut ll := &LinearLayout{} + mut lbl := &Label{ + x: 10 + y: 20 + } + ll.add(mut lbl) + + println(ll) + + assert ll.x == 10 + assert ll.y == 20 +} + +pub struct Rect { +mut: + x int + y int +} + +pub fn (r Rect) get_pos() (int, int) { + return r.x, r.y +} + +pub struct LayoutBase { + Rect +} + +pub struct Base { + LayoutBase +} + +pub fn (mut b Base) init() {} + +[heap] +pub struct Label { + Base +} + +pub interface Layoutable { + get_pos() (int, int) +mut: + init() +} + +[heap] +pub struct LinearLayout { + Base +mut: + layoutables []Layoutable +} + +pub fn (mut ll LinearLayout) add(mut l Layoutable) { + x, y := l.get_pos() + ll.x += x + ll.y += y +}