# HG changeset patch # User mcimadamore # Date 1464012430 -3600 # Node ID 8bdc63ff6961afa524825ac047b01bb9420ffc32 # Parent ba5503adca64cad6fabc78349b11d7e035967ddb 8157149: Inference: weird propagation of thrown inference variables Summary: Overhaul of treatment of thrown inference variables Reviewed-by: vromero diff -r ba5503adca64 -r 8bdc63ff6961 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Mon May 23 12:48:18 2016 +0200 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Mon May 23 15:07:10 2016 +0100 @@ -2666,7 +2666,7 @@ @Override public boolean compatible(Type found, Type req, Warner warn) { //return type must be compatible in both current context and assignment context - return chk.basicHandler.compatible(found, inferenceContext().asUndetVar(req), warn); + return chk.basicHandler.compatible(inferenceContext().asUndetVar(found), inferenceContext().asUndetVar(req), warn); } @Override diff -r ba5503adca64 -r 8bdc63ff6961 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Mon May 23 12:48:18 2016 +0200 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Mon May 23 15:07:10 2016 +0100 @@ -194,7 +194,7 @@ //inject return constraints earlier doIncorporation(inferenceContext, warn); //propagation - boolean shouldPropagate = resultInfo.checkContext.inferenceContext().free(resultInfo.pt); + boolean shouldPropagate = shouldPropagate(mt.getReturnType(), resultInfo, inferenceContext); InferenceContext minContext = shouldPropagate ? inferenceContext.min(roots(mt, deferredAttrContext), true, warn) : @@ -255,6 +255,13 @@ } } //where + private boolean shouldPropagate(Type restype, Attr.ResultInfo target, InferenceContext inferenceContext) { + return target.checkContext.inferenceContext() != emptyContext && //enclosing context is a generic method + inferenceContext.free(restype) && //return type contains inference vars + (!inferenceContext.inferencevars.contains(restype) || //no eager instantiation is required (as per 18.5.2) + !needsEagerInstantiation((UndetVar)inferenceContext.asUndetVar(restype), target.pt, inferenceContext)); + } + private List roots(MethodType mt, DeferredAttrContext deferredAttrContext) { ListBuffer roots = new ListBuffer<>(); roots.add(mt.getReturnType()); @@ -309,7 +316,7 @@ */ saved_undet = inferenceContext.save(); if (allowGraphInference && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) { - boolean shouldPropagate = resultInfo.checkContext.inferenceContext().free(resultInfo.pt); + boolean shouldPropagate = shouldPropagate(getReturnType(), resultInfo, inferenceContext); InferenceContext minContext = shouldPropagate ? inferenceContext.min(roots(asMethodType(), null), false, warn) : @@ -394,8 +401,9 @@ to = from.isPrimitive() ? from : syms.objectType; } else if (qtype.hasTag(UNDETVAR)) { if (resultInfo.pt.isReference()) { - to = generateReturnConstraintsUndetVarToReference( - tree, (UndetVar)qtype, to, resultInfo, inferenceContext); + if (needsEagerInstantiation((UndetVar)qtype, to, inferenceContext)) { + to = generateReferenceToTargetConstraint(tree, (UndetVar)qtype, to, resultInfo, inferenceContext); + } } else { if (to.isPrimitive()) { to = generateReturnConstraintsPrimitive(tree, (UndetVar)qtype, to, @@ -439,9 +447,7 @@ return types.boxedClass(to).type; } - private Type generateReturnConstraintsUndetVarToReference(JCTree tree, - UndetVar from, Type to, Attr.ResultInfo resultInfo, - InferenceContext inferenceContext) { + private boolean needsEagerInstantiation(UndetVar from, Type to, InferenceContext inferenceContext) { Type captureOfTo = types.capture(to); /* T is a reference type, but is not a wildcard-parameterized type, and either */ @@ -452,8 +458,7 @@ for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) { Type captureOfBound = types.capture(t); if (captureOfBound != t) { - return generateReferenceToTargetConstraint(tree, from, to, - resultInfo, inferenceContext); + return true; } } @@ -467,8 +472,7 @@ !inferenceContext.free(aLowerBound) && !inferenceContext.free(anotherLowerBound) && commonSuperWithDiffParameterization(aLowerBound, anotherLowerBound)) { - return generateReferenceToTargetConstraint(tree, from, to, - resultInfo, inferenceContext); + return true; } } } @@ -483,12 +487,11 @@ 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 true; } } } - return to; + return false; } private boolean commonSuperWithDiffParameterization(Type t, Type s) { @@ -1475,21 +1478,16 @@ //not a throws undet var return false; } - if (t.getBounds(InferenceBound.EQ, InferenceBound.LOWER, InferenceBound.UPPER) - .diff(t.getDeclaredBounds()).nonEmpty()) { - //not an unbounded undet var - return false; - } Infer infer = inferenceContext.infer; - for (Type db : t.getDeclaredBounds()) { + for (Type db : t.getBounds(InferenceBound.UPPER)) { if (t.isInterface()) continue; - if (infer.types.asSuper(infer.syms.runtimeExceptionType, db.tsym) != null) { - //declared bound is a supertype of RuntimeException - return true; + if (infer.types.asSuper(infer.syms.runtimeExceptionType, db.tsym) == null) { + //upper bound is not a supertype of RuntimeException - give up + return false; } } - //declared bound is more specific then RuntimeException - give up - return false; + + return true; } @Override diff -r ba5503adca64 -r 8bdc63ff6961 langtools/test/tools/javac/generics/inference/8157149/T8157149a.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/inference/8157149/T8157149a.java Mon May 23 15:07:10 2016 +0100 @@ -0,0 +1,28 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8157149 + * @summary Inference: weird propagation of thrown inference variables + * + * @compile/fail/ref=T8157149a.out -XDrawDiagnostics T8157149a.java + */ + +import java.io.IOException; + +class T8157149a { + Z m_T() throws Z { return null; } + Z m_E() throws Z { return null; } + + void test_T() { + Throwable t1 = m_T(); + Exception t2 = m_T(); + RuntimeException t3 = m_T(); + IOException t4 = m_T(); //thrown not caught + } + + void test_E() { + Throwable t1 = m_E(); + Exception t2 = m_E(); + RuntimeException t3 = m_E(); + IOException t4 = m_E(); //thrown not caught + } +} diff -r ba5503adca64 -r 8bdc63ff6961 langtools/test/tools/javac/generics/inference/8157149/T8157149a.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/inference/8157149/T8157149a.out Mon May 23 15:07:10 2016 +0100 @@ -0,0 +1,3 @@ +T8157149a.java:19:28: compiler.err.unreported.exception.need.to.catch.or.throw: java.io.IOException +T8157149a.java:26:28: compiler.err.unreported.exception.need.to.catch.or.throw: java.io.IOException +2 errors diff -r ba5503adca64 -r 8bdc63ff6961 langtools/test/tools/javac/generics/inference/8157149/T8157149b.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/inference/8157149/T8157149b.java Mon May 23 15:07:10 2016 +0100 @@ -0,0 +1,64 @@ +/* + * 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 8157149 + * @summary Inference: weird propagation of thrown inference variables + * + * @compile T8157149b.java + */ + +class T8157149b { + + void test() { + computeException1(this::computeThrowable); + computeException2(this::computeThrowable); + computeException1(() -> { + Integer integer = computeThrowable(); + return integer; + }); + computeException2(() -> { + Integer integer = computeThrowable(); + return integer; + }); + } + + void computeException1(ThrowableComputable1 c) throws E {} + + void computeException2(ThrowableComputable2 c) throws E {} + + Integer computeThrowable() throws E1 { + return 0; + } + + interface ThrowableComputable1 { + T compute() throws E; + } + + interface ThrowableComputable2 { + Integer compute() throws E; + } +} diff -r ba5503adca64 -r 8bdc63ff6961 langtools/test/tools/javac/generics/inference/8157149/T8157149c.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/inference/8157149/T8157149c.java Mon May 23 15:07:10 2016 +0100 @@ -0,0 +1,49 @@ +/* + * 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 8157149 + * @summary Inference: weird propagation of thrown inference variables + * + * @compile T8157149c.java + */ + +class T8157149c { + + interface I, U> { + T m(U o); + } + + static class C { + C(T f) { } + } + + void m(I, A> o1, A o2) { } + + void test(Object o) { + m(C::new, o); + } +}