"error: Cannot create delegate without target for instance method or closure" emitted even when anonymous function doesn't need a target
During compilation of this libunity code with Vala 0.43.5.3-005acf
namespace Dee {
[ CCode ( has_target = false ) ]
public delegate void StaticFilterMapFunc (Model orig_model, FilterModel filter_model, void* data);
class Filter {
public static Filter @new (StaticFilterMapFunc map_func, owned FilterMapNotify map_notify);
}
}
...
var model = new Dee.FilterModel (
backend, Dee.Filter.new (
() => {}, // no need for map func, the model is empty on creation
(orig_model, iter, filter_model) =>
{
// check that the row contains all required metadata
var metadata = orig_model.get_value (iter, METADATA_COLUMN);
unowned string field_name;
unowned VariantType schema;
var ht_iter = HashTableIter<string, VariantType> (types);
while (ht_iter.next (out field_name, out schema))
{
var field = metadata.lookup_value (field_name, schema);
if (field == null)
{
warning ("Row doesn't contain required data: missing '%s'",
field_name);
return false;
}
}
filter_model.insert_iter_with_original_order (iter);
return true;
}));
...
I got this error:
unity-scope-channel.vala:96.9-96.16: error: Cannot create delegate without target for instance method or closure
() => {}, // no need for map func, the model is empty on creation
^^^^^^^^
I can work around it with this patch:
diff --git a/src/unity-scope-channel.vala b/src/unity-scope-channel.vala
index ef18292..d6f4ad0 100644
--- a/src/unity-scope-channel.vala
+++ b/src/unity-scope-channel.vala
@@ -82,6 +82,9 @@ internal class ScopeChannel : Object
return search_type;
}
+ private static void static_filter_map_func_noop(Dee.Model orig_model, Dee.FilterModel filter_model, void* data)
+ {}
+
private static Dee.SerializableModel create_filter_model (
Dee.Model backend, HashTable<string, string> metadata_schema)
{
@@ -93,7 +96,7 @@ internal class ScopeChannel : Object
var model = new Dee.FilterModel (
backend, Dee.Filter.new (
- () => {}, // no need for map func, the model is empty on creation
+ static_filter_map_func_noop, // no need for map func, the model is empty on creation
(orig_model, iter, filter_model) =>
{
// check that the row contains all required metadata
However, I don't understand why Vala needs a target for an empty closure, so it looks like a Vala regression (valac 0.43.4.11-b9837 was ok).
A simple reproducer follows. The issue occurs in the last two dispatch()
calls where an anonymous function is passed as a targetless IntFunc and an anonymous function requiring a closure to hold the value of the divisor
variable is passed as FilterFunc.
// valac --save-temps targetless_closure.vala
[CCode (has_target = false)]
public delegate void IntFunc(int number);
public delegate bool FilterFunc(int number);
public void my_int_func(int number) {
stdout.printf("%d\n", number);
}
public void dispatch(int number, IntFunc func, FilterFunc? filter) {
if (filter == null || filter(number)) {
func(number);
}
}
void main () {
int number = 123;
dispatch(
number,
my_int_func,
null
);
dispatch(
number,
(n) => {stdout.printf("%d\n", n);},
null
);
dispatch(
number,
() => {},
null
);
dispatch(
number,
my_int_func,
(n) => {return n % 2== 0;}
);
dispatch(
number,
(n) => {stdout.printf("%d\n", n);},
(n) => {return n % 2 == 0;}
);
dispatch(
number,
() => {},
(n) => {return n % 2 == 0;}
);
int divisor = 2;
dispatch(
number,
my_int_func,
(n) => {return n % divisor == 0;}
);
dispatch(
number,
(n) => {stdout.printf("%d\n", n);},
(n) => {return n % divisor == 0;}
);
dispatch(
number,
() => {},
(n) => {return n % divisor == 0;}
);
}
$ valac --save-temps targetless_closure.vala
targetless_closure.vala:61.3-61.36: error: Cannot create delegate without target for instance method or closure
(n) => {stdout.printf("%d\n", n);},
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
targetless_closure.vala:66.3-66.10: error: Cannot create delegate without target for instance method or closure
() => {},
^^^^^^^^
Compilation failed: 2 error(s), 0 warning(s)