Skip to content
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

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

Open
scabug opened this issue Oct 31, 2015 · 3 comments
Open

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

scabug opened this issue Oct 31, 2015 · 3 comments

Comments

@scabug
Copy link

scabug commented Oct 31, 2015

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.

@scabug
Copy link
Author

scabug commented Oct 31, 2015

Imported From: https://issues.scala-lang.org/browse/SI-9543?orig=1
Reporter: Benedict Lee (benedictleejh)
Affected Versions: 2.11.7, 2.12.0-M3
Attachments:

@scabug
Copy link
Author

scabug commented Nov 5, 2015

Benedict Lee (benedictleejh) said:
Attached project had some minor errors in build.gradle

@scabug
Copy link
Author

scabug commented Nov 5, 2015

Benedict Lee (benedictleejh) said (edited on Nov 5, 2015 3:21:09 AM UTC):
Inspired by noticing that when using Java methods that take functions as parameters needing type parameters in Scala (from http://scala-language.1934581.n4.nabble.com/Sammy-wildcards-type-inference-td4641501.html), it seems that changing this line:

val undoManager = UndoManagerFactory.unlimitedHistoryUndoManager(

to

val undoManager = UndoManagerFactory.unlimitedHistoryUndoManager[Change](

allows the compiler to compile the project. The problem is then that the Scala compiler is unable to infer the type C for the signature

public static <C> UndoManager unlimitedHistoryUndoManager(
            EventStream<C> changeStream,
            Function<? super C, ? extends C> invert,
            Consumer<C> apply)

from the parameters given to the method.

Note that if this was

public static <C> UndoManager unlimitedHistoryUndoManager(
            EventStream<C> changeStream,
            Consumer<C> invert,
            Consumer<C> apply)

inference works perfectly.

On a somewhat related note, both 2.11.7 and 2.12.0-M3 are unable to apply SAM conversion to functions given to that method signature, and in fact, does not even seem to attempt to apply an SAM conversion. If this is not a known issue, should I file an issue for it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant