mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-05 20:47:53 +00:00
fixes #23952 It reorders `type Foo = enum A, B = -1` to `type Foo = enum B = -1, A` so that `firstOrd` etc. continue to work.
This commit is contained in:
@@ -84,6 +84,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||
let isPure = result.sym != nil and sfPure in result.sym.flags
|
||||
var symbols: TStrTable = initStrTable()
|
||||
var hasNull = false
|
||||
var needsReorder = false
|
||||
for i in 1..<n.len:
|
||||
if n[i].kind == nkEmpty: continue
|
||||
var useAutoCounter = false
|
||||
@@ -122,7 +123,9 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||
else:
|
||||
localError(c.config, v.info, errOrdinalTypeExpected % typeToString(v.typ, preferDesc))
|
||||
if i != 1:
|
||||
if x != counter: incl(result.flags, tfEnumHasHoles)
|
||||
if x != counter:
|
||||
needsReorder = true
|
||||
incl(result.flags, tfEnumHasHoles)
|
||||
e.ast = strVal # might be nil
|
||||
counter = x
|
||||
of nkSym:
|
||||
@@ -173,6 +176,13 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||
localError(c.config, n[i].info, errOverflowInEnumX % [e.name.s, $high(typeof(counter))])
|
||||
else:
|
||||
inc(counter)
|
||||
|
||||
if needsReorder:
|
||||
result.n.sons.sort(
|
||||
proc (x, y: PNode): int =
|
||||
result = cmp(x.sym.position, y.sym.position)
|
||||
)
|
||||
|
||||
if isPure and sfExported in result.sym.flags:
|
||||
addPureEnum(c, LazySym(sym: result.sym))
|
||||
if tfNotNil in e.typ.flags and not hasNull:
|
||||
|
||||
@@ -197,7 +197,7 @@ block: # unordered enum
|
||||
b = 0
|
||||
|
||||
doAssert (ord(a), ord(b)) == (1, 0)
|
||||
doAssert unordered_enum.toSeq == @[a, b]
|
||||
doAssert unordered_enum.toSeq == @[b, a]
|
||||
|
||||
block:
|
||||
type
|
||||
@@ -227,7 +227,7 @@ block: # unordered enum
|
||||
d
|
||||
|
||||
doAssert (ord(a), ord(b), ord(c), ord(d)) == (7, 6, 5, 8)
|
||||
doAssert unordered_enum.toSeq == @[a, b, c, d]
|
||||
doAssert unordered_enum.toSeq == @[c, b, a, d]
|
||||
|
||||
block:
|
||||
type
|
||||
@@ -265,3 +265,21 @@ block: # unordered enum
|
||||
seC = "foo"
|
||||
|
||||
doAssert (ord(seA), ord(seB), ord(seC)) == (3, 2, 4)
|
||||
|
||||
block: # bug #23952
|
||||
block:
|
||||
proc foo =
|
||||
type Foo = enum A B = -1
|
||||
doAssert cast[Foo](-1) == B
|
||||
doAssert ord(A) == 0
|
||||
static: foo()
|
||||
foo()
|
||||
|
||||
block:
|
||||
proc foo =
|
||||
type Foo = enum A B=8, C=1
|
||||
let s1 = {A}
|
||||
let s2 = {B}
|
||||
doAssert s1 != s2
|
||||
static: foo()
|
||||
foo()
|
||||
|
||||
Reference in New Issue
Block a user