JDK-6791481 : 15.12.2.6: Excessive erasure of return/thrown types is specified
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 5.0,7,8
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2009-01-08
  • Updated: 2024-04-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Reading from JLS 15.12.2.6:

"The result type of the chosen method is determined as follows: [...]
          o Otherwise, if unchecked conversion was necessary for the method to be applicable then the result type is the erasure (§4.6) of the method's declared return type.[...]"

Moreover

"The exception types of the throws clause of the chosen method are determined as follows:[...]
    * If unchecked conversion was necessary for the method to be applicable then the throws clause is composed of the erasure (§4.6) of the types in the method's declared throws clause."

which means that the following programs should *not* compile

Example 1.

class Test<X> {
	X m(Class<X> c) {return null;}
	X x = m((Class)String.class);
}

Example 2.

class Test {
   <T extends Throwable> void foo(Class<T> c, T t) throws T {}
   void test(Exception e) {
      try {
         foo((Class)String.class, e);
      } catch (Exception t) {}
   }   
}

Example 3.

class Test<T extends Throwable>  {
   void foo(Class<T> c, T t) throws T {}
   void test(Exception e) {
      try {
         new Test<Exception>().foo((Class)String.class, e);
      } catch (Exception t) {}
   }   
}

Comments
EVALUATION There are two problems that cause the current wrong behavior: *) Only generic methods are considered when checking as to whether return/thrown types should be erased or not following an unchecked conversion *) Thrown types currently are not erased TODO: investigate the compatibility risk of this change as it could cause compilation errors on programs that used to be accepted.
08-01-2009

SUGGESTED FIX diff -r e2f8f6daee9d src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Dec 19 10:39:02 2008 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jan 08 13:45:38 2009 +0000 @@ -2377,7 +2377,7 @@ public class Attr extends JCTree.Visitor varParam); } - if (warned && sym.type.tag == FORALL) { + if (warned) { chk.warnUnchecked(env.tree.pos(), "unchecked.meth.invocation.applied", kindName(sym), @@ -2386,10 +2386,10 @@ public class Attr extends JCTree.Visitor rs.methodArguments(argtypes), kindName(sym.location()), sym.location()); - owntype = new MethodType(owntype.getParameterTypes(), - types.erasure(owntype.getReturnType()), - owntype.getThrownTypes(), - syms.methodClass); + owntype = types.erasure(sym.type); } if (useVarargs) { JCTree tree = env.tree; maurizio@maurizio-laptop:/media/data/ws/j
08-01-2009