Fix 16001 - forbid lambda syntax followed by FunctionLiteralBody#12528
Fix 16001 - forbid lambda syntax followed by FunctionLiteralBody#12528dlang-bot merged 1 commit intodlang:masterfrom
Conversation
src/dmd/parse.d
Outdated
| check(TOK.goesTo); | ||
| if (token.value == TOK.leftCurly) | ||
| { | ||
| deprecation("=> { ... } is a lambda that returns a delegate. Use (args) { ... } for a multi-statement function literal or use => () { } if you intended to return a delegate."); |
There was a problem hiding this comment.
Use deprecationSupplemental for the suggestion.
Also, changelog.
Also, test.
But I thought this was warned against already, maybe in semantic ?
There was a problem hiding this comment.
There's no warning now, this has tripped up dozens of people (or more).
There was a problem hiding this comment.
this has nothing to do in a parser. too much expectactions on the semantics.
There was a problem hiding this comment.
@adamdruppe either way it still requires at least a test and changelog.
|
Also, commit title is terrible for history. "Deprecate ambiguous chained delegate syntax (=> {})" with a proper commit message explaining that this syntax is widely used with another meaning in other language would be much better. Form aside, I like the idea 👍 |
|
sorry but this has nothing to do with parsing. In no way this PR should be accepted. It this parses, then this should be rejected during decl sema let's say. D is context free. |
This rule can be expressed in a context-free grammar. However, since a function literal is a |
|
I'm not sure I'd ever actually remove the syntax, I just want the compiler to warn against the common mistake. |
|
Is there no other way of doing this without modifying the parser? |
|
My objection is not with the semantics. It is with this specific syntax. Syntax is handled by the parser. |
|
what's one more wart on a warthog |
|
|
yeah there's a druntime and phobos thing that needs changing too. what a hassle. i wish the error messages weren't so time consuming to fix. i'm tempted to just fork the compiler to have my private copy for my personal productivity |
WalterBright
left a comment
There was a problem hiding this comment.
This trips up
What is 'This' referring to? Please, folks, let's stop with the commit messages that assumes everyone is intimately familiar with what you're doing and are able to manually parse the code commits to try and reverse engineer what it is about. The opening message of a PR must say:
- What the PR does
- Why
|
Of course, if it has a bugzilla entry with that information, a reference would suffice. |
The issue is: https://issues.dlang.org/show_bug.cgi?id=16001 |
|
good im gonna do an amended commit at some point anyway so ill rewrite the message then |
|
Thanks for your pull request and interest in making D better, @adamdruppe! 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 references
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#12528" |
|
i hate the first line of the commit message, that's even worse but meh whatever |
You can add a description after it: |
|
What was that magic command to update the tests again? I know someone commented but I can't even find the comment now. This test process sucks btw, improving error messages shouldn't cause test failures. |
Well, the tests also ensure that the message don't get worse ... the test runner cannot decide if a different error message is an improvement or not |
This should be modeled after Lines 5961 to 5971 in 9b5db6b |
|
ping @adamdruppe |
|
The test process is broken. I did the output update and it still fails and I have no idea why. I can't even read these logs. |
The test case currently passes because it's not compiled with The other tests hit a bad case where adding the new error messages as
-runnable/funclit.d(415): Deprecation: `(args) => { ... }` is a lambda that returns a delegate, not a multi-line lambda.
-runnable/funclit.d(415): Use `(args) { ... }` for a multi-statement function literal or use `(args) => () { }` if you intended for the lambda to return a delegate.
+runnable/funclit.d(417): Deprecation: `(args) => { ... }` is a lambda that returns a delegate, not a multi-line lambda.
+runnable/funclit.d(417): Use `(args) { ... }` for a multi-statement function literal or use `(args) => () { }` if you intended for the lambda to return a delegate.
int delegate() pure nothrow @nogc @safe delegate() pure nothrow @nogc @safe delegate() pure nothrow @safe
int delegate() pure nothrow @nogc @safe delegate() pure nothrow @nogc @safe delegate() pure nothrow @safe
int-fail_compilation/ice10212.d(13): Deprecation: `(args) => { ... }` is a lambda that returns a delegate, not a multi-line lambda.
-fail_compilation/ice10212.d(13): Use `(args) { ... }` for a multi-statement function literal or use `(args) => () { }` if you intended for the lambda to return a delegate.
-fail_compilation/ice10212.d(13): Error: Expected return type of `int`, not `int function() pure nothrow @nogc @safe`:
-fail_compilation/ice10212.d(13): Return type of `int` inferred here.
+fail_compilation/ice10212.d(15): Deprecation: `(args) => { ... }` is a lambda that returns a delegate, not a multi-line lambda.
+fail_compilation/ice10212.d(15): Use `(args) { ... }` for a multi-statement function literal or use `(args) => () { }` if you intended for the lambda to return a delegate.
+fail_compilation/ice10212.d(15): Error: Expected return type of `int`, not `int function() pure nothrow @nogc @safe`:
+fail_compilation/ice10212.d(15): Return type of `int` inferred here. |
e9faa12 to
7e9c570
Compare
A common mistake D users make - sometimes even experienced D users - is
to use `() => { multi; line; lambda; }`. This syntax is common in
several other languages, including D's syntax relatives of Javascript
and C#, but in D, it is completely different (yet frequently still
compiles!) and leaves users puzzled why their code seemingly does
nothing.
This deprecation is aimed very specifically at that syntax rather than
the semantic construct to warn them that they're doing it wrong and it
offers easy suggestions to clarify their intent with existing D syntax,
similarly to how `if(a = x)` and switch fallthrough was deemed more
error-prone than it was worth given the easy and clear alternatives.
|
finally thx |
|
Common guys, where is the changelog ? We're deprecating a valid language construct because it is ambiguous. This requires an explanation to the end user, both in term of changelog and the actual message. |
|
On Wed, May 26, 2021 at 06:56:35PM -0700, Mathias LANG wrote:
Common guys, where is the changelog ?
generated from the bugzilla entry.
anyone who knows what this is knows it is problematic and anyone who
doesn't know what this is will get the most benefit out of the
deprecation message because they're 99% likely to be silently using it
wrong.
|
No. Simply no. It's a valid language construct, you can't just assume that no one out there isn't using it accurately the way it's defined to work. In fact, the two tests you amended, which were extracted from Bugzilla entries, used it correctly. It's quite likely that a large portion, if not most of the D users out there write code in a different fashion than you, me, or anyone contributing to DMD. And as a large amount of D code is private, we can't just go through all usages to know exactly how affected by this change people will be. We should always be aware of this when we do changes that impact users. Deprecating valid language constructs like this one (or features), is about making a decision which trade-off we favor. Is the cost of the change we're pushing to our users worth the perceived gain from the same change ? Here we believe the answer to be a resounding yes, but the problem with deprecations is that the people pushing for it are the ones that have a lot to gain, while the people that are likely to pay the cost will only be notified about it later. We can't really eliminate this imbalance, but there are trivial steps we can take to reduce it, such as a proper explanation about the deprecation, and how to address it. A key part of the former is a comprehensive changelog entry. I submitted #12592 to add said entry and improve the message. I'm not 100% satisfied with the wording so feel free to make suggestions. |
|
On Wed, May 26, 2021 at 08:47:38PM -0700, Mathias LANG wrote:
It's quite likely that a large portion, if not most of the D users out there write code in a different fashion than you, me, or anyone contributing to DMD.
Yeah, I know. I personally have answered about 1/6 of all the user
question threads over the last decade. Thousands of questions from
hundreds of different people of varying skill level.
This comes up a lot.
|
This trips up so many people and the alternatives are easy - more often than not, you just want to delete the
=>.Time to go ahead and get proactive.