After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 791060 - can't compile generic function where type parameter is passed on in return value
can't compile generic function where type parameter is passed on in return value
Status: RESOLVED DUPLICATE of bug 791283
Product: vala
Classification: Core
Component: Generics
0.38.x
Other Linux
: Normal normal
: ---
Assigned To: Vala maintainers
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2017-12-01 08:26 UTC by kosmolot17
Modified: 2017-12-06 23:07 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description kosmolot17 2017-12-01 08:26:07 UTC
This code doesn't compile:
------------------------------

public GenericArray<G> create_generic_array<G> () {
	GenericArray<G> array = new GenericArray<G>();
	return array;
}

void main () {
	create_generic_array<int>();
}

------------------------------

/tmp/test.vala.NN7LAZ.c: In function ‘_g_destroy_func0_’:
/tmp/test.vala.NN7LAZ.c:18:21: error: ‘g_destroy_func’ undeclared (first use in this function); did you mean ‘_g_destroy_func0_’?
  ((var == NULL) || (g_destroy_func == NULL)) ? NULL : (var = (g_destroy_func (var), NULL));
                     ^~~~~~~~~~~~~~
                     _g_destroy_func0_
/tmp/test.vala.NN7LAZ.c:18:21: note: each undeclared identifier is reported only once for each function it appears in
/tmp/test.vala.NN7LAZ.c:18:63: warning: implicit declaration of function ‘g_destroy_func’; did you mean ‘_g_destroy_func0_’? [-Wimplicit-function-declaration]
  ((var == NULL) || (g_destroy_func == NULL)) ? NULL : (var = (g_destroy_func (var), NULL));
                                                               ^~~~~~~~~~~~~~
                                                               _g_destroy_func0_
Comment 1 Daniel Espinosa 2017-12-02 00:42:12 UTC
Generics require to know value's type in order to create C code for type creation and destruction, so I think this code should be declared as invalid by the compiler.
Comment 2 Al Thomas 2017-12-02 09:11:53 UTC
(In reply to Daniel Espinosa from comment #1)
> Generics require to know value's type in order to create C code for type
> creation and destruction

The type is specified. See the line in main ():
create_generic_array<int>();

So in this example it is an int. Now the destroy function is passed to create_generic_array, which is fine, although it is null in this case when using int. What is happening is the return value of create_generic_array () is also containing a reference to the type parameter. Vala could just pass the destroy function straight through. So if you compile to the C code from Vala and amend it so the line:

_tmp0_ = g_ptr_array_new_full ((guint) 0, _g_destroy_func0_);

is changed to:

_tmp0_ = g_ptr_array_new_full ((guint) 0, g_destroy_func);

The C code will now compile and run for the example.

The hard part here is getting the Vala compiler to recognise the destroy function has been passed as an argument in a function call and modify the generated C code accordingly. At present g_destroy_func is a local variable in this example.

Also note g_ptr_array_new_full () only requires the size and free function, but no type information. I've not tested how Vala behaves when type information is also needed where a generic parameter is passed through to a return value.
Comment 3 Daniel Espinosa 2017-12-02 12:03:31 UTC
(In reply to Al Thomas from comment #2)
> (In reply to Daniel Espinosa from comment #1)
> > Generics require to know value's type in order to create C code for type
> > creation and destruction
> 
> The type is specified. See the line in main ():
> create_generic_array<int>();
> 
You are right, how I don't see it before.

> 
> The hard part here is getting the Vala compiler to recognise the destroy
> function has been passed as an argument in a function call and modify the
> generated C code accordingly. At present g_destroy_func is a local variable
> in this example.
> 
Why Vala is not using GLib.Value for its generics? So it will always know creation, destruction and more.

> Also note g_ptr_array_new_full () only requires the size and free function,
> but no type information. I've not tested how Vala behaves when type
> information is also needed where a generic parameter is passed through to a
> return value.

May using GLib.Value can improve this situation. I would like to describe my thoughts in more detail on how use it in Vala internals for generics.
Comment 4 Rico Tzschichholz 2017-12-02 13:31:51 UTC
Note this situation here is a bit more complicated since it is mixing "normal generics" with "simple generics" and all this in a static context (not wrapped in a class structure).
Comment 5 Rico Tzschichholz 2017-12-06 23:07:16 UTC

*** This bug has been marked as a duplicate of bug 791283 ***