-
-
Notifications
You must be signed in to change notification settings - Fork 788
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
fix: allow struct constants #2617
Conversation
With the above changes, if I try to return a constant struct, I am now getting an unhandled error.
|
seems like the constant is not getting propagated during folding |
Codecov Report
@@ Coverage Diff @@
## master #2617 +/- ##
==========================================
+ Coverage 86.55% 86.96% +0.41%
==========================================
Files 91 91
Lines 9852 9871 +19
Branches 2480 2478 -2
==========================================
+ Hits 8527 8584 +57
+ Misses 829 799 -30
+ Partials 496 488 -8
Continue to review full report at Codecov.
|
2913093
to
7358a28
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nested structs don't work here
struct Foo:
bar: Bar
struct Bar:
baz: String[100]
da: constant(Foo) = Foo({bar: Bar({baz: "hello"})})
@external
@view
def get() -> Foo:
return da
$ vyper --version && vyper tmp/bar.vy
0.3.2+commit.f80aedb3
vyper.exceptions.StateAccessViolation: Value must be a literal
contract "tmp/bar.vy", function "get", line 6:20
5
---> 6 da: constant(Foo) = Foo({bar: Bar({baz: "hello"})})
---------------------------^
7
ah, will look into this |
cf72a13
to
dd793c7
Compare
Updated initial write-up |
123a93c
to
b1bf935
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couple minor truthy checks need to be cleaned up but i think overall this is good
108c695
to
6607c17
Compare
d3245bd
to
8101c9c
Compare
vyper/semantics/validation/module.py
Outdated
raise StateAccessViolation("Value must be a literal", node.value) | ||
if isinstance(node.value, vy_ast.Attribute): | ||
# Check for environment variables | ||
if node.value.get("value.id") in get_constant_vars(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we can remove this now that we separated the behavior of check_constant
and check_kwargable
8888012
to
bc5d026
Compare
What I did
Fix for #1430, extending on #2396.
The following code results in an error in v0.3.1:
[UPDATE]
After the above changes, attempting to return a struct constant or any of its member values resulted in an unhandled compiler error (see comments below) due to struct constants not being propagated during constant folding. I have made changes to handle constant propagation for folding of struct constants, and a minor change to handle constant struct members.
How I did it
Type checking for struct constants
check_constant
function invyper/semantics/types/utils.py
to handle structs by checking if each member is a literal value.For nested structs, make a recursive call.visit_AnnAssign
function ofModuleNodeVisitor
class invyper/semantics/validation/module.py
to checknode.value
usingcheck_constants
(instead ofcheck_literals
), and to check for any reference to environment variables (which should not be accessible at compile time (?)).Folding for struct constants
Name
node with the entireCall
node of the defined constant.Where the constant to be replaced is a user-defined struct, loop through its members to also replace such references with the constant value of the respective struct member. This is done through a helper function_replace_struct_members
, which takes in a path of parent attributes that should be present in a Name node that is to be replaced. For example,Foo.a.b
wherea
is a struct will be represented as the following when usedbut during construction we visit in the orderFoo
>>a
>>b
. Since the search for nodes to be replaced is premised onName
nodes (i.e.Foo
), we need to store a path of parent attributes for all possible (plain and nested) struct members (including structs) in order to trace the path of parent attributes backwards.Add an additional parameterparent_attributes_ids
toreplace_constant()
helper function to supplement theid_
parameter, so as to enable additional filtering of nodes successively if they are referencing a struct member (plain or nested, including nested structs).Call
AST node in_replace()
helper function as this is the node type for structs.How to verify it
See test cases.
Commit message
Description for the changelog
Allow constant structs.
Cute Animal Picture