提交 10d352e9 编写于 作者: M mcimadamore

7015430: Incorrect thrown type determined for unchecked invocations

Summary: 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
上级 5325a778
......@@ -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 {
......@@ -518,25 +569,25 @@ public class Infer {
}
}
/** Try to instantiate argument type `that' to given type `to'.
* If this fails, try to insantiate `that' to `to' where
* every occurrence of a type variable in `tvars' is replaced
* by an unknown type.
*/
private Type instantiateArg(ForAll that,
Type to,
List<Type> tvars,
Warner warn) throws InferenceException {
List<Type> targs;
try {
return instantiateExpr(that, to, warn);
} catch (NoInstanceException ex) {
Type to1 = to;
for (List<Type> l = tvars; l.nonEmpty(); l = l.tail)
to1 = types.subst(to1, List.of(l.head), List.of(syms.unknownType));
return instantiateExpr(that, to1, warn);
}
/** Try to instantiate argument type `that' to given type `to'.
* If this fails, try to insantiate `that' to `to' where
* every occurrence of a type variable in `tvars' is replaced
* by an unknown type.
*/
private Type instantiateArg(ForAll that,
Type to,
List<Type> tvars,
Warner warn) throws InferenceException {
List<Type> targs;
try {
return instantiateExpr(that, to, warn);
} catch (NoInstanceException ex) {
Type to1 = to;
for (List<Type> l = tvars; l.nonEmpty(); l = l.tail)
to1 = types.subst(to1, List.of(l.head), List.of(syms.unknownType));
return instantiateExpr(that, to1, warn);
}
}
/** check that type parameters are within their bounds.
*/
......@@ -616,4 +667,4 @@ public class Infer {
return t;
}
};
}
}
/*
* @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<>();
}
}
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册