scastie icon indicating copy to clipboard operation
scastie copied to clipboard

`ArrayIndexOutOfBoundsException` for a wrong Scala 3 lambda parameter

Open KacperFKorban opened this issue 3 years ago • 8 comments

Link: https://scastie.scala-lang.org/KacperFKorban/xQWBNvfBRp6doXtHN2Rbtw/22 (Note: sometimes the full stack trace doesn't show)

Code snippet:

List(1,2,3).map { using i: Int => i }

Output

java.lang.ArrayIndexOutOfBoundsException: Index 105 out of bounds for length 56
	at scala.meta.tokens.Tokens.apply(Tokens.scala:34)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$trimmedPos$1(ScalametaParser.scala:898)
	at scala.collection.immutable.Range.dropWhile(Range.scala:294)
	at scala.meta.internal.parsers.ScalametaParser.skipTrivia$1(ScalametaParser.scala:898)
	at scala.meta.internal.parsers.ScalametaParser.trimmedPos(ScalametaParser.scala:905)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:891)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:881)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$expr$32(ScalametaParser.scala:2645)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.convertToParam$1(ScalametaParser.scala:2645)
	at scala.meta.internal.parsers.ScalametaParser.convertToParams$1(ScalametaParser.scala:2666)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$expr$22(ScalametaParser.scala:2668)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$expr$2(ScalametaParser.scala:2613)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.expr(ScalametaParser.scala:2397)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$blockStatSeq$2(ScalametaParser.scala:5196)
	at scala.meta.internal.parsers.ScalametaParser.stat(ScalametaParser.scala:5038)
	at scala.meta.internal.parsers.ScalametaParser.blockStatSeq(ScalametaParser.scala:5196)
	at scala.meta.internal.parsers.ScalametaParser.blockWithStats$1(ScalametaParser.scala:3208)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$block$2(ScalametaParser.scala:3210)
	at scala.meta.internal.parsers.ScalametaParser.inBraces(ScalametaParser.scala:800)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$block$1(ScalametaParser.scala:3210)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.block(ScalametaParser.scala:3207)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$blockExpr$1(ScalametaParser.scala:3204)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.blockExpr(ScalametaParser.scala:3199)
	at scala.meta.internal.parsers.ScalametaParser.argumentExprsWithUsing(ScalametaParser.scala:3173)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$simpleExprRest$4(ScalametaParser.scala:3124)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$simpleExprRest$1(ScalametaParser.scala:3124)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.simpleExprRest(ScalametaParser.scala:3090)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$simpleExprRest$1(ScalametaParser.scala:3109)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.simpleExprRest(ScalametaParser.scala:3090)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$simpleExprRest$1(ScalametaParser.scala:3129)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.simpleExprRest(ScalametaParser.scala:3090)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$simpleExpr0$5(ScalametaParser.scala:3036)
	at scala.util.Success.map(Try.scala:262)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$simpleExpr0$1(ScalametaParser.scala:3036)
	at scala.meta.internal.parsers.ScalametaParser.atPosTry(ScalametaParser.scala:915)
	at scala.meta.internal.parsers.ScalametaParser.autoPosTry(ScalametaParser.scala:925)
	at scala.meta.internal.parsers.ScalametaParser.simpleExpr0(ScalametaParser.scala:2985)
	at scala.meta.internal.parsers.ScalametaParser.simpleExpr(ScalametaParser.scala:2983)
	at scala.meta.internal.parsers.ScalametaParser.prefixExpr(ScalametaParser.scala:2967)
	at scala.meta.internal.parsers.ScalametaParser.postfixExpr(ScalametaParser.scala:2947)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$expr$12(ScalametaParser.scala:2514)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$expr$2(ScalametaParser.scala:2514)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.expr(ScalametaParser.scala:2397)
	at scala.meta.internal.parsers.ScalametaParser.templateStatSeq(ScalametaParser.scala:5092)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$templateBody$1(ScalametaParser.scala:4945)
	at scala.meta.internal.parsers.ScalametaParser.inBraces(ScalametaParser.scala:800)
	at scala.meta.internal.parsers.ScalametaParser.templateBody(ScalametaParser.scala:4945)
	at scala.meta.internal.parsers.ScalametaParser.templateBodyOpt(ScalametaParser.scala:4953)
	at scala.meta.internal.parsers.ScalametaParser.template(ScalametaParser.scala:4887)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$template$1(ScalametaParser.scala:4906)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.template(ScalametaParser.scala:4891)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$templateOpt$1(ScalametaParser.scala:4931)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.templateOpt(ScalametaParser.scala:4923)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$objectDef$1(ScalametaParser.scala:4682)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.objectDef(ScalametaParser.scala:4674)
	at scala.meta.internal.parsers.ScalametaParser.tmplDef(ScalametaParser.scala:4558)
	at scala.meta.internal.parsers.ScalametaParser.topLevelTmplDef(ScalametaParser.scala:4540)
	at scala.meta.internal.parsers.ScalametaParser$$anonfun$topStat$1.applyOrElse(ScalametaParser.scala:5079)
	at scala.meta.internal.parsers.ScalametaParser$$anonfun$topStat$1.applyOrElse(ScalametaParser.scala:5067)
	at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:35)
	at scala.meta.internal.parsers.ScalametaParser.statSeq(ScalametaParser.scala:5057)
	at scala.meta.internal.parsers.ScalametaParser.topStatSeq(ScalametaParser.scala:5066)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$batchSource$1(ScalametaParser.scala:5297)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.batchSource(ScalametaParser.scala:5256)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$source$1(ScalametaParser.scala:5239)
	at scala.meta.internal.parsers.ScalametaParser.atPos(ScalametaParser.scala:888)
	at scala.meta.internal.parsers.ScalametaParser.autoPos(ScalametaParser.scala:922)
	at scala.meta.internal.parsers.ScalametaParser.source(ScalametaParser.scala:5238)
	at scala.meta.internal.parsers.ScalametaParser.entrypointSource(ScalametaParser.scala:5244)
	at scala.meta.internal.parsers.ScalametaParser.$anonfun$parseSource$2(ScalametaParser.scala:143)
	at scala.meta.internal.parsers.ScalametaParser.parseRule(ScalametaParser.scala:53)
	at scala.meta.internal.parsers.ScalametaParser.parseSource(ScalametaParser.scala:143)
	at scala.meta.parsers.Parse$.$anonfun$parseSource$1(Parse.scala:29)
	at scala.meta.internal.parsers.ScalametaParser$$anon$264.apply(ScalametaParser.scala:5308)
	at scala.meta.parsers.Api$XtensionParseDialectInput.parse(Api.scala:25)
	at scala.meta.parsers.Api$XtensionParseInputLike.parse(Api.scala:14)
	at com.olegych.scastie.instrumentation.Instrument$.apply(Instrument.scala:199)
	at com.olegych.scastie.instrumentation.InstrumentedInputs$.apply(InstrumentedInputs.scala:23)
	at com.olegych.scastie.sbt.SbtProcess$$anonfun$4.applyOrElse(SbtProcess.scala:191)
	at com.olegych.scastie.sbt.SbtProcess$$anonfun$4.applyOrElse(SbtProcess.scala:177)
	at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:35)
	at akka.actor.FSM.processEvent(FSM.scala:707)
	at akka.actor.FSM.processEvent$(FSM.scala:704)
	at com.olegych.scastie.sbt.SbtProcess.processEvent(SbtProcess.scala:64)
	at akka.actor.FSM.akka$actor$FSM$$processMsg(FSM.scala:701)
	at akka.actor.FSM$$anonfun$receive$1.applyOrElse(FSM.scala:695)
	at akka.actor.Actor.aroundReceive(Actor.scala:539)
	at akka.actor.Actor.aroundReceive$(Actor.scala:537)
	at com.olegych.scastie.sbt.SbtProcess.aroundReceive(SbtProcess.scala:64)
	at akka.actor.ActorCell.receiveMessage(ActorCell.scala:614)
	at akka.actor.ActorCell.invoke(ActorCell.scala:583)
	at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:268)
	at akka.dispatch.Mailbox.run(Mailbox.scala:229)
	at akka.dispatch.Mailbox.exec(Mailbox.scala:241)
	at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
	at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
	at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
	at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

At first I thought that it's a scalameta parser issue https://github.com/scalameta/scalameta/issues/2567. But the parser seems to work properly. It may just be a case of bumping scalameta or re-deploying latest version of scastie.

KacperFKorban avatar Jan 31 '22 10:01 KacperFKorban

Hello @KacperFKorban, thank you for reporting this. Let's try to bump scalameta to latest version (4.4.33 right?)

vincenzobaz avatar Jan 31 '22 12:01 vincenzobaz

I see that the new version is deployed, but it seems that the issue still occurs. https://scastie.scala-lang.org/KacperFKorban/X4ThnFU0RfyaPA0nZr3iLA

The stack trace definitely suggests that it's a scalameta bug though. Maybe the parser only fails when the code is wrapped in the scastie wrapper? What do you think @vincenzobaz?

KacperFKorban avatar Feb 02 '22 14:02 KacperFKorban

You might be right. https://github.com/vincenzobaz/scastie/runs/5048295570?check_suite_focus=true is running with your snippet and the new version of scalameta and, locally, it fails

vincenzobaz avatar Feb 03 '22 07:02 vincenzobaz

When scastie instruments

List(1,2,3).map { using i: Int => i }

it produces

import _root_.com.olegych.scastie.api.runtime._
object Playground extends ScastieApp {
List(1,2,3).map { using i: Int => i }
}

which is not accepted by scalameta:

vincenzobaz avatar Feb 03 '22 10:02 vincenzobaz

@vincenzobaz it's not accepted by scalac either, with or without instrumentation

OlegYch avatar Feb 03 '22 11:02 OlegYch

Interesting. You mean scalac in Scala 3?

vincenzobaz avatar Feb 03 '22 11:02 vincenzobaz

@OlegYch is right, something else must be wrong. Since I would expect an exception from scalameta.

KacperFKorban avatar Feb 03 '22 11:02 KacperFKorban

[error] 3 |  List(1,2,3).map { using i: Int => i }
[error]   |                                 ^
[error]   |parentheses are required around the parameter of a lambda
[error]   |This construct can be rewritten automatically under -rewrite -source 3.0-migration.
[error] 3 |  List(1,2,3).map { using i: Int => i }
[error]   |                    ^^^^^^^^^^^^
[error]   |                    not a legal formal parameter
[error] 3 |  List(1,2,3).map { using i: Int => i }
[error]   |                                    ^
[error]   |                                    Not found: i

vincenzobaz avatar Feb 03 '22 12:02 vincenzobaz