Capture conversion and switch selectors

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Feb 5 11:41:47 UTC 2025


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.

Maurizio


On 28/01/2025 18:51, Liam Miller-Cushon wrote:
> Hi,
>
> Chris Povirk and I were trying to understand why examples like the 
> following are rejected:
>
> 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 ?
>
> I think this is a consequence of JLS 6.5.6.1, which says that the type 
> of the switch selector expression is subject to capture conversion, 
> and then the captured type is not convertible.
>
> In the implementation, this is happening here [1], where attribExpr 
> uses KindSelector.VAL, which causes the capture to happen.
>
> Has consideration been given to treating selector expressions 
> differently, to avoid the capture conversion, and allow examples like 
> this to compile? I couldn't find test coverage for this specific 
> combination of features, which made me wonder if this was a corner 
> case that hadn't been explored, rather than something that had 
> definitely been ruled out.
>
> Liam
>
> [1] 
> https://github.com/openjdk/jdk/blob/a224f12cb701b45df4706a403a05c66de2d623af/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java#L1702


More information about the compiler-dev mailing list