There seems to be a bug, however, by which this check doesn't catch such an error, even in debug mode.
For example, try the following example. type Kind = enum Zeroth, First, Thing = object case kind: Kind of Zeroth: f: float of First: i: int var t = Thing(kind: Zeroth, f: 3.14) t.kind = First echo t.i The code erroneously interprets the float as an int! This is a major safety issue. Output: 4614253070214989087 I believe that this is a bug (see above issues), because the inverse situation: var t = Thing(kind: First, i: 123) t.kind = Zeroth echo t.f raises an exception as it should. In fact, I believe (don't quote me on this, but I think I'm understanding correctly), that this is caused by the FieldDiscriminantCheck proc in system/assign.nim! The proc is fairly simple: proc FieldDiscriminantCheck(oldDiscVal, newDiscVal: int, a: ptr array[0x7fff, ptr TNimNode], L: int) {.compilerProc.} = var oldBranch = selectBranch(oldDiscVal, L, a) var newBranch = selectBranch(newDiscVal, L, a) if newBranch != oldBranch and oldDiscVal != 0: sysFatal(FieldError, "assignment to discriminant changes object branch") So this would explain how this bug comes about. The first listed enum variant will be encoded as 0. Here this is Zeroth. When attempting to change the branch from First to Zeroth, both conditions pass, and the exception is properly raised. Yet, in the broken example, the second condition fails. I am not sure why this condition is here. I assume that there is some significance of a discriminant of 0, but it seems to cause a conflict with the enum encoding, and it definitely breaks memory safety. This may be really easy or really hard to fix...