-
-
Notifications
You must be signed in to change notification settings - Fork 802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat[lang]: add linearization check for initializers #4038
base: master
Are you sure you want to change the base?
feat[lang]: add linearization check for initializers #4038
Conversation
add a check that each init function is called after its dependencies misc/refactor: - additional rewrite of a few lines without changing semantics
i'm not sure this shouldn't compile: # main
import lib1
import lib2
import lib3
initializes: lib2[lib1 := lib1]
initializes: lib3
@deploy
def __init__():
lib3.__init__(0)
lib2.__init__()
# lib1
a: public(uint256)
@deploy
@payable
def __init__(x: uint256):
self.a = x
# lib2
import lib1
uses: lib1
a: uint256
@deploy
def __init__():
# not initialized when called
self.a = lib1.a
# lib3
import lib1
initializes: lib1
a: uint256
@deploy
@payable
def __init__(x: uint256):
self.a = x
lib1.__init__(0) fails with:
but |
give us recursion # main
import lib1
import lib2
import lib3
import lib4
initializes: lib2[lib1 := lib1, lib4 := lib4]
initializes: lib3
@deploy
def __init__():
lib3.__init__(0)
lib2.__init__()
# lib1
import lib4
a: public(uint256)
initializes: lib4
@deploy
@payable
def __init__(x: uint256):
self.a = x
lib4.__init__(x)
# lib2
import lib1
import lib4
uses: lib1
uses: lib4
a: uint256
@deploy
def __init__():
# not initialized when called
self.a = lib1.a + lib4.a
# lib3
import lib1
initializes: lib1
a: uint256
@deploy
@payable
def __init__(x: uint256):
self.a = x
lib1.__init__(0)
# lib4
a: uint256
@deploy
@payable
def __init__(x: uint256):
self.a = x
|
The following compiles although it should not I guess? main.vy: import lib1
import lib2
initializes: lib2[lib1 := lib1]
initializes: lib1
@deploy
def __init__():
for i:uint256 in range(2):
if i == 1:
lib1.__init__()
if i == 0:
lib2.__init__() lib1.vy counter: uint256
@deploy
def __init__():
pass lib2.vy import lib1
uses: lib1
counter: uint256
@deploy
def __init__():
pass
@internal
def foo():
lib1.counter += 1 [EDIT] just saw this comment: #3779 (comment) |
yea we don't really care about branches, those get weird - just about AST order |
The following compiles on master but not on this branch since the analysis performed assumes that, given a module A which initializes a module B with some dependency C ( lib3.vy counter: uint256
@deploy
def __init__():
self.counter = 1 lib2.vy import lib3
uses: lib3
counter: uint256
@deploy
def __init__():
self.counter = 1
@external
def foo() ->uint256:
return lib3.counter lib1.vy import lib2
import lib3
uses: lib3
initializes: lib2[lib3 := lib3]
@deploy
def __init__():
lib2.__init__()
lib3.counter += 1
main.vy import lib1
import lib3
initializes: lib1[lib3 := lib3]
initializes: lib3
@deploy
def __init__():
lib3.__init__()
lib1.__init__()
|
yea i guess this represents a fundamental problem with the approach in this PR, which is that |
actually was re-reading the spec with @cyberthirst and it seems this PR is actually enforcing item 3 from the the spec (#3722):
the hint could be improved, though |
i rewrote the code to enforce spec point 3. but snekmate uses the current behavior here (touch |
This actually a very important pattern I need in snekmate and plan to use more often lol... |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #4038 +/- ##
===========================================
- Coverage 91.28% 48.89% -42.39%
===========================================
Files 109 109
Lines 15549 15565 +16
Branches 3416 3419 +3
===========================================
- Hits 14194 7611 -6583
- Misses 925 7340 +6415
- Partials 430 614 +184 ☔ View full report in Codecov by Sentry. |
--------- Co-authored-by: trocher <[email protected]>
add a check that each init function is called after its dependencies
misc/refactor:
What I did
fix #3779
How I did it
How to verify it
Commit message
Commit message for the final, squashed PR. (Optional, but reviewers will appreciate it! Please see our commit message style guide for what we would ideally like to see in a commit message.)
Description for the changelog
Cute Animal Picture