# HG changeset patch # User mcimadamore # Date 1374066241 -3600 # Node ID 8f9fc5d876e4adaba250308ed42e3730416090fd # Parent f76cab33bee3cc6cc79e3041adb291b4aac38a53 8012242: Lambda compatibility and checked exceptions Summary: Inference variables in 'throws' clause with no constraints should be inferred as RuntimeException Reviewed-by: jjg, vromero diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/src/share/classes/com/sun/tools/javac/code/Flags.java --- 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; diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java --- 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 steps; diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- 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 typarams, + Type signature(MethodSymbol msym, + List typarams, List params, JCTree res, JCVariableDecl recvparam, @@ -392,8 +393,12 @@ ListBuffer thrownbuf = new ListBuffer(); for (List 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); diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/test/tools/javac/generics/6723444/T6723444.java --- 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 { diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/test/tools/javac/generics/6723444/T6723444.out --- 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 diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/test/tools/javac/generics/6723444/T6723444_1.out --- /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 diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/test/tools/javac/generics/6723444/T6723444_2.out --- /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 diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/test/tools/javac/generics/7015430/T7015430.java --- 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 * */ diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/test/tools/javac/generics/7015430/T7015430.out --- 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, 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 -T7015430.java:50:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, 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 -T7015430.java:68:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 -T7015430.java:77:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 -T7015430.java:104:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 -T7015430.java:113:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 -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 diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/test/tools/javac/generics/7015430/T7015430_1.out --- /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, 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 +T7015430.java:51:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, 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 +T7015430.java:69:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:78:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:105:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:114:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +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 diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/test/tools/javac/generics/7015430/T7015430_2.out --- /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, 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 +T7015430.java:51:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, 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 +T7015430.java:69:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:78:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:105:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:114:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:130:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception +1 error +12 warnings diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/test/tools/javac/lambda/TargetType63.java --- /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 { + void m() throws T; + } + + void g1() { } + void g2() throws ClassNotFoundException { } + void g3() throws Exception { } + + void m1(F fz) throws Z { } + void m2(F 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) + } +} diff -r f76cab33bee3 -r 8f9fc5d876e4 langtools/test/tools/javac/lambda/TargetType63.out --- /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