Merge
This commit is contained in:
commit
6bccaed81e
@ -226,8 +226,18 @@ public class Analyzer {
|
||||
@Override
|
||||
void process(JCNewClass oldTree, JCNewClass newTree, boolean hasErrors) {
|
||||
if (!hasErrors) {
|
||||
List<Type> inferredArgs = newTree.type.getTypeArguments();
|
||||
List<Type> explicitArgs = oldTree.type.getTypeArguments();
|
||||
List<Type> inferredArgs, explicitArgs;
|
||||
if (oldTree.def != null) {
|
||||
inferredArgs = newTree.def.implementing.nonEmpty()
|
||||
? newTree.def.implementing.get(0).type.getTypeArguments()
|
||||
: newTree.def.extending.type.getTypeArguments();
|
||||
explicitArgs = oldTree.def.implementing.nonEmpty()
|
||||
? oldTree.def.implementing.get(0).type.getTypeArguments()
|
||||
: oldTree.def.extending.type.getTypeArguments();
|
||||
} else {
|
||||
inferredArgs = newTree.type.getTypeArguments();
|
||||
explicitArgs = oldTree.type.getTypeArguments();
|
||||
}
|
||||
for (Type t : inferredArgs) {
|
||||
if (!types.isSameType(t, explicitArgs.head)) {
|
||||
log.warning(oldTree.clazz, "diamond.redundant.args.1",
|
||||
|
@ -165,8 +165,6 @@ public class Attr extends JCTree.Visitor {
|
||||
unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
|
||||
unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
|
||||
recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
|
||||
|
||||
noCheckTree = make.at(-1).Skip();
|
||||
}
|
||||
|
||||
/** Switch: relax some constraints for retrofit mode.
|
||||
@ -225,26 +223,6 @@ public class Attr extends JCTree.Visitor {
|
||||
final Type found,
|
||||
final KindSelector ownkind,
|
||||
final ResultInfo resultInfo) {
|
||||
return check(tree, found, ownkind, resultInfo, true);
|
||||
}
|
||||
/** Check kind and type of given tree against protokind and prototype.
|
||||
* If check succeeds, store type in tree and return it.
|
||||
* If check fails, store errType in tree and return it.
|
||||
* No checks are performed if the prototype is a method type.
|
||||
* It is not necessary in this case since we know that kind and type
|
||||
* are correct.
|
||||
*
|
||||
* @param tree The tree whose kind and type is checked
|
||||
* @param found The computed type of the tree
|
||||
* @param ownkind The computed kind of the tree
|
||||
* @param resultInfo The expected result of the tree
|
||||
* @param recheckPostInference If true and inference is underway, arrange to recheck the tree after inference finishes.
|
||||
*/
|
||||
Type check(final JCTree tree,
|
||||
final Type found,
|
||||
final KindSelector ownkind,
|
||||
final ResultInfo resultInfo,
|
||||
boolean recheckPostInference) {
|
||||
InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
|
||||
Type owntype;
|
||||
boolean shouldCheck = !found.hasTag(ERROR) &&
|
||||
@ -259,12 +237,12 @@ public class Attr extends JCTree.Visitor {
|
||||
//delay the check if there are inference variables in the found type
|
||||
//this means we are dealing with a partially inferred poly expression
|
||||
owntype = shouldCheck ? resultInfo.pt : found;
|
||||
if (recheckPostInference) {
|
||||
if (resultInfo.checkMode.installPostInferenceHook()) {
|
||||
inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt),
|
||||
instantiatedContext -> {
|
||||
ResultInfo pendingResult =
|
||||
resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
|
||||
check(tree, inferenceContext.asInstType(found), ownkind, pendingResult, false);
|
||||
check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@ -272,7 +250,7 @@ public class Attr extends JCTree.Visitor {
|
||||
resultInfo.check(tree, found) :
|
||||
found;
|
||||
}
|
||||
if (tree != noCheckTree) {
|
||||
if (resultInfo.checkMode.updateTreeType()) {
|
||||
tree.type = owntype;
|
||||
}
|
||||
return owntype;
|
||||
@ -455,20 +433,60 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mode controlling behavior of Attr.Check
|
||||
*/
|
||||
enum CheckMode {
|
||||
|
||||
NORMAL,
|
||||
|
||||
NO_TREE_UPDATE { // Mode signalling 'fake check' - skip tree update
|
||||
@Override
|
||||
public boolean updateTreeType() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
NO_INFERENCE_HOOK { // Mode signalling that caller will manage free types in tree decorations.
|
||||
@Override
|
||||
public boolean installPostInferenceHook() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public boolean updateTreeType() {
|
||||
return true;
|
||||
}
|
||||
public boolean installPostInferenceHook() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ResultInfo {
|
||||
final KindSelector pkind;
|
||||
final Type pt;
|
||||
final CheckContext checkContext;
|
||||
final CheckMode checkMode;
|
||||
|
||||
ResultInfo(KindSelector pkind, Type pt) {
|
||||
this(pkind, pt, chk.basicHandler);
|
||||
this(pkind, pt, chk.basicHandler, CheckMode.NORMAL);
|
||||
}
|
||||
|
||||
ResultInfo(KindSelector pkind, Type pt, CheckMode checkMode) {
|
||||
this(pkind, pt, chk.basicHandler, checkMode);
|
||||
}
|
||||
|
||||
protected ResultInfo(KindSelector pkind,
|
||||
Type pt, CheckContext checkContext) {
|
||||
this(pkind, pt, checkContext, CheckMode.NORMAL);
|
||||
}
|
||||
|
||||
protected ResultInfo(KindSelector pkind,
|
||||
Type pt, CheckContext checkContext, CheckMode checkMode) {
|
||||
this.pkind = pkind;
|
||||
this.pt = pt;
|
||||
this.checkContext = checkContext;
|
||||
this.checkMode = checkMode;
|
||||
}
|
||||
|
||||
protected Type check(final DiagnosticPosition pos, final Type found) {
|
||||
@ -476,15 +494,23 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
protected ResultInfo dup(Type newPt) {
|
||||
return new ResultInfo(pkind, newPt, checkContext);
|
||||
return new ResultInfo(pkind, newPt, checkContext, checkMode);
|
||||
}
|
||||
|
||||
protected ResultInfo dup(CheckContext newContext) {
|
||||
return new ResultInfo(pkind, pt, newContext);
|
||||
return new ResultInfo(pkind, pt, newContext, checkMode);
|
||||
}
|
||||
|
||||
protected ResultInfo dup(Type newPt, CheckContext newContext) {
|
||||
return new ResultInfo(pkind, newPt, newContext);
|
||||
return new ResultInfo(pkind, newPt, newContext, checkMode);
|
||||
}
|
||||
|
||||
protected ResultInfo dup(Type newPt, CheckContext newContext, CheckMode newMode) {
|
||||
return new ResultInfo(pkind, newPt, newContext, newMode);
|
||||
}
|
||||
|
||||
protected ResultInfo dup(CheckMode newMode) {
|
||||
return new ResultInfo(pkind, pt, checkContext, newMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -550,10 +576,6 @@ public class Attr extends JCTree.Visitor {
|
||||
*/
|
||||
Type result;
|
||||
|
||||
/** Synthetic tree to be used during 'fake' checks.
|
||||
*/
|
||||
JCTree noCheckTree;
|
||||
|
||||
/** Visitor method: attribute a tree, catching any completion failure
|
||||
* exceptions. Return the tree's type.
|
||||
*
|
||||
@ -2055,9 +2077,9 @@ public class Attr extends JCTree.Visitor {
|
||||
enclosingContext.report(tree.clazz,
|
||||
diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", csym), details));
|
||||
}
|
||||
});
|
||||
}, CheckMode.NO_TREE_UPDATE);
|
||||
Type constructorType = tree.constructorType = types.createErrorType(clazztype);
|
||||
constructorType = checkId(noCheckTree, site,
|
||||
constructorType = checkId(tree, site,
|
||||
constructor,
|
||||
diamondEnv,
|
||||
diamondResult);
|
||||
@ -2083,11 +2105,11 @@ public class Attr extends JCTree.Visitor {
|
||||
tree.constructor = rs.resolveConstructor(
|
||||
tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
|
||||
if (cdef == null) { //do not check twice!
|
||||
tree.constructorType = checkId(noCheckTree,
|
||||
tree.constructorType = checkId(tree,
|
||||
clazztype,
|
||||
tree.constructor,
|
||||
rsEnv,
|
||||
new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
|
||||
new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes), CheckMode.NO_TREE_UPDATE));
|
||||
if (rsEnv.info.lastResolveVarargs())
|
||||
Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
|
||||
}
|
||||
@ -2220,15 +2242,15 @@ public class Attr extends JCTree.Visitor {
|
||||
tree.pos(), localEnv, clazztype, finalargtypes, typeargtypes);
|
||||
Assert.check(!sym.kind.isResolutionError());
|
||||
tree.constructor = sym;
|
||||
tree.constructorType = checkId(noCheckTree,
|
||||
tree.constructorType = checkId(tree,
|
||||
clazztype,
|
||||
tree.constructor,
|
||||
localEnv,
|
||||
new ResultInfo(pkind, newMethodTemplate(syms.voidType, finalargtypes, typeargtypes)));
|
||||
new ResultInfo(pkind, newMethodTemplate(syms.voidType, finalargtypes, typeargtypes), CheckMode.NO_TREE_UPDATE));
|
||||
}
|
||||
Type owntype = (tree.constructor != null && tree.constructor.kind == MTH) ?
|
||||
clazztype : types.createErrorType(tree.type);
|
||||
result = check(tree, owntype, KindSelector.VAL, resultInfo, false);
|
||||
result = check(tree, owntype, KindSelector.VAL, resultInfo.dup(CheckMode.NO_INFERENCE_HOOK));
|
||||
chk.validate(tree.typeargs, localEnv);
|
||||
}
|
||||
|
||||
@ -2840,9 +2862,9 @@ public class Attr extends JCTree.Visitor {
|
||||
resultInfo.dup(newMethodTemplate(
|
||||
desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(),
|
||||
that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes),
|
||||
new FunctionalReturnContext(resultInfo.checkContext));
|
||||
new FunctionalReturnContext(resultInfo.checkContext), CheckMode.NO_TREE_UPDATE);
|
||||
|
||||
Type refType = checkId(noCheckTree, lookupHelper.site, refSym, localEnv, checkInfo);
|
||||
Type refType = checkId(that, lookupHelper.site, refSym, localEnv, checkInfo);
|
||||
|
||||
if (that.kind.isUnbound() &&
|
||||
resultInfo.checkContext.inferenceContext().free(argtypes.head)) {
|
||||
@ -3996,8 +4018,8 @@ public class Attr extends JCTree.Visitor {
|
||||
all_multicatchTypes.append(ctype);
|
||||
}
|
||||
}
|
||||
Type t = check(noCheckTree, types.lub(multicatchTypes.toList()),
|
||||
KindSelector.TYP, resultInfo);
|
||||
Type t = check(tree, types.lub(multicatchTypes.toList()),
|
||||
KindSelector.TYP, resultInfo.dup(CheckMode.NO_TREE_UPDATE));
|
||||
if (t.hasTag(CLASS)) {
|
||||
List<Type> alternatives =
|
||||
((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList();
|
||||
|
@ -841,6 +841,15 @@ public class Check {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitTypeVar(TypeVar t, Void s) {
|
||||
/* Any type variable mentioned in the inferred type must have been declared as a type parameter
|
||||
(i.e cannot have been produced by capture conversion (5.1.10) or by inference (18.4)
|
||||
*/
|
||||
return t.tsym.owner.type.getTypeArguments().contains(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitCapturedType(CapturedType t, Void s) {
|
||||
return false;
|
||||
|
@ -2006,6 +2006,8 @@ public class Resolve {
|
||||
* @param name The type's name.
|
||||
*/
|
||||
Symbol findType(Env<AttrContext> env, Name name) {
|
||||
if (name == names.empty)
|
||||
return typeNotFound; // do not allow inadvertent "lookup" of anonymous types
|
||||
Symbol bestSoFar = typeNotFound;
|
||||
Symbol sym;
|
||||
boolean staticOnly = false;
|
||||
|
@ -69,7 +69,6 @@ public class Gen extends JCTree.Visitor {
|
||||
private final TreeMaker make;
|
||||
private final Names names;
|
||||
private final Target target;
|
||||
private final Type stringBufferType;
|
||||
private final Map<Type,Symbol> stringBufferAppend;
|
||||
private Name accessDollar;
|
||||
private final Types types;
|
||||
@ -107,7 +106,6 @@ public class Gen extends JCTree.Visitor {
|
||||
target = Target.instance(context);
|
||||
types = Types.instance(context);
|
||||
methodType = new MethodType(null, null, null, syms.methodClass);
|
||||
stringBufferType = syms.stringBuilderType;
|
||||
stringBufferAppend = new HashMap<>();
|
||||
accessDollar = names.
|
||||
fromString("access" + target.syntheticNameChar());
|
||||
@ -2070,10 +2068,10 @@ public class Gen extends JCTree.Visitor {
|
||||
/** Make a new string buffer.
|
||||
*/
|
||||
void makeStringBuffer(DiagnosticPosition pos) {
|
||||
code.emitop2(new_, makeRef(pos, stringBufferType));
|
||||
code.emitop2(new_, makeRef(pos, syms.stringBuilderType));
|
||||
code.emitop0(dup);
|
||||
callMethod(
|
||||
pos, stringBufferType, names.init, List.<Type>nil(), false);
|
||||
pos, syms.stringBuilderType, names.init, List.<Type>nil(), false);
|
||||
}
|
||||
|
||||
/** Append value (on tos) to string buffer (on tos - 1).
|
||||
@ -2091,7 +2089,7 @@ public class Gen extends JCTree.Visitor {
|
||||
if (method == null) {
|
||||
method = rs.resolveInternalMethod(tree.pos(),
|
||||
attrEnv,
|
||||
stringBufferType,
|
||||
syms.stringBuilderType,
|
||||
names.append,
|
||||
List.of(t),
|
||||
null);
|
||||
@ -2122,7 +2120,7 @@ public class Gen extends JCTree.Visitor {
|
||||
void bufferToString(DiagnosticPosition pos) {
|
||||
callMethod(
|
||||
pos,
|
||||
stringBufferType,
|
||||
syms.stringBuilderType,
|
||||
names.toString,
|
||||
List.<Type>nil(),
|
||||
false);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2015, 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
|
||||
@ -690,7 +690,7 @@ public class TreeMaker implements JCTree.Factory {
|
||||
break;
|
||||
case WILDCARD: {
|
||||
WildcardType a = ((WildcardType) t);
|
||||
tp = Wildcard(TypeBoundKind(a.kind), Type(a.type));
|
||||
tp = Wildcard(TypeBoundKind(a.kind), a.kind == BoundKind.UNBOUND ? null : Type(a.type));
|
||||
break;
|
||||
}
|
||||
case CLASS:
|
||||
|
@ -35,7 +35,8 @@ enum Profile {
|
||||
COMPACT2("compact2", 2, "java.compact2"),
|
||||
COMPACT3("compact3", 3, "java.compact3", "java.smartcardio", "jdk.sctp",
|
||||
"jdk.httpserver", "jdk.security.auth",
|
||||
"jdk.naming.dns", "jdk.naming.rmi"),
|
||||
"jdk.naming.dns", "jdk.naming.rmi",
|
||||
"jdk.management"),
|
||||
FULL_JRE("Full JRE", 4, "java.se", "jdk.deploy.osx", "jdk.charsets",
|
||||
"jdk.crypto.ec", "jdk.crypto.pkcs11",
|
||||
"jdk.crypto.mscapi", "jdk.crypto.ucrypto", "jdk.jvmstat",
|
||||
|
@ -3,11 +3,11 @@ T6939780.java:22:28: compiler.warn.diamond.redundant.args
|
||||
T6939780.java:23:28: compiler.warn.diamond.redundant.args.1: T6939780.Foo<java.lang.Integer>, T6939780.Foo<java.lang.Number>
|
||||
T6939780.java:24:33: compiler.warn.diamond.redundant.args
|
||||
T6939780.java:25:28: compiler.warn.diamond.redundant.args
|
||||
T6939780.java:26:28: compiler.warn.diamond.redundant.args
|
||||
T6939780.java:26:28: compiler.warn.diamond.redundant.args.1: T6939780.Foo<java.lang.Integer>, T6939780.Foo<java.lang.Number>
|
||||
T6939780.java:30:19: compiler.warn.diamond.redundant.args
|
||||
T6939780.java:31:19: compiler.warn.diamond.redundant.args
|
||||
T6939780.java:32:19: compiler.warn.diamond.redundant.args.1: T6939780.Foo<java.lang.Integer>, T6939780.Foo<java.lang.Number>
|
||||
T6939780.java:33:19: compiler.warn.diamond.redundant.args
|
||||
T6939780.java:34:19: compiler.warn.diamond.redundant.args
|
||||
T6939780.java:35:19: compiler.warn.diamond.redundant.args
|
||||
T6939780.java:35:19: compiler.warn.diamond.redundant.args.1: T6939780.Foo<java.lang.Integer>, T6939780.Foo<java.lang.Number>
|
||||
12 warnings
|
||||
|
36
langtools/test/tools/javac/generics/diamond/neg/Neg20.java
Normal file
36
langtools/test/tools/javac/generics/diamond/neg/Neg20.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8078592
|
||||
* @summary Compiler fails to reject erroneous use of diamond with anonymous classes involving "fresh" type variables.
|
||||
* @compile/fail/ref=Neg20.out Neg20.java -XDrawDiagnostics
|
||||
*/
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
public class Neg20 {
|
||||
static class Foo<E extends B<E>> {
|
||||
public Foo<E> complexMethod(E a) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
static class Goo<@T E> {
|
||||
public Goo<E> complexMethod(E a) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
static class B<V> {
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
static @interface T {
|
||||
}
|
||||
|
||||
public static void check() {
|
||||
Foo<?> t4 = new Foo<>() {
|
||||
};
|
||||
Goo<?> g4 = new Goo<>() {
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
Neg20.java:31:28: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg20.Foo), (compiler.misc.diamond.invalid.arg: E, (compiler.misc.diamond: Neg20.Foo))
|
||||
1 error
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8078473
|
||||
* @summary javac diamond finder crashes when used to build java.base module
|
||||
* @compile/ref=T8078473.out T8078473.java -XDrawDiagnostics -XDfind=diamond
|
||||
*/
|
||||
|
||||
class T8078473<P, Q> {
|
||||
|
||||
static class C<T, U> {
|
||||
C(T8078473<?, ?> p) {}
|
||||
}
|
||||
|
||||
{
|
||||
new C<Q, Q>(this) {};
|
||||
new C<Q, Q>(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
T8078473.java:15:14: compiler.warn.diamond.redundant.args.1: T8078473.C<Q,Q>, T8078473.C<java.lang.Object,java.lang.Object>
|
||||
T8078473.java:16:14: compiler.warn.diamond.redundant.args.1: T8078473.C<Q,Q>, T8078473.C<java.lang.Object,java.lang.Object>
|
||||
2 warnings
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8078473
|
||||
* @summary javac diamond finder crashes when used to build java.base module
|
||||
* @compile/ref=T8078473_2.out T8078473_2.java -XDrawDiagnostics -XDfind=diamond
|
||||
*/
|
||||
|
||||
package java.util.stream;
|
||||
|
||||
class T8078473_2<P, Q> {
|
||||
|
||||
static class C<T, U> {
|
||||
C(T8078473_2<?, ?> p) {}
|
||||
}
|
||||
|
||||
{
|
||||
new C<Q, Q>(this) {};
|
||||
new C<Q, Q>(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
T8078473_2.java:17:13: compiler.warn.diamond.redundant.args.1: java.util.stream.T8078473_2.C<Q,Q>, java.util.stream.T8078473_2.C<java.lang.Object,java.lang.Object>
|
||||
T8078473_2.java:18:13: compiler.warn.diamond.redundant.args.1: java.util.stream.T8078473_2.C<Q,Q>, java.util.stream.T8078473_2.C<java.lang.Object,java.lang.Object>
|
||||
2 warnings
|
Loading…
Reference in New Issue
Block a user