nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.28k stars 1.46k forks source link

Instantiating enums with ARC gives different error messages than with the default GC #19006

Open johnnovak opened 2 years ago

johnnovak commented 2 years ago

Example

type Foo* = enum
  a = ( 0, "a"),
  b = ( 1, "b"),
  c = (20, "c")

var i = 1
let f1 = Foo(i)
echo f1     # prints:  b

i = 2
let f2 = Foo(i)
echo f2     # prints:
            #    default GC:  2 (invalid data!)
            #      --gc:arc:  <empty string>

Expected Output

The output should be the same as with the default GC (e.g. 2 (invalid data!).

Possible Solution

This change in behaviour is unfortunate because converting the result to string is currently the only way to reliably instantiate enums from their ordinal numbers when the enums ranges have holes in them. The different ARC behaviour can lead to unexpected runtime problems when switching the GC implementation in code that uses the above method to instantiate enums. Therefore, I strongly suggest to keep the original error message with ARC as well.

Additional Information

Nim Compiler Version 1.4.8 [Windows: amd64]
Araq commented 2 years ago

This change in behaviour is unfortunate because converting the result to string is currently the only way to reliably instantiate enums from their ordinal numbers when the enums ranges have holes in them.

A macro should be able to produce a precise mapping, holes in the enum or not. Have you tried a macro instead of parsing "(invalid data!)"?

johnnovak commented 2 years ago

No I haven't. I raised another ticket about the enum mappings with holes problem about a year ago, and I vaguely remember you didn't mention the macro possibility then, so I've been usinig this method since then.

I reverted back to the default GC anyway because I was getting deterministic crashes on ARC/ORC with some complex object graph and closure combinations. It would be good to reproduce it in a small test and raise a bug, but it would take me a day to narrow it down (it's a complex app), and I don't have the time & energy for that right now...

ringabout commented 1 year ago

lol, there is an important package parsing "(Invalid data!)"

let check = quote do:
  if $(`source`) == $(ord(`source`)) & " (invalid data!)":
    raise newException(ValueError, "Enum value is out of range: " &
      $(`source`) & "\nCorrect values are:\n" & `enumdecl`)