First sorry if this is inconvenient but I am opening an issue/feature request here as I do not want to use github.
\--- Currently items that are ordinal values in an enum are required to be in ascending order. I would like to remove or relax that requirement so that the code below compiles: type unordered_enum = enum a = 1 b = 0 Run Some usecases are: 1. Grouping and ordering enum items by semantics and not by value. 2. Easier C code conversion, also asked by [1]. 3. Reduce constraints on generated code (specs or standards to code). These are the options I see, in order of preference and feasability: 1. the requirement be removed entirely. 2. if not possible, the requirement be removed when all the values are specified. 3. if not possible, have a pragma that lets the user request an unordered enum. I am not a language designer and I am not familiar with nim compiler internals. It is difficult for me to assess the implications of option1 on the language/compiler/existing code. So I attempted a patch for option 2. diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index c88795517..0efc3f47c 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -69,6 +69,9 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = e: PSym = nil base: PType = nil identToReplace: ptr PNode = nil + containsUnspecifiedValues = false + containsUnorderedValues = false + firstUnorderedValueIndex = 0 counter = 0 base = nil result = newOrPrevType(tyEnum, prev, c) @@ -121,16 +124,21 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = if i != 1: if x != counter: incl(result.flags, tfEnumHasHoles) if x < counter: - localError(c.config, n[i].info, errInvalidOrderInEnumX % e.name.s) + if not containsUnorderedValues: + firstUnorderedValueIndex = i + containsUnorderedValues = true x = counter e.ast = strVal # might be nil counter = x of nkSym: + containsUnspecifiedValues = true e = n[i].sym of nkIdent, nkAccQuoted: + containsUnspecifiedValues = true e = newSymS(skEnumField, n[i], c) identToReplace = addr n[i] of nkPragmaExpr: + containsUnspecifiedValues = true e = newSymS(skEnumField, n[i][0], c) pragma(c, e, n[i][1], enumFieldPragmas) identToReplace = addr n[i][0] @@ -162,6 +170,8 @@ 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 containsUnorderedValues and containsUnspecifiedValues: + localError(c.config, n[firstUnorderedValueIndex].info, errInvalidOrderInEnumX % e.name.s) if isPure and sfExported in result.sym.flags: addPureEnum(c, LazySym(sym: result.sym)) if tfNotNil in e.typ.flags and not hasNull: Run Any comments? [1] <https://github.com/nim-lang/Nim/issues/1043>