8176265: Method overload resolution on a covariant base type doesn't work in 9
authormcimadamore
Thu, 09 Mar 2017 12:08:02 +0000
changeset 44186 fe848a208b20
parent 44185 309b455e3ccc
child 44187 c56d85ea6c89
8176265: Method overload resolution on a covariant base type doesn't work in 9 Summary: Some type mappings should not be recursive Reviewed-by: vromero, jlahoda
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/VarTypePrinter.java
langtools/test/tools/javac/overload/T8176265.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java	Wed Mar 08 20:42:17 2017 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java	Thu Mar 09 12:08:02 2017 +0000
@@ -30,12 +30,12 @@
 import java.util.Collections;
 import java.util.EnumMap;
 import java.util.Map;
-import java.util.function.Function;
 
 import javax.lang.model.type.*;
 
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.TypeMetadata.Entry;
+import com.sun.tools.javac.code.Types.TypeMapping;
 import com.sun.tools.javac.comp.Infer.IncorporationAction;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.DefinedBy.Api;
@@ -222,18 +222,12 @@
         this.metadata = metadata;
     }
 
-    /** An abstract class for mappings from types to types
+    /**
+     * A subclass of {@link Types.TypeMapping} which applies a mapping recursively to the subterms
+     * of a given type expression. This mapping returns the original type is no changes occurred
+     * when recursively mapping the original type's subterms.
      */
-    public static abstract class TypeMapping<S> extends Types.MapVisitor<S> implements Function<Type, Type> {
-
-        @Override
-        public Type apply(Type type) {
-            return visit(type);
-        }
-
-        List<Type> visit(List<Type> ts, S s) {
-            return ts.map(t -> visit(t, s));
-        }
+    public static abstract class StructuralTypeMapping<S> extends Types.TypeMapping<S> {
 
         @Override
         public Type visitClassType(ClassType t, S s) {
@@ -299,11 +293,6 @@
         }
 
         @Override
-        public Type visitCapturedType(CapturedType t, S s) {
-            return visitTypeVar(t, s);
-        }
-
-        @Override
         public Type visitForAll(ForAll t, S s) {
             return visit(t.qtype, s);
         }
@@ -373,7 +362,7 @@
         return accept(stripMetadata, null);
     }
     //where
-        private final static TypeMapping<Void> stripMetadata = new TypeMapping<Void>() {
+        private final static TypeMapping<Void> stripMetadata = new StructuralTypeMapping<Void>() {
             @Override
             public Type visitClassType(ClassType t, Void aVoid) {
                 return super.visitClassType((ClassType)t.typeNoMetadata(), aVoid);
@@ -2125,7 +2114,7 @@
             }
         }
         //where
-            TypeMapping<Void> toTypeVarMap = new TypeMapping<Void>() {
+            TypeMapping<Void> toTypeVarMap = new StructuralTypeMapping<Void>() {
                 @Override
                 public Type visitUndetVar(UndetVar uv, Void _unused) {
                     return uv.inst != null ? uv.inst : uv.qtype;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Wed Mar 08 20:42:17 2017 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Thu Mar 09 12:08:02 2017 +0000
@@ -34,6 +34,7 @@
 import java.util.Set;
 import java.util.WeakHashMap;
 import java.util.function.BiPredicate;
+import java.util.function.Function;
 import java.util.stream.Collector;
 
 import javax.tools.JavaFileObject;
@@ -2095,7 +2096,7 @@
         }
         }
     // where
-        private TypeMapping<Boolean> erasure = new TypeMapping<Boolean>() {
+        private TypeMapping<Boolean> erasure = new StructuralTypeMapping<Boolean>() {
             private Type combineMetadata(final Type s,
                                          final Type t) {
                 if (t.getMetadata() != TypeMetadata.EMPTY) {
@@ -3019,7 +3020,7 @@
         return t.map(new Subst(from, to));
     }
 
-    private class Subst extends TypeMapping<Void> {
+    private class Subst extends StructuralTypeMapping<Void> {
         List<Type> from;
         List<Type> to;
 
@@ -4707,6 +4708,25 @@
         final public Type visit(Type t) { return t.accept(this, null); }
         public Type visitType(Type t, S s) { return t; }
     }
+
+    /**
+     * An abstract class for mappings from types to types (see {@link Type#map(TypeMapping)}.
+     * This class implements the functional interface {@code Function}, that allows it to be used
+     * fluently in stream-like processing.
+     */
+    public static class TypeMapping<S> extends MapVisitor<S> implements Function<Type, Type> {
+        @Override
+        public Type apply(Type type) { return visit(type); }
+
+        List<Type> visit(List<Type> ts, S s) {
+            return ts.map(t -> visit(t, s));
+        }
+
+        @Override
+        public Type visitCapturedType(CapturedType t, S s) {
+            return visitTypeVar(t, s);
+        }
+    }
     // </editor-fold>
 
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Wed Mar 08 20:42:17 2017 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Mar 09 12:08:02 2017 +0000
@@ -28,7 +28,8 @@
 import com.sun.source.tree.LambdaExpressionTree.BodyKind;
 import com.sun.source.tree.NewClassTree;
 import com.sun.tools.javac.code.*;
-import com.sun.tools.javac.code.Type.TypeMapping;
+import com.sun.tools.javac.code.Type.StructuralTypeMapping;
+import com.sun.tools.javac.code.Types.TypeMapping;
 import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
 import com.sun.tools.javac.comp.Resolve.ResolveError;
 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
@@ -929,7 +930,7 @@
      * where T is computed by retrieving the type that has already been
      * computed for D during a previous deferred attribution round of the given kind.
      */
-    class DeferredTypeMap extends TypeMapping<Void> {
+    class DeferredTypeMap extends StructuralTypeMapping<Void> {
         DeferredAttrContext deferredAttrContext;
 
         protected DeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Mar 08 20:42:17 2017 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Mar 09 12:08:02 2017 +0000
@@ -26,6 +26,7 @@
 package com.sun.tools.javac.comp;
 
 import com.sun.tools.javac.code.Type.UndetVar.UndetVarListener;
+import com.sun.tools.javac.code.Types.TypeMapping;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCTypeCast;
 import com.sun.tools.javac.tree.TreeInfo;
@@ -61,9 +62,6 @@
 import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.function.BiPredicate;
-import java.util.stream.Collectors;
-
-import com.sun.tools.javac.main.Option;
 
 import static com.sun.tools.javac.code.TypeTag.*;
 
@@ -628,7 +626,7 @@
             }
         }
 
-    TypeMapping<Void> fromTypeVarFun = new TypeMapping<Void>() {
+    TypeMapping<Void> fromTypeVarFun = new StructuralTypeMapping<Void>() {
         @Override
         public Type visitTypeVar(TypeVar tv, Void aVoid) {
             UndetVar uv = new UndetVar(tv, incorporationEngine(), types);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/VarTypePrinter.java	Wed Mar 08 20:42:17 2017 +0100
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/VarTypePrinter.java	Thu Mar 09 12:08:02 2017 +0000
@@ -36,7 +36,7 @@
 import com.sun.tools.javac.code.Flags;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.code.Type.CapturedType;
-import com.sun.tools.javac.code.Type.TypeMapping;
+import com.sun.tools.javac.code.Type.StructuralTypeMapping;
 import com.sun.tools.javac.code.Type.TypeVar;
 import com.sun.tools.javac.code.Type.WildcardType;
 import com.sun.tools.javac.code.Types;
@@ -158,7 +158,7 @@
         }
     }
 
-    class TypeProjection extends TypeMapping<Boolean> {
+    class TypeProjection extends StructuralTypeMapping<Boolean> {
 
         List<Type> vars;
         Set<Type> seen = new HashSet<>();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/overload/T8176265.java	Thu Mar 09 12:08:02 2017 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 8176265
+ * @summary Method overload resolution on a covariant base type doesn't work in 9
+ * @compile T8176265.java
+ */
+
+class T8176265<T> {
+    static class Sup<E> { }
+    static class Sub<E> extends Sup<E> { }
+
+    void method(Sup<? super T> f) { }
+    void method(Sub<? super T> f) { }
+
+
+    static <Z> void m(T8176265<? extends Z> test, Sub<Z> sz) {
+        test.method(sz);
+    }
+}