I was working on a project of mine when I realized I had written this, which
the Nim compiler declared as GC-unsafe:
type
StateKind = enum
stProcessing, stDone
State = ref object
case kind: StateKind
of stProcessing:
progress: int
of stDone:
discard
let doneState = State(kind: stDone) # can't be const since both ref and
case object
proc main() =
var state: State
state = doneState # unsafe
Run
I thought this must have been a solved problem, so I took a bit and remembered
defaultSslContext from asynchttpclient and [the
fix](https://github.com/nim-lang/Nim/commit/35d48765fb5f5b2f58bf6def54fd744492212097#diff-232b8586e82bf9dedf2b071ec6fd52aa)
for the [same mistake I made now](https://github.com/nim-lang/Nim/issues/4998).
The fixed code looked a bit overkill, however.
var doneStateVal {.threadvar.}: State
template doneState*: State =
if doneStateVal.isNil:
doneStateVal = State(kind: stDone)
doneStateVal
Run
My question is, is there a simpler way to write this, or am I missing the point
completely and applying the wrong fix?
I have quite a bit of these doneState variables so for the moment I devised a
template.
template defaultVar(name, value): untyped {.dirty.} =
var `name val` {.gensym, threadvar.}: type(value)
template `name`*: type(value) =
if `name val`.isNil:
`name val` = value
`name val`
Run