8147546: regression when type-checking generic calls inside nested declarations occurring in method context
authormcimadamore
Wed, 20 Jan 2016 10:53:29 +0000
changeset 35350 5ec1564e7b1f
parent 35349 4a13a361309a
child 35351 2c8aa590f3d5
8147546: regression when type-checking generic calls inside nested declarations occurring in method context Summary: Attr.visitClassDef should set a temporary ArgumentAttr cache when in speculative mode Reviewed-by: vromero
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/test/tools/javac/lambda/speculative/8147546/T8147546a.java
langtools/test/tools/javac/lambda/speculative/8147546/T8147546b.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jan 20 10:50:28 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jan 20 10:53:29 2016 +0000
@@ -42,6 +42,7 @@
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.code.TypeMetadata.Annotations;
 import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError;
+import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
 import com.sun.tools.javac.comp.Check.CheckContext;
 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
@@ -885,40 +886,46 @@
     }
 
     public void visitClassDef(JCClassDecl tree) {
-        // Local and anonymous classes have not been entered yet, so we need to
-        // do it now.
-        if (env.info.scope.owner.kind.matches(KindSelector.VAL_MTH)) {
-            enter.classEnter(tree, env);
-        } else {
-            // If this class declaration is part of a class level annotation,
-            // as in @MyAnno(new Object() {}) class MyClass {}, enter it in
-            // order to simplify later steps and allow for sensible error
-            // messages.
-            if (env.tree.hasTag(NEWCLASS) && TreeInfo.isInAnnotation(env, tree))
+        Optional<ArgumentAttr.LocalCacheContext> localCacheContext =
+                Optional.ofNullable(env.info.isSpeculative ?
+                        argumentAttr.withLocalCacheContext() : null);
+        try {
+            // Local and anonymous classes have not been entered yet, so we need to
+            // do it now.
+            if (env.info.scope.owner.kind.matches(KindSelector.VAL_MTH)) {
                 enter.classEnter(tree, env);
-        }
-
-        ClassSymbol c = tree.sym;
-        if (c == null) {
-            // exit in case something drastic went wrong during enter.
-            result = null;
-        } else {
-            // make sure class has been completed:
-            c.complete();
-
-            // If this class appears as an anonymous class
-            // in a superclass constructor call where
-            // no explicit outer instance is given,
-            // disable implicit outer instance from being passed.
-            // (This would be an illegal access to "this before super").
-            if (env.info.isSelfCall &&
-                env.tree.hasTag(NEWCLASS) &&
-                ((JCNewClass) env.tree).encl == null)
-            {
-                c.flags_field |= NOOUTERTHIS;
+            } else {
+                // If this class declaration is part of a class level annotation,
+                // as in @MyAnno(new Object() {}) class MyClass {}, enter it in
+                // order to simplify later steps and allow for sensible error
+                // messages.
+                if (env.tree.hasTag(NEWCLASS) && TreeInfo.isInAnnotation(env, tree))
+                    enter.classEnter(tree, env);
             }
-            attribClass(tree.pos(), c);
-            result = tree.type = c.type;
+
+            ClassSymbol c = tree.sym;
+            if (c == null) {
+                // exit in case something drastic went wrong during enter.
+                result = null;
+            } else {
+                // make sure class has been completed:
+                c.complete();
+
+                // If this class appears as an anonymous class
+                // in a superclass constructor call where
+                // no explicit outer instance is given,
+                // disable implicit outer instance from being passed.
+                // (This would be an illegal access to "this before super").
+                if (env.info.isSelfCall &&
+                        env.tree.hasTag(NEWCLASS) &&
+                        ((JCNewClass)env.tree).encl == null) {
+                    c.flags_field |= NOOUTERTHIS;
+                }
+                attribClass(tree.pos(), c);
+                result = tree.type = c.type;
+            }
+        } finally {
+            localCacheContext.ifPresent(LocalCacheContext::leave);
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/speculative/8147546/T8147546a.java	Wed Jan 20 10:53:29 2016 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, 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 8147546
+  * @summary regression when type-checking generic calls inside nested declarations occurring in method context
+  * @compile T8147546a.java
+  */
+abstract class T8147546a {
+
+    interface I<O> { void t(O clazz); }
+    abstract <A> I<A> a(Class<A> clazz);
+    abstract <B> B b(Class<B> t);
+    abstract <C> C c(C a);
+
+    Object f(Iterable<Object> xs) {
+        return c(c(new Object() {
+            <T> void g(Class<T> clazz) {
+                a(clazz).t(b(clazz));
+            }
+        }));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/speculative/8147546/T8147546b.java	Wed Jan 20 10:53:29 2016 +0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016, 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 8147546
+  * @summary regression when type-checking generic calls inside nested declarations occurring in method context
+  * @compile T8147546b.java
+  */
+abstract class T8147546b {
+
+    interface I<O> { void t(O clazz); }
+
+    abstract <B> B b(Class<B> t);
+    abstract <C> C c(C a);
+
+    abstract Object d(Runnable r);
+
+    Object f(Iterable<Object> xs) {
+        return c(d(
+                () -> {
+                    class Foo {
+                        <T> void g(Class<T> clazz, I<T> i) {
+                            i.t(b(clazz));
+                        }
+                    }
+                }));
+    }
+}