mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-24 09:10:08 +00:00
8012242: Lambda compatibility and checked exceptions
Inference variables in 'throws' clause with no constraints should be inferred as RuntimeException Reviewed-by: jjg, vromero
This commit is contained in:
parent
9dd2fe90d4
commit
941752ea25
@ -261,6 +261,11 @@ public class Flags {
|
||||
*/
|
||||
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 @@ public class Flags {
|
||||
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;
|
||||
|
||||
@ -967,6 +967,39 @@ public class Infer {
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 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 @@ public class Infer {
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@ -358,7 +358,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
* @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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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);
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
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: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
|
||||
@ -10,4 +9,5 @@ T6723444.java:52:9: compiler.err.unreported.exception.need.to.catch.or.throw: ja
|
||||
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
|
||||
11
langtools/test/tools/javac/generics/6723444/T6723444_2.out
Normal file
11
langtools/test/tools/javac/generics/6723444/T6723444_2.out
Normal file
@ -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
|
||||
@ -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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@ -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
|
||||
19
langtools/test/tools/javac/generics/7015430/T7015430_1.out
Normal file
19
langtools/test/tools/javac/generics/7015430/T7015430_1.out
Normal file
@ -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
|
||||
15
langtools/test/tools/javac/generics/7015430/T7015430_2.out
Normal file
15
langtools/test/tools/javac/generics/7015430/T7015430_2.out
Normal file
@ -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
|
||||
40
langtools/test/tools/javac/lambda/TargetType63.java
Normal file
40
langtools/test/tools/javac/lambda/TargetType63.java
Normal file
@ -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)
|
||||
}
|
||||
}
|
||||
9
langtools/test/tools/javac/lambda/TargetType63.out
Normal file
9
langtools/test/tools/javac/lambda/TargetType63.out
Normal file
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user