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

scalafmt breaks for/yield blocks using significant indentation #4219

Closed
zainab-ali opened this issue Sep 9, 2024 · 2 comments · Fixed by #4416
Closed

scalafmt breaks for/yield blocks using significant indentation #4219

zainab-ali opened this issue Sep 9, 2024 · 2 comments · Fixed by #4416

Comments

@zainab-ali
Copy link

Formatted for/yield blocks with long variable names fail to compile. scalafmt inserts a newline, which breaks code using significant indentation.

Configuration

version = 3.8.3
runner.dialect = scala3

Command-line parameters

When I run scalafmt via CLI like this: scalafmt reproduction.scala

Steps

Given code like this:

val loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu
    : Option[Int] = Some(1)

val expression = for (
  x <- loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu;
  y <- loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu
) yield x + y

Problem

Scalafmt formats code like this:

val loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu
    : Option[Int] = Some(1)

val expression = for (
  x <-
    loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu;
  y <- loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu
) yield x + y

This fails to compile with:

λ> scala-cli compile reproduction.scala
Compiling project (Scala 3.2.2, JVM)
[error] ./reproduction.scala:7:5
[error] expression expected but <- found
[error]   y <- loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu
[error]     ^^
[error] ./reproduction.scala:6:5
[error] value y is not a member of Option[Int].
[error] Note that `y` is treated as an infix operator in Scala 3.
[error] If you do not want that, insert a `;` or empty line in front
[error] or drop any spaces behind the operator.

Expectation

I would like the formatted output to compile.

val loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu
    : Option[Int] = Some(1)

val expression = for (
  x <- loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu;
  y <- loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu
) yield x + y

Workaround

The indentation is not introduced if maxColumns is increased, e.g. maxColumns=100. It is not introduced if the variable name is shorter in length.

@zainab-ali zainab-ali changed the title for/yield blocks with newlines fail to compile due to significant indentation scalafmt breaks for/yield blocks using significant indentation Sep 9, 2024
@kitbellew
Copy link
Collaborator

my guess is, if you're using scala3 (with optional braces), another workaround is:

val expression = for
  x <-
    loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu
  y <-
    loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididu
yield x + y

@kitbellew
Copy link
Collaborator

@zainab-ali can you please point where on this page it explains why your code doesn't compile: https://docs.scala-lang.org/scala3/reference/syntax.html

all i can see is that there's no special treatment of parens vs braces vs opt-braces in

ForExpr           ::=  ‘for’ ‘(’ Enumerators0 ‘)’ {nl} [‘do‘ | ‘yield’] Expr
                    |  ‘for’ ‘{’ Enumerators0 ‘}’ {nl} [‘do‘ | ‘yield’] Expr
                    |  ‘for’     Enumerators0          (‘do‘ | ‘yield’) Expr

@tgodzik who is the expert on scala3 syntax who may have authored the page above?

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 a pull request may close this issue.

2 participants