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