8012242: Lambda compatibility and checked exceptions
Summary: Inference variables in 'throws' clause with no constraints should be inferred as RuntimeException
Reviewed-by: jjg, vromero
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Jul 12 13:11:12 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Jul 17 14:04:01 2013 +0100
@@ -261,6 +261,11 @@
*/
public static final long SIGNATURE_POLYMORPHIC = 1L<<46;
+ /**
+ * Flag that marks inference variables used in a 'throws' clause
+ */
+ public static final long THROWS = 1L<<47;
+
/** Modifier masks.
*/
public static final int
@@ -365,7 +370,9 @@
CLASH(Flags.CLASH),
AUXILIARY(Flags.AUXILIARY),
NOT_IN_PROFILE(Flags.NOT_IN_PROFILE),
- BAD_OVERRIDE(Flags.BAD_OVERRIDE);
+ BAD_OVERRIDE(Flags.BAD_OVERRIDE),
+ SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC),
+ THROWS(Flags.THROWS);
Flag(long flag) {
this.value = flag;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Jul 12 13:11:12 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Wed Jul 17 14:04:01 2013 +0100
@@ -968,6 +968,39 @@
}
},
/**
+ * Infer uninstantiated/unbound inference variables occurring in 'throws'
+ * clause as RuntimeException
+ */
+ THROWS(InferenceBound.UPPER) {
+ @Override
+ public boolean accepts(UndetVar t, InferenceContext inferenceContext) {
+ if ((t.qtype.tsym.flags() & Flags.THROWS) == 0) {
+ //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()) {
+ if (t.isInterface()) continue;
+ if (infer.types.asSuper(infer.syms.runtimeExceptionType, db.tsym) != null) {
+ //declared bound is a supertype of RuntimeException
+ return true;
+ }
+ }
+ //declared bound is more specific then RuntimeException - give up
+ return false;
+ }
+
+ @Override
+ Type solve(UndetVar uv, InferenceContext inferenceContext) {
+ return inferenceContext.infer().syms.runtimeExceptionType;
+ }
+ },
+ /**
* Instantiate an inference variables using its (ground) upper bounds. Such
* bounds are merged together using glb().
*/
@@ -1056,7 +1089,7 @@
EQ(EnumSet.of(InferenceStep.EQ)),
EQ_LOWER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER)),
- EQ_LOWER_UPPER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER, InferenceStep.UPPER));
+ EQ_LOWER_THROWS_UPPER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER, InferenceStep.THROWS, InferenceStep.UPPER));
final EnumSet<InferenceStep> steps;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Jul 12 13:11:12 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Jul 17 14:04:01 2013 +0100
@@ -358,7 +358,8 @@
* @param thrown The method's thrown exceptions.
* @param env The method's (local) environment.
*/
- Type signature(List<JCTypeParameter> typarams,
+ Type signature(MethodSymbol msym,
+ List<JCTypeParameter> typarams,
List<JCVariableDecl> params,
JCTree res,
JCVariableDecl recvparam,
@@ -392,8 +393,12 @@
ListBuffer<Type> thrownbuf = new ListBuffer<Type>();
for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
Type exc = attr.attribType(l.head, env);
- if (!exc.hasTag(TYPEVAR))
+ if (!exc.hasTag(TYPEVAR)) {
exc = chk.checkClassType(l.head.pos(), exc);
+ } else if (exc.tsym.owner == msym) {
+ //mark inference variables in 'throws' clause
+ exc.tsym.flags_field |= THROWS;
+ }
thrownbuf.append(exc);
}
MethodType mtype = new MethodType(argbuf.toList(),
@@ -557,7 +562,7 @@
chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
try {
// Compute the method type
- m.type = signature(tree.typarams, tree.params,
+ m.type = signature(m, tree.typarams, tree.params,
tree.restype, tree.recvparam,
tree.thrown,
localEnv);
--- a/langtools/test/tools/javac/generics/6723444/T6723444.java Fri Jul 12 13:11:12 2013 -0700
+++ b/langtools/test/tools/javac/generics/6723444/T6723444.java Wed Jul 17 14:04:01 2013 +0100
@@ -4,7 +4,8 @@
*
* @summary javac fails to substitute type variables into a constructor's throws clause
* @author Mark Mahieu
- * @compile/fail/ref=T6723444.out -XDrawDiagnostics T6723444.java
+ * @compile/fail/ref=T6723444_1.out -Xlint:-options -source 7 -XDrawDiagnostics T6723444.java
+ * @compile/fail/ref=T6723444_2.out -XDrawDiagnostics T6723444.java
*
*/
public class T6723444 {
--- a/langtools/test/tools/javac/generics/6723444/T6723444.out Fri Jul 12 13:11:12 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-T6723444.java:42:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:43:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:45:32: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:46:17: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:48:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:49:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:50:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:51:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:52:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:53:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:54:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-T6723444.java:55:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
-12 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6723444/T6723444_1.out Wed Jul 17 14:04:01 2013 +0100
@@ -0,0 +1,13 @@
+T6723444.java:43:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:44:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:46:32: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:47:17: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:49:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:50:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:51:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:52:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:53:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:54:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:55:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:56:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+12 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6723444/T6723444_2.out Wed Jul 17 14:04:01 2013 +0100
@@ -0,0 +1,11 @@
+T6723444.java:46:32: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:47:17: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:49:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:50:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:51:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:52:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:53:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:54:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:55:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+T6723444.java:56:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+10 errors
--- a/langtools/test/tools/javac/generics/7015430/T7015430.java Fri Jul 12 13:11:12 2013 -0700
+++ b/langtools/test/tools/javac/generics/7015430/T7015430.java Wed Jul 17 14:04:01 2013 +0100
@@ -4,7 +4,8 @@
*
* @summary Incorrect thrown type determined for unchecked invocations
* @author Daniel Smith
- * @compile/fail/ref=T7015430.out -Xlint:unchecked -XDrawDiagnostics T7015430.java
+ * @compile/fail/ref=T7015430_1.out -source 7 -Xlint:-options,unchecked -XDrawDiagnostics T7015430.java
+ * @compile/fail/ref=T7015430_2.out -Xlint:unchecked -XDrawDiagnostics T7015430.java
*
*/
--- a/langtools/test/tools/javac/generics/7015430/T7015430.out Fri Jul 12 13:11:12 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-T7015430.java:41:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
-T7015430.java:50:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:50:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
-T7015430.java:68:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
-T7015430.java:77:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:77:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
-T7015430.java:104:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:104:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
-T7015430.java:113:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
-T7015430.java:41:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
-T7015430.java:68:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
-T7015430.java:95:15: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
-T7015430.java:113:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
-T7015430.java:129:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
-5 errors
-12 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/7015430/T7015430_1.out Wed Jul 17 14:04:01 2013 +0100
@@ -0,0 +1,19 @@
+T7015430.java:42:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:42:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
+T7015430.java:51:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:51:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
+T7015430.java:69:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:69:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
+T7015430.java:78:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:78:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
+T7015430.java:105:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:105:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
+T7015430.java:114:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:114:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
+T7015430.java:42:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+T7015430.java:69:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+T7015430.java:96:15: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+T7015430.java:114:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+T7015430.java:130:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+5 errors
+12 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/7015430/T7015430_2.out Wed Jul 17 14:04:01 2013 +0100
@@ -0,0 +1,15 @@
+T7015430.java:42:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:42:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
+T7015430.java:51:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:51:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
+T7015430.java:69:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:69:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
+T7015430.java:78:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:78:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
+T7015430.java:105:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:105:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
+T7015430.java:114:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:114:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
+T7015430.java:130:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+1 error
+12 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType63.java Wed Jul 17 14:04:01 2013 +0100
@@ -0,0 +1,40 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary smoke test for inference of throws type variables
+ * @compile/fail/ref=TargetType63.out -XDrawDiagnostics TargetType63.java
+ */
+class TargetType63 {
+
+ interface F<T extends Throwable> {
+ void m() throws T;
+ }
+
+ void g1() { }
+ void g2() throws ClassNotFoundException { }
+ void g3() throws Exception { }
+
+ <Z extends Throwable> void m1(F<Z> fz) throws Z { }
+ <Z extends ClassNotFoundException> void m2(F<Z> fz) throws Z { }
+
+ void test1() {
+ m1(()->{ }); //ok (Z = RuntimeException)
+ m1(this::g1); //ok (Z = RuntimeException)
+ }
+
+ void test2() {
+ m2(()->{ }); //fail (Z = ClassNotFoundException)
+ m2(this::g1); //fail (Z = ClassNotFoundException)
+ }
+
+ void test3() {
+ m1(()->{ throw new ClassNotFoundException(); }); //fail (Z = ClassNotFoundException)
+ m1(this::g2); //fail (Z = ClassNotFoundException)
+ m2(()->{ throw new ClassNotFoundException(); }); //fail (Z = ClassNotFoundException)
+ m2(this::g2); //fail (Z = ClassNotFoundException)
+ }
+
+ void test4() {
+ m1(()->{ throw new Exception(); }); //fail (Z = Exception)
+ m1(this::g3); //fail (Z = Exception)
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType63.out Wed Jul 17 14:04:01 2013 +0100
@@ -0,0 +1,9 @@
+TargetType63.java:25:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
+TargetType63.java:26:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
+TargetType63.java:30:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
+TargetType63.java:31:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
+TargetType63.java:32:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
+TargetType63.java:33:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
+TargetType63.java:37:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+TargetType63.java:38:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+8 errors