From 6d40bb8374f938d13455a7335cdf5c5941ad22b6 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 20 Jan 2025 16:33:35 +0800 Subject: [PATCH] cgen: fix interface casting in anon fn (fix #23530) (#23533) --- vlib/v/gen/c/auto_eq_methods.v | 1 - vlib/v/gen/c/cgen.v | 1 + .../interface_as_cast_in_anon_fn_test.v | 26 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/interfaces/interface_as_cast_in_anon_fn_test.v diff --git a/vlib/v/gen/c/auto_eq_methods.v b/vlib/v/gen/c/auto_eq_methods.v index cce9f9c75a57c4..1198cead3aadf0 100644 --- a/vlib/v/gen/c/auto_eq_methods.v +++ b/vlib/v/gen/c/auto_eq_methods.v @@ -605,7 +605,6 @@ fn (mut g Gen) gen_interface_equality_fn(left_type ast.Type) string { left_arg := g.read_field(left_type, '_typ', 'a') right_arg := g.read_field(left_type, '_typ', 'b') - fn_builder.writeln('${g.static_non_parallel}int v_typeof_interface_idx_${idx_fn}(int sidx); // for auto eq method') fn_builder.writeln('${g.static_non_parallel}inline bool ${fn_name}_interface_eq(${ptr_styp} a, ${ptr_styp} b) {') fn_builder.writeln('\tif (${left_arg} == ${right_arg}) {') fn_builder.writeln('\t\tint idx = v_typeof_interface_idx_${idx_fn}(${left_arg});') diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 36830e82cac738..b7305b28ca680c 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1157,6 +1157,7 @@ pub fn (mut g Gen) write_typeof_functions() { g.writeln('\tif (sidx == _${sym.cname}_${sub_sym.cname}_index) return "${util.strip_main_name(sub_sym.name)}";') } g.writeln2('\treturn "unknown ${util.strip_main_name(sym.name)}";', '}') + g.definitions.writeln('int v_typeof_interface_idx_${sym.cname}(int sidx);') g.writeln2('', 'int v_typeof_interface_idx_${sym.cname}(int sidx) {') if g.pref.parallel_cc { g.extern_out.writeln('extern int v_typeof_interface_idx_${sym.cname}(int sidx);') diff --git a/vlib/v/tests/interfaces/interface_as_cast_in_anon_fn_test.v b/vlib/v/tests/interfaces/interface_as_cast_in_anon_fn_test.v new file mode 100644 index 00000000000000..e7b00c4db40bb6 --- /dev/null +++ b/vlib/v/tests/interfaces/interface_as_cast_in_anon_fn_test.v @@ -0,0 +1,26 @@ +@[heap] +struct Foo { +mut: + val int +} + +@[heap] +struct Bar { +mut: + val int +} + +interface FooBar { +mut: + val int +} + +fn test_interface_as_cast_in_anon_fn() { + mut fbs := []&FooBar{} + fbs << &Foo{1} + do_something := fn [mut fbs] () { + _ := fbs.last() as Foo // this line works outside of anon fn + } + do_something() + assert true +}