Nim icon indicating copy to clipboard operation
Nim copied to clipboard

Size/Signedness issues with unordered enums

Open autumngray opened this issue 1 year ago • 3 comments
trafficstars

Description

While #23951 fixes casting negative enum values for ordinal types, it is still broken for "holey" enums:

type Foo = enum A B = -1
proc foo =
  doAssert cast[Foo](-1) == A
  doAssert ord(A) == -1
static: foo()
foo()

In fact, both CT and RT fail the assertion.

This is because, in order to determine the storage type during codegen, we depend on the assumption that firstOrd(Foo) < 0 implies NI. Likewise, this example:

proc foo =
  type Foo = enum A B=8, C=1
  let s1 = {A}
  let s2 = {B}
  doAssert s1 != s2
static: foo()
foo()

fails the assertion at CT and fails to compile without static. In this case, we only look at lastOrd(Foo) to choose between u8..u64.

Nim Version

Nim Compiler Version 2.1.9 [Linux: amd64] Compiled at 2024-08-13 Copyright (c) 2006-2024 by Andreas Rumpf

git hash: 1de181604e9b893388177128c1d337c5cd8b1bb2 active boot switches: -d:release

Current Output

No response

Expected Output

No response

Possible Solution

  1. In firstOrd/lastOrd for tyEnum with holes, iterate through all fields to choose lowest/highest value. This should probably be cached somewhere (where?). Pro: Less code to change Con: This changes the semantics of low/high i.e in the first example, low(Foo) != A. In any case, since holey enums are not ordinal, they can't be iterated over or used in range types, so the utility of low/high is debatable.
  2. As above, but introduce minOrd/maxOrd and use those only for size/sign computation. Pro: Lower possibility to introduce new bugs...

Additional Information

No response

autumngray avatar Aug 13 '24 14:08 autumngray