Open
Description
A similar starting point to #23784
The following confuses the type inference with the error
[...]/nim-2.0.8/lib/system.nim(700, 10) Error: invalid type: 'typeof(matchingBigInt(C))' in this context: 'proc (x: array[0..2, Fp[Fp3prj.C]]): int{.noSideEffect, gcsafe.}' for proc
Line 700 of system.nim in 2.0.8 corresponds to len
of array
It seems like the signature func len*(x: (type array)|array): int
is buggy with distinct type indirection.
import std/macros
import std/bitops
proc replaceNodes(ast: NimNode, what: NimNode, by: NimNode): NimNode =
# Replace "what" ident node by "by"
proc inspect(node: NimNode): NimNode =
case node.kind:
of {nnkIdent, nnkSym}:
if node.eqIdent(what):
return by
return node
of nnkEmpty:
return node
of nnkLiterals:
return node
else:
var rTree = node.kind.newTree()
for child in node:
rTree.add inspect(child)
return rTree
result = inspect(ast)
macro staticFor*(idx: untyped{nkIdent}, start, stopEx: static int, body: untyped): untyped =
result = newStmtList()
for i in start ..< stopEx:
result.add nnkBlockStmt.newTree(
ident("unrolledIter_" & $idx & $i),
body.replaceNodes(idx, newLit i))
# --------------------------------------------------------------
type Curve = enum
BLS12_381
const WordBitWidth* = sizeof(uint64) * 8
func wordsRequired*(bits: int): int {.inline.} =
const divShiftor = fastLog2(WordBitWidth)
result = (bits + WordBitWidth - 1) shr divShiftor
type
BigInt*[bits: static int] = object
limbs*: array[bits.wordsRequired, uint64]
# --------------------------------------------------------------
const CurveBitWidth = [
BLS12_381: 381
]
template matchingBigInt*(Name: static Curve): untyped =
## BigInt type necessary to store the prime field Fp
BigInt[CurveBitWidth[Name]]
type
Fp[C: static Curve] = object
residue: matchingBigInt(C)
type
CubicExt*[F] = object
## Cubic Extension field
coords*: array[3, F]
Fp3[C: static Curve] = CubicExt[Fp[C]]
type
Fp3prj[C: static Curve] {.borrow: `.`.} = distinct Fp3[C]
func `+=`*(a: var Fp, b: Fp) =
for i in 0 ..< a.residue.limbs.len:
a.residue.limbs[i] += b.limbs[i]
func `+=`*(a: var CubicExt, b: CubicExt) =
## Addition in the extension field
staticFor i, 0, a.coords.len:
a.coords[i] += b.coords[i]
# --------------------------------------------------------------
var a: Fp3prj[BLS12_381]
echo a.coords.len
echo a.coords[0].residue.limbs.len
# Up until there everything works
func `+=`*(a: var Fp3prj, b: Fp3prj) {.borrow.}
# Comment this out and code compiles
# Error is:
# Error: invalid type: 'typeof(matchingBigInt(C))'
# in this context: 'proc (x: array[0..2, Fp[Fp3prj.C]]): int{.noSideEffect, gcsafe.}' for proc
#
# The proc name isn't specified but it's `len` in system.nim which does type(array)|array