Description
Changing statement order in simpleTreeDiff
causes compilation error. I'm not entirely sure if this is a bug, or some insanely convoluted generic interaction, but since the behavior of the compiler wildly differs only based on the order of generic instantiations it is probably a bug.
Example
import std/[tables, hashes]
type
NodeId*[L] = object
isSource: bool
index: Table[NodeId[L], seq[NodeId[L]]]
func hash*[L](id: NodeId[L]): Hash = discard
func `==`[L](a, b: NodeId[L]): bool = discard
proc makeIndex*[T, L](tree: T) =
var parent = NodeId[L]()
var tmp: Table[NodeId[L], seq[NodeId[L]]]
tmp[parent] = @[parent]
proc simpleTreeDiff*[T, L](source, target: T) =
# Swapping these two lines makes error disappear
var m: Table[NodeId[L], NodeId[L]]
makeIndex[T, L](target)
var tmp: Table[string, seq[string]] # removing this forward declaration also removes error
proc diff(x1, x2: string): auto =
simpleTreeDiff[int, string](12, 12)
Current Output
/usercode/in.nim(29, 17) template/generic instantiation of `simpleTreeDiff` from here
/usercode/in.nim(24, 21) template/generic instantiation of `makeIndex` from here
/usercode/in.nim(18, 15) template/generic instantiation of `[]=` from here
/playground/nim/lib/pure/collections/tableimpl.nim(58, 21) template/generic instantiation of `rawGet` from here
/playground/nim/lib/pure/collections/hashcommon.nim(60, 48) Error: type mismatch: got <string, NodeId[system.string, system.string]>
Expected Output
No compilation errors
Additional
I added static: echo typeof ...
in tables.[]=
to printf-debug instantiation. Concreted code now is (module runnable example and documentation):
proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) =
static:
echo "proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) ="
echo " typeof(A) ", typeof(A)
echo " typeof(B) ", typeof(B)
echo " typeof(t) ", typeof(t)
echo " typeof(t.data) ", typeof(t.data)
putImpl(enlarge)
And it produces different results based on order of the statements in code above or whether var tmp: Table[string, seq[string]]
is present. When I try to compile example it outputs
proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) =
typeof(A) NodeId[system.string]
typeof(B) seq[NodeId[system.string]]
typeof(t) Table[NodeId[system.string], seq[NodeId[system.string]]]
typeof(t.data) KeyValuePairSeq[system.string, seq[string]]
When I remove var tmp: Table[string, seq[string]]
compilations succeeds, printing out
proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) =
typeof(A) NodeId[system.string]
typeof(B) seq[NodeId[system.string]]
typeof(t) Table[NodeId[system.string], seq[NodeId[system.string]]]
typeof(t.data) KeyValuePairSeq[NodeId[system.string], seq[NodeId[system.string]]]
Which is what one could expect (t.data
generic parameters are the same as in table itself).
Nim version
$ nim -v
Nim Compiler Version 1.4.0 [Linux: amd64]
Compiled at 2020-10-16
Copyright (c) 2006-2020 by Andreas Rumpf
git hash: bdcd87afca238a0a7b2c70971827cf9172817b12
active boot switches: -d:release -d:danger