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 issue_8684 by bailing early in parseArguments #10529
Conversation
Thanks for your pull request and interest in making D better, @benjones! 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 fetch digger
dub run digger -- build "master + dmd#10529" |
Seems like most of the generated errors are from check(endtok). This suggests a more general solution of suppressing that if any errors occurred in the lexing process. |
The big list of errors came from staying in the while loop and calling check(comma) and trying to parse arguments a bunch of times. The check(endtok) only basically affects whether we correctly parse what comes after a malformed arglist. I agree there's probably something more general to do with the loop + check(comma) that could be used for for + foreach. Does the benefit of better diagnostics outweigh the cost of extra checks when parsing? |
test/fail_compilation/ice11967.d
Outdated
fail_compilation/ice11967.d(12): Error: found `g` when expecting `,` or `)` | ||
fail_compilation/ice11967.d(12): Error: found `g` when expecting `,` or `]` | ||
fail_compilation/ice11967.d(12): Error: no identifier for declarator `g` | ||
fail_compilation/ice11967.d(12): Error: declaration expected, not `{` |
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'd recommend also adding a more obvious test case.
Good idea @rainers . That changes the behavior, but I think still gives pretty good diagnostics and is simpler code. The test case output that changed previously was unrelated and is improved slightly from before, but is a bit longer than my first attempt which I think is fine. I added the test case from the bug report. |
src/dmd/parse.d
Outdated
while (token.value != endtok && token.value != TOK.endOfFile) | ||
{ | ||
auto arg = parseAssignExp(); | ||
arguments.push(arg); | ||
if (token.value == endtok) | ||
if (token.value == endtok || token.value != TOK.comma || errorCount != errorsBefore) |
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 think you should not check the error count, as an error from an inner expression can be completely unrelated and might have been recovered from.
src/dmd/parse.d
Outdated
while (token.value != endtok && token.value != TOK.endOfFile) | ||
{ | ||
auto arg = parseAssignExp(); | ||
arguments.push(arg); | ||
if (token.value == endtok) | ||
if (token.value == endtok || token.value != TOK.comma) |
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.
As endtok
is never a comma, the first part of the condition is unnecessary now. The braces below can also be omitted.
Other than that, LGTM.
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.
is it worth checking for endTok before the loop and switching to while(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.
A trailing comma is optional, so the check in the while condition should be kept.
added test example, simplified logic per @rainers suggestion
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.
Thanks
This does make the error messages better for the code from the bug report:
goes from a bunch of lines down to
bad.d(3): Error: found ; when expecting , or )
Not sure if this was the best way to approach or implement a fix, so open to feedback.