8030741: Inference: implement eager resolution of return types, consistent with JDK-8028800
Reviewed-by: dlsmith, jjg
This commit is contained in:
parent
89be14bfe5
commit
71a85db2be
@ -43,6 +43,7 @@ import com.sun.tools.javac.comp.Check;
|
||||
import com.sun.tools.javac.comp.Enter;
|
||||
import com.sun.tools.javac.comp.Env;
|
||||
import com.sun.tools.javac.jvm.ClassReader;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import static com.sun.tools.javac.code.BoundKind.*;
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
@ -304,8 +305,8 @@ public class Types {
|
||||
}
|
||||
|
||||
/**
|
||||
* Is t a subtype of or convertiable via boxing/unboxing
|
||||
* convertions to s?
|
||||
* Is t a subtype of or convertible via boxing/unboxing
|
||||
* conversions to s?
|
||||
*/
|
||||
public boolean isConvertible(Type t, Type s) {
|
||||
return isConvertible(t, s, noWarnings);
|
||||
@ -1933,6 +1934,17 @@ public class Types {
|
||||
* @param sym a symbol
|
||||
*/
|
||||
public Type asSuper(Type t, Symbol sym) {
|
||||
/* Some examples:
|
||||
*
|
||||
* (Enum<E>, Comparable) => Comparable<E>
|
||||
* (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum<c.s.s.d.AttributeTree.ValueKind>
|
||||
* (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree
|
||||
* (j.u.List<capture#160 of ? extends c.s.s.d.DocTree>, Iterable) =>
|
||||
* Iterable<capture#160 of ? extends c.s.s.d.DocTree>
|
||||
*/
|
||||
if (sym.type == syms.objectType) { //optimization
|
||||
return syms.objectType;
|
||||
}
|
||||
return asSuper.visit(t, sym);
|
||||
}
|
||||
// where
|
||||
@ -3867,9 +3879,11 @@ public class Types {
|
||||
}
|
||||
return buf.reverse();
|
||||
}
|
||||
|
||||
public Type capture(Type t) {
|
||||
if (!t.hasTag(CLASS))
|
||||
if (!t.hasTag(CLASS)) {
|
||||
return t;
|
||||
}
|
||||
if (t.getEnclosingType() != Type.noType) {
|
||||
Type capturedEncl = capture(t.getEnclosingType());
|
||||
if (capturedEncl != t.getEnclosingType()) {
|
||||
|
@ -515,6 +515,11 @@ public class Check {
|
||||
public DeferredAttrContext deferredAttrContext() {
|
||||
return deferredAttr.emptyDeferredAttrContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CheckContext: basicHandler";
|
||||
}
|
||||
};
|
||||
|
||||
/** Check that a given type is assignable to a given proto-type.
|
||||
|
@ -109,6 +109,11 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
void complete() {
|
||||
Assert.error("Empty deferred context!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Empty deferred context!";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -141,24 +141,24 @@ public class Infer {
|
||||
* Main inference entry point - instantiate a generic method type
|
||||
* using given argument types and (possibly) an expected target-type.
|
||||
*/
|
||||
public Type instantiateMethod(Env<AttrContext> env,
|
||||
List<Type> tvars,
|
||||
MethodType mt,
|
||||
Attr.ResultInfo resultInfo,
|
||||
Symbol msym,
|
||||
List<Type> argtypes,
|
||||
boolean allowBoxing,
|
||||
boolean useVarargs,
|
||||
Resolve.MethodResolutionContext resolveContext,
|
||||
Warner warn) throws InferenceException {
|
||||
Type instantiateMethod( Env<AttrContext> env,
|
||||
List<Type> tvars,
|
||||
MethodType mt,
|
||||
Attr.ResultInfo resultInfo,
|
||||
MethodSymbol msym,
|
||||
List<Type> argtypes,
|
||||
boolean allowBoxing,
|
||||
boolean useVarargs,
|
||||
Resolve.MethodResolutionContext resolveContext,
|
||||
Warner warn) throws InferenceException {
|
||||
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
|
||||
final InferenceContext inferenceContext = new InferenceContext(tvars);
|
||||
final InferenceContext inferenceContext = new InferenceContext(tvars); //B0
|
||||
inferenceException.clear();
|
||||
try {
|
||||
DeferredAttr.DeferredAttrContext deferredAttrContext =
|
||||
resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
|
||||
|
||||
resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext,
|
||||
resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext, //B2
|
||||
argtypes, mt.getParameterTypes(), warn);
|
||||
|
||||
if (allowGraphInference &&
|
||||
@ -166,7 +166,8 @@ public class Infer {
|
||||
!warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
|
||||
//inject return constraints earlier
|
||||
checkWithinBounds(inferenceContext, warn); //propagation
|
||||
Type newRestype = generateReturnConstraints(resultInfo, mt, inferenceContext);
|
||||
Type newRestype = generateReturnConstraints(env.tree, resultInfo, //B3
|
||||
mt, inferenceContext);
|
||||
mt = (MethodType)types.createMethodTypeWithReturn(mt, newRestype);
|
||||
//propagate outwards if needed
|
||||
if (resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
|
||||
@ -192,7 +193,7 @@ public class Infer {
|
||||
inferenceContext.restvars().nonEmpty() &&
|
||||
resultInfo != null &&
|
||||
!warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
|
||||
generateReturnConstraints(resultInfo, mt, inferenceContext);
|
||||
generateReturnConstraints(env.tree, resultInfo, mt, inferenceContext);
|
||||
inferenceContext.solveLegacy(false, warn, LegacyInferenceSteps.EQ_UPPER.steps); //maximizeInst
|
||||
mt = (MethodType)inferenceContext.asInstType(mt);
|
||||
}
|
||||
@ -209,6 +210,12 @@ public class Infer {
|
||||
} else {
|
||||
inferenceContext.notifyChange(inferenceContext.boundedVars());
|
||||
}
|
||||
if (resultInfo == null) {
|
||||
/* if the is no result info then we can clear the capture types
|
||||
* cache without affecting any result info check
|
||||
*/
|
||||
inferenceContext.captureTypeCache.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,7 +224,7 @@ public class Infer {
|
||||
* call occurs in a context where a type T is expected, use the expected
|
||||
* type to derive more constraints on the generic method inference variables.
|
||||
*/
|
||||
Type generateReturnConstraints(Attr.ResultInfo resultInfo,
|
||||
Type generateReturnConstraints(JCTree tree, Attr.ResultInfo resultInfo,
|
||||
MethodType mt, InferenceContext inferenceContext) {
|
||||
InferenceContext rsInfoInfContext = resultInfo.checkContext.inferenceContext();
|
||||
Type from = mt.getReturnType();
|
||||
@ -231,13 +238,29 @@ public class Infer {
|
||||
}
|
||||
}
|
||||
}
|
||||
Type qtype1 = inferenceContext.asUndetVar(from);
|
||||
Type to = returnConstraintTarget(qtype1, resultInfo.pt);
|
||||
Type qtype = inferenceContext.asUndetVar(from);
|
||||
Type to = resultInfo.pt;
|
||||
|
||||
if (qtype.hasTag(VOID)) {
|
||||
to = syms.voidType;
|
||||
} else if (to.hasTag(NONE)) {
|
||||
to = from.isPrimitive() ? from : syms.objectType;
|
||||
} else if (qtype.hasTag(UNDETVAR)) {
|
||||
if (resultInfo.pt.isReference()) {
|
||||
to = generateReturnConstraintsUndetVarToReference(
|
||||
tree, (UndetVar)qtype, to, resultInfo, inferenceContext);
|
||||
} else {
|
||||
if (to.isPrimitive()) {
|
||||
to = generateReturnConstraintsPrimitive(tree, (UndetVar)qtype, to,
|
||||
resultInfo, inferenceContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.check(allowGraphInference || !rsInfoInfContext.free(to),
|
||||
"legacy inference engine cannot handle constraints on both sides of a subtyping assertion");
|
||||
//we need to skip capture?
|
||||
Warner retWarn = new Warner();
|
||||
if (!resultInfo.checkContext.compatible(qtype1, rsInfoInfContext.asUndetVar(to), retWarn) ||
|
||||
if (!resultInfo.checkContext.compatible(qtype, rsInfoInfContext.asUndetVar(to), retWarn) ||
|
||||
//unchecked conversion is not allowed in source 7 mode
|
||||
(!allowGraphInference && retWarn.hasLint(Lint.LintCategory.UNCHECKED))) {
|
||||
throw inferenceException
|
||||
@ -247,30 +270,96 @@ public class Infer {
|
||||
return from;
|
||||
}
|
||||
|
||||
Type returnConstraintTarget(Type from, Type to) {
|
||||
if (from.hasTag(VOID)) {
|
||||
return syms.voidType;
|
||||
} else if (to.hasTag(NONE)) {
|
||||
return from.isPrimitive() ? from : syms.objectType;
|
||||
} else if (from.hasTag(UNDETVAR) && to.isPrimitive()) {
|
||||
if (!allowGraphInference) {
|
||||
//if legacy, just return boxed type
|
||||
return types.boxedClass(to).type;
|
||||
private Type generateReturnConstraintsPrimitive(JCTree tree, UndetVar from,
|
||||
Type to, Attr.ResultInfo resultInfo, InferenceContext inferenceContext) {
|
||||
if (!allowGraphInference) {
|
||||
//if legacy, just return boxed type
|
||||
return types.boxedClass(to).type;
|
||||
}
|
||||
//if graph inference we need to skip conflicting boxed bounds...
|
||||
for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.UPPER,
|
||||
InferenceBound.LOWER)) {
|
||||
Type boundAsPrimitive = types.unboxedType(t);
|
||||
if (boundAsPrimitive == null || boundAsPrimitive.hasTag(NONE)) {
|
||||
continue;
|
||||
}
|
||||
//if graph inference we need to skip conflicting boxed bounds...
|
||||
UndetVar uv = (UndetVar)from;
|
||||
for (Type t : uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
|
||||
Type boundAsPrimitive = types.unboxedType(t);
|
||||
if (boundAsPrimitive == null) continue;
|
||||
if (types.isConvertible(boundAsPrimitive, to)) {
|
||||
//effectively skip return-type constraint generation (compatibility)
|
||||
return syms.objectType;
|
||||
return generateReferenceToTargetConstraint(tree, from, to,
|
||||
resultInfo, inferenceContext);
|
||||
}
|
||||
return types.boxedClass(to).type;
|
||||
}
|
||||
|
||||
private Type generateReturnConstraintsUndetVarToReference(JCTree tree,
|
||||
UndetVar from, Type to, Attr.ResultInfo resultInfo,
|
||||
InferenceContext inferenceContext) {
|
||||
Type captureOfTo = types.capture(to);
|
||||
/* T is a reference type, but is not a wildcard-parameterized type, and either
|
||||
*/
|
||||
if (captureOfTo == to) { //not a wildcard parameterized type
|
||||
/* i) B2 contains a bound of one of the forms alpha = S or S <: alpha,
|
||||
* where S is a wildcard-parameterized type, or
|
||||
*/
|
||||
for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
|
||||
Type captureOfBound = types.capture(t);
|
||||
if (captureOfBound != t) {
|
||||
return generateReferenceToTargetConstraint(tree, from, to,
|
||||
resultInfo, inferenceContext);
|
||||
}
|
||||
}
|
||||
|
||||
/* ii) B2 contains two bounds of the forms S1 <: alpha and S2 <: alpha,
|
||||
* where S1 and S2 have supertypes that are two different
|
||||
* parameterizations of the same generic class or interface.
|
||||
*/
|
||||
for (Type aLowerBound : from.getBounds(InferenceBound.LOWER)) {
|
||||
for (Type anotherLowerBound : from.getBounds(InferenceBound.LOWER)) {
|
||||
if (aLowerBound != anotherLowerBound &&
|
||||
commonSuperWithDiffParameterization(aLowerBound, anotherLowerBound)) {
|
||||
/* self comment check if any lower bound may be and undetVar,
|
||||
* in that case the result of this call may be a false positive.
|
||||
* Should this be restricted to non free types?
|
||||
*/
|
||||
return generateReferenceToTargetConstraint(tree, from, to,
|
||||
resultInfo, inferenceContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
return types.boxedClass(to).type;
|
||||
} else {
|
||||
return to;
|
||||
}
|
||||
|
||||
/* T is a parameterization of a generic class or interface, G,
|
||||
* and B2 contains a bound of one of the forms alpha = S or S <: alpha,
|
||||
* where there exists no type of the form G<...> that is a
|
||||
* supertype of S, but the raw type G is a supertype of S
|
||||
*/
|
||||
if (to.isParameterized()) {
|
||||
for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
|
||||
Type sup = types.asSuper(t, to.tsym);
|
||||
if (sup != null && sup.isRaw()) {
|
||||
return generateReferenceToTargetConstraint(tree, from, to,
|
||||
resultInfo, inferenceContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
private boolean commonSuperWithDiffParameterization(Type t, Type s) {
|
||||
Pair<Type, Type> supers = getParameterizedSupers(t, s);
|
||||
return (supers != null && !types.isSameType(supers.fst, supers.snd));
|
||||
}
|
||||
|
||||
private Type generateReferenceToTargetConstraint(JCTree tree, UndetVar from,
|
||||
Type to, Attr.ResultInfo resultInfo,
|
||||
InferenceContext inferenceContext) {
|
||||
inferenceContext.solve(List.of(from.qtype), new Warner());
|
||||
Type capturedType = resultInfo.checkContext.inferenceContext()
|
||||
.cachedCapture(tree, from.inst, false);
|
||||
if (types.isConvertible(capturedType,
|
||||
resultInfo.checkContext.inferenceContext().asUndetVar(to))) {
|
||||
//effectively skip additional return-type constraint generation (compatibility)
|
||||
return syms.objectType;
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2132,8 +2221,10 @@ public class Infer {
|
||||
* Copy variable in this inference context to the given context
|
||||
*/
|
||||
void dupTo(final InferenceContext that) {
|
||||
that.inferencevars = that.inferencevars.appendList(inferencevars);
|
||||
that.undetvars = that.undetvars.appendList(undetvars);
|
||||
that.inferencevars = that.inferencevars.appendList(
|
||||
inferencevars.diff(that.inferencevars));
|
||||
that.undetvars = that.undetvars.appendList(
|
||||
undetvars.diff(that.undetvars));
|
||||
//set up listeners to notify original inference contexts as
|
||||
//propagated vars are inferred in new context
|
||||
for (Type t : inferencevars) {
|
||||
@ -2252,6 +2343,30 @@ public class Infer {
|
||||
return "Inference vars: " + inferencevars + '\n' +
|
||||
"Undet vars: " + undetvars;
|
||||
}
|
||||
|
||||
/* Method Types.capture() generates a new type every time it's applied
|
||||
* to a wildcard parameterized type. This is intended functionality but
|
||||
* there are some cases when what you need is not to generate a new
|
||||
* captured type but to check that a previously generated captured type
|
||||
* is correct. There are cases when caching a captured type for later
|
||||
* reuse is sound. In general two captures from the same AST are equal.
|
||||
* This is why the tree is used as the key of the map below. This map
|
||||
* stores a Type per AST.
|
||||
*/
|
||||
Map<JCTree, Type> captureTypeCache = new HashMap<>();
|
||||
|
||||
Type cachedCapture(JCTree tree, Type t, boolean readOnly) {
|
||||
Type captured = captureTypeCache.get(tree);
|
||||
if (captured != null) {
|
||||
return captured;
|
||||
}
|
||||
|
||||
Type result = types.capture(t);
|
||||
if (result != t && !readOnly) { // then t is a wildcard parameterized type
|
||||
captureTypeCache.put(tree, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
final InferenceContext emptyContext = new InferenceContext(List.<Type>nil());
|
||||
|
@ -564,7 +564,7 @@ public class Resolve {
|
||||
tvars,
|
||||
(MethodType)mt,
|
||||
resultInfo,
|
||||
m,
|
||||
(MethodSymbol)m,
|
||||
argtypes,
|
||||
allowBoxing,
|
||||
useVarargs,
|
||||
@ -772,6 +772,7 @@ public class Resolve {
|
||||
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
|
||||
return nilMethodCheck;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -783,6 +784,11 @@ public class Resolve {
|
||||
void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
|
||||
//do nothing - actual always compatible to formals
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "arityMethodCheck";
|
||||
}
|
||||
};
|
||||
|
||||
List<Type> dummyArgs(int length) {
|
||||
@ -868,6 +874,11 @@ public class Resolve {
|
||||
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
|
||||
return new MostSpecificCheck(strict, actuals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "resolveMethodCheck";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -899,7 +910,9 @@ public class Resolve {
|
||||
@Override
|
||||
public boolean compatible(Type found, Type req, Warner warn) {
|
||||
found = pendingInferenceContext.asUndetVar(found);
|
||||
req = infer.returnConstraintTarget(found, req);
|
||||
if (found.hasTag(UNDETVAR) && req.isPrimitive()) {
|
||||
req = types.boxedClass(req).type;
|
||||
}
|
||||
return super.compatible(found, req, warn);
|
||||
}
|
||||
|
||||
@ -915,6 +928,11 @@ public class Resolve {
|
||||
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
|
||||
return new MostSpecificCheck(strict, actuals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MethodReferenceCheck";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -954,6 +972,11 @@ public class Resolve {
|
||||
public DeferredAttrContext deferredAttrContext() {
|
||||
return deferredAttrContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MethodCheckContext";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -972,7 +995,12 @@ public class Resolve {
|
||||
DeferredType dt = (DeferredType)found;
|
||||
return dt.check(this);
|
||||
} else {
|
||||
return super.check(pos, chk.checkNonVoid(pos, types.capture(U(found.baseType()))));
|
||||
Type uResult = U(found.baseType());
|
||||
Type capturedType = pos == null || pos.getTree() == null ?
|
||||
types.capture(uResult) :
|
||||
checkContext.inferenceContext()
|
||||
.cachedCapture(pos.getTree(), uResult, true);
|
||||
return super.check(pos, chk.checkNonVoid(pos, capturedType));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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 8030741
|
||||
* @summary Inference: implement eager resolution of return types, consistent with JDK-8028800
|
||||
* @compile EagerReturnTypeResolutionTesta.java
|
||||
*/
|
||||
|
||||
public class EagerReturnTypeResolutionTesta {
|
||||
|
||||
abstract class Test1<T>{
|
||||
abstract <S> S foo(S x, S y);
|
||||
<S extends Number & Comparable<? extends Number>> void baz(Test1<S> a){}
|
||||
|
||||
void bar(Test1<Long> x, Test1<Integer> y){
|
||||
baz(foo(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Test2<T>{
|
||||
abstract <S> S foo(S x, S y);
|
||||
abstract <S1> void baz(Test2<S1> a);
|
||||
|
||||
void bar(Test2<Integer> y, Test2<Long> x){
|
||||
baz(foo(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Test3<T>{
|
||||
abstract <S> S foo(S x, S y);
|
||||
<T extends Number & Comparable<?>,
|
||||
S extends Number & Comparable<? extends T>> void baz(Test3<S> a){}
|
||||
|
||||
void bar(Test3<Long> x, Test3<Integer> y){
|
||||
baz(foo(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Test4 {
|
||||
abstract class A0<T> {}
|
||||
|
||||
abstract class A1<T> extends A0<T> {}
|
||||
|
||||
abstract class A2<T> extends A0<T> {}
|
||||
|
||||
abstract <S> S foo(S x, S y);
|
||||
abstract <S1> void baz(A0<S1> a);
|
||||
|
||||
void bar(A2<Integer> y, A1<Long> x){
|
||||
baz(foo(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8030741
|
||||
* @summary Inference: implement eager resolution of return types, consistent with JDK-8028800
|
||||
* @compile/fail/ref=EagerReturnTypeResolutionTestb.out -XDrawDiagnostics EagerReturnTypeResolutionTestb.java
|
||||
* @author Dan Smith
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EagerReturnTypeResolutionTestb {
|
||||
interface I<S> {}
|
||||
interface J<S> extends I<S> {}
|
||||
interface K extends I<String> {}
|
||||
interface L<S> extends I {}
|
||||
|
||||
<T> T lower(List<? extends T> l) { return null; }
|
||||
<T> T lower2(List<? extends T> l1, List<? extends T> l2) { return null; }
|
||||
|
||||
<T> T upper(List<? super T> l) { return null; }
|
||||
<T> T upper2(List<? super T> l1, List<? super T> l2) { return null; }
|
||||
|
||||
<T> T eq(List<T> l) { return null; }
|
||||
<T> T eq2(List<T> l1, List<T> l2) { return null; }
|
||||
|
||||
<X> void takeI(I<X> i) {}
|
||||
void takeIString(I<String> i) {}
|
||||
I<String> iStringField;
|
||||
|
||||
void takeLong(long arg) {}
|
||||
long longField;
|
||||
|
||||
void testSimpleCaptureOK(List<I<?>> i1) {
|
||||
takeI(lower(i1)); // ok*
|
||||
takeI(eq(i1)); // ok*
|
||||
takeI(upper(i1)); // ok, no capture
|
||||
takeIString(upper(i1)); // ok
|
||||
iStringField = upper(i1); // ok
|
||||
}
|
||||
|
||||
void testSimpleCaptureKO(List<I<?>> i1) {
|
||||
takeIString(lower(i1)); // ERROR
|
||||
takeIString(eq(i1)); // ERROR
|
||||
iStringField = lower(i1); // ERROR
|
||||
iStringField = eq(i1); // ERROR
|
||||
}
|
||||
|
||||
void testMultiCaptureOK(List<I<String>> i1, List<I<Integer>> i2, List<I<?>> i3,
|
||||
List<J<String>> j1, List<J<Integer>> j2, List<K> k1) {
|
||||
/* Lines marked with JDK-8029002 should be uncommented once this bug is
|
||||
* fixed
|
||||
*/
|
||||
takeI(lower2(i1, i2)); // ok*
|
||||
takeI(lower2(i1, i3)); // ok*
|
||||
takeI(upper2(i1, i3)); // ok, no capture* JDK-8029002
|
||||
|
||||
takeIString(upper2(i1, i3)); // ok, no capture
|
||||
iStringField = upper2(i1, i3); // ok, no capture
|
||||
|
||||
takeI(lower2(j1, j2)); // ok*
|
||||
takeI(lower2(j1, k1)); // ok, no capture
|
||||
takeI(upper2(j1, k1)); // ok, no capture* JDK-8029002
|
||||
|
||||
takeIString(lower2(j1, k1)); // ok, no capture
|
||||
takeIString(upper2(j1, k1)); // ok, no capture
|
||||
|
||||
iStringField = lower2(j1, k1); // ok, no capture
|
||||
iStringField = upper2(j1, k1); // ok, no capture
|
||||
takeI(lower2(j2, k1)); // ok*
|
||||
}
|
||||
|
||||
void testMultiCaptureKO(List<I<String>> i1, List<I<Integer>> i2, List<I<?>> i3,
|
||||
List<J<String>> j1, List<J<Integer>> j2, List<K> k1) {
|
||||
takeI(eq2(i1, i2)); // ERROR, bad bounds
|
||||
takeI(upper2(i1, i2)); // ERROR, bad bounds
|
||||
|
||||
takeIString(lower2(i1, i2)); // ERROR
|
||||
takeIString(eq2(i1, i2)); // ERROR, bad bounds
|
||||
takeIString(upper2(i1, i2)); // ERROR, bad bounds
|
||||
|
||||
iStringField = lower2(i1, i2); // ERROR
|
||||
iStringField = eq2(i1, i2); // ERROR, bad bounds
|
||||
iStringField = upper2(i1, i2); // ERROR, bad bounds
|
||||
|
||||
takeI(eq2(i1, i3)); // ERROR, bad bounds
|
||||
takeIString(lower2(i1, i3)); // ERROR
|
||||
takeIString(eq2(i1, i3)); // ERROR, bad bounds
|
||||
|
||||
iStringField = lower2(i1, i3); // ERROR
|
||||
iStringField = eq2(i1, i3); // ERROR, bad bounds
|
||||
takeI(eq2(j1, j2)); // ERROR, bad bounds
|
||||
takeI(upper2(j1, j2)); // ERROR, bad bounds
|
||||
|
||||
takeIString(lower2(j1, j2)); // ERROR
|
||||
takeIString(eq2(j1, j2)); // ERROR, bad bounds
|
||||
takeIString(upper2(j1, j2)); // ERROR, bad bounds
|
||||
|
||||
iStringField = lower2(j1, j2); // ERROR
|
||||
iStringField = eq2(j1, j2); // ERROR, bad bounds
|
||||
iStringField = upper2(j1, j2); // ERROR, bad bounds
|
||||
|
||||
takeI(eq2(j1, k1)); // ERROR, bad bounds
|
||||
takeIString(eq2(j1, k1)); // ERROR, bad bounds
|
||||
iStringField = eq2(j1, k1); // ERROR, bad bounds
|
||||
takeI(eq2(j2, k1)); // ERROR, bad bounds
|
||||
takeI(upper2(j2, k1)); // ERROR, bad bounds; actual: no error, see JDK-8037474
|
||||
|
||||
takeIString(lower2(j2, k1)); // ERROR
|
||||
takeIString(eq2(j2, k1)); // ERROR, bad bounds
|
||||
takeIString(upper2(j2, k1)); // ERROR, bad bounds
|
||||
|
||||
iStringField = lower2(j2, k1); // ERROR
|
||||
iStringField = eq2(j2, k1); // ERROR, bad bounds
|
||||
iStringField = upper2(j2, k1); // ERROR, bad bounds
|
||||
}
|
||||
|
||||
void testRawOK(List<I> i1, List<J> j1, List<L<String>> l1) {
|
||||
takeI(lower(i1)); // ok, unchecked
|
||||
takeI(eq(i1)); // ok, unchecked
|
||||
takeI(upper(i1)); // ok, no capture, not unchecked
|
||||
|
||||
takeIString(lower(i1)); // ok, unchecked
|
||||
takeIString(eq(i1)); // ok, unchecked
|
||||
takeIString(upper(i1)); // ok, no capture, not unchecked
|
||||
|
||||
iStringField = lower(i1); // ok, unchecked
|
||||
iStringField = eq(i1); // ok, unchecked
|
||||
iStringField = upper(i1); // ok, no capture, not unchecked
|
||||
|
||||
takeI(lower(j1)); // ok, unchecked
|
||||
takeI(eq(j1)); // ok, unchecked
|
||||
takeI(upper(j1)); // bad bounds? -- spec is unclear
|
||||
|
||||
takeIString(lower(j1)); // ok, unchecked
|
||||
takeIString(eq(j1)); // ok, unchecked
|
||||
takeIString(upper(j1)); // bad bounds? -- spec is unclear
|
||||
|
||||
iStringField = lower(j1); // ok, unchecked
|
||||
iStringField = eq(j1); // ok, unchecked
|
||||
iStringField = upper(j1); // bad bounds? -- spec is unclear
|
||||
|
||||
takeI(lower(l1)); // ok, unchecked
|
||||
takeI(eq(l1)); // ok, unchecked
|
||||
takeI(upper(l1)); // bad bounds? -- spec is unclear
|
||||
|
||||
takeIString(lower(l1)); // ok, unchecked
|
||||
takeIString(eq(l1)); // ok, unchecked
|
||||
takeIString(upper(l1)); // bad bounds? -- spec is unclear
|
||||
|
||||
iStringField = lower(l1); // ok, unchecked
|
||||
iStringField = eq(l1); // ok, unchecked
|
||||
iStringField = upper(l1); // bad bounds? -- spec is unclear
|
||||
}
|
||||
|
||||
void testPrimOK(List<Integer> i1, List<Long> l1, List<Double> d1) {
|
||||
takeLong(lower(i1)); // ok
|
||||
takeLong(eq(i1)); // ok
|
||||
takeLong(upper(i1)); // ok*
|
||||
|
||||
longField = lower(i1); // ok
|
||||
longField = eq(i1); // ok
|
||||
longField = upper(i1); // ok*
|
||||
|
||||
takeLong(lower(l1)); // ok
|
||||
takeLong(eq(l1)); // ok
|
||||
takeLong(upper(l1)); // ok
|
||||
|
||||
longField = lower(l1); // ok
|
||||
longField = eq(l1); // ok
|
||||
longField = upper(l1); // ok
|
||||
}
|
||||
|
||||
void testPrimKO(List<Integer> i1, List<Long> l1, List<Double> d1) {
|
||||
takeLong(lower(d1)); // ERROR
|
||||
takeLong(eq(d1)); // ERROR
|
||||
takeLong(upper(d1)); // ERROR
|
||||
|
||||
longField = lower(d1); // ERROR
|
||||
longField = eq(d1); // ERROR
|
||||
longField = upper(d1); // ERROR
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
EagerReturnTypeResolutionTestb.java:42:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ?>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
|
||||
EagerReturnTypeResolutionTestb.java:43:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ?>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
|
||||
EagerReturnTypeResolutionTestb.java:44:29: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:45:26: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:74:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:75:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:77:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
|
||||
EagerReturnTypeResolutionTestb.java:78:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:79:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:81:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:82:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:83:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:85:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<?>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<?>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:86:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ?>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
|
||||
EagerReturnTypeResolutionTestb.java:87:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<?>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<?>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:89:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:90:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<?>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<?>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:91:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:92:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:94:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.J<compiler.misc.type.captureof: 1, ? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
|
||||
EagerReturnTypeResolutionTestb.java:95:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:96:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:98:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:99:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:100:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:102:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:103:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:104:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.String>)
|
||||
EagerReturnTypeResolutionTestb.java:105:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>)
|
||||
EagerReturnTypeResolutionTestb.java:106:9: compiler.err.cant.apply.symbol: kindname.method, takeI, EagerReturnTypeResolutionTestb.I<X>, java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Integer, java.lang.Integer,java.lang.String)
|
||||
EagerReturnTypeResolutionTestb.java:108:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
|
||||
EagerReturnTypeResolutionTestb.java:109:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>)
|
||||
EagerReturnTypeResolutionTestb.java:110:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.I<java.lang.String>,EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>,java.lang.Object))
|
||||
EagerReturnTypeResolutionTestb.java:112:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:113:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>)
|
||||
EagerReturnTypeResolutionTestb.java:114:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.I<java.lang.String>,EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>,java.lang.Object)
|
||||
EagerReturnTypeResolutionTestb.java:174:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long))
|
||||
EagerReturnTypeResolutionTestb.java:175:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long))
|
||||
EagerReturnTypeResolutionTestb.java:176:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long))
|
||||
EagerReturnTypeResolutionTestb.java:178:26: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long)
|
||||
EagerReturnTypeResolutionTestb.java:179:23: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long)
|
||||
EagerReturnTypeResolutionTestb.java:180:26: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long)
|
||||
- compiler.note.unchecked.filename: EagerReturnTypeResolutionTestb.java
|
||||
- compiler.note.unchecked.recompile
|
||||
42 errors
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8030741
|
||||
* @summary Inference: implement eager resolution of return types, consistent with JDK-8028800
|
||||
* @compile/fail/ref=PrimitiveTypeBoxingTest.out -XDrawDiagnostics PrimitiveTypeBoxingTest.java
|
||||
*/
|
||||
|
||||
public class PrimitiveTypeBoxingTest {
|
||||
|
||||
static void foo(long arg) {}
|
||||
static void bar(int arg) {}
|
||||
|
||||
interface F<X> { void get(X arg); }
|
||||
|
||||
<Z> void m1(F<Z> f, Z arg) {}
|
||||
<Z> void m2(Z arg, F<Z> f) {}
|
||||
|
||||
void test() {
|
||||
m1(PrimitiveTypeBoxingTest::foo, 23); // expected: error
|
||||
m2(23, PrimitiveTypeBoxingTest::foo); // expected: error
|
||||
|
||||
m1(PrimitiveTypeBoxingTest::bar, 23); // expected: success
|
||||
m2(23, PrimitiveTypeBoxingTest::bar); // expected: success
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
PrimitiveTypeBoxingTest.java:19:9: compiler.err.cant.apply.symbol: kindname.method, m1, PrimitiveTypeBoxingTest.F<Z>,Z, @490,int, kindname.class, PrimitiveTypeBoxingTest, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.Long,java.lang.Object)
|
||||
PrimitiveTypeBoxingTest.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m2, Z,PrimitiveTypeBoxingTest.F<Z>, int,@559, kindname.class, PrimitiveTypeBoxingTest, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.Long,java.lang.Object)
|
||||
2 errors
|
Loading…
x
Reference in New Issue
Block a user