ADDITIONAL SYSTEM INFORMATION :
Debian stable, Linux
A DESCRIPTION OF THE PROBLEM :
I have a method in file “MyImpl” with header “MyImpl andConsume(TConsumer<?> consumer)”, which compiles fine (MyImpl actually extends “MyInterface<Random>”; I skip the details here).
But when using it using an instance of “TConsumer<?> consumer” and assigning the result to a variable declared as type “MyImpl”, the compiler reports “error: incompatible types: MyInterface<Random> cannot be converted to MyImpl”.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
git clone https://github.com/oliviercailloux/JARiS.git
git checkout simplified
javac -d "out/" somebug/*.java
javac -classpath "out/" "someuser/UserClass.java"
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Either javac should refuse to compile the first method, or it should allow to use it as its header declares.
ACTUAL -
javac compiles the files in the “somebug” package fine, thus, seems happy with the method that declares that it returns “MyImpl”; but then it refuses to compile the file in “someuser” which calls the method and expects it to return an instance of “MyImpl”.
---------- BEGIN SOURCE ----------
package somebug;
import java.util.Random;
public interface MyImpl extends MyInterface<Random> {
public static MyImpl instance() {
return new MyImpl() {
@Override
public MyImpl andConsume(TConsumer<?> consumer) {
return this;
}
};
}
@Override
public MyImpl andConsume(TConsumer<? extends Random> consumer);
}
package somebug;
import java.util.Random;
public interface MyImpl extends MyInterface<Random> {
public static MyImpl instance() {
return new MyImpl() {
@Override
public MyImpl andConsume(TConsumer<?> consumer) {
return this;
}
};
}
@Override
public MyImpl andConsume(TConsumer<? extends Random> consumer);
}
package somebug;
import java.util.Random;
public interface TConsumer<X extends Random> {
public void consuming(Integer t);
}
---
To be compiled afterwards (separately).
---
package someuser;
import somebug.MyImpl;
import somebug.TConsumer;
public class UserClass {
public void gradeCode() {
MyImpl tryTarget = MyImpl.instance();
TConsumer<?> consumer = i -> {};
MyImpl got = tryTarget.andConsume(consumer);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
In MyImpl.java, change “andConsume(TConsumer<?> consumer);” to “andConsume(TConsumer<? extends Random> consumer);”
As implemented in https://github.com/oliviercailloux/JARiS/compare/simplified...solved
FREQUENCY : always
Debian stable, Linux
A DESCRIPTION OF THE PROBLEM :
I have a method in file “MyImpl” with header “MyImpl andConsume(TConsumer<?> consumer)”, which compiles fine (MyImpl actually extends “MyInterface<Random>”; I skip the details here).
But when using it using an instance of “TConsumer<?> consumer” and assigning the result to a variable declared as type “MyImpl”, the compiler reports “error: incompatible types: MyInterface<Random> cannot be converted to MyImpl”.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
git clone https://github.com/oliviercailloux/JARiS.git
git checkout simplified
javac -d "out/" somebug/*.java
javac -classpath "out/" "someuser/UserClass.java"
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Either javac should refuse to compile the first method, or it should allow to use it as its header declares.
ACTUAL -
javac compiles the files in the “somebug” package fine, thus, seems happy with the method that declares that it returns “MyImpl”; but then it refuses to compile the file in “someuser” which calls the method and expects it to return an instance of “MyImpl”.
---------- BEGIN SOURCE ----------
package somebug;
import java.util.Random;
public interface MyImpl extends MyInterface<Random> {
public static MyImpl instance() {
return new MyImpl() {
@Override
public MyImpl andConsume(TConsumer<?> consumer) {
return this;
}
};
}
@Override
public MyImpl andConsume(TConsumer<? extends Random> consumer);
}
package somebug;
import java.util.Random;
public interface MyImpl extends MyInterface<Random> {
public static MyImpl instance() {
return new MyImpl() {
@Override
public MyImpl andConsume(TConsumer<?> consumer) {
return this;
}
};
}
@Override
public MyImpl andConsume(TConsumer<? extends Random> consumer);
}
package somebug;
import java.util.Random;
public interface TConsumer<X extends Random> {
public void consuming(Integer t);
}
---
To be compiled afterwards (separately).
---
package someuser;
import somebug.MyImpl;
import somebug.TConsumer;
public class UserClass {
public void gradeCode() {
MyImpl tryTarget = MyImpl.instance();
TConsumer<?> consumer = i -> {};
MyImpl got = tryTarget.andConsume(consumer);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
In MyImpl.java, change “andConsume(TConsumer<?> consumer);” to “andConsume(TConsumer<? extends Random> consumer);”
As implemented in https://github.com/oliviercailloux/JARiS/compare/simplified...solved
FREQUENCY : always