Re: Idea why this does not compile?

2020-05-13 Thread Stefan_Salewski
> need to define your destructor earlier

Yes, my initial guess was indeed that, as it was done in that way in the 
earlier gintro code.

But I became unsure if it would work really fine also that way.

And it remains strange, as my fnew template should fully hide the use of the 
finalizer when we compile with --gc:arc. So I assume that both branches of the 
when construct are processed by the compiler and that confuses the compiler? In 
the same way as discarded code is always syntax checked?

Unfortunately ordering the code is not that easy, as it is autogenerated from 
the gobject-introspection database, and for latest gtk 3.98.3 which will become 
4.0 there are some serious changes. I can not just put the =destroy just after 
the type declaration, as =destroy calls low level procs like 
gdk_event_unref(self.impl) above. So carefully sorting will be necessary.

Note that forward declarations like below do not compile:


proc gdk_event_unref(self: ptr Event00)

proc gdk_event_unref(self: ptr Event00) {.importc, libprag.}


Run


Error: pragmas are only allowed in the header of a proc; redefinition of 
'gdk_event_unref'


Run

What should work is declaring a special unref function before declaring the 
=destroy and using that one in the =destroy like


proc destroy_gdk_event_unref(self: ptr Event00) {.importc: gdk_event_unref, 
libprag.}


Run


Re: Idea why this does not compile?

2020-05-13 Thread Araq
I know why it doesn't compile but my reply would be identical to the compiler's 
error message. You need to define your destructor earlier, like so:


when defined(gcDestructors):
  proc `=destroy`*(self: var typeof(Event()[])) =
if not self.ignoreFinalizer and self.impl != nil:
  echo "gdk_event_unref(self.impl)"
  self.impl = nil

template fnew*(a: untyped; finalizer: untyped) =
  when defined(gcDestructors):
new(a)
  else:
new(a, finalizer)

proc `ref`*(self: Event): Event =
  fnew(result, generic_gdk_event_unref)
  echo "result.impl = gdk_event_ref(cast[ptr Event00](self.impl))"

proc generic_gdk_event_unref*[T](self: ref T) =
  if not self.ignoreFinalizer:
echo "gdk_event_unref(self.impl)"



Run


Idea why this does not compile?

2020-05-13 Thread Stefan_Salewski
I was just working a bit on gintro for latest GTK4 and got a really confusing 
error message.

Luckely I was just able to generate a minimal example, but I have still no real 
idea what the problem may be. I guess there must be something special in this 
code, because I have used similar constructs before and it was working fine...


type
  Event* = ref object of RootRef
impl*: pointer
ignoreFinalizer*: bool

template fnew*(a: untyped; finalizer: untyped) =
  when defined(gcDestructors):
new(a)
  else:
new(a, finalizer)

proc `ref`*(self: Event): Event =
  fnew(result, generic_gdk_event_unref)
  echo "result.impl = gdk_event_ref(cast[ptr Event00](self.impl))"

proc generic_gdk_event_unref*[T](self: ref T) =
  if not self.ignoreFinalizer:
echo "gdk_event_unref(self.impl)"

when defined(gcDestructors):
  proc `=destroy`*(self: var typeof(Event()[])) =
if not self.ignoreFinalizer and self.impl != nil:
  echo "gdk_event_unref(self.impl)"
  self.impl = nil

proc main =
  var x: Event
  fnew(x, generic_gdk_event_unref)

main()


Run


$ nim c --gc:arc t2.nim

/tmp/hhh/t2.nim(21, 3) Error: cannot bind another '=destroy' to: 
Event:ObjectType; previous declaration was constructed here implicitly: 
/tmp/hhh/t2.nim(13, 3)



Run


$ nim -v
Nim Compiler Version 1.3.3 [Linux: amd64]
Compiled at 2020-05-11
Copyright (c) 2006-2020 by Andreas Rumpf

git hash: 7c24250a575b4d441ba6d7301714cbb246425fb6
active boot switches: -d:release


Run