pyteal
pyteal copied to clipboard
ScratchVar load before store conflicting with Subroutines.
Subject of the issue
Compiler checks for load before store do not work as expected when Subroutines that takes ScratchVar as arguments are used.
Steps to reproduce
from pyteal import *
def example():
var = ScratchVar(TealType.uint64)
@Subroutine(TealType.none)
def sub(x: ScratchVar):
return x.store(Int(0))
return Seq([
sub(var),
Pop(var.load()),
Approve()
])
if __name__ == '__main__':
print(compileTeal(example(), mode=Mode.Application, version=6))
Expected behaviour
Contract can compile correctly
Actual behaviour
pyteal.TealCompileError: Scratch slot load occurs before store
Thanks for reporting this issue, I've reproduced it on the current master branch.
The problem occurs on the Pop(var.load())
line. The issue here is that the compiler doesn't do enough analysis to make sure that line is safe. The sub
subroutine happens to always stores a value in the subroutine argument slot, but the compiler isn't aware of that currently. For all it knows, that subroutine could only conditionally store something in the argument slot, or never store anything there.
With enhanced analysis in the compiler, we could detect across subroutine calls whether a scratch slot is safe to load.