7015715: lub gets stuck on type with complex supertype
Summary: lub should not scan supertypes unnecessarily
Reviewed-by: jjg, dlsmith
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Mon Feb 28 11:48:53 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Mon Feb 28 11:50:56 2011 +0000
@@ -2832,12 +2832,26 @@
while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR)
ts = ts.tail;
Assert.check(!ts.isEmpty());
- List<Type> cl = closure(ts.head);
+ //step 1 - compute erased candidate set (EC)
+ List<Type> cl = erasedSupertypes(ts.head);
for (Type t : ts.tail) {
if (t.tag == CLASS || t.tag == TYPEVAR)
- cl = intersect(cl, closure(t));
+ cl = intersect(cl, erasedSupertypes(t));
}
- return compoundMin(cl);
+ //step 2 - compute minimal erased candidate set (MEC)
+ List<Type> mec = closureMin(cl);
+ //step 3 - for each element G in MEC, compute lci(Inv(G))
+ List<Type> candidates = List.nil();
+ for (Type erasedSupertype : mec) {
+ List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym));
+ for (Type t : ts) {
+ lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym)));
+ }
+ candidates = candidates.appendList(lci);
+ }
+ //step 4 - let MEC be { G1, G2 ... Gn }, then we have that
+ //lub = lci(Inv(G1)) & lci(Inv(G2)) & ... & lci(Inv(Gn))
+ return compoundMin(candidates);
default:
// calculate lub(A, B[])
@@ -2851,6 +2865,18 @@
}
}
// where
+ List<Type> erasedSupertypes(Type t) {
+ ListBuffer<Type> buf = lb();
+ for (Type sup : closure(t)) {
+ if (sup.tag == TYPEVAR) {
+ buf.append(sup);
+ } else {
+ buf.append(erasure(sup));
+ }
+ }
+ return buf.toList();
+ }
+
private Type arraySuperType = null;
private Type arraySuperType() {
// initialized lazily to avoid problems during compiler startup
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/T7015715.java Mon Feb 28 11:50:56 2011 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7015715
+ *
+ * @summary lub gets stuck on type with complex supertype
+ * @author Neal Gafter
+ * @compile T7015715.java
+ *
+ */
+
+class T7015715 {
+
+ interface I<T> {}
+
+ interface A<T> extends I<A<A<T>>>{}
+
+ static abstract class X {
+ abstract <T> T foo(T x, T y);
+ void bar(A<Integer> x, A<String> y){
+ foo(x, y);
+ }
+ }
+}