changeset 2231:f590791ede42

8016175: Add bottom-up type-checking support for unambiguous method references (take three) Fix bug in inference context save/restore logic.
author mcimadamore
date Tue, 02 Jul 2013 13:14:29 +0100
parents 5f45a6810db9
children e2dd301496d6
files src/share/classes/com/sun/tools/javac/code/Type.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Infer.java test/tools/javac/lambda/TargetType76.java
diffstat 4 files changed, 87 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Mon Jul 01 14:12:37 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Tue Jul 02 13:14:29 2013 +0100
@@ -1356,6 +1356,11 @@
             }
             return buf.toList();
         }
+        
+        /** internal method used to override an undetvar bounds */
+        public void setBounds(InferenceBound ib, List<Type> newBounds) {
+            bounds.put(ib, newBounds);
+        }
 
         /** get the list of declared (upper) bounds */
         public List<Type> getDeclaredBounds() {
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Jul 01 14:12:37 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Jul 02 13:14:29 2013 +0100
@@ -2684,13 +2684,13 @@
             }
             
             Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = null;
+            List<Type> saved_undet = resultInfo.checkContext.inferenceContext().save();
             try {
-                resultInfo.checkContext.inferenceContext().save();
                 refResult = rs.resolveMemberReference(that.pos(), localEnv, that, that.expr.type,
                         that.name, argtypes, typeargtypes, true, referenceCheck,
                         resultInfo.checkContext.inferenceContext());
             } finally {
-                resultInfo.checkContext.inferenceContext().rollback();
+                resultInfo.checkContext.inferenceContext().rollback(saved_undet);
             }
 
             Symbol refSym = refResult.fst;
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Jul 01 14:12:37 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Jul 02 13:14:29 2013 +0100
@@ -1175,7 +1175,7 @@
             while (!sstrategy.done()) {
                 InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
                 List<Type> varsToSolve = List.from(nodeToSolve.data);
-                inferenceContext.save();
+                List<Type> saved_undet = inferenceContext.save();
                 try {
                     //repeat until all variables are solved
                     outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) {
@@ -1192,7 +1192,7 @@
                 }
                 catch (InferenceException ex) {
                     //did we fail because of interdependent ivars?
-                    inferenceContext.rollback();
+                    inferenceContext.rollback(saved_undet);
                     instantiateAsUninferredVars(varsToSolve, inferenceContext);
                     checkWithinBounds(inferenceContext, warn);
                 }
@@ -1385,9 +1385,6 @@
         /** list of inference vars in this context */
         List<Type> inferencevars;
 
-        /** backed up inference variables */
-        List<Type> saved_undet;
-
         java.util.Map<FreeTypeListener, List<Type>> freeTypeListeners =
                 new java.util.HashMap<FreeTypeListener, List<Type>>();
 
@@ -1599,7 +1596,7 @@
         /**
          * Save the state of this inference context
          */
-        void save() {
+        List<Type> save() {
             ListBuffer<Type> buf = ListBuffer.lb();
             for (Type t : undetvars) {
                 UndetVar uv = (UndetVar)t;
@@ -1612,16 +1609,24 @@
                 uv2.inst = uv.inst;
                 buf.add(uv2);
             }
-            saved_undet = buf.toList();
+            return buf.toList();
         }
 
         /**
          * Restore the state of this inference context to the previous known checkpoint
          */
-        void rollback() {
+        void rollback(List<Type> saved_undet) {
             Assert.check(saved_undet != null && saved_undet.length() == undetvars.length());
-            undetvars = saved_undet;
-            saved_undet = null;
+            //restore bounds (note: we need to preserve the old instances)
+            for (Type t : undetvars) {
+                UndetVar uv = (UndetVar)t;
+                UndetVar uv_saved = (UndetVar)saved_undet.head;
+                for (InferenceBound ib : InferenceBound.values()) {
+                    uv.setBounds(ib, uv_saved.getBounds(ib));
+                }
+                uv.inst = uv_saved.inst;
+                saved_undet = saved_undet.tail;
+            }
         }
 
         /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType76.java	Tue Jul 02 13:14:29 2013 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2013, 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 8016175
+ * @summary Add bottom-up type-checking support for unambiguous method references
+ * @compile TargetType76.java
+ */
+class TargetType76 {
+
+    interface Function<X, Y> {
+        Y m(X x);
+    }
+
+    interface OfRef<T> { }
+
+    interface Supplier<X> {
+        X make();
+    }
+
+    interface Stream<X> { }
+
+    interface Node<E> {
+        Spliterator<E> spliterator();
+    }
+
+    interface Spliterator<X> {
+        Spliterator<X> spliterator();
+    }
+
+    class RefTestData<T, I> implements OfRef<T> { 
+        RefTestData(I state,
+                    Function<I, Stream<T>> streamFn,
+                    Function<I, Spliterator<T>> splitrFn) { }
+    }
+
+    <O> OfRef<O> ofCollection(Node<O> collection) {
+        return new RefTestData<>(collection,
+                                 x->stream(x::spliterator),
+                                 Node::spliterator);
+    }
+
+    <S> Stream<S> stream(Supplier<? extends Spliterator<S>> supplier) { return null; }
+}