This is not entirely unrelated, but I things there must be a good built-in way
to disable this checking locally, because sometimes it _really_ messes up
things (specifically serialization and initialization with cases like these).
About #368 - I'm not even sure it is possible to implement prover that would
guarantee assignment safety in the simple (current) case. It would need some
sort of typestate/dataflow analysis to figure out set of all possible
initialization values, and act based on that. So, I suppose I'm missing
something here, but we are _already_ in trouble with single discriminant (and
we can have multiple discriminant fields at the same time as well), so how
having shared fields would make tings harder?
type
NodeKind = enum
foo
bar
bif
baz
bad
Node = object
case kind: NodeKind
of foo, bar, baz:
children: seq[Node]
of bad, bif:
dad: Node
case kind:
of foo:
additionalFieldForFoo: int
of bar:
onlyValidForBar: float
else:
discard
case kind:
of foo, bar:
validForFooAndBar: string
else:
discard
proc node(kind: NodeKind) =
case kind:
of foo:
# safe to init `children`, `additionalFieldForFoo`,
`validForFooAndBar`
# Assigning to any other field would be a compile-time error
# with 'cannot init'. With `{.cast(safeAssign).}` it would turn into
# a warning? hint? nothing?
of bar:
# safe to init `children`, `onlyValidForBar`, `validForFooAndBar`
of bif:
# safe to init `dad`
of baz:
# safe to init `children`
of bad:
# safe to init `dad`
# When trying to init `additionalFieldForFoo` shoudl error out (as it
does now),
# with something like 'cannot prove <XXX> init safety, with unchecked
runtime value
# for discriminant - possible values are <list of dataflow-inferred
values>
Run
This is not a proposal of any sort, but for me it doesn't look like things are
going to be _worse_. At least that's my current understanding.