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
Allow named parameters in mapping types #13384
base: develop
Are you sure you want to change the base?
Conversation
| @@ -10,4 +10,6 @@ contract Error2 { | |||
| mapping (address => uint balances; // missing ) before "balances" | |||
| } | |||
| // ---- | |||
| // ParserError 6635: (417-425): Expected ')' but got identifier | |||
| // ParserError 6635: (425-426): Expected ')' but got ';' | |||
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.
Some existing error recovery tests change their behavior because a syntax that was illegal before (i.e. ability to place an identifier next to type in mapping) is legal now, hence the parser passes further and generates a different error.
Looks quite good! Some small comments.
We were wondering with the annotations, if it makes sense to have the function call options syntax for mappings. For example, for mapping (address user => uint balance) balanceOf, would the syntax balanceOf[{user: 0xaddress}] be allowed? It's not needed to implement it in this PR, but worth thinking about.
Also, it's missing a changelog entry.
|
Can you add a semantic test as well? https://github.com/ethereum/solidity/blob/develop/test/libsolidity/semanticTests/getters/mapping.sol here is an example |
|
Could you also add an example in the documentation? |
|
Thanks for the review! I've made the changes.
This might be tricky for nested mappings: |
already looking very good.
Additionally to the comments, I am wondering if it makes sense to make it an optional<ASTPointer<ASTString>>.
Would love to hear @cameel and @christianparpart on that topic
Depends if we prefer to treat it as a missing name or an empty name. That will show up in the AST. But overall Also, I can't see any place in the AST where we'd have a single optional name but in a few cases we do have vectors of names and that's closer to |
|
I have rebased over the latest Edit: I'm not able to request reviews from multiple people. cc: @hrkrshnn, @Marenz, @cameel, @nishant-sachdeva. (Sorry for tagging). |
|
Will rebase now |
| // Convert key type to memory. | ||
| keyType = TypeProvider::withLocationIfReference(DataLocation::Memory, keyType); | ||
|
|
||
| // Convert value type to storage reference. | ||
| valueType = TypeProvider::withLocationIfReference(DataLocation::Storage, valueType); | ||
| _mapping.annotation().type = TypeProvider::mapping(keyType, valueType); | ||
| _mapping.annotation().type = TypeProvider::mapping(keyType, valueType, keyName, valueName); |
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.
Nit: I would have preferred the order to be keyType, KeyName, valueType, valueName. But no strong argument on changing this.
- Add changelog
|
Summary of the changes done:
|
| } | ||
| // ---- | ||
| // DeclarationError 5609: (45-84): Conflicting parameter name "owner" in mapping. | ||
| // DeclarationError 1809: (20-85): Conflicting parameter name "owner" in recursive mapping. |
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.
Why does this one have a different error code, i.e. 1809 vs 5609? Ah OK, it's a different error in case the nested type is a mapping, so you're differentiating between conflicting key -> key and key -> value names. The error message is the same though, which is perfectly fine, but in that case, the errors should have the same code.
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.
Since both these cases serve the same purpose, it might make sense to just have the same error and code in both cases.
so you're differentiating between conflicting key -> key and key -> value names
I did that because the error logic was at different places in the code and I tend to write more descriptive error msg if possible. But here I agree the solidity dev that ends up on this error doesn't benefit much.
| @@ -0,0 +1,6 @@ | |||
| contract test { | |||
| struct Person { | |||
| mapping(uint phone => mapping(uint call => uint time) callTimes) friends; | |||
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.
Adding another test case with an additional level of nesting would be nice, especially if it hits the conflicting parameter error between the root and leaf mapping, e.g.
mapping(uint phone => mapping(uint call => mapping(uint phone => something) leafMapping) callTimes) friends;
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.
There was a typo in the logic and this test case caught that. I've updated the fix in commit 7438248.
| m_errorReporter.declarationError( | ||
| 1809_error, | ||
| _mapping.location(), | ||
| "Conflicting parameter name \"" + keyName + "\" in recursive mapping." |
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.
Oh yeah, one thing that kinda irks me is this being called a recursive mapping. Nested would be a more appropriate term here.
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.
I've just combined the error into single one, removing the "recursive" word itself. So now it looks like: Conflicting parameter name "nameSame" in mapping.. Lmk if we have to change this into something better.
|
I've pushed an empty commit, squash and pushed in the hopes of restarting the build successfully, but unfortunately we seem to have CI problems, which will hopefully be resolved soon. In fact, as soon as that happens, I'll restart the build to see whether everything passes, and then I'll resume reviewing. |
| ASTString childKeyName = childMappingType->keyName(); | ||
| if (keyName == childKeyName) | ||
| { | ||
| m_errorReporter.declarationError( |
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.
The chk_errorcodes step is failing because you can't throw an error with the same code twice, i.e. this one, and the one on line 310; instead you'll have to use a boolean to indicate whether an error needs to be thrown, and then check at the end of the loop iteration and report error if true.
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.
I've just pushed a change for this.
Co-authored-by: Nikola Matić <nikola.matic@ethereum.org>
| if (keyName == currentValueName) | ||
| { | ||
| isError = true; | ||
| break; | ||
| } |
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.
| if (keyName == currentValueName) | |
| { | |
| isError = true; | |
| break; | |
| } | |
| if (keyName == currentValueName) | |
| isError = true; |
| @@ -0,0 +1,7 @@ | |||
| contract test { | |||
| struct Person { | |||
| mapping(uint nameSame => mapping(uint name1 => mapping(uint nameSame => uint name2) name3) name4) name5; | |||
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.
Another three-level nested mapping test, but this time valid, please :)
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.
I've added that, please review.
Closes #11407
Please let me know of any changes that are needed.