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
--- 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));
+ }
+ }
+ }));
+ }
+}