changeset 651:cbf392027ba0

More bug fixes: *) 'void' as explicit method type-parameter should be handled correctly *) nil-ary disjunctive types should be handled properly while inferring 'throws' type-vars from lambdas
author mcimadamore
date Fri, 13 Aug 2010 16:22:50 +0100
parents fd3c998a07b0
children c3232ad98c72
files src/share/classes/com/sun/tools/javac/code/Types.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/comp/Infer.java src/share/classes/com/sun/tools/javac/comp/Resolve.java src/share/classes/com/sun/tools/javac/util/List.java test/tools/javac/lambda/ExceptionTransparency02.java test/tools/javac/transparency/Pos04.java
diffstat 7 files changed, 144 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Aug 12 15:38:26 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Aug 13 16:22:50 2010 +0100
@@ -3198,6 +3198,11 @@
      * does not exist return the type of null (bottom).
      */
     public Type lub(List<Type> ts) {
+        if (ts.size() == 1) {
+            return ts.head.isPrimitive() ?
+                syms.errType :
+                ts.head;
+        }
         final int ARRAY_BOUND = 1;
         final int CLASS_BOUND = 2;
         int boundkind = 0;
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Aug 12 15:38:26 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Aug 13 16:22:50 2010 +0100
@@ -693,14 +693,15 @@
     }
 
     Type checkParameterType(JCExpression tree, Type actual, Type formal) {
-        if ((formal.tsym.flags() & THROWS) != 0 &&
-                actual.tag == VOID) {
-            tree.type = new DisjunctiveType(List.<Type>nil(), syms.disjointClass);
-            return tree.type;
-        }
-        else {
-            return checkRefType(tree.pos(), actual);
-        }
+        tree.type = checkParameterType(actual, formal);
+        return checkRefType(tree.pos(), tree.type);
+    }
+
+    Type checkParameterType(Type actual, Type formal) {
+        return ((formal.tsym.flags() & THROWS) != 0 &&
+                actual.tag == VOID) ?
+            new DisjunctiveType(List.<Type>nil(), syms.disjointClass) :
+            actual;
     }
 
     /** Check that type is a null or reference type.
@@ -1294,10 +1295,21 @@
      *  @param handled    The list of handled exceptions.
      */
     public List<Type> unhandled(List<Type> thrown, List<Type> handled) {
-        List<Type> unhandled = List.nil();
-        for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
-            if (!isHandled(l.head, handled)) unhandled = unhandled.prepend(l.head);
-        return unhandled;
+        if (handled.size() == 1 &&
+                handled.head.tag == UNDETVAR &&
+                (((UndetVar)handled.head).qtype.tsym.flags() & THROWS) != 0) {
+            //special case for inference of 'throws' type-parameters
+            UndetVar uv = (UndetVar)handled.head;
+            uv.lobounds = thrown.isEmpty() ?
+                uv.lobounds.prepend(syms.voidType) :
+                uv.lobounds.appendList(thrown);
+            return List.nil();
+        } else {
+            List<Type> unhandled = List.nil();
+            for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
+                if (!isHandled(l.head, handled)) unhandled = unhandled.prepend(l.head);
+            return unhandled;
+        }
     }
 
 /* *************************************************************************
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Aug 12 15:38:26 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri Aug 13 16:22:50 2010 +0100
@@ -213,12 +213,11 @@
         if (that.inst == null) {
             if (that.lobounds.isEmpty())
                 that.inst = syms.botType;
-            else if (that.lobounds.tail.isEmpty())
-                that.inst = that.lobounds.head.isPrimitive() ? syms.errType : that.lobounds.head;
-            else {
-                that.inst = (that.qtype.tsym.flags() & Flags.THROWS) == 0 ?
-                    types.lub(that.lobounds) :
-                    new DisjunctiveType(chk.union(that.lobounds), syms.disjointClass);
+            else if ((that.qtype.tsym.flags() & Flags.THROWS) != 0 ) {
+                List<Type> compTypes = List.filter(that.lobounds, syms.voidType);
+                that.inst = new DisjunctiveType(chk.union(compTypes), syms.disjointClass);
+            } else {
+                that.inst = types.lub(that.lobounds);
             }
             if (that.inst == null || that.inst.tag == ERROR)
                     throw ambiguousNoInstanceException
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Aug 12 15:38:26 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Aug 13 16:22:50 2010 +0100
@@ -319,16 +319,19 @@
             // Check type arguments are within bounds
             List<Type> formals = pmt.tvars;
             List<Type> actuals = typeargtypes;
+            ListBuffer<Type> actuals2 = ListBuffer.lb();
             while (formals.nonEmpty() && actuals.nonEmpty()) {
+                Type actual = chk.checkParameterType(actuals.head, formals.head);
+                actuals2.append(actual);
                 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
                                                 pmt.tvars, typeargtypes);
                 for (; bounds.nonEmpty(); bounds = bounds.tail)
-                    if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
+                    if (!types.isSubtypeUnchecked(actual, bounds.head, warn))
                         return null;
                 formals = formals.tail;
                 actuals = actuals.tail;
             }
-            mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
+            mt = types.subst(pmt.qtype, pmt.tvars, actuals2.toList());
         } else if (mt.tag == FORALL) {
             ForAll pmt = (ForAll) mt;
             List<Type> tvars1 = types.newInstances(pmt.tvars);
--- a/src/share/classes/com/sun/tools/javac/util/List.java	Thu Aug 12 15:38:26 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/util/List.java	Fri Aug 13 16:22:50 2010 +0100
@@ -83,6 +83,18 @@
         }
     };
 
+    /** Returns the list obtained from 'l' after removing all elements 'elem'
+     */
+    public static <A> List<A> filter(List<A> l, A elem) {
+        List<A> res = List.nil();
+        for (A a : l) {
+            if (!a.equals(elem)) {
+                res = res.prepend(a);
+            }
+        }
+        return res.reverse();
+    }
+
     /** Construct a list consisting of given element.
      */
     public static <A> List<A> of(A x1) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/ExceptionTransparency02.java	Fri Aug 13 16:22:50 2010 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 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
+ * @summary check that nil-ary disjunctive types are handled properly during method type-inference
+ * @author  Maurizio Cimadamore
+ * @compile ExceptionTransparency02.java
+ */
+
+class ExceptionTransparency02 {
+
+    static class A extends Exception {}
+    static class B extends Exception {}
+
+    public interface Block<throws E> { void run() throws E; }
+
+    public static <throws E> void m1(Block<E> block) throws E {}
+    public static <throws E> void m2(Block<E> block1, Block<E> block2) throws E {}
+
+    public static void main(String[] args) {
+        m1(# { } );
+        m2(# { }, # { });
+        try {
+            m2(# { throw new A(); }, # { });
+            m2(# { }, # { throw new A(); });
+        }
+        catch (A a) {}
+        try {
+            m2(# { throw new A(); }, # { throw new B(); });
+            m2(# { throw new B(); }, # { throw new A(); });
+        }
+        catch (final A | B ex) {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/transparency/Pos04.java	Fri Aug 13 16:22:50 2010 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 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
+ * @summary check that 'void' as explicit method type-parameter is handled properly
+ * @author  Maurizio Cimadamore
+ * @compile Pos04.java
+ */
+
+class Pos04 {
+
+    <throws E> void m() throws E {}
+
+    void test() {
+        this.<void>m();
+    }
+}