Eclipse: "Unknown error" during type inference

While working with some existing code, I ran into a runtime issue when running the code from Eclipse Neon . 3 . Unfortunately I was unable to reproduce the exception in a minimal working example, but the following release was produced by the classloader:

Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    ...
  Reason:
    Type 'java/lang/Object' (current frame, stack[8]) is not assignable to 'MyMap'
  Current Frame:
    ...
  Bytecode:
    ...
  Stackmap Table:
    ...

      

It works on the command line and in older versions of eclipse, so it didn't really matter much at the time. Eclipse Oxygen.1 was released last week and we started using it. Now the same code throws a compile-time exception:

Problem detected during type inference: Unknown error at invocation of reduce(Main.MyMap<MyKey,MyValue>, BiFunction<Main.MyMap<MyKey,MyValue>,? super MyValue,Main.MyMap<MyKey,MyValue>>, BinaryOperator<Main.MyMap<MyKey,MyValue>>)

      

I was able to put together a minimal working example that creates this error in Eclipse but works on the command line:

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class Main<MyKey, MyValue> {

    static class MyMap<K, V> extends HashMap<K, V> {
        public MyMap<K, V> putAllReturning(MyMap<K, V> c) { putAll(c); return this; }
        public MyMap<K, V> putReturning(K key, V value) { put(key, value); return this; }
    }

    public Main() {
        Set<MyValue> values = new HashSet<>(); // actually something better
        final MyMap<MyKey, MyValue> myMap =
                values.stream()
                    .reduce(
                        new MyMap<MyKey, MyValue>(),
                        (map, value) -> {
                            Set<MyKey> keys = new HashSet<>(); // actually something better

                            return keys.stream()
                                .reduce(
                                    map, // this would work syntactically: new MyMap<MyKey, MyValue>(),
                                    (map2, key) -> map2.putReturning(key, value),
                                    MyMap::putAllReturning);
                        },
                        MyMap::putAllReturning
                    );
    }
}

      

It seems that the first parameter of the inner shortening causes the type-output to break as it is replaced by another instance of the same type (but explicitly declared, not inferred) clears up the error.

Knowing the exact source of the error in the class allowed us to rewrite the code (extracting the lambda expression passed to the external vault into our own method). That said, I would still be interested in explaining why such a construct might break both new eclipse compilers.

+3


source to share


1 answer


Okay for me on Oxygen

, it worked with simple parameter declarations to shorten:

(MyMap<MyKey, MyValue> map, MyValue value) -> .... 

      



Knowing the exact problem and why the eclipse compiler cannot infer the types is too much for me; it should be reported anyway (this may already be known by the eclipse team).

I can also confirm that it compiles OK with jdk-8-131

andjdk-9-175

+3


source







All Articles