Compilation error for Hashable extension
Acton Version
0.14.2.20221201.12.18.21
Steps to Reproduce
class Key:
@property
x: int
def __init__(self, x):
self.x = x
extension Key(Eq):
def __eq__(a, b) -> bool:
return a.x == b.x
extension Key(Hashable):
def __hash__(self):
return hash(self.x)
actor main(env):
var dct: dict[Key, int] = {}
Expected Behavior
Success!
Actual Behavior
Building project in /home/ddjoh/workspaces/act-test-1
Compiling mod1.act for development
Finished compilation in 0.111 s
Building executable out/dev/bin/mod1
ERROR: internal compiler error: compilation of generated C code of the root actor failed
NOTE: this is likely a bug in actonc, please report this at:
NOTE: https://github.com/actonlang/acton/issues/new?template=ice.yaml
NOTE: acton 0.14.2.20221201.12.18.21 compiled by ghc 8.10 on linux x86_64
NOTE: cc: 0.10.0
cc stdout:
cc stderr:
ld.lld: error: undefined symbol: mod1$$Hashable$Key$new
>>> referenced by mod1.c:155 (act-test-1/out/types/mod1.c:155)
>>> mod1.o:(mod1$$main$__init__) in archive /home/ddjoh/workspaces/act-test-1/out/dev/lib/libActonProject.a
Placing __eq__ under the Hashable extension seems to generate working code, e.g:
class Key:
@property
x: int
def __init__(self, x):
self.x = x
extension Key(Hashable):
def __eq__(a, b) -> bool:
return a.x == b.x
def __hash__(self):
return hash(self.x)
actor main(env):
var dct: dict[Key, int] = {}
@nordlander do you know how to fix this? Like if you know exactly what the problem is and how you think it should be fixed?
It seems to me that the problem is that in the CodeGen pass, the Hashable extension for Key is seen as a class and when it's not implementing eq (which it inherited from the Eq protocol) then it is considered an abstract class and won't have the constructor code generated.
I don't think there is such a thing as an abstract extension conceptually - either they implement all the methods or you get an error earlier on. We can also rely on the parent protocols being implemented, so we won't really have any abstract methods.
However, I'm not sure how to differentiate protocols from other classes in CodeGen - if we can? By name? feels ugly. What is even the point of having abstract classes propagated all the way to CodeGen, can't we filter them out earlier so that only concrete classes (including then some extensions) are passed to codegen?
@plajjan See my comment in #2380