sbt / sbt

sbt, the interactive build tool
https://scala-sbt.org
Apache License 2.0
4.79k stars 931 forks source link

complex refinement types can lead to hang in OutOfMemoryError during extraction #889

Open retronym opened 10 years ago

retronym commented 10 years ago

As reported: https://groups.google.com/d/msg/scala-user/gPYnBOu4_Jo/c0zzbwV7j8QJ

 tail build.sbt test.scala
==> build.sbt <==
scalaVersion := "2.10.2"

==> test.scala <==
    type Val <: ILam[E, Val] with E;
    type Let <: ILetLam[E, Val, Let] with E
  }](bs: Map[Idn, E]) extends LetInWaiter[E] {
  def in(e: E): E = ???
}
trait Idn

trait LetInWaiter[E]
trait LazyExp[A]
trait ILetLam[A, B, C]

sbt
[info] Loading project definition from /Users/jason/code/scratch4/project
[info] Updating {file:/Users/jason/code/scratch4/project/}scratch4-build...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Set current project to scratch4 (in build file:/Users/jason/code/scratch4/)
> sbtVersion
[info] 0.13.0
> compile
[info] Compiling 1 Scala source to /Users/jason/code/scratch4/target/scala-2.10/classes...
[warn] /Users/jason/code/scratch4/test.scala:4: sbt-api: approximated refinement refLazyExp[E]{type Val <: ILam[E,this.Val] with E; type Let <: ILetLam[E,this.Val,this.Let] with E} (== LazyExp[E]{type Val <: ILam[E,this.Val] with E; type Let <: ILetLam[E,this.Val,this.Let] with E}) to LazyExp[E]{type Val <: ILam[E,<notype>#Val] with E; type Let <: ILetLam[E,<notype>#Val,<notype>#Let] with E}
[warn] This is currently untested, please report the code you were compiling.
[warn]   E <: LazyExp[E]{
[warn]        ^
...
[error] uncaught exception during compilation: java.lang.OutOfMemoryError
[error] java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: Java heap space
[error] Use 'last' for the full log.
% jstack 37014
"pool-4-thread-5" prio=5 tid=7fb649171000 nid=0x1270a2000 runnable [12709e000]
   java.lang.Thread.State: RUNNABLE
    at scala.collection.GenTraversable$class.$init$(GenTraversable.scala:25)
    at scala.collection.AbstractTraversable.<init>(Traversable.scala:105)
    at scala.collection.AbstractIterable.<init>(Iterable.scala:54)
    at scala.collection.AbstractSeq.<init>(Seq.scala:40)
    at scala.collection.mutable.AbstractSeq.<init>(Seq.scala:47)
    at scala.collection.mutable.StringBuilder.<init>(StringBuilder.scala:28)
    at scala.collection.mutable.StringBuilder.<init>(StringBuilder.scala:46)
    at scala.collection.mutable.StringBuilder.<init>(StringBuilder.scala:51)
    at scala.reflect.internal.Symbols$Symbol.defStringCompose(Symbols.scala:2391)
    at scala.reflect.internal.Symbols$Symbol.defString(Symbols.scala:2396)
    at scala.reflect.internal.Scopes$Scope$$anonfun$mkString$1.apply(Scopes.scala:324)
    at scala.reflect.internal.Scopes$Scope$$anonfun$mkString$1.apply(Scopes.scala:324)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.AbstractTraversable.map(Traversable.scala:105)
    at scala.reflect.internal.Scopes$Scope.mkString(Scopes.scala:324)
    at scala.reflect.internal.Types$CompoundType.safeToString(Types.scala:1662)
    at scala.reflect.internal.Types$class.typeToString(Types.scala:7346)
    at scala.reflect.internal.SymbolTable.typeToString(SymbolTable.scala:13)
    at scala.reflect.internal.Types$Type.toString(Types.scala:1018)
    at java.lang.String.valueOf(String.java:2826)
    at scala.reflect.internal.Types$RefinementTypeRef.finishPrefix(Types.scala:2126)
    at scala.reflect.internal.Types$TypeRef.safeToString(Types.scala:2506)
    at scala.reflect.internal.Types$class.typeToString(Types.scala:7346)
    at scala.reflect.internal.SymbolTable.typeToString(SymbolTable.scala:13)
    at scala.reflect.internal.Types$Type.toString(Types.scala:1018)
    at java.lang.String.valueOf(String.java:2826)
    at scala.collection.mutable.StringBuilder.append(StringBuilder.scala:197)
    at xsbt.ExtractAPI.xsbt$ExtractAPI$$makeType(ExtractAPI.scala:334)
    at xsbt.ExtractAPI$$anonfun$xsbt$ExtractAPI$$processType$1.apply(ExtractAPI.scala:293)
    at xsbt.ExtractAPI$$anonfun$xsbt$ExtractAPI$$processType$1.apply(ExtractAPI.scala:293)
    at scala.collection.mutable.MapLike$class.getOrElseUpdate(MapLike.scala:189)
    at scala.collection.mutable.AbstractMap.getOrElseUpdate(Map.scala:91)
    at xsbt.ExtractAPI.xsbt$ExtractAPI$$processType(ExtractAPI.scala:293)
    at xsbt.ExtractAPI$$anonfun$xsbt$ExtractAPI$$types$1.apply(ExtractAPI.scala:83)
    at xsbt.ExtractAPI$$anonfun$xsbt$ExtractAPI$$types$1.apply(ExtractAPI.scala:83)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:108)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:108)
    at xsbt.ExtractAPI.xsbt$ExtractAPI$$types(ExtractAPI.scala:83)
retronym commented 10 years ago

A workaround:

trait ILam[A, B]

object O {
  type T[E] = LazyExp[E]{
    type Val <: ILam[E, Val] with E;
    type Let <: ILetLam[E, Val, Let] with E
  }
}

final class LetInWaiterLam[
  E <: O.T[E]](bs: Map[Idn, E]) extends LetInWaiter[E] {
  def in(e: E): E = ???
}
trait Idn

trait LetInWaiter[E]
trait LazyExp[A]
trait ILetLam[A, B, C]
harrah commented 10 years ago

Related to #715 and possibly caused by #611, which was a fix for #610.