ceylon icon indicating copy to clipboard operation
ceylon copied to clipboard

Backend error in Java functional-interface interop

Open kingjon3377 opened this issue 7 years ago • 1 comments

While the compiler usually accepts Ceylon Callables with a matching signature when a Java method wants an object satisfying a functional (only-one-abstract-method) interface, whether it's a reference to a local method or a parameter (or field) of type Callable, I've stumbled on one interface that triggers a backend error: java.awt.image::ImageObserver. As the following error-inducing code shows, passing a direct method reference where the method wants an ImageObserver compiles fine, but if that method reference is stored in a field or parameter of type Boolean(Image, Integer, Integer, Integer, Integer, Integer), this causes a backend error; it also produces a CompilerBugException stacktrace when compiling on the command line, and a RuntimeException "Error generating bytecode" with a stacktrace in the Eclipse IDE.

import java.awt {
	Image,
	Graphics
}
class SwingSMI(Boolean(Image, Integer, Integer, Integer, Integer, Integer) observer) {
	Boolean observerImpl(Image img, Integer one, Integer two, Integer three, Integer four, Integer five)
			=> false;
	Boolean(Image, Integer, Integer, Integer, Integer, Integer) reference = observerImpl;
	shared void draw(Graphics pen, Image image) {
		pen.drawImage(image, 0, 0, 0, 0, observerImpl); // works
		// Next line: additionally: error: Ceylon backend error: method invoked with incorrect number of arguments; expected 6, found 0
		pen.drawImage(image, 0, 0, 0, 0, reference); // Ceylon backend error: cannot find symbol // symbol: variable getReference$priv$
		pen.drawImage(image, 0, 0, 0, 0, observer); // Ceylon backend error: cannot find symbol // symbol: variable getObserver$priv$
	}
}

The stack trace on the command line:

com.redhat.ceylon.compiler.CompilerBugException: Codegen Error
	at com.redhat.ceylon.compiler.CeylonCompileTool.handleExitCode(CeylonCompileTool.java:933)
	at com.redhat.ceylon.compiler.CeylonCompileTool.run(CeylonCompileTool.java:915)
	at com.redhat.ceylon.common.tools.CeylonTool.run(CeylonTool.java:547)
	at com.redhat.ceylon.common.tools.CeylonTool.execute(CeylonTool.java:423)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.redhat.ceylon.launcher.Launcher.runInJava7Checked(Launcher.java:108)
	at com.redhat.ceylon.launcher.Launcher.run(Launcher.java:38)
	at com.redhat.ceylon.launcher.Launcher.run(Launcher.java:31)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.redhat.ceylon.launcher.Bootstrap.runVersion(Bootstrap.java:162)
	at com.redhat.ceylon.launcher.Bootstrap.runInternal(Bootstrap.java:117)
	at com.redhat.ceylon.launcher.Bootstrap.run(Bootstrap.java:93)
	at com.redhat.ceylon.launcher.Bootstrap.main(Bootstrap.java:85)
Caused by: java.lang.RuntimeException: Error generating bytecode for source/mwe/SwingSMI.ceylon
	at com.redhat.ceylon.compiler.java.tools.LanguageCompiler.genCodeUnlessError(LanguageCompiler.java:839)
	at com.redhat.ceylon.compiler.java.tools.LanguageCompiler.genCode(LanguageCompiler.java:776)
	at com.redhat.ceylon.langtools.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1575)
	at com.redhat.ceylon.compiler.java.tools.LanguageCompiler.generate(LanguageCompiler.java:953)
	at com.redhat.ceylon.langtools.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1539)
	at com.redhat.ceylon.langtools.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:904)
	at com.redhat.ceylon.langtools.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:862)
	at com.redhat.ceylon.compiler.java.tools.LanguageCompiler.compile(LanguageCompiler.java:270)
	at com.redhat.ceylon.compiler.java.launcher.Main.compile(Main.java:660)
	at com.redhat.ceylon.compiler.java.launcher.Main.compile(Main.java:563)
	at com.redhat.ceylon.compiler.java.launcher.Main.compile(Main.java:555)
	at com.redhat.ceylon.compiler.java.launcher.Main.compile(Main.java:544)
	at com.redhat.ceylon.compiler.CeylonCompileTool.run(CeylonCompileTool.java:914)
	... 17 more
Caused by: java.lang.AssertionError: typecode ERROR
	at com.redhat.ceylon.langtools.tools.javac.jvm.Code.typecode(Code.java:248)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Items$Item.coerce(Items.java:269)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genExpr(Gen.java:951)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.visitSelect(Gen.java:2345)
	at com.redhat.ceylon.langtools.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1896)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genExpr(Gen.java:949)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.visitApply(Gen.java:1843)
	at com.redhat.ceylon.langtools.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1464)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genExpr(Gen.java:949)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.visitReturn(Gen.java:1809)
	at com.redhat.ceylon.langtools.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1383)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genDef(Gen.java:739)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genStat(Gen.java:774)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genStat(Gen.java:760)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genStats(Gen.java:811)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.visitBlock(Gen.java:1159)
	at com.redhat.ceylon.langtools.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:908)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genDef(Gen.java:739)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genStat(Gen.java:774)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genMethod(Gen.java:1033)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.visitMethodDef(Gen.java:996)
	at com.redhat.ceylon.langtools.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:777)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genDef(Gen.java:739)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genClass(Gen.java:2461)
	at com.redhat.ceylon.compiler.java.tools.LanguageCompiler.genCodeUnlessError(LanguageCompiler.java:810)
	... 29 more

The stack trace in Eclipse:

The Ceylon Java backend compilation failed
  with 6 malformed Javac tree cases
  with a throwable : java.lang.RuntimeException: Error generating bytecode for /Users/kingjon/tmp/ceylon/source/mwe/SwingSMI.ceylon
	at com.redhat.ceylon.compiler.java.tools.LanguageCompiler.genCodeUnlessError(LanguageCompiler.java:839)
	at com.redhat.ceylon.compiler.java.tools.LanguageCompiler.genCode(LanguageCompiler.java:776)
	at com.redhat.ceylon.langtools.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1575)
	at com.redhat.ceylon.compiler.java.tools.LanguageCompiler.generate(LanguageCompiler.java:953)
	at com.redhat.ceylon.langtools.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1539)
	at com.redhat.ceylon.langtools.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:904)
	at com.redhat.ceylon.langtools.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:862)
	at com.redhat.ceylon.compiler.java.tools.LanguageCompiler.compile(LanguageCompiler.java:270)
	at com.redhat.ceylon.compiler.java.launcher.Main.compile(Main.java:660)
	at com.redhat.ceylon.langtools.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:132)
	at com.redhat.ceylon.langtools.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:141)
	at com.redhat.ceylon.compiler.java.tools.CeyloncTaskImpl.call(CeyloncTaskImpl.java:59)
	at com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.compile(CeylonBuilder.java:2663)
	at com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.generateBinaries(CeylonBuilder.java:2392)
	at com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.access$100(CeylonBuilder.java:210)
	at com.redhat.ceylon.eclipse.core.builder.CeylonBuilder$4.call(CeylonBuilder.java:1075)
	at com.redhat.ceylon.eclipse.core.builder.CeylonBuilder$4.call(CeylonBuilder.java:1072)
	at com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.doWithCeylonModelCaching(CeylonBuilder.java:260)
	at com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.build(CeylonBuilder.java:1072)
	at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:735)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:206)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246)
	at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:301)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:304)
	at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:360)
	at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:383)
	at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:142)
	at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:232)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56)
Caused by: java.lang.AssertionError: typecode ERROR
	at com.redhat.ceylon.langtools.tools.javac.jvm.Code.typecode(Code.java:248)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Items$Item.coerce(Items.java:269)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genExpr(Gen.java:951)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.visitSelect(Gen.java:2345)
	at com.redhat.ceylon.langtools.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1896)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genExpr(Gen.java:949)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.visitApply(Gen.java:1843)
	at com.redhat.ceylon.langtools.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1464)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genExpr(Gen.java:949)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.visitReturn(Gen.java:1809)
	at com.redhat.ceylon.langtools.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1383)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genDef(Gen.java:739)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genStat(Gen.java:774)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genStat(Gen.java:760)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genStats(Gen.java:811)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.visitBlock(Gen.java:1159)
	at com.redhat.ceylon.langtools.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:908)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genDef(Gen.java:739)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genStat(Gen.java:774)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genMethod(Gen.java:1033)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.visitMethodDef(Gen.java:996)
	at com.redhat.ceylon.langtools.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:777)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genDef(Gen.java:739)
	at com.redhat.ceylon.langtools.tools.javac.jvm.Gen.genClass(Gen.java:2461)
	at com.redhat.ceylon.compiler.java.tools.LanguageCompiler.genCodeUnlessError(LanguageCompiler.java:810)
	... 30 more

ceylon --version reports ceylon version 1.3.3 0d594b3 (Contents May Differ); the Eclipse plugin looks to be version 1.3.3.v20170818-1632-Final, and I'm running Eclipse 4.7.3a. For completeness, this is MacOS Sierra, and the Ceylon command-line SDK was installed via Homebrew.

kingjon3377 avatar May 29 '18 18:05 kingjon3377

Related issue #7379.

gavinking avatar Sep 14 '18 23:09 gavinking