Is there a generic way to hack discriminant assignment in a way that works for
both VM and C backend (and Js backend as well if possible). I've come up with a
solution that works for a C backend, but it fails in a VM.
type
Obj = object
notKind: bool
case kind: bool
of true: discard
of false: discard
template setKind*[T, K](t: var T, kind: untyped, target: K) =
cast[ptr K](cast[int](addr t) + offsetOf(typeof(t), kind))[] = target
var test = Obj()
echo test
setKind test, kind, true
echo test
Run
(notKind: false, kind: false)
(notKind: false, kind: true)
Run
I need this to fix another issue -
type
Requires {.requiresinit.} = object
# Object MUST be a requiresinit for a reasons that are out of the scope
of this
# question (and the code I have to write now as well). It is a given
requirement.
Obj = object
case kind: bool
of true:
req: Requires
of false: discard
func build(inKind: bool): Obj =
# I need to init `Obj` with a runtime value for a discriminant, but it is
not possible
# because
Obj(kind: inKind, req: default(Requires)) # Error: The Obj type requires
the following fields to be initialized: req.
Obj(kind: inKind, req: default(Requires)) # Error: cannot prove that it's
safe to initialize 'req' with the runtime value for the discriminator 'kind'
# I'm cornered by 'requires init' and 'cannot change discriminant', so I
need hack around this
# limitation using
setKind(result, kind, inKind)
if result.kind == true:
result.req = default(Requires)
# Which is possible on a C backend, not on other ones.
Run