]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Fix capturing generic variables within generic methods
authorLuca Bruno <lucabru@src.gnome.org>
Wed, 2 Nov 2011 21:14:10 +0000 (22:14 +0100)
committerLuca Bruno <lucabru@src.gnome.org>
Wed, 2 Nov 2011 21:35:42 +0000 (22:35 +0100)
Fixes bug 663210.

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/methods/bug663210.vala [new file with mode: 0644]

index d008e1f16a47a364899e2e8712d342bfd3083bcb..1d2032906cb15e7640bd80daf586974149b6b912 100644 (file)
@@ -1905,21 +1905,40 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_ref_count_")));
                        ccode.open_if (ccall);
 
+                       CCodeExpression outer_block = new CCodeIdentifier ("_data%d_".printf (block_id));
+                       unowned Block parent_closure_block = b;
+                       while (true) {
+                               parent_closure_block = next_closure_block (parent_closure_block.parent_symbol);
+                               if (parent_closure_block == null) {
+                                       break;
+                               }
+                               int parent_block_id = get_block_id (parent_closure_block);
+                               outer_block = new CCodeMemberAccess.pointer (outer_block, "_data%d_".printf (parent_block_id));
+                       }
+
                        if (get_this_type () != null) {
                                // assign "self" for type parameters
-                               CCodeExpression cself = new CCodeIdentifier ("_data%d_".printf (block_id));
-                               unowned Block parent_closure_block = b;
-                               while (true) {
-                                       parent_closure_block = next_closure_block (parent_closure_block.parent_symbol);
-                                       if (parent_closure_block == null) {
-                                               break;
-                                       }
-                                       int parent_block_id = get_block_id (parent_closure_block);
-                                       cself = new CCodeMemberAccess.pointer (cself, "_data%d_".printf (parent_block_id));
-                               }
-                               cself = new CCodeMemberAccess.pointer (cself, "self");
                                ccode.add_declaration ("%s *".printf (get_ccode_name (current_type_symbol)), new CCodeVariableDeclarator ("self"));
-                               ccode.add_assignment (new CCodeIdentifier ("self"), cself);
+                               ccode.add_assignment (new CCodeIdentifier ("self"), new CCodeMemberAccess.pointer (outer_block, "self"));
+                       }
+
+                       if (current_method != null) {
+                               // assign captured generic type parameters
+                               foreach (var type_param in current_method.get_type_parameters ()) {
+                                       string func_name;
+
+                                       func_name = "%s_type".printf (type_param.name.down ());
+                                       ccode.add_declaration ("GType", new CCodeVariableDeclarator (func_name));
+                                       ccode.add_assignment (new CCodeIdentifier (func_name), new CCodeMemberAccess.pointer (outer_block, func_name));
+
+                                       func_name = "%s_dup_func".printf (type_param.name.down ());
+                                       ccode.add_declaration ("GBoxedCopyFunc", new CCodeVariableDeclarator (func_name));
+                                       ccode.add_assignment (new CCodeIdentifier (func_name), new CCodeMemberAccess.pointer (outer_block, func_name));
+
+                                       func_name = "%s_destroy_func".printf (type_param.name.down ());
+                                       ccode.add_declaration ("GDestroyNotify", new CCodeVariableDeclarator (func_name));
+                                       ccode.add_assignment (new CCodeIdentifier (func_name), new CCodeMemberAccess.pointer (outer_block, func_name));
+                               }
                        }
 
                        // free in reverse order
index 180caccf261af9f133623be8135803776219dc2a..66194551bf0feb7beee56c8351ad56b8862b0840 100644 (file)
@@ -48,6 +48,7 @@ TESTS = \
        methods/bug649562.vala \
        methods/bug653391.vala \
        methods/bug653908.vala \
+       methods/bug663210.vala \
        control-flow/break.vala \
        control-flow/expressions-conditional.vala \
        control-flow/for.vala \
diff --git a/tests/methods/bug663210.vala b/tests/methods/bug663210.vala
new file mode 100644 (file)
index 0000000..61989d3
--- /dev/null
@@ -0,0 +1,12 @@
+class Foo {
+       void foo<T> () {
+               T retval = null;
+               GLib.SourceFunc f = () => {
+                       retval = null;
+                       return false;
+               };
+       }
+}
+
+void main () {
+}