ADDITIONAL SYSTEM INFORMATION :
$ javac --version
javac 14.0.2
$ java --version
openjdk 14.0.2 2020-07-14
OpenJDK Runtime Environment (build 14.0.2+12-Debian-1)
OpenJDK 64-Bit Server VM (build 14.0.2+12-Debian-1, mixed mode, sharing)
$ uname -a
Linux xxxxxx 5.7.0-1-amd64 #1 SMP Debian 5.7.6-1 (2020-06-24) x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
It's hard to pinpoint the issue specifically, but it seems that somehow lower bound of type variable that contains wildcard get lost during type inference and as a result unification fail.
The problem is frustrating because there seems to be no workaround besides duplicating and inlining the code.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The problem can be reproduced by compiling the test program.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
It is expected that this program should compile. In the `requireUniquieTs` method body `V` type-variable should have lower-bound `HasT<CAP#1>`. When calling `requireUniquieTsTyped` javac should try to unify `V#1 extends HasT<CAP#1>` and `V#1 extends HasT<T#1>` and derive that `T#1 = CAP#1`.
ACTUAL -
Running javac results in the following error:
````
HasT.java:7: error: method requireUniquieTsTyped in interface HasT<T#2> cannot be applied to given types;
return requireUniquieTsTyped(vs);
^
required: Set<V#1>
found: Set<V#2>
reason: inference variable V#1 has incompatible bounds
equality constraints: V#2
lower bounds: HasT<T#1>
where V#1,T#1,V#2,T#2 are type-variables:
V#1 extends HasT<T#1> declared in method <V#1,T#1>requireUniquieTsTyped(Set<V#1>)
T#1 extends Object declared in method <V#1,T#1>requireUniquieTsTyped(Set<V#1>)
V#2 extends HasT<?> declared in method <V#2>requireUniquieTs(Set<V#2>)
T#2 extends Object declared in interface HasT
1 error
````
---------- BEGIN SOURCE ----------
import java.util.Set;
interface HasT<T> {
static
<V extends HasT<?>>
Set<V> requireUniquieTs(Set<V> vs) {
return requireUniquieTsTyped(vs);
}
static
<V extends HasT<T>, T>
Set<V> requireUniquieTsTyped(Set<V> vs) {
throw new UnsupportedOperationException("Not implemented");
}
T getT();
}
---------- END SOURCE ----------
FREQUENCY : always