vyper
vyper copied to clipboard
Ternary operator in conditions does not compile
Version Information
- vyper Version (output of
vyper --versionOR linkable commit hash vyperlang/vyper@commitish):0.4.0rc5+commit.98370f50
Issue description
When a ternary operator is used inside conditions, e.g. if or assert compilation fails.
Typically the error looks something like:
vyper.exceptions.CompilerPanic: missing symbols: {'self.foo()4'}
PoC
Minimal with assert:
@internal
def foo() -> uint256:
return 42
@external
def bar():
assert 43 == (self.foo() if True else self.foo()), "test"
Minimal with if:
@internal
def foo() -> uint256:
return 42
@external
def bar():
if 43 == (self.foo() if True else self.foo()):
pass
More extensive:
#@version 0.4.0.rc5
@internal
def foo() -> uint256:
return 42
@internal
def baz() -> bool:
return False
@external
def bar():
b: bool = False
# These compile
assert 43 == (self.foo() if self.baz() else self.foo()), "test"
u: uint256 = self.foo() if empty(bool) else self.foo()
# These do not compile
#assert 43 == (self.foo() if empty(bool) else self.foo()), "test"
#assert (self.foo() if empty(bool) else self.foo()) == 43, "test"
#assert (self.foo() if empty(bool) else self.foo()) == (self.foo() if empty(bool) else self.foo()), "test"
Credit: @pcaversaccio and @trocher
whe i run this example without optimizations --no-optimize, the revert doesn't happen
@internal
def foo() -> uint256:
return 42
@external
def bar():
assert 43 == (self.foo() if True else self.foo()), "test"
whe i run this example without optimizations
--no-optimize, the revert doesn't happen@internal def foo() -> uint256: return 42 @external def bar(): assert 43 == (self.foo() if True else self.foo()), "test"
I'd expect such behaviour as I think the issue is due to the optimizer removing the if or else expression with the dead branch eliminator but the symbol check is not being deactivated since arithmetic operations optimizations have should_check_symbols set (and in those case the if/else is in an arithmetic op)
https://github.com/vyperlang/vyper/blob/24cfe0bcc10ec9418054c8def5cf4eeaa3ed0164/vyper/ir/optimizer.py#L448-L450
https://github.com/vyperlang/vyper/blob/24cfe0bcc10ec9418054c8def5cf4eeaa3ed0164/vyper/ir/optimizer.py#L498