7015430: Incorrect thrown type determined for unchecked invocations
Thrown types do not get updated after 15.12.2.8, and do not get erased as per 15.12.2.6 Reviewed-by: jjg, dlsmith
This commit is contained in:
parent
78ebde094c
commit
32216fc797
@ -2806,7 +2806,7 @@ public class Attr extends JCTree.Visitor {
|
||||
sym.location());
|
||||
owntype = new MethodType(owntype.getParameterTypes(),
|
||||
types.erasure(owntype.getReturnType()),
|
||||
owntype.getThrownTypes(),
|
||||
types.erasure(owntype.getThrownTypes()),
|
||||
syms.methodClass);
|
||||
}
|
||||
if (useVarargs) {
|
||||
|
@ -465,10 +465,9 @@ public class Infer {
|
||||
// quantify result type with them
|
||||
final List<Type> inferredTypes = insttypes.toList();
|
||||
final List<Type> all_tvars = tvars; //this is the wrong tvars
|
||||
final MethodType mt2 = new MethodType(mt.argtypes, null, mt.thrown, syms.methodClass);
|
||||
mt2.restype = new ForAll(restvars.toList(), mt.restype) {
|
||||
return new UninferredMethodType(mt, restvars.toList()) {
|
||||
@Override
|
||||
public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
|
||||
List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
|
||||
for (Type t : restundet.toList()) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
if (uv.qtype == tv) {
|
||||
@ -481,21 +480,17 @@ public class Infer {
|
||||
}
|
||||
return List.nil();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type inst(List<Type> inferred, Types types) throws NoInstanceException {
|
||||
List<Type> formals = types.subst(mt2.argtypes, tvars, inferred);
|
||||
void check(List<Type> inferred, Types types) throws NoInstanceException {
|
||||
// check that actuals conform to inferred formals
|
||||
checkArgumentsAcceptable(env, capturedArgs, formals, allowBoxing, useVarargs, warn);
|
||||
checkArgumentsAcceptable(env, capturedArgs, getParameterTypes(), allowBoxing, useVarargs, warn);
|
||||
// check that inferred bounds conform to their bounds
|
||||
checkWithinBounds(all_tvars,
|
||||
types.subst(inferredTypes, tvars, inferred), warn);
|
||||
if (useVarargs) {
|
||||
chk.checkVararg(env.tree.pos(), formals, msym);
|
||||
chk.checkVararg(env.tree.pos(), getParameterTypes(), msym);
|
||||
}
|
||||
return super.inst(inferred, types);
|
||||
}};
|
||||
return mt2;
|
||||
}
|
||||
else {
|
||||
// check that actuals conform to inferred formals
|
||||
@ -506,6 +501,62 @@ public class Infer {
|
||||
}
|
||||
//where
|
||||
|
||||
/**
|
||||
* A delegated type representing a partially uninferred method type.
|
||||
* The return type of a partially uninferred method type is a ForAll
|
||||
* type - when the return type is instantiated (see Infer.instantiateExpr)
|
||||
* the underlying method type is also updated.
|
||||
*/
|
||||
static abstract class UninferredMethodType extends DelegatedType {
|
||||
|
||||
final List<Type> tvars;
|
||||
|
||||
public UninferredMethodType(MethodType mtype, List<Type> tvars) {
|
||||
super(METHOD, new MethodType(mtype.argtypes, null, mtype.thrown, mtype.tsym));
|
||||
this.tvars = tvars;
|
||||
asMethodType().restype = new UninferredReturnType(tvars, mtype.restype);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodType asMethodType() {
|
||||
return qtype.asMethodType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type map(Mapping f) {
|
||||
return qtype.map(f);
|
||||
}
|
||||
|
||||
void instantiateReturnType(Type restype, List<Type> inferred, Types types) throws NoInstanceException {
|
||||
//update method type with newly inferred type-arguments
|
||||
qtype = new MethodType(types.subst(getParameterTypes(), tvars, inferred),
|
||||
restype,
|
||||
types.subst(UninferredMethodType.this.getThrownTypes(), tvars, inferred),
|
||||
UninferredMethodType.this.qtype.tsym);
|
||||
check(inferred, types);
|
||||
}
|
||||
|
||||
abstract void check(List<Type> inferred, Types types) throws NoInstanceException;
|
||||
|
||||
abstract List<Type> getConstraints(TypeVar tv, ConstraintKind ck);
|
||||
|
||||
class UninferredReturnType extends ForAll {
|
||||
public UninferredReturnType(List<Type> tvars, Type restype) {
|
||||
super(tvars, restype);
|
||||
}
|
||||
@Override
|
||||
public Type inst(List<Type> actuals, Types types) {
|
||||
Type newRestype = super.inst(actuals, types);
|
||||
instantiateReturnType(newRestype, actuals, types);
|
||||
return newRestype;
|
||||
}
|
||||
@Override
|
||||
public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
|
||||
return UninferredMethodType.this.getConstraints(tv, ck);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkArgumentsAcceptable(Env<AttrContext> env, List<Type> actuals, List<Type> formals,
|
||||
boolean allowBoxing, boolean useVarargs, Warner warn) {
|
||||
try {
|
||||
@ -616,4 +667,4 @@ public class Infer {
|
||||
return t;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
131
langtools/test/tools/javac/generics/7015430/T7015430.java
Normal file
131
langtools/test/tools/javac/generics/7015430/T7015430.java
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 7015430
|
||||
*
|
||||
* @summary Incorrect thrown type determined for unchecked invocations
|
||||
* @author Daniel Smith
|
||||
* @compile/fail/ref=T7015430.out -Xlint:unchecked -XDrawDiagnostics T7015430.java
|
||||
*
|
||||
*/
|
||||
|
||||
class T7015430 {
|
||||
static <E extends Exception> Iterable<E> empty(Iterable<E> arg) throws E {
|
||||
return null;
|
||||
}
|
||||
|
||||
<E extends Exception> T7015430(Iterable<E> arg) throws E { }
|
||||
|
||||
static <E extends Exception> Iterable<E> empty2(Iterable x) throws E {
|
||||
return null;
|
||||
}
|
||||
|
||||
static class Foo<X extends Exception> {
|
||||
Foo() throws X {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method invocation, no unchecked
|
||||
* inferred: RuntimeException - should pass
|
||||
*/
|
||||
void m1() {
|
||||
Iterable<RuntimeException> i = java.util.Collections.emptyList();
|
||||
empty(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method invocation, unchecked, inferred arguments
|
||||
* inferred: Exception - should fail
|
||||
*/
|
||||
void m2() {
|
||||
Iterable i = java.util.Collections.EMPTY_LIST;
|
||||
empty(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method invocation, unchecked, explicit arguments
|
||||
* inferred: RuntimeException - should pass
|
||||
*/
|
||||
void m3() {
|
||||
Iterable i = java.util.Collections.EMPTY_LIST;
|
||||
T7015430.<RuntimeException>empty(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invocation, no unchecked
|
||||
* inferred: RuntimeException - should pass
|
||||
*/
|
||||
void m4() {
|
||||
Iterable<RuntimeException> i = java.util.Collections.emptyList();
|
||||
new T7015430(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invocation, unchecked, inferred arguments
|
||||
* inferred: Exception - should fail
|
||||
*/
|
||||
void m5() {
|
||||
Iterable i = java.util.Collections.EMPTY_LIST;
|
||||
new T7015430(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invocation, unchecked, explicit arguments
|
||||
* inferred: RuntimeException - should pass
|
||||
*/
|
||||
void m6() {
|
||||
Iterable i = java.util.Collections.EMPTY_LIST;
|
||||
new <RuntimeException>T7015430(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method invocation, no unchecked, inferred arguments
|
||||
* inferred: RuntimeException - should pass
|
||||
*/
|
||||
void m7() {
|
||||
Iterable i = java.util.Collections.EMPTY_LIST;
|
||||
Iterable<RuntimeException> e = empty2(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method invocation, no unchecked, inferred arguments
|
||||
* inferred: Exception - should fail
|
||||
*/
|
||||
void m8() {
|
||||
Iterable i = java.util.Collections.EMPTY_LIST;
|
||||
empty2(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invocation, unchecked, explicit arguments
|
||||
* inferred: RuntimeException - should pass
|
||||
*/
|
||||
void m9() {
|
||||
Iterable i = java.util.Collections.EMPTY_LIST;
|
||||
new <RuntimeException> T7015430(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invocation, unchecked, inferred arguments
|
||||
* inferred: Exception - should fail
|
||||
*/
|
||||
void m10() {
|
||||
Iterable i = java.util.Collections.EMPTY_LIST;
|
||||
new T7015430(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invocation, no unchecked, inferred arguments (diamond)
|
||||
* inferred: RuntimeException - should pass
|
||||
*/
|
||||
void m11() {
|
||||
Foo<RuntimeException> o = new Foo<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invocation, no unchecked, inferred arguments (diamond)
|
||||
* inferred: Exception - should fail
|
||||
*/
|
||||
void m12() {
|
||||
new Foo<>();
|
||||
}
|
||||
}
|
19
langtools/test/tools/javac/generics/7015430/T7015430.out
Normal file
19
langtools/test/tools/javac/generics/7015430/T7015430.out
Normal file
@ -0,0 +1,19 @@
|
||||
T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
|
||||
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:50:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
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:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
|
||||
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:77:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
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:104:41: 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:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
|
||||
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: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
|
Loading…
x
Reference in New Issue
Block a user