js compile crash for generic proc that has return type marked by `exportc`
Nim Version
2.3.1 2.*
Description
static: assert defined(js)
proc f(_: SomeFloat): int{.exportc.} = discard
Current Output
Error: unhandled exception: index 7 not in 0 .. 6 [IndexDefect]
Expected Output
(compiles with no error)
Known Workarounds
Delete one of these properties:
- exportc
- generic
- has return type
- (js backend)
Additional Information
real world example: nimpylib/nimpylib#43
Traceback:
compiler/jsgen.nim:3063
genSym accesses n[namePos] (and the line above it checks proc has sfExportc and no sfCompilerProc)
→ genProcForSymIfNeeded →attachProc →
genProc checks
if prc.typ.returnType != nil and sfPure notin prc.flags:
and then call gen(p, prc.ast[resultPos], a) where prc is n[namePos]
But n[namePos].sym.ast.sons.len != 8
So n[namePos].sym.ast[resultPos](resultPos = 7) raises IndexDefect
compiler/pipelines
However, we can find that even in C backend, the node that'll be passed as n[namePos].sym.ast in JS backend still doesn't contain Item#7
Generic procs cannot really be exported because Nim differentiates between instantiations so it would generate multiple functions with the same name on the backend, and it has to be manually instantiated for it to be generated at all. So this also produces a codegen error on the C backend:
proc f(_: SomeFloat): int{.exportc.} = discard
discard f(1'f64)
discard f(1'f32)
In general you can do something like:
proc fImpl(x: SomeFloat): int = discard
proc f*(x: float64): int {.exportc: "f_f64".} = fImpl(x)
proc f*(x: float32): int {.exportc: "f_f32".} = fImpl(x)
But in JS's case you can just use float64 since float32 is treated the same as float64 on JS.
Maybe the compiler should warn/error on codegen exports for generic procs, idk.