I'm trying to write a "Any Value" type, so I can create a type-safe string-to-any-value table. First I noticed the compiler seems to "confuse" byte and uint8, but I think it's normal, since I've read byte is just an alias for uint8. Unfortunately, it also has problems with float vs float64 (on 64bit architecture), which is strange, because it has no problem with int vs int64 and uint vs uint64. Therefore, I think it's a bug.
Here's the code that compiles but fails to run:
type
AnyValueType* = enum
avBool,
# ...
avFloat,
avFloat64
AnyValue* = object
case kind*: AnyValueType
of avBool: boolValue*: bool
# ...
of avFloat: floatValue*: float
of avFloat64: float64Value*: float64
converter toBoolAnyValue*(v: bool): AnyValue {.inline, noSideEffect.} =
result.kind = avBool
result.boolValue = v
converter toFloatAnyValue*(v: float): AnyValue {.inline, noSideEffect.} =
result.kind = avFloat
result.floatValue = v
converter toFloat64AnyValue*(v: float64): AnyValue {.inline, noSideEffect.} =
result.kind = avFloat64
result.float64Value = v
when isMainModule:
let boolValue: bool = true
let floatValue: float = 42.0
let float64Value: float64 = 42.0'f64
let boolValueAV: AnyValue = boolValue
let floatValueAV: AnyValue = floatValue
let float64ValueAV: AnyValue = float64Value
assert(boolValueAV.boolValue == boolValue)
assert(floatValueAV.floatValue == floatValue)
assert(float64ValueAV.float64Value == float64Value) # Compiler bug :(
And returns:
float64value.nim(38) float64value
system.nim(2839) sysFatal
Error: unhandled exception: float64Value is not accessible [FieldError]
Error: execution of an external program failed: 'bin/float64value '
The terminal process terminated with exit code: 1
float and float64 are equivalent, even on 32bit architectures. int and int64 on the other hand are distinct types which may or may not have the same underlying type. So you only need avFloat64, not avFloat.
You can observe this by naming the two converters the same - the compiler will complain that they have the same signature. Perhaps the compiler should complain when there are multiple converters with the same arguments/return type in the scope, since it's not clear which one will be called.