Skip to content

Type inference failure when dealing with generic method from Java #9543

Open
@scabug

Description

@scabug

When compiling a Scala project that uses UndoFX, the Scala compiler throws up an AssertionError. The library does work in a Java project, according to the project owner, so it does seem like a bug in the Scala compiler. The stack trace is as follows:

java.lang.AssertionError: assertion failed: TVar<?0=null>
	at scala.reflect.internal.Types$TypeVar.addLoBound(Types.scala:3013)
	at scala.reflect.internal.tpe.TypeConstraints$class.solveOne$1(TypeConstraints.scala:228)
	at scala.reflect.internal.tpe.TypeConstraints$class.scala$reflect$internal$tpe$TypeConstraints$class$$$anonfun$12(TypeConstraints.scala:260)
	at scala.reflect.internal.tpe.TypeConstraints$class.scala$reflect$internal$tpe$TypeConstraints$class$$$anonfun$12$adapted(TypeConstraints.scala:260)
	at scala.reflect.internal.tpe.TypeConstraints$class.solve(TypeConstraints.scala:260)
	at scala.reflect.internal.SymbolTable.solve(SymbolTable.scala:16)
	at scala.reflect.internal.Types$ExistentialType.withTypeVars(Types.scala:2737)
	at scala.reflect.internal.tpe.TypeComparers$class.thirdTry$1(TypeComparers.scala:483)
	at scala.reflect.internal.tpe.TypeComparers$class.secondTry$1(TypeComparers.scala:450)
	at scala.reflect.internal.tpe.TypeComparers$class.firstTry$1(TypeComparers.scala:426)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType2(TypeComparers.scala:552)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType1(TypeComparers.scala:320)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType(TypeComparers.scala:278)
	at scala.reflect.internal.SymbolTable.isSubType(SymbolTable.scala:16)
	at scala.reflect.internal.tpe.TypeComparers$class.isWeakSubType(TypeComparers.scala:575)
	at scala.reflect.internal.SymbolTable.isWeakSubType(SymbolTable.scala:16)
	at scala.reflect.internal.Types$Type.weak_$less$colon$less(Types.scala:832)
	at scala.tools.nsc.typechecker.Infer$Inferencer.isCompatible(Infer.scala:305)
	at scala.tools.nsc.typechecker.Infer$Inferencer.scala$tools$nsc$typechecker$Infer$Inferencer$$$anonfun$35(Infer.scala:545)
	at scala.tools.nsc.typechecker.Infer$Inferencer.scala$tools$nsc$typechecker$Infer$Inferencer$$$anonfun$35$adapted(Infer.scala:539)
	at scala.tools.nsc.typechecker.Infer$Inferencer.methTypeArgs(Infer.scala:539)
	at scala.tools.nsc.typechecker.Infer$Inferencer.scala$tools$nsc$typechecker$Infer$Inferencer$$$anonfun$50(Infer.scala:736)
	at scala.tools.nsc.typechecker.Infer$Inferencer.tryInstantiating$1(Infer.scala:734)
	at scala.tools.nsc.typechecker.Infer$Inferencer.typesCompatible$1(Infer.scala:746)
	at scala.tools.nsc.typechecker.Infer$Inferencer.isApplicableToMethod(Infer.scala:757)
	at scala.tools.nsc.typechecker.Infer$Inferencer.scala$tools$nsc$typechecker$Infer$Inferencer$$isApplicable(Infer.scala:776)
	at scala.tools.nsc.typechecker.Infer$Inferencer.scala$tools$nsc$typechecker$Infer$Inferencer$$$anonfun$52(Infer.scala:778)
	at scala.tools.nsc.typechecker.Infer$Inferencer.scala$tools$nsc$typechecker$Infer$Inferencer$$$anonfun$52$adapted(Infer.scala:778)
	at scala.reflect.internal.SymbolTable.createFromClonedSymbols(SymbolTable.scala:16)
	at scala.tools.nsc.typechecker.Infer$Inferencer.scala$tools$nsc$typechecker$Infer$Inferencer$$isApplicable(Infer.scala:778)
	at scala.tools.nsc.typechecker.Infer$Inferencer.applicableExpectingPt$1(Infer.scala:793)
	at scala.tools.nsc.typechecker.Infer$Inferencer.isApplicableSafe(Infer.scala:799)
	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$$anonfun$230(Typers.scala:3230)
	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$$anonfun$230$adapted(Typers.scala:3219)
	at scala.reflect.internal.Symbols$Symbol.filter(Symbols.scala:1928)
	at scala.tools.nsc.typechecker.Typers$Typer.preSelectOverloaded$1(Typers.scala:3219)
	at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3246)
	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$$anonfun$321(Typers.scala:4485)
	at scala.tools.nsc.typechecker.Typers$Typer.silent(Typers.scala:684)
	at scala.tools.nsc.typechecker.Typers$Typer.tryTypedApply$1(Typers.scala:4485)
	at scala.tools.nsc.typechecker.Typers$Typer.normalTypedApply$1(Typers.scala:4533)
	at scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:4569)
	at scala.tools.nsc.typechecker.Typers$Typer.typedInAnyMode$1(Typers.scala:5332)
	at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5349)
	at scala.tools.nsc.typechecker.Typers$Typer.runTyper$1(Typers.scala:5385)
	at scala.tools.nsc.typechecker.Typers$Typer.typedInternal(Typers.scala:5412)
	at scala.tools.nsc.typechecker.Typers$Typer.body$2(Typers.scala:5359)
	at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5363)
	at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5452)
	at scala.tools.nsc.typechecker.Typers$Typer.computeType(Typers.scala:5543)
	at scala.tools.nsc.typechecker.Namers$Namer.assignTypeToTree(Namers.scala:873)
	at scala.tools.nsc.typechecker.Namers$Namer.valDefSig(Namers.scala:1375)
	at scala.tools.nsc.typechecker.Namers$Namer.getSig$1(Namers.scala:1526)
	at scala.tools.nsc.typechecker.Namers$Namer.typeSig(Namers.scala:1535)
	at scala.tools.nsc.typechecker.Namers$Namer.scala$tools$nsc$typechecker$Namers$Namer$$$anonfun$39(Namers.scala:775)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
	at scala.tools.nsc.typechecker.Namers$Namer.scala$tools$nsc$typechecker$Namers$Namer$$$anonfun$38(Namers.scala:1562)
	at scala.tools.nsc.typechecker.Namers$Namer.scala$tools$nsc$typechecker$Namers$Namer$$$anonfun$38$adapted(Namers.scala:766)
	at scala.tools.nsc.typechecker.Namers$$anon$1.completeImpl(Namers.scala:1678)
	at scala.tools.nsc.typechecker.Namers$LockingTypeCompleter$class.complete(Namers.scala:1686)
	at scala.tools.nsc.typechecker.Namers$$anon$1.complete(Namers.scala:1676)
	at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1513)
	at scala.reflect.internal.Symbols$Symbol.initialize(Symbols.scala:1658)
	at scala.tools.nsc.typechecker.MethodSynthesis$MethodSynth$class.addDerivedTrees(MethodSynthesis.scala:182)
	at scala.tools.nsc.typechecker.Namers$Namer.addDerivedTrees(Namers.scala:54)
	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$$anonfun$107(Typers.scala:1897)
	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$$anonfun$101(Typers.scala:1834)
	at scala.collection.immutable.List.flatMap(List.scala:324)
	at scala.tools.nsc.typechecker.Typers$Typer.typedTemplate(Typers.scala:1897)
	at scala.tools.nsc.typechecker.Typers$Typer.typedModuleDef(Typers.scala:1798)
	at scala.tools.nsc.typechecker.Typers$Typer.typedMemberDef$1(Typers.scala:5299)
	at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5348)
	at scala.tools.nsc.typechecker.Typers$Typer.runTyper$1(Typers.scala:5385)
	at scala.tools.nsc.typechecker.Typers$Typer.typedInternal(Typers.scala:5412)
	at scala.tools.nsc.typechecker.Typers$Typer.body$2(Typers.scala:5359)
	at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5363)
	at scala.tools.nsc.typechecker.Typers$Typer.typedByValueExpr(Typers.scala:5441)
	at scala.tools.nsc.typechecker.Typers$Typer.typedStat$1(Typers.scala:3036)
	at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$$anonfun$219(Typers.scala:3140)
	at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:3140)
	at scala.tools.nsc.typechecker.Typers$Typer.typedPackageDef$1(Typers.scala:5004)
	at scala.tools.nsc.typechecker.Typers$Typer.typedMemberDef$1(Typers.scala:5301)
	at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5348)
	at scala.tools.nsc.typechecker.Typers$Typer.runTyper$1(Typers.scala:5385)
	at scala.tools.nsc.typechecker.Typers$Typer.typedInternal(Typers.scala:5412)
	at scala.tools.nsc.typechecker.Typers$Typer.body$2(Typers.scala:5359)
	at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5363)
	at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5437)
	at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.apply(Analyzer.scala:102)
	at scala.tools.nsc.Global$GlobalPhase.scala$tools$nsc$Global$GlobalPhase$$$anonfun$11(Global.scala:440)
	at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:431)
	at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.scala$tools$nsc$typechecker$Analyzer$typerFactory$$anon$3$$$anonfun$1(Analyzer.scala:94)
	at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.scala$tools$nsc$typechecker$Analyzer$typerFactory$$anon$3$$$anonfun$1$adapted(Analyzer.scala:93)
	at scala.collection.AbstractIterator.foreach(Iterator.scala:1370)
	at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.run(Analyzer.scala:93)
	at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1505)
	at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1490)
	at scala.tools.nsc.Global$Run.compileSources(Global.scala:1485)
	at scala.tools.nsc.Global$Run.compile(Global.scala:1586)
	at xsbt.CachedCompiler0.run(CompilerInterface.scala:116)
	at xsbt.CachedCompiler0.run(CompilerInterface.scala:95)
	at xsbt.CompilerInterface.run(CompilerInterface.scala:26)
	at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:101)
	at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:47)
	at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
	at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply$mcV$sp(AggressiveCompile.scala:97)
	at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:97)
	at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:97)
	at sbt.compiler.AggressiveCompile.sbt$compiler$AggressiveCompile$$timed(AggressiveCompile.scala:162)
	at sbt.compiler.AggressiveCompile$$anonfun$3.compileScala$1(AggressiveCompile.scala:96)
	at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:139)
	at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:86)
	at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:38)
	at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:36)
	at sbt.inc.IncrementalCommon.cycle(IncrementalCommon.scala:31)
	at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:39)
	at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:38)
	at sbt.inc.Incremental$.manageClassfiles(Incremental.scala:66)
	at sbt.inc.Incremental$.compile(Incremental.scala:38)
	at sbt.inc.IncrementalCompile$.apply(Compile.scala:26)
	at sbt.compiler.AggressiveCompile.compile2(AggressiveCompile.scala:153)
	at sbt.compiler.AggressiveCompile.compile1(AggressiveCompile.scala:70)
	at com.typesafe.zinc.Compiler.compile(Compiler.scala:201)
	at com.typesafe.zinc.Compiler.compile(Compiler.scala:183)
	at com.typesafe.zinc.Compiler.compile(Compiler.scala:174)
	at com.typesafe.zinc.Compiler.compile(Compiler.scala:165)
	at org.gradle.api.internal.tasks.scala.ZincScalaCompiler$Compiler.execute(ZincScalaCompiler.java:69)
	at org.gradle.api.internal.tasks.scala.ZincScalaCompiler.execute(ZincScalaCompiler.java:48)
	at org.gradle.api.internal.tasks.scala.ZincScalaCompiler.execute(ZincScalaCompiler.java:37)
	at org.gradle.api.internal.tasks.compile.daemon.CompilerDaemonServer.execute(CompilerDaemonServer.java:53)
	at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
	at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
	... 2 more

The code that throws up this error is

import java.util.function.{Consumer, Function => JFunction}

import org.fxmisc.undo.UndoManagerFactory
import org.reactfx.EventSource

object Main {
  val changes = new EventSource[Change]

  val undoManager = UndoManagerFactory.unlimitedHistoryUndoManager(
  changes,
  new JFunction[Change, Change] {
    override def apply(t: Change): Change = t.invert
  },
  new Consumer[Change] {
    override def accept(t: Change): Unit = t.apply()
  }
  )

}

case class Change(oldVal: Boolean, newVal: Boolean) {
  def invert: Change = Change(newVal, oldVal)

  def apply(): Unit = println(newVal)
}

There seems to be an issue with the type checker when dealing with the Java Function class, at least from what I can glean from that stack trace.

I've attached a minimal example project built with Gradle, containing the above code, that exhibits the error.

I've also reported this problem to the project owner here: FXMisc/UndoFX#6, and he suggested that a bug be filed against the Scala compiler.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions