Description
Description
Define a module lpt.nim
(idea being a generic hash table with user types):
type
LPs*[K,V] = concept
proc key(c: Self, i: int): K # Cell ops, i-th various
proc val(c: Self, i: int): V # Cell ops, i-th various
Void* = distinct int
Voids* = Void|distinct char
proc incl*[K,V: Voids](s: var LPs[K,V], key: K) =
when V is not Voids: echo "whoa" # runs yet call matched!?
echo "did incl"
iterator pairs*[K,V:not Voids](s: LPs[K,V]): (K, V) =
var k: K; var v: V
for i in 1..3: yield (k, v)
Now a client module, kv.nim
that accesses the not Voids
branch of the type constraint compiles when it should fail:
import lpt
var str = newStringOfCap(81920) # Unique data stacked bk2bk
const bOff = 26 # <64 MiB UNIQUE word data
const bLen = 6 # <64B long; Give 1 To Below?
const bCnt = 32 # <2 GiCount; Could be RT w/less convenience
type
Count {.packed.} = object # Dense-ish hash Count type
off {.bitsize: bOff.}: uint32
len {.bitsize: bLen.}: uint8
cnt {.bitsize: bCnt.}: uint32
Counts = object
dat: seq[Count]
len: int
proc key(c: Count): string = str[c.off ..< c.off + c.len]
proc `==`(a: string|Count, b: Count):bool = true
proc key(c: Counts, i: int): string = c.dat[i].key
proc val(c: Counts, i: int): uint32 = c.dat[i].cnt
proc incFailed(h: var Counts, ms: string): bool = false
proc main() =
var h: Counts
var nTot = 0
block IO:
for line in stdin.lines:
inc nTot # Always bump `nTot`
if h.incFailed(line): break IO
echo h.len," unique ",nTot," total ",str.len," B"
for (k, c) in h.pairs: echo c," ",k
h.incl "heyho" # Should fail;DOESN'T
main()
However, a key-only variant ko.nim
works & fails correctly (EDIT: and differs from kv.nim
only in the lack of bCnt
& cnt
and the return type of val
):
import lpt
var str = newStringOfCap(81920) # Unique data stacked bk2bk
const bOff = 26 # <64 MiB UNIQUE word data
const bLen = 6 # <64B long; Give 1 To Below?
type
Count {.packed.} = object # Dense-ish hash Count type
off {.bitsize: bOff.}: uint32
len {.bitsize: bLen.}: uint8
Counts = object
dat: seq[Count]
len: int
proc key(c: Count): string = str[c.off ..< c.off + c.len]
proc `==`(a: string|Count, b: Count):bool = true
proc key(c: Counts, i: int): string = c.dat[i].key
proc val(c: Counts, i: int): Void {.used.} = discard
proc incFailed(h: var Counts, ms: string): bool = false
proc main() =
var h: Counts
var nTot = 0
block IO:
for line in stdin.lines:
inc nTot # Always bump `nTot`
if h.incFailed(line): break IO
echo h.len," unique ",nTot," total ",str.len," B"
# for (k, c) in h.pairs: echo c," ",k # Should & DOES fail
h.incl "heyho"
main()
Nim Version
Nim Compiler Version 1.9.1 [Linux: amd64]
Compiled at 2023-01-10
Copyright (c) 2006-2023 by Andreas Rumpf
active boot switches: -d:release -d:danger -d:nimUseLinenoise -d:nimHasLibFFI
commit hash: b68b28f
However, this has been failing for at least the last few weeks of nim-devel and also fails on nim-1.6.10
Current Output
{ EDIT: When given an empty file as stdin, } the incorrect kv.nim output is
0 unique 0 total 0 B
0
0
0
whoa
did incl
while the correct ko.nim
output is
0 unique 0 total 0 B
did incl
Expected Output
ko.nim
output is as expected. kv.nim
is not expected to compile.. Additionally, it is not expected to both sigmatch the incl
and emit "whoa\n" from the when
.
Possible Solution
No response
Additional Information
No response