Skip to content

Don't assume leading infix if next line is indented less #12400

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

Merged
merged 1 commit into from
May 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/parsing/Scanners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,8 @@ object Scanners {
* - it does not follow a blank line, and
* - it is followed by at least one whitespace character and a
* token that can start an expression.
* - if the operator appears on its own line, the next line must have at least
* the same indentation width as the operator. See pos/i12395 for a test where this matters.
* If a leading infix operator is found and the source version is `3.0-migration`, emit a change warning.
*/
def isLeadingInfixOperator(nextWidth: IndentWidth = indentWidth(offset), inConditional: Boolean = true) =
Expand Down Expand Up @@ -397,7 +399,9 @@ object Scanners {
// force a NEWLINE a after current token if it is on its own line
lookahead.nextToken()
assumeStartsExpr(lookahead)
|| lookahead.token == NEWLINE && assumeStartsExpr(lookahead.next)
|| lookahead.token == NEWLINE
&& assumeStartsExpr(lookahead.next)
&& indentWidth(offset) <= indentWidth(lookahead.next.offset)
}
&& {
currentRegion match
Expand Down
10 changes: 6 additions & 4 deletions docs/docs/reference/changed-features/operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,12 @@ would have treated the continuations `++ " world"` or `|| xs.isEmpty` as separat

To make this syntax work, the rules are modified to not infer semicolons in front of leading infix operators.
A _leading infix operator_ is
- a symbolic identifier such as `+`, or `approx_==`, or an identifier in backticks,
- that starts a new line,
- that precedes a token on the same or the next line that can start an expression,
- and that is immediately followed by at least one whitespace character.
- a symbolic identifier such as `+`, or `approx_==`, or an identifier in backticks that
- starts a new line, and
- is not following a blank line, and
- is followed by at least one whitespace character and a token that can start an expression.
- Furthermore, if the operator appears on its own line, the next line must have at least
the same indentation width as the operator.

Example:

Expand Down
9 changes: 9 additions & 0 deletions tests/pos/i12395.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@main def main : Unit =
val x = 1

val y = x match
case 1 => 1
case _ =>
println("bad")
???
println(x)