The following example is rejected, but should possibly be accepted.
sealed interface A<T> {
enum B implements A<String> {
C;
}
static void d(A<?> a) {
switch (a) {
case B.C:
}
}
}
A.java:8: error: incompatible types: B cannot be converted to A<CAP#1>
case B.C:
^
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
This was initially reported on compiler-dev@, see Maurizio's comment here: https://mail.openjdk.org/pipermail/compiler-dev/2025-February/029342.html
> I'm not sure the capture is the issue here. Note that if the case is
rewritten to
>
> case B b
>
> Then everything works as expected and javac doesn't get confused by
capture conversion. Note that capture conversion is always problematic
when it comes to cast expressions -- because the cast has to "relax"
some of the captured variable that might be introduced by capture
conversion. This is an area of the specification that is underspecified,
so javac (and other implementations) have to workaround such issues the
best they can.
>
> The particular example you pose seems like it should work to me --
there's only one possible parameterization for A<T> coming up from B.C -
and that's A<String>, so the conversion should be safe here. It seems to
me like a case of bad interplay between enums constants and patterns.
sealed interface A<T> {
enum B implements A<String> {
C;
}
static void d(A<?> a) {
switch (a) {
case B.C:
}
}
}
A.java:8: error: incompatible types: B cannot be converted to A<CAP#1>
case B.C:
^
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
This was initially reported on compiler-dev@, see Maurizio's comment here: https://mail.openjdk.org/pipermail/compiler-dev/2025-February/029342.html
> I'm not sure the capture is the issue here. Note that if the case is
rewritten to
>
> case B b
>
> Then everything works as expected and javac doesn't get confused by
capture conversion. Note that capture conversion is always problematic
when it comes to cast expressions -- because the cast has to "relax"
some of the captured variable that might be introduced by capture
conversion. This is an area of the specification that is underspecified,
so javac (and other implementations) have to workaround such issues the
best they can.
>
> The particular example you pose seems like it should work to me --
there's only one possible parameterization for A<T> coming up from B.C -
and that's A<String>, so the conversion should be safe here. It seems to
me like a case of bad interplay between enums constants and patterns.