Bug 536585 - Regression: Code using type bounds and raw types compiles under Oxygen, has errors under Photon
Summary: Regression: Code using type bounds and raw types compiles under Oxygen, has e...
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.8   Edit
Hardware: PC Linux
: P3 normal with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on: 528970
Blocks:
  Show dependency tree
 
Reported: 2018-07-02 06:15 EDT by Andreas Sewe CLA
Modified: 2022-07-17 19:42 EDT (History)
2 users (show)

See Also:


Attachments
Test project exhibiting two compiler regressions under Photon (2.08 KB, application/zip)
2018-07-02 06:15 EDT, Andreas Sewe CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Sewe CLA 2018-07-02 06:15:30 EDT
Created attachment 274741 [details]
Test project exhibiting two compiler regressions under Photon

The attached project compiles fine with Oxygen.3a, with just single warning:

- IXmlFileVersion is a raw type. References to generic type IXmlFileVersion<T> should be parameterized

With Photon.R, however, it exhibits two compile errors in addition to the warning:

- The method extractVersion(String, Class<VERSION>) in the type VersionContainer is not applicable for the arguments (String, Class<VersionContainerTest.ETestDataVersion>)

- The method toXml(T, VERSION, String...) in the type VersionContainer is not applicable for the arguments (VersionContainerTest.TestData1, VersionContainerTest.ETestDataVersion)

I am afraid the attached test project is a bit complex, using type bounds together with raw types, but I've already reduced it as much as I could. Hope that helps.
Comment 1 Till Brychcy CLA 2018-07-02 06:33:32 EDT
Still compiles in Eclipse4.8I20171217-2000
Reports errors in Eclipse4.8I20180112-2000

Further reduced example:

interface IXmlFileVersion<T> {
}

class VersionContainer<VERSION extends Enum<VERSION> & IXmlFileVersion<?>> {

    public static <T, VERSION extends Enum<VERSION> & IXmlFileVersion<T>> void toXml(VERSION version) {
    }

    public static <VERSION extends Enum<VERSION> & IXmlFileVersion<?>> void extractVersion(Class<VERSION> versionEnum) {
    }
}

public class VersionContainerTest {

    public void testToXml() {
        VersionContainer.toXml(ETestDataVersion.VERSION1);
    }

    public void testExtractVersion() {
        VersionContainer.extractVersion(ETestDataVersion.class);
    }

    public static enum ETestDataVersion implements IXmlFileVersion {
        VERSION1
    }
}
Comment 2 Till Brychcy CLA 2018-07-02 06:53:24 EDT
Caused by commit ec76c89defa5f96571519ef98af5fe717abfdb09 for bug 528970.
Comment 3 Andrey Loskutov CLA 2018-07-02 07:17:38 EDT
(In reply to Till Brychcy from comment #1)
>     public static enum ETestDataVersion implements IXmlFileVersion {
>         VERSION1
>     }

Just wondering why one would let enums (usually constants) implement a *generic* interface. Enums can't be generified AFAIK, and I guess this is the reason why one uses here raw IXmlFileVersion interface.

@Andreas: in the example, IXmlFileVersion T type is not used. I'm just curious, what is the purpose of T in the real code, and how enums are using this T? The only use in the example was in the static methods, which do not need to be in the enum itself. Are there other uses of T in the Enum itself?
Comment 4 Andreas Sewe CLA 2018-07-02 08:56:10 EDT
(In reply to Andrey Loskutov from comment #3)
> (In reply to Till Brychcy from comment #1)
> >     public static enum ETestDataVersion implements IXmlFileVersion {
> >         VERSION1
> >     }
> 
> Just wondering why one would let enums (usually constants) implement a
> *generic* interface. Enums can't be generified AFAIK, and I guess this is
> the reason why one uses here raw IXmlFileVersion interface.
>
> @Andreas: in the example, IXmlFileVersion T type is not used. I'm just
> curious, what is the purpose of T in the real code, and how enums are using
> this T? The only use in the example was in the static methods, which do not
> need to be in the enum itself. Are there other uses of T in the Enum itself?

A bit more context:

We have a lot of things in our code base that can be versions and which need to be migrated from one version to the next. So you find types like

  enum EProjectConfigurationVersion implements XmlFileVersion<ProjectConfiguration>

or

   enum EAnalysisProfileVersion implements IXmlFileVersion<AnalysisProfile>

with constants like VERSION_1_0, VERSION_1_1, etc. Each individual enum constant implements a version-specific migrate(String) method that migrates the XML string, if necessary.

The type parameter T is used by the static toXml(T, VERSION extends Enum<VERSION> & IXmlFileVersion<T>) method to ensure that the enum VERSION_x_y constant passed as the second parameter knows how to migrate the payload type T passed as the first argument.

So, outside the test, we don't use IXmlFileVersion as a raw type -- and generified enums work quite well.

Hope this clarifies things.
Comment 5 Eclipse Genie CLA 2022-07-17 19:42:17 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.