You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is a problem with selecting the right overload of hash and == for a generic objects inferred by a concept.
The not working example is as follows:
import sets, hashes
typeIterable[T] =concept x
for value initems(x):
type(value) is T
Foo[T] =object
t: T
procmyToSet[T](keys: Iterable[T]): HashSet[T] =for x initems(keys): result.incl(x)
prochash[T](foo: Foo[T]): Hash=echo"specific hash"proc`==`[T](lhs, rhs: Foo[T]): bool=echo"specific equals"let
f =Foo[string](t: "test")
hs = [f, f].myToSet()
/some_path/nimtest/comilerbug.nim(22, 14) template/generic instantiation of `myToSet` from here
/some_path/nimtest/comilerbug.nim(12, 31) template/generic instantiation of `incl` from here
/some_path/Nim/lib/pure/collections/setimpl.nim(49, 21) template/generic instantiation of `rawGet` from here
/some_path/Nim/lib/pure/collections/hashcommon.nim(73, 14) template/generic instantiation of `genHashImpl` from here
/some_path/Nim/lib/pure/collections/hashcommon.nim(63, 12) Error: type mismatch: got <Foo>
but expected one of:
proc hash(sBuf: string; sPos, ePos: int): Hash
first type mismatch at position: 1
required type for sBuf: string
but expression 'key' is of type: Foo
proc hash(x: cstring): Hash
first type mismatch at position: 1
required type for x: cstring
but expression 'key' is of type: Foo
proc hash(x: float): Hash
first type mismatch at position: 1
required type for x: float
but expression 'key' is of type: Foo
proc hash(x: pointer): Hash
first type mismatch at position: 1
required type for x: pointer
but expression 'key' is of type: Foo
proc hash(x: string): Hash
first type mismatch at position: 1
required type for x: string
but expression 'key' is of type: Foo
proc hash[A](aBuf: openArray[A]; sPos, ePos: int): Hash
first type mismatch at position: 1
required type for aBuf: openArray[A]
but expression 'key' is of type: Foo
proc hash[A](s: HashSet[A]): Hash
first type mismatch at position: 1
required type for s: HashSet[hash.A]
but expression 'key' is of type: Foo
proc hash[A](s: OrderedSet[A]): Hash
first type mismatch at position: 1
required type for s: OrderedSet[hash.A]
but expression 'key' is of type: Foo
proc hash[A](x: openArray[A]): Hash
first type mismatch at position: 1
required type for x: openArray[A]
but expression 'key' is of type: Foo
proc hash[A](x: set[A]): Hash
first type mismatch at position: 1
required type for x: set[A]
but expression 'key' is of type: Foo
proc hash[T: Ordinal | enum](x: T): Hash
first type mismatch at position: 1
required type for x: T: Ordinal or enum
but expression 'key' is of type: Foo
proc hash[T: proc](x: T): Hash
first type mismatch at position: 1
required type for x: T: proc
but expression 'key' is of type: Foo
proc hash[T: tuple](x: T): Hash
first type mismatch at position: 1
required type for x: T: tuple
but expression 'key' is of type: Foo
proc hash[T](foo: Foo[T]): Hash
first type mismatch at position: 1
required type for foo: Foo[hash.T]
but expression 'key' is of type: Foo
expression: hash(key)
If the type Foo is not generic the example works Ok
import sets, hashes
typeIterable[T] =concept x
for value initems(x):
type(value) is T
Foo=object
t: stringprocmyToSet[T](keys: Iterable[T]): HashSet[T] =for x initems(keys): result.incl(x)
prochash(foo: Foo): Hash=echo"specific hash"proc`==`(lhs, rhs: Foo): bool=echo"specific equals"let
f =Foo(t: "test")
hs = [f, f].myToSet()
producing the output:
specific hash
specific hash
specific equals
The same output is expected for the version when the type Foo is generic.
Alternatively if the Foo is generic but instead using a concept for myToSet parameter, an operArray parameter is used the example also works correct:
import sets, hashes
typeFoo[T] =object
t: T
procmyToSet[T](keys: openArray[T]): HashSet[T] =for x initems(keys): result.incl(x)
prochash[T](foo: Foo[T]): Hash=echo"specific hash"proc`==`[T](lhs, rhs: Foo[T]): bool=echo"specific equals"let
f =Foo[string](t: "test")
hs = [f, f].myToSet()
$ nim -v
Nim Compiler Version 1.3.5 [Linux: amd64]
Compiled at 2020-06-19
Copyright (c) 2006-2020 by Andreas Rumpf
git hash: 99c198625c602984578f9c53b05a28c54de4f4cb
active boot switches: -d:release -d:danger
The text was updated successfully, but these errors were encountered:
I managed to workaround a few similar issues when working on #14481, but despite putting a huge amount of effort I didn't manage to find how to overcome this on a library level. Maybe a fix in the compiler is needed.
There is a problem with selecting the right overload of
hash
and==
for a generic objects inferred by a concept.The not working example is as follows:
If the type
Foo
is not generic the example works Okproducing the output:
The same output is expected for the version when the type
Foo
is generic.Alternatively if the
Foo
is generic but instead using a concept formyToSet
parameter, anoperArray
parameter is used the example also works correct:This issue is blocking #14481
The text was updated successfully, but these errors were encountered: