8015505: Spurious inference error when return type of generic method requires unchecked conversion to target
Summary: Use check context compatibility during 15.12.2.8 check (only when JDK 8 inference is enabled)
Reviewed-by: jjg
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Jun 04 11:31:12 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Jun 04 11:34:31 2013 +0100
@@ -218,8 +218,8 @@
//we need to skip capture?
Warner retWarn = new Warner();
if (!resultInfo.checkContext.compatible(qtype1, resultInfo.checkContext.inferenceContext().asFree(to), retWarn) ||
- //unchecked conversion is not allowed
- retWarn.hasLint(Lint.LintCategory.UNCHECKED)) {
+ //unchecked conversion is not allowed in source 7 mode
+ (!allowGraphInference && retWarn.hasLint(Lint.LintCategory.UNCHECKED))) {
throw inferenceException
.setMessage("infer.no.conforming.instance.exists",
inferenceContext.restvars(), mt.getReturnType(), to);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8015505/T8015505.java Tue Jun 04 11:34:31 2013 +0100
@@ -0,0 +1,18 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 8015505
+ * @summary Spurious inference error when return type of generic method requires unchecked conversion to target
+ * @compile/fail/ref=T8015505.out -Xlint:-options -source 7 -XDrawDiagnostics T8015505.java
+ * @compile T8015505.java
+ */
+
+import java.util.List;
+
+class T8015505 {
+
+ <Z> List m() { return null; }
+
+ void test() {
+ List<?> l = m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8015505/T8015505.out Tue Jun 04 11:34:31 2013 +0100
@@ -0,0 +1,2 @@
+T8015505.java:16:22: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: Z, java.util.List, java.util.List<?>)
+1 error
--- a/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java Tue Jun 04 11:31:12 2013 +0100
+++ b/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java Tue Jun 04 11:34:31 2013 +0100
@@ -46,6 +46,17 @@
extends JavacTestingAbstractThreadedTest
implements Runnable {
+ enum SourceLevel {
+ SOURCE_7("-source", "7"),
+ SOURCE_DEFAULT();
+
+ String[] opts;
+
+ SourceLevel(String... opts) {
+ this.opts = opts;
+ }
+ }
+
enum SignatureKind {
NON_GENERIC(""),
GENERIC("<X>");
@@ -112,12 +123,13 @@
}
}
- boolean assignableTo(TypeArgumentKind that, SignatureKind sig) {
+ boolean assignableTo(TypeArgumentKind that, SignatureKind sig, SourceLevel level) {
switch (this) {
case NONE:
//this case needs to workaround to javac's impl of 15.12.2.8 being too strict
- //ideally should be just 'return true' (see 7067746)
- return sig == SignatureKind.NON_GENERIC || that == NONE;
+ //ideally should be just 'return true' (see 7067746/8015505)
+ return level == SourceLevel.SOURCE_DEFAULT ||
+ sig == SignatureKind.NON_GENERIC || that == NONE;
case UNBOUND:
return that == this || that == NONE;
case INTEGER:
@@ -143,10 +155,12 @@
for (TypeArgumentKind ta3 : TypeArgumentKind.values()) {
if (!ta3.compatibleWith(SignatureKind.NON_GENERIC))
continue;
- pool.execute(
- new GenericOverrideTest(sig1,
- rt1, ta1, sig2, rt2,
- ta2, rt3, ta3));
+ for (SourceLevel level : SourceLevel.values()) {
+ pool.execute(
+ new GenericOverrideTest(sig1,
+ rt1, ta1, sig2, rt2,
+ ta2, rt3, ta3, level));
+ }
}
}
}
@@ -162,12 +176,13 @@
SignatureKind sig1, sig2;
ReturnTypeKind rt1, rt2, rt3;
TypeArgumentKind ta1, ta2, ta3;
+ SourceLevel level;
JavaSource source;
DiagnosticChecker diagChecker;
GenericOverrideTest(SignatureKind sig1, ReturnTypeKind rt1, TypeArgumentKind ta1,
SignatureKind sig2, ReturnTypeKind rt2, TypeArgumentKind ta2,
- ReturnTypeKind rt3, TypeArgumentKind ta3) {
+ ReturnTypeKind rt3, TypeArgumentKind ta3, SourceLevel level) {
this.sig1 = sig1;
this.sig2 = sig2;
this.rt1 = rt1;
@@ -176,6 +191,7 @@
this.ta1 = ta1;
this.ta2 = ta2;
this.ta3 = ta3;
+ this.level = level;
this.source = new JavaSource();
this.diagChecker = new DiagnosticChecker();
}
@@ -213,7 +229,8 @@
@Override
public void run() {
JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
- null, null, Arrays.asList(source));
+ level.opts != null ? Arrays.asList(level.opts) : null,
+ null, Arrays.asList(source));
try {
ct.analyze();
} catch (Throwable ex) {
@@ -271,7 +288,7 @@
SignatureKind mssig = mostSpecific == 1 ? sig1 : sig2;
if (!msrt.moreSpecificThan(rt3) ||
- !msta.assignableTo(ta3, mssig)) {
+ !msta.assignableTo(ta3, mssig, level)) {
errorExpected = true;
}
}