Skip to content
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

Warn on misleading indentation in single-case catch #14738

Merged
merged 5 commits into from Mar 23, 2022

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Mar 21, 2022

Fixes #14721

Surprisingly, caught two instances in the compiler code base itself.

Fixes scala#14721

Surprisingly, caught two instances in the compiler code base itself.
@odersky odersky requested a review from sjrd March 21, 2022 20:16
@som-snytt
Copy link
Contributor

som-snytt commented Mar 21, 2022

Make that three.

Error:  -- Error: /__w/dotty/dotty/compiler/test/dotty/tools/repl/ShadowingTests.scala:36:4 
Error:  36 |    assert(Files.isDirectory(subdir), s"failed to create shadowed subdirectory $subdir")
Error:     |    ^
Error:     |misleading indentation: this expression forms part of the preceding catch case,
Error:     |it should be indented for clarity.

Are we sure a warning is sufficient punishment? It could say something more humiliating, or maybe just sound mad.

Edit: I don't actually want to keep people from the indentation of their choice, if it parses. Except for scaladoc comments, for comments my thinking is absolutely rigid.

Comment on lines 35 to +36
catch case _: java.nio.file.FileAlreadyExistsException =>
assert(Files.isDirectory(subdir), s"failed to create shadowed subdirectory $subdir")
assert(Files.isDirectory(subdir), s"failed to create shadowed subdirectory $subdir")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, I believe my intention there was to swallow the FileAlreadyExistsException, not for the assert to be the body of the catch ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, fixed. Goes to show that this really is a dangerous trap.

Can we make it an error? I don't see how without undermining fundamental assumptions how the parser works. According to the syntax we need an Expr and that's what we can parse. Rejecting it would mean we throw aspects which are outside the context-free syntax into the parsing algorithm.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No wait, it's asserting that the existing thing is a dir, right? If createDir succeeds, it better be a dir.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One way to clarify the syntax is to require the expr to begin on the same line as the arrow. So the arrow could move to the following line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact the warning occurrences in the backend were also assuming an empty
catch handler. I changed them to do the right thing, and fixed the warning message
to point out this possibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@som-snytt I think you are right for ShadowingTests. The assert really is meant as a handler. @griggt can you confirm?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm almost certain that when I wrote it I meant for the catch handler to be empty. But in this case it works either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, we need more forms of syntax that work either way. If Booleans worked either way, we'd never take the wrong branch.

In fact the warning occurrences in the backend were also assuming an empty
catch handler. Change them to do the right thing, and fix the warning message
to point out this possibility.
@som-snytt
Copy link
Contributor

Why isn't

catch case K0 =>
case K1 =>

equivalent to normal syntax, except that it is ugly? Then normal indentation rules apply to

case case K0 =>
  something

without further ado.

@odersky
Copy link
Contributor Author

odersky commented Mar 21, 2022

Why isn't

catch case K0 =>
case K1 =>

equivalent to normal syntax, except that it is ugly?

What would the context free syntax be to support that? We can't just parse the way we like, it has to be backed by context-free syntax rules.

@@ -0,0 +1,9 @@
import scala.util.chaining.given
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be useless/irrelevant.

@odersky odersky merged commit e64fc49 into scala:main Mar 23, 2022
@odersky odersky deleted the fix-14721 branch March 23, 2022 14:53
@Kordyjan Kordyjan added this to the 3.1.3 milestone Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Single line case is multi-line
5 participants