-
-
Notifications
You must be signed in to change notification settings - Fork 610
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
Add named arguments to struct literals #14776
Conversation
|
Thanks for your pull request and interest in making D better, @dkorpel! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + dmd#14776" |
6744923 to
528d990
Compare
|
Currently fails with tuples: void main() {
auto t = tuple("H", "I");
}
Tuple!T tuple(T...)(T values)
{
return Tuple!T(values); // < (param1, param2) gets rewritten to (null, paramX)
}
struct Tuple(T...)
{
T values;
alias values this;
}Will look at it tomorrow |
b633451 to
ed2c265
Compare
ddec9a4 to
b5650db
Compare
| foreach (i; 0..exps.length) | ||
| (*names)[i] = null; | ||
| } | ||
| if (exps.length != names.length) |
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 keep the dead 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.
It catches bugs
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.
Note that it's basically an assert, but using if and printf to give a more fluent assert message.
b5650db to
88fc33b
Compare
Co-authored-by: Razvan Nitu <razvan.nitu1305@gmail.com>
6d34239 to
95a3167
Compare
|
@RazvanN7 Anything else? |
| // (UFCS/operator overloading) are fixed to take named arguments into account | ||
| names.setDim(exps.length); | ||
| foreach (i; 0..exps.length) | ||
| (*names)[i] = null; |
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.
What are the situations where names.length != exps.length? I assume from your comment that this is here to catch bugs in other places, however, why do you nullify the names array? Also, you're printing the elements in the next branch so you're putting yourself at risk of a segfault.
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 next branch won't be taken, because this branch does names.setDim(exps.length);. It nullifies them because setDim doesn't initialize new elements, and you don't want it to search a garbage identifier. I could just nullify the new elements, but it doesn't matter, the names aren't correct anyway. This is not a problem, because named arguments don't exist yet, so there's no code relying on it being correct. This whole branch is just scaffolding to make it not crash for various constructed CallExps.
I don't know all situations where names.length != exps.length. One of them was where a.fun(name: b) gets rewritten to fun(a, b) without also prepending a null name, but I fixed that. There are a lot more, but I'll defer them to the PR that implements named function arguments.
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.
Ok, makes sense, thanks for the explanation.
| { | ||
| if (length == 0) | ||
| { | ||
| names.remove(index); |
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.
This behavior should be documented in the spec PR. I agree that this is the most sane approach, but others might expect that the named arg is attached to the following argument after the empty AliasSeq (and error if the arg already has a name).
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.
Okay
| } | ||
| foreach (i; 1 .. length) | ||
| { | ||
| names.insert(index + i, cast(Identifier) null); |
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.
| names.insert(index + i, cast(Identifier) null); | |
| names.insert(index + i, null); |
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.
That gives an ambiguity error, because insert also has an overload with an Array*
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 guess you will post a documentation PR when named arguments are implemented. Just do not forget to mention that struct literals obey the same rules as any other function with named args.
|
I created a project to give an overview, and to help me remember: |
Best reviewed per commit, because the big copy-paste Move out resolveStructLiteralNamedArgs does not give a pleasant diff.
Array!Identifierinstead of aNamedArgExp, which was disliked in Add named argument parsing support #14475StructInitializerre-usableCallExpon a constructor-less structThis PR does not do function calls / constructors, that's #14575, which is stalled because checking which of two overloads is more specialized still needs to be adjusted for named parameters.
I haven't started on named template arguments.