6838943: inference: javac is not handling type-variable substitution properly
Summary: free type-variables are being replaced with type-variables bound to forall type leading to unsoundness
Reviewed-by: jjg, dlsmith
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Jan 28 12:03:49 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Jan 28 12:06:21 2011 +0000
@@ -2259,6 +2259,13 @@
@Override
public Type visitForAll(ForAll t, Void ignored) {
+ if (Type.containsAny(to, t.tvars)) {
+ //perform alpha-renaming of free-variables in 't'
+ //if 'to' types contain variables that are free in 't'
+ List<Type> freevars = newInstances(t.tvars);
+ t = new ForAll(freevars,
+ Types.this.subst(t.qtype, t.tvars, freevars));
+ }
List<Type> tvars1 = substBounds(t.tvars, from, to);
Type qtype1 = subst(t.qtype);
if (tvars1 == t.tvars && qtype1 == t.qtype) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6838943/T6838943.java Fri Jan 28 12:06:21 2011 +0000
@@ -0,0 +1,16 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 6838943
+ * @summary inference: javac is not handling type-variable substitution properly
+ * @compile/fail/ref=T6838943.out -XDrawDiagnostics T6838943.java
+ */
+class T6838943 {
+ static class A<X> {}
+ static class B {}
+ static class C<X> {
+ <Z> void m(X x, Z z) {
+ C<A<Z>> c = new C<A<Z>>();
+ c.m(new A<B>(), new B()); //should fail
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/6838943/T6838943.out Fri Jan 28 12:06:21 2011 +0000
@@ -0,0 +1,2 @@
+T6838943.java:13:14: compiler.err.cant.apply.symbol.1: kindname.method, m, T6838943.A<Z>,Z, T6838943.A<T6838943.B>,T6838943.B, kindname.class, T6838943.C<X>, (compiler.misc.infer.no.conforming.assignment.exists: Z, T6838943.A<T6838943.B>, T6838943.A<Z>)
+1 error