Skip to content

Stack overflow error on compile #8357

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
gzoller opened this issue Feb 22, 2020 · 6 comments · Fixed by #8482
Closed

Stack overflow error on compile #8357

gzoller opened this issue Feb 22, 2020 · 6 comments · Fixed by #8482
Assignees

Comments

@gzoller
Copy link
Contributor

gzoller commented Feb 22, 2020

Issue description

Something I changed in my code now causes a StackOverflowError on compile.
Dotty: 0.23.0-bin-20200220-228e593-NIGHTLY
Code: https://github.com/gzoller/dotty_reflection/tree/broken

Should be noted that I'm not using any macro/metaprogramming in the code (that I'm aware of)

I'm using a custom build of scalameta munit, but you don't need test code to reproduce this issue--you can safely comment out this dependency in build.sbt.

I've been trying to narrow down what I changed to cause it to do this, but thus far haven't found a culprit. Will continue narrowing and post any learnings on this bug report.

Steps

  1. Download repo
  2. sbt compile

Crash output (click arrow to expand)

[error] ## Exception when compiling 14 sources to /Users/wmy965/git/dotty_reflection/target/scala-0.23/classes
[error] java.lang.StackOverflowError
[error] java.base/java.util.WeakHashMap.getTable(WeakHashMap.java:350)
[error] java.base/java.util.WeakHashMap.put(WeakHashMap.java:451)
[error] dotty.tools.dotc.core.SymDenotations$InheritedCacheImpl.addDependent(SymDenotations.scala:2436)
[error] dotty.tools.dotc.core.SymDenotations$BaseDataImpl.apply(SymDenotations.scala:2526)
[error] dotty.tools.dotc.core.SymDenotations$ClassDenotation.baseData(SymDenotations.scala:1673)
[error] dotty.tools.dotc.core.SymDenotations$ClassDenotation.baseClassSet(SymDenotations.scala:1684)
[error] dotty.tools.dotc.core.SymDenotations$ClassDenotation.derivesFrom(SymDenotations.scala:1709)
[error] dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2261)
[error] dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2333)
[error] dotty.tools.dotc.core.TypeComparer.provablyDisjoint$$anonfun$1(TypeComparer.scala:2274)
[error] scala.collection.immutable.List.forall(List.scala:358)
[error] dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2274)
[error] dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2333)
[error] dotty.tools.dotc.core.TypeComparer.provablyDisjoint$$anonfun$1(TypeComparer.scala:2274)
[error] scala.collection.immutable.List.forall(List.scala:358)
(repeats)
@gzoller
Copy link
Contributor Author

gzoller commented Feb 22, 2020

Timing is everything--just found the change that crashes the compiler.

  1. In UnionInfo.scala, in object UnionKind, comment out case t: UnionContainer if t.hasUnion => true

Then it compiles fine.

@gzoller
Copy link
Contributor Author

gzoller commented Feb 22, 2020

More learnings... code for context:

object UnionKind:
  def unapply(f: FieldInfo): Boolean = 
    f.fieldType match {
      case _: StaticUnionInfo => true
      case t: AliasInfo if t.isUnion =>  true
      case t: UnionContainer if t.hasUnion => true  // this line here causes crash
      case _ => false
    }

I discovered that if I move the problematic UnionContainer line to the first position, it compiles fine:

object UnionKind:
  def unapply(f: FieldInfo): Boolean = 
    f.fieldType match {
      case t: UnionContainer if t.hasUnion => true  // same line moved here works
      case _: StaticUnionInfo => true
      case t: AliasInfo if t.isUnion =>  true
      case _ => false
    }

@odersky
Copy link
Contributor

odersky commented Mar 1, 2020

It would be helpful to minimize this further. The fact that the stack overflow happens in provablyDisjoint means it's related to pattern matching exhaustivity checking.

Also, did you try to increase the JVM stack size with -Xss? Just to make sure it's a true overflow and not just a very deep recursion.

@gzoller
Copy link
Contributor Author

gzoller commented Mar 2, 2020

I bumped -Xss to 5M and can confirm I still got the overflow error.

@anatoliykmetyuk anatoliykmetyuk added the stat:needs minimization Needs a self contained minimization label Mar 3, 2020
@liufengyun
Copy link
Contributor

@gzoller I tried to minimize from your repo, it's almost done. However, I couldn't find the definition for UnionContainer anywhere. Could you please provide its definition?

trait FieldInfo {
  val fieldType: ALL_TYPE
}

opaque type TypeSymbol = String

trait ConcreteType {
  val name: String
  val typeParameters: List[TypeSymbol]
}

type ALL_TYPE = ConcreteType | TypeSymbol

case class StaticUnionInfo(name: String, typeParameters: List[TypeSymbol]) extends ConcreteType
case class AliasInfo(name: String, typeParameters: List[TypeSymbol]) extends ConcreteType

object UnionKind {
  def unapply(f: FieldInfo): Boolean =
    f.fieldType match {
      case _: StaticUnionInfo => true
      case t: AliasInfo if t.isUnion =>  true
      case t: UnionContainer if t.hasUnion => true  // this line here causes crash
      case _ => false
    }
}

@gzoller
Copy link
Contributor Author

gzoller commented Mar 4, 2020

It's in ReflectedThing.scala:

trait UnionContainer:
  val hasUnion: Boolean

liufengyun added a commit to dotty-staging/dotty that referenced this issue Mar 9, 2020
nicolasstucki added a commit that referenced this issue Mar 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants