[vala] codegen: Allow scope=async delegates to be used in vala code



commit 6d07669384cdb70c3c657dba67d5048212f25da9
Author: Luca Bruno <lucabru src gnome org>
Date:   Thu Jul 11 22:39:53 2013 +0200

    codegen: Allow scope=async delegates to be used in vala code
    
    Fixes bug 703804

 codegen/valaccodeassignmentmodule.vala    |   10 ++++++++--
 codegen/valaccodebasemodule.vala          |   14 +++++++-------
 codegen/valaccodedelegatemodule.vala      |   12 ++++++------
 codegen/valaccodememberaccessmodule.vala  |   18 ++++++++++--------
 codegen/valaccodemethodcallmodule.vala    |    6 +++---
 codegen/valaccodemethodmodule.vala        |    4 ++--
 codegen/valaccodestructmodule.vala        |    2 +-
 codegen/valagtypemodule.vala              |    4 ++--
 tests/Makefile.am                         |    1 +
 tests/delegates/bug703804.vala            |   15 +++++++++++++++
 vala/valadelegatetype.vala                |    2 +-
 vala/valareferencetransferexpression.vala |    4 +++-
 12 files changed, 59 insertions(+), 33 deletions(-)
---
diff --git a/codegen/valaccodeassignmentmodule.vala b/codegen/valaccodeassignmentmodule.vala
index 21a2d42..67be9c9 100644
--- a/codegen/valaccodeassignmentmodule.vala
+++ b/codegen/valaccodeassignmentmodule.vala
@@ -149,8 +149,14 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
                if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
                        if (get_delegate_target_cvalue (lvalue) != null) {
                                ccode.add_assignment (get_delegate_target_cvalue (lvalue), 
get_delegate_target_cvalue (value));
-                               if (get_delegate_target_destroy_notify_cvalue (lvalue) != null) {
-                                       ccode.add_assignment (get_delegate_target_destroy_notify_cvalue 
(lvalue), get_delegate_target_destroy_notify_cvalue (value));
+                               var lvalue_destroy_notify = get_delegate_target_destroy_notify_cvalue 
(lvalue);
+                               var rvalue_destroy_notify = get_delegate_target_destroy_notify_cvalue (value);
+                               if (lvalue_destroy_notify != null) {
+                                       if (rvalue_destroy_notify != null) {
+                                               ccode.add_assignment (lvalue_destroy_notify, 
rvalue_destroy_notify);
+                                       } else {
+                                               ccode.add_assignment (lvalue_destroy_notify, new 
CCodeConstant ("NULL"));
+                                       }
                                }
                        }
                }
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 1a90ec0..e42c578 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1048,7 +1048,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                }
                                decl_space.add_type_member_declaration (cdecl);
 
-                               if (delegate_type.value_owned) {
+                               if (delegate_type.value_owned && !delegate_type.is_called_once) {
                                        cdecl = new CCodeDeclaration ("GDestroyNotify");
                                        cdecl.add_declarator (new CCodeVariableDeclarator 
(get_delegate_target_destroy_notify_cname  (get_ccode_name (f))));
                                        if (f.is_private_symbol ()) {
@@ -1250,7 +1250,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                                }
                                                cfile.add_type_member_declaration (target_def);
 
-                                               if (delegate_type.value_owned) {
+                                               if (delegate_type.is_disposable ()) {
                                                        var target_destroy_notify_def = new CCodeDeclaration 
("GDestroyNotify");
                                                        target_destroy_notify_def.add_declarator (new 
CCodeVariableDeclarator (get_delegate_target_destroy_notify_cname (get_ccode_name (f)), new CCodeConstant 
("NULL")));
                                                        if (!f.is_private_symbol ()) {
@@ -1823,7 +1823,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        }
                } else if (deleg_type != null && deleg_type.delegate_symbol.has_target) {
                        data.add_field ("gpointer", get_ccode_delegate_target_name (param));
-                       if (param.variable_type.value_owned) {
+                       if (param.variable_type.is_disposable ()) {
                                data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname 
(get_variable_cname (param.name)));
                                // reference transfer for delegates
                                var lvalue = get_parameter_cvalue (param);
@@ -2416,7 +2416,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        if (!deleg_type.delegate_symbol.has_target) {
                                value.delegate_target_cvalue = new CCodeConstant ("NULL");
                                ((GLibValue) value).lvalue = false;
-                       } else if (!deleg_type.value_owned) {
+                       } else if (!deleg_type.is_disposable ()) {
                                value.delegate_target_destroy_notify_cvalue = new CCodeConstant ("NULL");
                                ((GLibValue) value).lvalue = false;
                        }
@@ -3543,7 +3543,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
                if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
                        ccode.add_assignment (new CCodeUnaryExpression 
(CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (get_ccode_delegate_target_name (param))), 
get_delegate_target_cvalue (value));
-                       if (delegate_type.value_owned) {
+                       if (delegate_type.is_disposable ()) {
                                ccode.add_assignment (new CCodeUnaryExpression 
(CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (get_delegate_target_destroy_notify_cname 
(param.name))), get_delegate_target_destroy_notify_cvalue (get_parameter_cvalue (param)));
                        }
                }
@@ -3612,7 +3612,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                }
                                var target_r = get_delegate_target_cvalue (temp_value);
                                ccode.add_assignment (target_l, target_r);
-                               if (delegate_type.value_owned) {
+                               if (delegate_type.is_disposable ()) {
                                        var target_l_destroy_notify = get_result_cexpression 
(get_delegate_target_destroy_notify_cname ("result"));
                                        if (!is_in_coroutine ()) {
                                                target_l_destroy_notify = new CCodeUnaryExpression 
(CCodeUnaryOperator.POINTER_INDIRECTION, target_l_destroy_notify);
@@ -4583,7 +4583,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                                                CCodeExpression 
delegate_target_destroy_notify;
                                                                var delegate_target = 
get_delegate_target_cexpression (arg, out delegate_target_destroy_notify);
                                                                carg_map.set (get_param_pos 
(get_ccode_delegate_target_pos (param)), delegate_target);
-                                                               if (deleg_type.value_owned && 
!deleg_type.is_called_once) {
+                                                               if (deleg_type.is_disposable ()) {
                                                                        carg_map.set (get_param_pos 
(get_ccode_delegate_target_pos (param) + 0.01), delegate_target_destroy_notify);
                                                                }
                                                        }
diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala
index 959bdcb..cf367a5 100644
--- a/codegen/valaccodedelegatemodule.vala
+++ b/codegen/valaccodedelegatemodule.vala
@@ -73,7 +73,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                                if (param_d.has_target) {
                                        cparam = new CCodeParameter (get_delegate_target_cname 
(get_variable_cname (param.name)), "void*");
                                        cfundecl.add_parameter (cparam);
-                                       if (deleg_type.value_owned) {
+                                       if (deleg_type.is_disposable ()) {
                                                cparam = new CCodeParameter 
(get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)), "GDestroyNotify*");
                                                cfundecl.add_parameter (cparam);
                                        }
@@ -97,7 +97,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                        if (result_d.has_target) {
                                var cparam = new CCodeParameter (get_delegate_target_cname ("result"), 
"void**");
                                cfundecl.add_parameter (cparam);
-                               if (deleg_type.value_owned) {
+                               if (deleg_type.is_disposable ()) {
                                        cparam = new CCodeParameter (get_delegate_target_destroy_notify_cname 
("result"), "GDestroyNotify*");
                                        cfundecl.add_parameter (cparam);
                                }
@@ -248,7 +248,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                        if (deleg_type.delegate_symbol.has_target) {
                                var cparam = new CCodeParameter (get_delegate_target_cname ("result"), 
"void**");
                                cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (d)), cparam);
-                               if (deleg_type.value_owned) {
+                               if (deleg_type.is_disposable ()) {
                                        cparam = new CCodeParameter (get_delegate_target_destroy_notify_cname 
("result"), "GDestroyNotify*");
                                        cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (d) + 
0.01), cparam);
                                }
@@ -341,7 +341,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                                if (deleg_type.delegate_symbol.has_target) {
                                        var ctarget = new CCodeIdentifier (get_ccode_delegate_target_name 
(d_params.get (i)));
                                        carg_map.set (get_param_pos (get_ccode_delegate_target_pos (param)), 
ctarget);
-                                       if (deleg_type.value_owned) {
+                                       if (deleg_type.is_disposable ()) {
                                                var ctarget_destroy_notify = new CCodeIdentifier 
(get_delegate_target_destroy_notify_cname (d_params.get (i).name));
                                                carg_map.set (get_param_pos (get_ccode_delegate_target_pos 
(m) + 0.01), ctarget_destroy_notify);
                                        }
@@ -367,7 +367,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                        if (deleg_type.delegate_symbol.has_target) {
                                var ctarget = new CCodeIdentifier (get_delegate_target_cname ("result"));
                                carg_map.set (get_param_pos (get_ccode_delegate_target_pos (m)), ctarget);
-                               if (deleg_type.value_owned) {
+                               if (deleg_type.is_disposable ()) {
                                        var ctarget_destroy_notify = new CCodeIdentifier 
(get_delegate_target_destroy_notify_cname ("result"));
                                        carg_map.set (get_param_pos (get_ccode_delegate_target_pos (m) + 
0.01), ctarget_destroy_notify);
                                }
@@ -478,7 +478,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                                if (carg_map != null) {
                                        carg_map.set (get_param_pos (get_ccode_delegate_target_pos (param)), 
get_variable_cexpression (cparam.name));
                                }
-                               if (deleg_type.value_owned) {
+                               if (deleg_type.is_disposable ()) {
                                        cparam = new CCodeParameter (get_delegate_target_destroy_notify_cname 
(get_variable_cname (param.name)), target_destroy_notify_ctypename);
                                        cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (param) 
+ 0.01), cparam);
                                        if (carg_map != null) {
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 6becb19..82f9d06 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -100,7 +100,9 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                        var ref_call = new CCodeFunctionCall (get_dup_func_expression 
(expr.inner.value_type, expr.source_reference));
                                        ref_call.add_argument (delegate_target);
                                        delegate_target = ref_call;
-                                       set_delegate_target_destroy_notify (expr, get_destroy_func_expression 
(expr.inner.value_type));
+                                       if (delegate_type != null && delegate_type.is_disposable ()) {
+                                               set_delegate_target_destroy_notify (expr, 
get_destroy_func_expression (expr.inner.value_type));
+                                       }
                                }
                                set_delegate_target (expr, delegate_target);
                        }
@@ -360,7 +362,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                }
                        } else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
                                result.delegate_target_cvalue = new CCodeMemberAccess.pointer 
(get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname 
(get_local_cname (local)));
-                               if (delegate_type.value_owned) {
+                               if (delegate_type.is_disposable ()) {
                                        result.delegate_target_destroy_notify_cvalue = new 
CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), 
get_delegate_target_destroy_notify_cname (get_local_cname (local)));
                                }
                        }
@@ -437,7 +439,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                        }
                                } else if (delegate_type != null && delegate_type.delegate_symbol.has_target) 
{
                                        result.delegate_target_cvalue = new CCodeMemberAccess.pointer 
(get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_ccode_delegate_target_name (param));
-                                       if (result.value_type.value_owned) {
+                                       if (result.value_type.is_disposable ()) {
                                                result.delegate_target_destroy_notify_cvalue = new 
CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), 
get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
                                        }
                                }
@@ -446,7 +448,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                result.cvalue = get_variable_cexpression (param.name);
                                if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
                                        result.delegate_target_cvalue = new CCodeMemberAccess.pointer (new 
CCodeIdentifier ("_data_"), get_ccode_delegate_target_name (param));
-                                       if (delegate_type.value_owned) {
+                                       if (delegate_type.is_disposable ()) {
                                                result.delegate_target_destroy_notify_cvalue = new 
CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), get_delegate_target_destroy_notify_cname 
(get_variable_cname (param.name)));
                                        }
                                }
@@ -487,7 +489,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                                delegate_target_destroy_notify = new CCodeUnaryExpression 
(CCodeUnaryOperator.POINTER_INDIRECTION, delegate_target_destroy_notify);
                                        }
                                        result.delegate_target_cvalue = target_expr;
-                                       if (result.value_type.value_owned) {
+                                       if (result.value_type.is_disposable ()) {
                                                result.delegate_target_destroy_notify_cvalue = 
delegate_target_destroy_notify;
                                        }
                                }
@@ -589,12 +591,12 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 
                                if (((TypeSymbol) field.parent_symbol).is_reference_type ()) {
                                        result.delegate_target_cvalue = new CCodeMemberAccess.pointer (inst, 
target_cname);
-                                       if (result.value_type.value_owned) {
+                                       if (result.value_type.is_disposable ()){
                                                result.delegate_target_destroy_notify_cvalue = new 
CCodeMemberAccess.pointer (inst, target_destroy_notify_cname);
                                        }
                                } else {
                                        result.delegate_target_cvalue = new CCodeMemberAccess (inst, 
target_cname);
-                                       if (result.value_type.value_owned) {
+                                       if (result.value_type.is_disposable ()) {
                                                result.delegate_target_destroy_notify_cvalue = new 
CCodeMemberAccess (inst, target_destroy_notify_cname);
                                        }
                                }
@@ -651,7 +653,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                }
                        } else if (delegate_type != null && delegate_type.delegate_symbol.has_target && 
get_ccode_delegate_target (field)) {
                                result.delegate_target_cvalue = new CCodeIdentifier 
(get_ccode_delegate_target_name (field));
-                               if (result.value_type.value_owned) {
+                               if (result.value_type.is_disposable ()) {
                                        result.delegate_target_destroy_notify_cvalue = new CCodeIdentifier 
(get_delegate_target_destroy_notify_cname (get_ccode_name (field)));
                                }
                        }
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 5d968b0..0bd462a 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -364,7 +364,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                                                                        cexpr = new 
CCodeConditionalExpression (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, cexpr, new 
CCodeIdentifier ("NULL")), new CCodeIdentifier ("NULL"), closure_new);
                                                                } else {
                                                                        carg_map.set (get_param_pos 
(get_ccode_delegate_target_pos (param)), delegate_target);
-                                                                       if (deleg_type.value_owned && 
!deleg_type.is_called_once) {
+                                                                       if (deleg_type.is_disposable ()) {
                                                                                assert 
(delegate_target_destroy_notify != null);
                                                                                carg_map.set (get_param_pos 
(get_ccode_delegate_target_pos (param) + 0.01), delegate_target_destroy_notify);
                                                                        }
@@ -420,7 +420,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                                                                emit_temp_var (temp_var);
                                                                set_delegate_target (arg, 
get_variable_cexpression (temp_var.name));
                                                                carg_map.set (get_param_pos 
(get_ccode_delegate_target_pos (param)), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, 
get_delegate_target (arg)));
-                                                               if (deleg_type.value_owned) {
+                                                               if (deleg_type.is_disposable ()) {
                                                                        temp_var = get_temp_variable 
(gdestroynotify_type);
                                                                        emit_temp_var (temp_var);
                                                                        set_delegate_target_destroy_notify 
(arg, get_variable_cexpression (temp_var.name));
@@ -514,7 +514,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 
                                set_delegate_target (expr, temp_ref);
 
-                               if (deleg_type.value_owned) {
+                               if (deleg_type.is_disposable ()) {
                                        temp_var = get_temp_variable (gdestroynotify_type);
                                        temp_ref = get_variable_cexpression (temp_var.name);
 
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 94edfe1..0dc6963 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -100,7 +100,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                                if (carg_map != null) {
                                        carg_map.set (get_param_pos (get_ccode_delegate_target_pos (m)), 
get_variable_cexpression (cparam.name));
                                }
-                               if (deleg_type.value_owned) {
+                               if (deleg_type.is_disposable ()) {
                                        cparam = new CCodeParameter (get_delegate_target_destroy_notify_cname 
("result"), "GDestroyNotify*");
                                        cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (m) + 
0.01), cparam);
                                        if (carg_map != null) {
@@ -582,7 +582,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                                                                vardecl = new CCodeVariableDeclarator.zero 
("_vala_" + get_ccode_delegate_target_name (param), new CCodeConstant ("NULL"));
                                                                ccode.add_declaration ("void *", vardecl);
 
-                                                               if (deleg_type.value_owned) {
+                                                               if (deleg_type.is_disposable ()) {
                                                                        vardecl = new 
CCodeVariableDeclarator.zero (get_delegate_target_destroy_notify_cname (get_variable_cname ("_vala_" + 
param.name)), new CCodeConstant ("NULL"));
                                                                        ccode.add_declaration 
("GDestroyNotify", vardecl);
                                                                }
diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala
index df33939..51cef5d 100644
--- a/codegen/valaccodestructmodule.vala
+++ b/codegen/valaccodestructmodule.vala
@@ -102,7 +102,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
                                        if (delegate_type.delegate_symbol.has_target) {
                                                // create field to store delegate target
                                                instance_struct.add_field ("gpointer", 
get_ccode_delegate_target_name (f));
-                                               if (delegate_type.value_owned) {
+                                               if (delegate_type.is_disposable ()) {
                                                        instance_struct.add_field ("GDestroyNotify", 
get_delegate_target_destroy_notify_cname (f.name));
                                                }
                                        }
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 552d4e6..67d1051 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -341,7 +341,7 @@ public class Vala.GTypeModule : GErrorModule {
                                                if (delegate_type.delegate_symbol.has_target) {
                                                        // create field to store delegate target
                                                        instance_struct.add_field ("gpointer", 
get_ccode_delegate_target_name (f));
-                                                       if (delegate_type.value_owned) {
+                                                       if (delegate_type.is_disposable ()) {
                                                                instance_struct.add_field ("GDestroyNotify", 
get_delegate_target_destroy_notify_cname (f.name));
                                                        }
                                                }
@@ -447,7 +447,7 @@ public class Vala.GTypeModule : GErrorModule {
                                                if (delegate_type.delegate_symbol.has_target) {
                                                        // create field to store delegate target
                                                        instance_priv_struct.add_field ("gpointer", 
get_ccode_delegate_target_name (f));
-                                                       if (delegate_type.value_owned) {
+                                                       if (delegate_type.is_disposable ()) {
                                                                instance_priv_struct.add_field 
("GDestroyNotify", get_delegate_target_destroy_notify_cname (f.name));
                                                        }
                                                }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 07c505e..8a0df29 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -98,6 +98,7 @@ TESTS = \
        delegates/bug595639.vala \
        delegates/bug638415.vala \
        delegates/bug639751.vala \
+       delegates/bug703804.vala \
        objects/classes.vala \
        objects/fields.vala \
        objects/interfaces.vala \
diff --git a/tests/delegates/bug703804.vala b/tests/delegates/bug703804.vala
new file mode 100644
index 0000000..8bb2d15
--- /dev/null
+++ b/tests/delegates/bug703804.vala
@@ -0,0 +1,15 @@
+[CCode (scope = "async")]
+public delegate void Run();
+
+static void eval(owned Run run) {
+       Run own = (owned) run;
+       own ();
+}
+
+void main() {
+       int i = 0;
+       eval(() => {
+               i++;
+       });
+       assert(i == 1);
+}
diff --git a/vala/valadelegatetype.vala b/vala/valadelegatetype.vala
index 92bd1e2..704f98c 100644
--- a/vala/valadelegatetype.vala
+++ b/vala/valadelegatetype.vala
@@ -120,6 +120,6 @@ public class Vala.DelegateType : DataType {
        }
 
        public override bool is_disposable () {
-               return delegate_symbol.has_target && value_owned;
+               return delegate_symbol.has_target && value_owned && !is_called_once;
        }
 }
diff --git a/vala/valareferencetransferexpression.vala b/vala/valareferencetransferexpression.vala
index cd2f154..7ceba6d 100644
--- a/vala/valareferencetransferexpression.vala
+++ b/vala/valareferencetransferexpression.vala
@@ -94,8 +94,10 @@ public class Vala.ReferenceTransferExpression : Expression {
                        return false;
                }
 
+               var is_owned_delegate = inner.value_type is DelegateType && inner.value_type.value_owned;
                if (!inner.value_type.is_disposable ()
-                   && !(inner.value_type is PointerType)) {
+                   && !(inner.value_type is PointerType)
+                       && !is_owned_delegate) {
                        error = true;
                        Report.error (source_reference, "No reference to be transferred");
                        return false;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]