haxe
haxe copied to clipboard
[jvm] cannot fulfill native interface requirements?
I am trying to implement a java.util.List<T> with haxe code:
class Main {
static function main() {
trace(new MyArray());
}
}
class MyArray<E> implements java.util.List<E> {
public function new() {}
overload public function add(o:E) {
return false;
}
overload public function add(index:Int, e:E) {
}
overload public function addAll(c:java.util.Collection<E>) {
return false;
}
overload public function addAll(index:Int, c:java.util.Collection<E>) {
return false;
}
public function clear() {
}
public function contains(o:Dynamic) {
return false;
}
public function containsAll(c:java.util.Collection<Dynamic>) {
return false;
}
public function equals(o:Dynamic) {
return false;
}
public function get(index:Int):E {
return null;
}
public function hashCode() {
return 0;
}
public function indexOf(o:Dynamic) {
return 0;
}
public function isEmpty() {
return false;
}
public function iterator():java.util.Iterator<E> {
return null;
}
overload public function lastIndexOf(o:Dynamic) {
return 0;
}
overload public function listIterator():java.util.ListIterator<E> {
return null;
}
overload public function listIterator(index:Int):java.util.ListIterator<E> {
return null;
}
overload public function remove(index:Int):E {
return null;
}
overload public function remove(o:Dynamic) {
return false;
}
overload public function removeAll(c:java.util.Collection<Dynamic>) {
return false;
}
overload public function retainAll(c:java.util.Collection<Dynamic>) {
return false;
}
overload public function set(index:Int, e:E):E {
return null;
}
public function size() {
return 0;
}
public function subList(fromIndex:Int, toIndex:Int):java.util.List<E> {
return null;
}
overload public function toArray():java.NativeArray<Dynamic> {
return null;
}
overload public function toArray<T>(var1:java.NativeArray<T>):java.NativeArray<T> {
return null;
}
}
and got errors:
src/Main.hx:7: characters 7-14 : No suitable overload for toArray( param1 : java.NativeArray<toArray.T> ), as needed by java.util.Collection was found
src/Main.hx:7: characters 7-14 : No suitable overload for toArray( param1 : java.NativeArray<toArray.T> ), as needed by java.util.List was found
hxjava/4.2.0/haxelib/lib/hxjava-std.jar@java/lang/Iterable.class@spliterator:1: character 1 : Field spliterator has different type than in java.util.List
hxjava/4.2.0/haxelib/lib/hxjava-std.jar@java/util/List.class@spliterator:1: character 1 : ... Interface field is defined here
hxjava/4.2.0/haxelib/lib/hxjava-std.jar@java/lang/Iterable.class@spliterator:1: character 1 : ... error: java.lang.Iterable.T should be MyArray.E
hxjava/4.2.0/haxelib/lib/hxjava-std.jar@java/lang/Iterable.class@spliterator:1: character 1 : ... have: (...) -> java.util.Spliterator<java.lang.Iterable.T>
hxjava/4.2.0/haxelib/lib/hxjava-std.jar@java/lang/Iterable.class@spliterator:1: character 1 : ... want: (...) -> java.util.Spliterator<MyArray.E>
hxjava/4.2.0/haxelib/lib/hxjava-std.jar@java/lang/Iterable.class@spliterator:1: character 1 : Field spliterator has different type than in java.util.Collection
hxjava/4.2.0/haxelib/lib/hxjava-std.jar@java/util/Collection.class@spliterator:1: character 1 : ... Interface field is defined here
hxjava/4.2.0/haxelib/lib/hxjava-std.jar@java/lang/Iterable.class@spliterator:1: character 1 : ... error: java.lang.Iterable.T should be MyArray.E
hxjava/4.2.0/haxelib/lib/hxjava-std.jar@java/lang/Iterable.class@spliterator:1: character 1 : ... have: (...) -> java.util.Spliterator<java.lang.Iterable.T>
hxjava/4.2.0/haxelib/lib/hxjava-std.jar@java/lang/Iterable.class@spliterator:1: character 1 : ... want: (...) -> java.util.Spliterator<MyArray.E>
I tried to remove the implement clause and check the output bytecode and apparently it does match the required signatures, so I reckon this is an issue of the haxe compiler being unable to recognize them.
Am I reading this correctly that it's (also) complaining about java.lang.Iterable not conforming to java.util.List?
Yeah I think so...
That means we have three issues here:
- We shouldn't check a native lib type during type-loading.
- Even if we do, there's clearly some bad inference going on.
- The actual issue.
Ooooh spliterator has @:java.default, that changes everything.
I've fixed one issue. Another is that these type parameters seem to have an implicit constraint to java.lang.Object, which causes the redefinition check to fail. Your example no longer emits the first error if I change it to T:Dynamic. Not quite sure how to handle that part yet.
The spliterator thing is also still failing. That one looks like some missing type parameter application.
Another is that these type parameters seem to have an implicit constraint to
java.lang.Object
I am wondering if the compiler should just insert that constraint where no explicit constraints exist? Because iirc in jvm primitives can't be type parameters.
I don't want to actually insert the constraint because that would just waste everyone's time and memory, but we can allow a redefinition that omits it.
Actually, I think constraints could always be allowed to be more general, and that includes omitting them entirely. At worst, we access through our more constrained parent type, which is still going to be sound.