JEP 406 type inference

Jakob Brünker jakob.bruenker at gmail.com
Thu Jul 8 02:00:10 UTC 2021


Hi all,

I've been excited to try doing some things with JEP 406 for a while now,
and when attempting to implement some things, I stumbled over an apparent
shortcoming that surprised me:

Compiling this code:

import java.util.function.Function;

sealed interface Either<A, B> permits Either.Left, Either.Right {
    final record Left<A, B>(A a) implements Either<A, B> {}
    final record Right<A, B>(B b) implements Either<A, B> {}

    default <C> Either<C, B> first(Function<A, C> f) {
        return switch (this) {
            case Left l -> new Left<C, B>(f.apply(l.a));
            case Right r -> new Right<C, B>(r.b);
        };
    }
}

with javac Either.java --enable-preview --release 18, results in

Either.java:9: error: incompatible types: Object cannot be converted to A
            case Left l -> new Left<C, B>(f.apply(l.a));
                                                   ^
  where A is a type-variable:
    A extends Object declared in interface Either
Either.java:10: error: incompatible types: Object cannot be converted to B
            case Right r -> new Right<C, B>(r.b);
                                             ^
  where B is a type-variable:
    B extends Object declared in interface Either


It seems to determine that the field b of the Right record, which should be
a B, is actually an Object, and similarly for Left.

It's possible to implement this method with the visitor-pattern, but I
would have expected this to be equivalent.

Is this intentional?

Cheers,
Jakob


More information about the amber-dev mailing list