RFR: 8357653: Inner classes of type parameters emitted as raw types in signatures [v2]
Aggelos Biboudis
abimpoudis at openjdk.org
Wed Jun 11 09:54:17 UTC 2025
> In the following example, `G.Getter` is erroneously treated as a raw type by javac:
>
>
> static abstract class Getters<X> {
> abstract class Getter {
> abstract X get();
> }
> }
>
> static class Usage1<T, G extends Getters<T>> {
> public T test(G.Getter getter) {
> return getter.get();
> }
> }
>
>
> The (now reverted) https://github.com/openjdk/jdk/pull/25346 attempted to fix this by skipping type variables in the calculation of `allparams()`.
>
> While that seemed to fix the type checking error, it was a fragile solution in a number of ways.
>
> - `allparams()` is passed to a method that calculates substitutions. This signals that the method adheres to invariants during substitutions where lists of type parameters are expected to be of the same length (for the from and to parts). Affecting directly the `allparams_field` seems not the right approach.
> - Another observation (thx @liach) was that in the generated bytecode, the fully qualified type of the inner class `G` still appeared as if it originated from a raw type. `assembleClassSig` independently examines `outer` to detect whether it is raw or not.
> - Finally, there is already a proper area in javac, earlier in the pipeline, where javac handles/detects "rare types" (`test/langtools/tools/javac/generics/rare`): That method is `checkId` and specifically `checkIdInternal`. While in the general case the type of an identifier is the symbol's type, `checkIdInternal` computes a new type in two occasions. In one of those occasions, `checkIdInternal` is computing the type when the symbol's type is an inner class. Here, we can start normalizing (by skipping the type variables).
>
> Moreover, it has been observed that `asEnclosingSuper` is a generalization of `asOuterSuper` and additionally the former is used only in `checkIdInternal`. As a result, this PR performs two simplifications:
>
> As a first simplification this PR replaces `asOuterSuper` with `asEnclosingSuper`.
> As a second simplification this PR relies only on the owner's `enclClass()` based on the following subsequent observations:
> - An `enclosingType()` call returns the `outer_field` directly and `Type.noType` otherwise (in the case of an inner class it refers to the type of its enclosing instance class.)
> - An `enclClass()` call returns the closest enclosing class and the behavior in `asEnclosingSuper` containing a loop with the condition `t.hasTag(CLASS)` combined with `asSuper(t, sym)` is believed to be the same.
>
> The test now includes bytecode tests additionally t...
Aggelos Biboudis has updated the pull request incrementally with two additional commits since the last revision:
- Restore formatting of asOuterSuper
- Address review
-------------
Changes:
- all: https://git.openjdk.org/jdk/pull/25451/files
- new: https://git.openjdk.org/jdk/pull/25451/files/f33753bf..6cec56aa
Webrevs:
- full: https://webrevs.openjdk.org/?repo=jdk&pr=25451&range=01
- incr: https://webrevs.openjdk.org/?repo=jdk&pr=25451&range=00-01
Stats: 32 lines in 3 files changed: 27 ins; 0 del; 5 mod
Patch: https://git.openjdk.org/jdk/pull/25451.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/25451/head:pull/25451
PR: https://git.openjdk.org/jdk/pull/25451
More information about the compiler-dev
mailing list