Skip to content

ArrayIndexOutOfBoundsException while unpickling quote #5161

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

Closed
nicolasstucki opened this issue Sep 25, 2018 · 6 comments · Fixed by #6700
Closed

ArrayIndexOutOfBoundsException while unpickling quote #5161

nicolasstucki opened this issue Sep 25, 2018 · 6 comments · Fixed by #6700

Comments

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Sep 25, 2018

import scala.quoted._

object Test {
  implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make
  enum Exp {
    case Int2(x: Int)
    case Add(e1: Exp, e2: Exp)
  }
  import Exp._

  def evalTest(e: Exp): Expr[Option[Int]] = e match {
    case Int2(x) => '(Some(~x.toExpr))
    case Add(e1, e2) =>
      '{
        (~evalTest(e1), ~evalTest(e2)) match {
          case (Some(x), Some(y)) => Some(x+y)
          case _ => None
        }
      }
    case null => '(None)
  }


  def main(args: Array[String]): Unit = {
    val test = Add(Int2(1), Int2(1))
    val res = evalTest(test)
    println("run : " + res.run)
    println("show : " + res.show)
  }
}

fails at runtime with

run : Some(2)
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 39
	at dotty.tools.dotc.core.Periods.hasSameBaseTypesAs(Periods.scala:48)
	at dotty.tools.dotc.core.SymDenotations$ClassDenotation.baseTypeCache(SymDenotations.scala:1326)
	at dotty.tools.dotc.core.SymDenotations$ClassDenotation.baseTypeOf(SymDenotations.scala:1632)
	at dotty.tools.dotc.core.Types$Type.baseType(Types.scala:901)
	at dotty.tools.dotc.core.TypeComparer.tryBaseType$1(TypeComparer.scala:612)
	at dotty.tools.dotc.core.TypeComparer.compareAppliedType2$1(TypeComparer.scala:853)
	at dotty.tools.dotc.core.TypeComparer.thirdTry$1(TypeComparer.scala:426)
	at dotty.tools.dotc.core.TypeComparer.secondTry$1(TypeComparer.scala:317)
	at dotty.tools.dotc.core.TypeComparer.firstTry$1(TypeComparer.scala:305)
	at dotty.tools.dotc.core.TypeComparer.recur(TypeComparer.scala:936)
	at dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:130)
	at dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:137)
	at dotty.tools.dotc.core.ConstraintHandling.isSubTypeWhenFrozen(ConstraintHandling.scala:187)
	at dotty.tools.dotc.core.ConstraintHandling.isSubType(ConstraintHandling.scala:170)
	at dotty.tools.dotc.core.TypeComparer.mergeIfSuper(TypeComparer.scala:1523)
	at dotty.tools.dotc.core.TypeComparer.lub(TypeComparer.scala:1404)
	at dotty.tools.dotc.core.TypeComparer.lub$$anonfun$1(TypeComparer.scala:1421)
	at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:122)
	at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:118)
	at scala.collection.immutable.List.foldLeft(List.scala:86)
	at scala.collection.TraversableOnce.$div$colon(TraversableOnce.scala:151)
	at scala.collection.TraversableOnce.$div$colon$(TraversableOnce.scala:151)
	at scala.collection.AbstractTraversable.$div$colon(Traversable.scala:104)
	at dotty.tools.dotc.core.TypeComparer.lub(TypeComparer.scala:1421)
	at dotty.tools.dotc.typer.TypeAssigner.assignType(TypeAssigner.scala:481)
	at dotty.tools.dotc.ast.tpd$.Match(tpd.scala:121)
	at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthTerm$1(TreeUnpickler.scala:1078)
	at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTerm(TreeUnpickler.scala:1156)
	at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readBlock$1(TreeUnpickler.scala:1045)
	at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthTerm$1(TreeUnpickler.scala:1067)
	at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTerm(TreeUnpickler.scala:1156)
	at dotty.tools.dotc.core.tasty.TreeUnpickler.unpickle(TreeUnpickler.scala:100)
	at dotty.tools.dotc.core.tasty.DottyUnpickler.computeTrees(DottyUnpickler.scala:64)
	at dotty.tools.dotc.ast.tpd$TreeProvider.trees(tpd.scala:960)
	at dotty.tools.dotc.ast.tpd$TreeProvider.tree(tpd.scala:964)
	at dotty.tools.dotc.core.quoted.PickledQuotes$.unpickle(PickledQuotes.scala:113)
	at dotty.tools.dotc.core.quoted.PickledQuotes$.unpickleExpr(PickledQuotes.scala:70)
	at dotty.tools.dotc.core.quoted.PickledQuotes$.quotedExprToTree(PickledQuotes.scala:44)
	...
@nicolasstucki
Copy link
Contributor Author

nicolasstucki commented Sep 25, 2018

It can be minimized to

import scala.quoted._

object Test {
  implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make

  def main(args: Array[String]): Unit = {
    val res = '{
      val x: Option[Int] = Option(3)
      if (x.isInstanceOf[Some[_]]) Option(1)
      else None
    }
    println("show0 : " + res.show)
    println("run1 : " + res.run)
    println("run2 : " + res.run)
    println("show3 : " + res.show)
  }
}

and fails with

show0 : {
  val x: scala.Option[scala.Int] = scala.Option.apply[scala.Int](3)
  if (x.isInstanceOf[scala.Some[_ >: scala.Nothing <: scala.Any]]) scala.Option.apply[scala.Int](1) else scala.None
}
run1 : Some(1)
run2 : Some(1)
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 39
	at dotty.tools.dotc.core.Periods.hasSameBaseTypesAs(Periods.scala:48)
	at dotty.tools.dotc.core.SymDenotations$ClassDenotation.baseTypeCache(SymDenotations.scala:1326)
	at dotty.tools.dotc.core.SymDenotations$ClassDenotation.baseTypeOf(SymDenotations.scala:1632)
	at dotty.tools.dotc.core.Types$Type.baseType(Types.scala:901)
	at dotty.tools.dotc.core.TypeComparer.tryBaseType$1(TypeComparer.scala:612)
	at dotty.tools.dotc.core.TypeComparer.compareAppliedType2$1(TypeComparer.scala:853)
	at dotty.tools.dotc.core.TypeComparer.thirdTry$1(TypeComparer.scala:426)
	at dotty.tools.dotc.core.TypeComparer.secondTry$1(TypeComparer.scala:317)
	at dotty.tools.dotc.core.TypeComparer.firstTry$1(TypeComparer.scala:305)
	at dotty.tools.dotc.core.TypeComparer.recur(TypeComparer.scala:936)
	at dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:130)
	at dotty.tools.dotc.core.TypeComparer.isSubType(TypeComparer.scala:137)
	at dotty.tools.dotc.core.ConstraintHandling.isSubTypeWhenFrozen(ConstraintHandling.scala:187)
	at dotty.tools.dotc.core.ConstraintHandling.isSubType(ConstraintHandling.scala:170)
	at dotty.tools.dotc.core.TypeComparer.mergeIfSuper(TypeComparer.scala:1523)
	at dotty.tools.dotc.core.TypeComparer.lub(TypeComparer.scala:1404)
	at dotty.tools.dotc.core.Types$Type.$bar(Types.scala:936)
	at dotty.tools.dotc.typer.TypeAssigner.assignType(TypeAssigner.scala:456)
	at dotty.tools.dotc.ast.tpd$.If(tpd.scala:85)
	at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthTerm$1(TreeUnpickler.scala:1072)
	...

It only fail if we execute a show after a run for this particular code.

@nicolasstucki
Copy link
Contributor Author

The issue can be workaround by upcasting the branches manually

if (x.isInstanceOf[Some[_]]) Option(1)
else (None: Option[Int])

@biboudis
Copy link
Contributor

Are you on top off this issue @nicolasstucki or is it up for grabs?

@nicolasstucki nicolasstucki removed their assignment Sep 26, 2018
@nicolasstucki
Copy link
Contributor Author

You can take it if you want

@biboudis biboudis self-assigned this Sep 26, 2018
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Dec 17, 2018
Changes:
* Make quotes eager: fixes scala#5376 (requires context)
* Fix bugs shown in scala#5429: Tree from the macro parameters is passed to another compiler to show it.
* Protect against scope extrusion with early (meaningful) runtime failure (rather than in the compiler)
* Add an implicit function type to provide context.
* Fixes scala#5161
@nicolasstucki
Copy link
Contributor Author

#5297 fixes this issue

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Dec 17, 2018
Changes:
* Make quotes eager: fixes scala#5376 (requires context)
* Fix bugs shown in scala#5429: Tree from the macro parameters is passed to another compiler to show it.
* Protect against scope extrusion with early (meaningful) runtime failure (rather than in the compiler)
* Add an implicit function type to provide context.
* Fixes scala#5161
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Dec 18, 2018
Changes:
* Make quotes eager: fixes scala#5376 (requires context)
* Fix bugs shown in scala#5429: Tree from the macro parameters is passed to another compiler to show it.
* Protect against scope extrusion with early (meaningful) runtime failure (rather than in the compiler)
* Add an implicit function type to provide context.
* Fixes scala#5161
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Jan 7, 2019
Changes:
* Make quotes eager: fixes scala#5376 (requires context)
* Fix bugs shown in scala#5429: Tree from the macro parameters is passed to another compiler to show it.
* Protect against scope extrusion with early (meaningful) runtime failure (rather than in the compiler)
* Add an implicit function type to provide context.
* Fixes scala#5161
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Jan 7, 2019
Changes:
* Make quotes eager: fixes scala#5376 (requires context)
* Fix bugs shown in scala#5429: Tree from the macro parameters is passed to another compiler to show it.
* Protect against scope extrusion with early (meaningful) runtime failure (rather than in the compiler)
* Add an implicit function type to provide context.
* Fixes scala#5161
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Jan 8, 2019
Changes:
* Make quotes eager: fixes scala#5376 (requires context)
* Fix bugs shown in scala#5429: Tree from the macro parameters is passed to another compiler to show it.
* Protect against scope extrusion with early (meaningful) runtime failure (rather than in the compiler)
* Add an implicit function type to provide context.
* Fixes scala#5161
@nicolasstucki
Copy link
Contributor Author

The source of this error is that we create some trees in one compiler instance and use them in another. There the symbols will not coincide and hell breaks loose. #5297 fixes this by making sure the compiler instance that handles everything is in contextual scope.

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Apr 5, 2019
Changes:
* Make quotes eager: fixes scala#5376 (requires context)
* Fix bugs shown in scala#5429: Tree from the macro parameters is passed to another compiler to show it.
* Protect against scope extrusion with early (meaningful) runtime failure (rather than in the compiler)
* Add an implicit function type to provide context.
* Fixes scala#5161
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Apr 17, 2019
anatoliykmetyuk pushed a commit to dotty-staging/dotty that referenced this issue Apr 23, 2019
anatoliykmetyuk pushed a commit to dotty-staging/dotty that referenced this issue May 2, 2019
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue May 7, 2019
Changes:
* Make quotes eager: fixes scala#5376 (requires context)
* Fix bugs shown in scala#5429: Tree from the macro parameters is passed to another compiler to show it.
* Protect against scope extrusion with early (meaningful) runtime failure (rather than in the compiler)
* Add an implicit function type to provide context.
* Fixes scala#5161
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Jun 20, 2019
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Jun 20, 2019
The main idea is to correctly keep track of the current compiler. This is paramount to support correctly `show` and quote patterns. This PR only contains the addition of the `QuoteContext` to the `run` but not the top level `$` (which will come in a second step).

* Add `QuoteContext`
* Define a single `Expr.show` entry point in `QuoteContext`(for `expr.show`)
* Define `show(expr)` which is an alias of `run(expr.show.toExpr)` that provides a `QuoteContext`
* Remove coloring options from the `Reflection.Context` and `Toolbox` settings (`show` never has colors unless a coloring format is given)
* Replace `TreeCleaner` with `@quoteTypeTag` and logic in the printers
* Fix scala#5161
* Regression local definitions are not renamed in quotes (postponed for future PR). See tests/run-with-compiler/quote-run-2.check.
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Jun 21, 2019
The main idea is to correctly keep track of the current compiler. This is paramount to support correctly `show` and quote patterns. This PR only contains the addition of the `QuoteContext` to the `run` but not the top level `$` (which will come in a second step).

* Add `QuoteContext`
* Define a single `Expr.show` entry point in `QuoteContext`(for `expr.show`)
* Define `show(expr)` which is an alias of `run(expr.show.toExpr)` that provides a `QuoteContext`
* Remove coloring options from the `Reflection.Context` and `Toolbox` settings (`show` never has colors unless a coloring format is given)
* Replace `TreeCleaner` with `@quoteTypeTag` and logic in the printers
* Fix scala#5161
* Regression local definitions are not renamed in quotes (postponed for future PR). See tests/run-with-compiler/quote-run-2.check.
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Jun 27, 2019
The main idea is to correctly keep track of the current compiler. This is paramount to support correctly `show` and quote patterns. This PR only contains the addition of the `QuoteContext` to the `run` but not the top level `$` (which will come in a second step).

* Add `QuoteContext`
* Define a single `Expr.show` entry point in `QuoteContext`(for `expr.show`)
* Define `show(expr)` which is an alias of `run(expr.show.toExpr)` that provides a `QuoteContext`
* Remove coloring options from the `Reflection.Context` and `Toolbox` settings (`show` never has colors unless a coloring format is given)
* Replace `TreeCleaner` with `@quoteTypeTag` and logic in the printers
* Fix scala#5161
* Regression local definitions are not renamed in quotes (postponed for future PR). See tests/run-with-compiler/quote-run-2.check.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants