RFR: 5059679: name clash not reported for interface inheritance

Archie L. Cobbs duke at openjdk.org
Thu Feb 9 21:07:32 UTC 2023


Consider this input:

public class NarrowingNameClash {

    public interface Upper<T> {
        void method(T param);
    }

    public interface Lower<R> extends Upper<Class<R>> {
        void method(Class<?> param);        // erasure name clash here
    }
}

This violates §8.4.8.3 because `method(Class<R>)` and `method(Class<?>)` have the same erasure. However, the compiler is not reporting an error in this case.

Here's my understanding of the bug... (reviewer please double-check this :)

§8.4.8.3 "Requirements in Overriding and Hiding" says:

It is a compile-time error if a class or interface C has a member method m1 and there exists a method m2 declared in C or a superclass or superinterface of C, A, such that all of the following are true:

* m1 and m2 have the same name.
* m2 is accessible (§6.6) from C.
* The signature of m1 is not a subsignature (§8.4.2) of the signature of m2 as a member of the supertype of C that names A.
* The declared signature of m1 or some method m1 overrides (directly or indirectly) has the same erasure as the declared signature of m2 or some method m2 overrides (directly or indirectly).

Method `method(Class<R>)` is inherited by `Lower` from `Upper` and is therefore a member of `Lower`. Note that upon inheritance its parameter `T` is reinterpreted as `Class<R>` in the context of `Lower`'s generic parameterization.

Let C = `Lower`, A = `Upper`, m1 = `method(Class<R>)` and m2 = `method(Class<?>)`.

The compiler is comparing the erasures of `method(T)`, which is "some method m1 overrides", and m2 = `method(Class<?>)`, and these are different, so no bug is reported.

That comparison is appropriate, however, what it also needs to do is compare the erasures of m1 and m2, which are both `method(Class)`.

In a nutshell: within the context of `Lower`, the method `method(Class<R>)` inherited from `Upper`, when erased, has a different signature from its original form `method(T)` in `Upper`, when erased. The possibility of this different form was not being taken into account in the compiler.

-------------

Commit messages:
 - Fix bug where certain erasure name clashes were not being detected.

Changes: https://git.openjdk.org/jdk/pull/12503/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12503&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-5059679
  Stats: 23 lines in 3 files changed: 22 ins; 0 del; 1 mod
  Patch: https://git.openjdk.org/jdk/pull/12503.diff
  Fetch: git fetch https://git.openjdk.org/jdk pull/12503/head:pull/12503

PR: https://git.openjdk.org/jdk/pull/12503


More information about the compiler-dev mailing list