Can't make simple Streams over indirect projects work

Srikanth srikanth.adayapalam at oracle.com
Wed Aug 14 08:45:26 UTC 2019


Hello Ben,

With this push: 
http://hg.openjdk.java.net/valhalla/valhalla/rev/7ec951ef532d for 
https://bugs.openjdk.java.net/browse/JDK-8229537, I believe the code 
snippet below
compiles fine (once suitable imports are typed in)

However, this program fails at runtime with "Exception in thread "main" 
java.lang.ClassCircularityError: OptionalInt" - this circularity error 
is a bogus error that is being addressed as we speak by the good folks 
at the VM team.

See 
https://mail.openjdk.java.net/pipermail/valhalla-dev/2019-August/006229.html 
which initiates a review of a fix for 
https://bugs.openjdk.java.net/browse/JDK-8229372.

In the meantime, you can easily workaround the circularity problem by 
manually constant propagating OptionalInt.default into the only place 
OptionalInt.EMPTY is used.

You may want to peruse the tests I have added here, 
http://hg.openjdk.java.net/valhalla/valhalla/rev/7ec951ef532d

Thanks!
Srikanth

On 28/07/19 6:44 PM, Ben Evans wrote:
> Hi,
>
> I'm probably missing something really obvious, but I've been playing
> with this code for several days and can't find my bug.
>
> Given an inline class defined like this:
>
> public inline class OptionalInt {
>      private static final OptionalInt EMPTY = OptionalInt.default;
>
>      private boolean isPresent = false;
>      private int v = 0;
>
>      public static OptionalInt empty() {
>          return EMPTY;
>      }
>
>      public static OptionalInt of(int val) {
>          OptionalInt self = OptionalInt.default;
>          self = __WithField(self.v, val);
>          self = __WithField(self.isPresent, true);
>          return self;
>      }
>
>      public int getAsInt() {
>          if (!isPresent)
>              throw new NoSuchElementException("No value present");
>
>          return v;
>      }
>
>      public boolean isPresent() {
>          return isPresent;
>      }
>
>      public void ifPresent(IntConsumer consumer) {
>          if (isPresent)
>              consumer.accept(v);
>      }
>
>      public int orElse(int other) {
>          return isPresent ? v : other;
>      }
> }
>
> and some code that attempts to use it like this:
>
> public final class Main4 {
>      public static void main(String[] args) {
>          List<OptionalInt?> opts = new ArrayList<>();
>          for (int i=0; i < 5; i++) {
>              opts.add(OptionalInt.of(i));
>              opts.add(OptionalInt.empty());
>              opts.add(null);
>          }
>
>          Integer total = opts.stream()
>              .map((OptionalInt? o) -> {
>                  if (o == null)
>                      return 0;
>
>                  OptionalInt op = (OptionalInt)o;
>                  return op.orElse(0);
>              })
>              .reduce(0, (x, y) -> x + y);
>
>          System.out.println("Total: "+ total);
>      }
> }
>
> Then javac barfs like this:
>
> bevans$ javac -XDallowWithFieldOperator -XDallowGenericsOverValues
> javamag/Main4.java
>
> javamag/Main4.java:15: error: ')' expected
>              .map((OptionalInt? o) -> {
>                               ^
> javamag/Main4.java:15: error: : expected
>              .map((OptionalInt? o) -> {
>                                  ^
> javamag/Main4.java:15: error: ';' expected
>              .map((OptionalInt? o) -> {
>                                   ^
> javamag/Main4.java:20: error: illegal start of expression\
>              })
>               ^
> 4 errors
>
> Could some kind person put me out of my misery and tell me what I'm
> doing wrong here, and what the proper way to express this should be?
>
> Thanks,
>
> Ben



More information about the valhalla-dev mailing list