Summary
CSE hashes every statement attribute via
Info.__post_init__, which calls hash(attr) → PyAttr.__hash__ →
hash((self.type, self.data)). When a py.constant wraps an unhashable
Python value (e.g. a default @dataclass instance), this raises
TypeError: unhashable type: ... from deep inside an optimization pass,
instead of a clean, actionable error.
Minimal reproduction
from dataclasses import dataclass
from kirin import ir
from kirin.dialects.py.constant import Constant
from kirin.rewrite.cse import CommonSubexpressionElimination
# A default dataclass instance is UNHASHABLE (eq=True sets __hash__ = None)
@dataclass
class DataclassObj:
x: int = 1
obj = DataclassObj()
blk = ir.Block()
blk.stmts.append(Constant(obj))
blk.stmts.append(Constant(obj))
CommonSubexpressionElimination().rewrite_Block(blk)
# TypeError: unhashable type: 'DataclassObj'
Summary
CSE hashes every statement attribute via
Info.__post_init__, which callshash(attr)→PyAttr.__hash__→hash((self.type, self.data)). When apy.constantwraps an unhashablePython value (e.g. a default
@dataclassinstance), this raisesTypeError: unhashable type: ...from deep inside an optimization pass,instead of a clean, actionable error.
Minimal reproduction