mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-05 03:05:47 +00:00
8147546: regression when type-checking generic calls inside nested declarations occurring in method context
Attr.visitClassDef should set a temporary ArgumentAttr cache when in speculative mode Reviewed-by: vromero
This commit is contained in:
parent
9dcc8b2068
commit
e782acbf37
@ -42,6 +42,7 @@ import com.sun.tools.javac.code.Symbol.*;
|
||||
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 class Attr extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user