Braceless syntax with higher order functions and case
See original GitHub issueCompiler version
3.0.0
Minimized code
object Foo:
def joe(): List[(Int, Int)] =
List((2, 3), (3, 4)).filter { case (a, b) => b > a }
Output (click arrow to expand)
If I remove the {}
I get a parser error and exception. If I then wrap the case onto the next line and indent it doesn’t like that. I can replace the {}
with ()
but then it doesn’t like the case so then I can remove the case and it seems fine with that. I can’t wrap the case or without the case to the next line. It is like ()
is required but is that going to work with a multi-line lambda?
I would expect that Scala 3 would still take the case
syntax like Scala 2 but maybe warn because it it not needed.
I would also expect that I could wrap the (a, b) => b > a
or other statements to the next line and indent.
The context of this investigation is related to the default in scalafmt
that keeps the case
on the same line as the HOF like foreach
below where we would assume it should start on the next line. We think the current format is correct and that we should be able to remove the {}
and it should “just work” in Scala 3.
- times.foreach {
- case (k, v) =>
- val key = k.split(":")(1)
- totalTimes(key) = totalTimes.getOrElse(key, 0L) + v
- totalThreads(key) = totalThreads.getOrElse(key, 0L) + 1
+ times.foreach { case (k, v) =>
+ val key = k.split(":")(1)
+ totalTimes(key) = totalTimes.getOrElse(key, 0L) + v
+ totalThreads(key) = totalThreads.getOrElse(key, 0L) + 1
Note: couldn’t get details to work without code example getting unformatted.
[info] compiling 1 Scala source to /Users/eric/workspace/sconfig/sconfig/js/target/scala-3.0.0/classes ...
[error] -- [E040] Syntax Error: /Users/eric/workspace/sconfig/sconfig/shared/src/main/scala-3/org/ekrich/config/Foo.scala:3:33
[error] 3 | List((2, 3), (3, 4)).filter case (a, b) => b > a
[error] | ^^^^
[error] | unindent expected, but 'case' found
[error] -- [E040] Syntax Error: /Users/eric/workspace/sconfig/sconfig/shared/src/main/scala-3/org/ekrich/config/Foo.scala:4:0
[error] 4 |
[error] |^
[error] |unindent expected, but eof found
[info] exception occurred while parsing /Users/eric/workspace/sconfig/sconfig/shared/src/main/scala-3/org/ekrich/config/Foo.scala
[info] exception occurred while compiling /Users/eric/workspace/sconfig/sconfig/shared/src/main/scala-3/org/ekrich/config/Foo.scala
java.lang.AssertionError: assertion failed: dotty.tools.dotc.parsing.Scanners$$anon$1@65705702 while compiling /Users/eric/workspace/sconfig/sconfig/shared/src/main/scala-3/org/ekrich/config/Foo.scala
[error] ## Exception when compiling 108 sources to /Users/eric/workspace/sconfig/sconfig/js/target/scala-3.0.0/classes
[error] java.lang.AssertionError: assertion failed: dotty.tools.dotc.parsing.Scanners$$anon$1@65705702
[error] scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
[error] dotty.tools.dotc.parsing.Scanners$Scanner.insert(Scanners.scala:360)
[error] dotty.tools.dotc.parsing.Scanners$Scanner.observeOutdented(Scanners.scala:586)
[error] dotty.tools.dotc.parsing.Parsers$Parser.acceptStatSepUnlessAtEnd(Parsers.scala:327)
[error] dotty.tools.dotc.parsing.Parsers$Parser.blockStatSeq$$anonfun$1(Parsers.scala:3938)
[error] dotty.tools.dotc.parsing.Parsers$Parser.checkNoEscapingPlaceholders(Parsers.scala:462)
[error] dotty.tools.dotc.parsing.Parsers$Parser.blockStatSeq(Parsers.scala:3941)
[error] dotty.tools.dotc.parsing.Parsers$Parser.block(Parsers.scala:2416)
[error] dotty.tools.dotc.parsing.Parsers$Parser.blockExpr$$anonfun$1(Parsers.scala:2408)
[error] dotty.tools.dotc.parsing.Parsers$Parser.enclosed(Parsers.scala:518)
[error] dotty.tools.dotc.parsing.Parsers$Parser.inBracesOrIndented(Parsers.scala:530)
[error] dotty.tools.dotc.parsing.Parsers$Parser.inDefScopeBraces(Parsers.scala:538)
[error] dotty.tools.dotc.parsing.Parsers$Parser.blockExpr(Parsers.scala:2406)
[error] dotty.tools.dotc.parsing.Parsers$Parser.simpleExpr(Parsers.scala:2235)
[error] dotty.tools.dotc.parsing.Parsers$Parser.$init$$$anonfun$6(Parsers.scala:2191)
[error] dotty.tools.dotc.parsing.Parsers$Parser.postfixExpr(Parsers.scala:2168)
[error] dotty.tools.dotc.parsing.Parsers$Parser.expr1(Parsers.scala:2013)
[error] dotty.tools.dotc.parsing.Parsers$Parser.expr(Parsers.scala:1892)
[error] dotty.tools.dotc.parsing.Parsers$Parser.$init$$$anonfun$5(Parsers.scala:1872)
[error] dotty.tools.dotc.parsing.Parsers$Parser.subPart(Parsers.scala:590)
[error] dotty.tools.dotc.parsing.Parsers$Parser.subExpr(Parsers.scala:1874)
[error] dotty.tools.dotc.parsing.Parsers$Parser.defDefOrDcl(Parsers.scala:3328)
[error] dotty.tools.dotc.parsing.Parsers$Parser.defOrDcl(Parsers.scala:3219)
[error] dotty.tools.dotc.parsing.Parsers$Parser.templateStatSeq$$anonfun$1(Parsers.scala:3851)
[error] dotty.tools.dotc.parsing.Parsers$Parser.checkNoEscapingPlaceholders(Parsers.scala:462)
[error] dotty.tools.dotc.parsing.Parsers$Parser.templateStatSeq(Parsers.scala:3861)
[error] dotty.tools.dotc.parsing.Parsers$Parser.$anonfun$33(Parsers.scala:3740)
[error] dotty.tools.dotc.parsing.Parsers$Parser.enclosed(Parsers.scala:518)
[error] dotty.tools.dotc.parsing.Parsers$Parser.inBracesOrIndented(Parsers.scala:530)
[error] dotty.tools.dotc.parsing.Parsers$Parser.inDefScopeBraces(Parsers.scala:538)
[error] dotty.tools.dotc.parsing.Parsers$Parser.templateBody(Parsers.scala:3740)
[error] dotty.tools.dotc.parsing.Parsers$Parser.templateBodyOpt(Parsers.scala:3733)
[error] dotty.tools.dotc.parsing.Parsers$Parser.template(Parsers.scala:3710)
[error] dotty.tools.dotc.parsing.Parsers$Parser.templateOpt(Parsers.scala:3722)
[error] dotty.tools.dotc.parsing.Parsers$Parser.objectDef(Parsers.scala:3474)
[error] dotty.tools.dotc.parsing.Parsers$Parser.tmplDef(Parsers.scala:3433)
[error] dotty.tools.dotc.parsing.Parsers$Parser.defOrDcl(Parsers.scala:3225)
[error] dotty.tools.dotc.parsing.Parsers$Parser.topStatSeq(Parsers.scala:3797)
[error] dotty.tools.dotc.parsing.Parsers$Parser.topstats$2(Parsers.scala:3977)
[error] dotty.tools.dotc.parsing.Parsers$Parser.compilationUnit$$anonfun$1(Parsers.scala:3982)
[error] dotty.tools.dotc.parsing.Parsers$Parser.checkNoEscapingPlaceholders(Parsers.scala:462)
[error] dotty.tools.dotc.parsing.Parsers$Parser.compilationUnit(Parsers.scala:3987)
[error] dotty.tools.dotc.parsing.Parsers$Parser.parse(Parsers.scala:175)
[error] dotty.tools.dotc.typer.FrontEnd.parse$$anonfun$1(FrontEnd.scala:57)
[error] dotty.tools.dotc.typer.FrontEnd.monitor(FrontEnd.scala:43)
[error] dotty.tools.dotc.typer.FrontEnd.parse(FrontEnd.scala:67)
[error] dotty.tools.dotc.typer.FrontEnd.runOn$$anonfun$1(FrontEnd.scala:108)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.immutable.List.foreach(List.scala:333)
[error] dotty.tools.dotc.typer.FrontEnd.runOn(FrontEnd.scala:108)
[error] dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:205)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
[error] dotty.tools.dotc.Run.runPhases$5(Run.scala:215)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:223)
[error] scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
[error] dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
[error] dotty.tools.dotc.Run.compileUnits(Run.scala:230)
[error] dotty.tools.dotc.Run.compileSources(Run.scala:166)
[error] dotty.tools.dotc.Run.compile(Run.scala:150)
[error] dotty.tools.dotc.Driver.doCompile(Driver.scala:39)
[error] dotty.tools.xsbt.CompilerBridgeDriver.run(CompilerBridgeDriver.java:88)
[error] dotty.tools.xsbt.CompilerBridge.run(CompilerBridge.java:22)
[error] sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:91)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$7(MixedAnalyzingCompiler.scala:186)
[error] scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
[error] sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:241)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:176)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4$adapted(MixedAnalyzingCompiler.scala:157)
[error] sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:239)
[error] sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:157)
[error] sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:204)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:528)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:528)
[error] sbt.internal.inc.Incremental$.$anonfun$apply$5(Incremental.scala:174)
[error] sbt.internal.inc.Incremental$.$anonfun$apply$5$adapted(Incremental.scala:172)
[error] sbt.internal.inc.Incremental$$anon$2.run(Incremental.scala:457)
[error] sbt.internal.inc.IncrementalCommon$CycleState.next(IncrementalCommon.scala:116)
[error] sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:56)
[error] sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:52)
[error] sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:261)
[error] sbt.internal.inc.Incremental$.$anonfun$incrementalCompile$8(Incremental.scala:412)
[error] sbt.internal.inc.Incremental$.withClassfileManager(Incremental.scala:499)
[error] sbt.internal.inc.Incremental$.incrementalCompile(Incremental.scala:399)
[error] sbt.internal.inc.Incremental$.apply(Incremental.scala:166)
[error] sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:528)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:482)
[error] sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:332)
[error] sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:420)
[error] sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:137)
[error] sbt.Defaults$.compileIncrementalTaskImpl(Defaults.scala:2346)
[error] sbt.Defaults$.$anonfun$compileIncrementalTask$2(Defaults.scala:2303)
[error] sbt.internal.io.Retry$.apply(Retry.scala:46)
[error] sbt.internal.io.Retry$.apply(Retry.scala:28)
[error] sbt.internal.io.Retry$.apply(Retry.scala:23)
[error] sbt.internal.server.BspCompileTask$.compute(BspCompileTask.scala:31)
[error] sbt.Defaults$.$anonfun$compileIncrementalTask$1(Defaults.scala:2299)
[error] scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error] sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error] sbt.std.Transform$$anon$4.work(Transform.scala:68)
[error] sbt.Execute.$anonfun$submit$2(Execute.scala:282)
[error] sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
[error] sbt.Execute.work(Execute.scala:291)
[error] sbt.Execute.$anonfun$submit$1(Execute.scala:282)
[error] sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
[error] sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
[error] java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error] java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[error] java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[error] java.lang.Thread.run(Thread.java:748)
Issue Analytics
- State:
- Created 2 years ago
- Comments:12 (8 by maintainers)
No it’s not, I missed that part, could you open an issue just about that?
I see now, Scala 3 supports both with and without the
case
so it is backward compatible.