eclipse-archived/ceylon

Backend error when method reference passed to method triggering SAM-interface interop

Opened this issue · 2 comments

The following code fails to compile with a backend error:

import javax.swing {
	JComponent,
	JButton
}
import java.awt.event {
	ActionEvent
}
Anything(ActionEvent) silentListener(Anything() listener) =>
		void (ActionEvent event) => listener();
void consumer(Anything(ActionEvent) val) {}
class Sample() extends JComponent() {
	value memberVariable = JButton();
	consumer(silentListener(memberVariable.updateUI)); // works
	value listener = silentListener(memberVariable.updateUI); // works
	memberVariable.addActionListener(listener); // works
	// Ceylon backend error: variable $instance$ is already defined in constructor Sample()
	memberVariable.addActionListener(silentListener(memberVariable.updateUI));
}

The backend error does not occur if the return value of the transforming method (silentListener in the code above) is assigned to a variable, even if that variable is used in a way that the compiler transforms to a Java SAM interface, nor if it is passed to a method expecting a Ceylon Callable.

I've reproduced this both on the command line (ceylon --version reports ceylon version 1.3.3 0d594b3 (Contents May Differ); I'm on Mac OS X Sierra, with the Ceylon distribution installed via Homebrew) and in the Eclipse IDE (AFAICT the latest version, which the "About Eclipse Features" reports as version 1.3.3v20170818-1632-Final, running on Eclipse 4.7.3a).

Related issue #7380.

It looks like this may not be (entirely) specific to the SAM-interface interop; I ran into the same error with code that I distilled to the following:

void callee(String?() arg) {}
void caller(Resource resource) =>
    callee(LinkedList(resource.textContent().split('\n'.equals)).accept);

The compiler output puts the "error here" caret underneath the first character of '\n'.equals.