Bug 231709 - [1.5][compiler] JDT doesn't report javac error incompatible types found short require Integer
Summary: [1.5][compiler] JDT doesn't report javac error incompatible types found short...
Status: VERIFIED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.4   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.5 M2   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-05-12 22:47 EDT by Stevi Deter CLA
Modified: 2008-09-16 04:22 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stevi Deter CLA 2008-05-12 22:47:48 EDT
Build ID: M20070921-1145

Steps To Reproduce:
1. Write code with incompatible types between switch and case statement: 

public class SwitchTest {
    public static void main(String[] args) {
        Integer d = 10 ;
        final short k = 100;
        switch (d)
        {
            case k:
        }
    }
}

2. save, run as java application, note it's successful
3. attempt to compile with javac (1.6.0_05)
4. note error when compiling:
SwitchTest.java:7: incompatible types
found   : short
required: java.lang.Integer
            case k:
                 ^



More information:
Comment 1 Philipe Mulet CLA 2008-05-13 06:34:48 EDT
It seems that autoboxing rules have evolved in latest JDK versions.
None of the integral subtypes (short, byte, char) seem to be auto-boxable into Integer any longer.

public class X {
    public void foo() {
        Integer i1 = 10 ;
        final short s = 100;
        i1 = s;
        switch (i1)
        {
            case s:
        }
    }
    public void bar() {
        Integer i2 = 10 ;
        final byte b = 100;
        i2 = b;
        switch (i2)
        {
            case b:
        }
    }   
    public void baz() {
        Integer i3 = 10 ;
        final char c = 100;
        i3 = c;
        switch (i3)
        {
            case c:
        }
    }     
}
Comment 2 Philipe Mulet CLA 2008-05-13 06:36:31 EDT
Tested against build 1.7.0-ea-b25, build 1.6.0_10-beta-b20 and build 1.5.0_16-ea-b01.

X.java:5: incompatible types
found   : short
required: java.lang.Integer
        i1 = s;
             ^
X.java:8: incompatible types
found   : short
required: java.lang.Integer
            case s:
                 ^
X.java:14: incompatible types
found   : byte
required: java.lang.Integer
        i2 = b;
             ^
X.java:17: incompatible types
found   : byte
required: java.lang.Integer
            case b:
                 ^
X.java:23: incompatible types
found   : char
required: java.lang.Integer
        i3 = c;
             ^
X.java:26: incompatible types
found   : char
required: java.lang.Integer
            case c:
                 ^
6 errors
Comment 3 Maxime Daniel CLA 2008-05-13 10:06:16 EDT
According to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6578574, javac would be considered as wrong in this instance. Yet, as far as JLS 3 is concerned, there seems to be no valid path to assign a short to an Integer (short would be boxed to Short, which does not extend Integer; widening short to int then boxing it to Integer is not permitted - see §5.2 on assignment conversions). Moreover, the switch/case behavior is specified as aligned with assignment (§14.11). Note also that javac hasn't changed recently wrt this peculiar behavior (tested a few versions).

Bottom-line:
- the current behavior of javac matches the spec, which mandates an error;
- there is an accepted javac bug that asks for a the error be suppressed.
Comment 4 Philipe Mulet CLA 2008-05-14 16:39:21 EDT
Feels like we were wrong since day 1 by assuming a widening conversion before boxing for assignment conversion, JLS 5.2 doesn't support it.

Comment 5 Philipe Mulet CLA 2008-08-29 10:49:01 EDT
The Eclipse compiler correctly prevents boxing from short to Integer already,
e.g.

short s = 0;
Integer i = s; // error already

The issue only arises in presence of constant values being boxed as part of the representation question (a short can be represented as an int).
Comment 6 Philipe Mulet CLA 2008-08-29 11:07:46 EDT
Interestingly javac does accept the following:
		Short si = (byte) 0;
where it requires widening before boxing to Short (against the JLS 5.2, which only allows widening conversion to be performed for constants).
Comment 7 Philipe Mulet CLA 2008-08-29 11:17:19 EDT
[ignore previous comment]

Interestingly javac does accept the following:
		Short si = (byte) 0;
where it requires widening before boxing to Short (against the JLS 5.2, which only allows narrowing conversion to be performed for constants).
Comment 8 Philipe Mulet CLA 2008-08-29 11:23:31 EDT
Added AutoboxingTest#test165-test166 with present behavior.
Comment 9 Philipe Mulet CLA 2008-09-04 03:58:37 EDT
Spec master confirmed this should be allowed, and is currently a hole in the spec itself. 
"This does look like a spec hole.. [...] JLS 5.2 should allow: "a widening primitive conversion (5.1.2), ***optionally followed by a boxing conversion***". The switch code in 6578574 would then compile." 

Also see:
http://bugs.sun.com/view_bug.do?bug_id=6558543

Closing as a bug in javac&spec. 
Comment 10 Jerome Lanneluc CLA 2008-09-16 04:22:34 EDT
Verified for 3.5M2