Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 454497

Summary: [1.8][compiler] Non-static method references erroneously reported as syntax errors
Product: [Eclipse Project] JDT Reporter: Trejkaz pen name <trejkaz>
Component: CoreAssignee: Sasikanth Bharadwaj <sasikanth.bharadwaj>
Status: CLOSED WORKSFORME QA Contact:
Severity: normal    
Priority: P3 CC: sasikanth.bharadwaj, stephan.herrmann
Version: 4.5   
Target Milestone: 4.5   
Hardware: PC   
OS: Mac OS X   
Whiteboard:

Description Trejkaz pen name CLA 2014-12-08 19:31:59 EST
We have the following code in our project which implements a collector to Guava's ImmutableList. It compiles fine with javac (and which IDEA does not note as a syntax error either):

    public static <T> Collector<T, ?, ImmutableList<T>> toImmutableList1()
    {
        return Collector.<T, ImmutableList.Builder<T>, ImmutableList<T>>of(
            ImmutableList::builder,
            ImmutableList.Builder::add,
            (left, right) -> left.addAll(right.build()),
            ImmutableList.Builder::build);
    }

Eclipse lights up with 5 errors. It seems to pick the wrong Collector.of and mistake the types of pretty much every parameter.

To help it out, I thought I would try adding explicit casts:

    public static <T> Collector<T, ?, ImmutableList<T>> toImmutableList()
    {
        return Collector.<T, ImmutableList.Builder<T>, ImmutableList<T>>of(
            (Supplier<ImmutableList.Builder<T>>) ImmutableList::builder,
            (BiConsumer<ImmutableList.Builder<T>, T>) ImmutableList.Builder::add,
            (BinaryOperator<ImmutableList.Builder<T>>) (left, right) -> left.addAll(right.build()),
            (Function<ImmutableList.Builder<T>, ImmutableList<T>>) ImmutableList.Builder::build);
    }

This still gives an error on ImmutableList.Builder::add:

    "Cannot make a static reference to the non-static method add(Object[]) from the type
     ImmutableList.Builder"

I tried isolating that one piece of the code and yes, it still happens on this one-liner:

    BiConsumer<ImmutableList.Builder<T>, T> accumulator = ImmutableList.Builder::add;

So it seems that method references to non-static methods are perhaps not being resolved correctly. It's picking add(Object[]) when add(Object) exists as well and would probably have worked.

This occurs on v4.4.1 as well as Mars build N20141206-2000.
Comment 1 Manoj N Palat CLA 2014-12-08 22:09:47 EST
Sasi: Can you please take a look?
Comment 2 Stephan Herrmann CLA 2014-12-09 06:37:32 EST
A few general remarks to fill the time until Sasi will provide more details:

(In reply to Trejkaz (pen name) from comment #0)
> We have the following code in our project which implements a collector to
> Guava's ImmutableList. It compiles fine with javac (and which IDEA does not
> note as a syntax error either):

Please don't take this as a majority vote :)
Between javac, IDEA and JDT it's only a game of
   javac vs. ecj (Eclipse Compiler for Java);  referee : JLS
IDEA doesn't participate, they don't provide a compiler, but simply delegate to your choice of javac or ecj.


> To help it out, I thought I would try adding explicit casts:

To "help" inference, casts are not the best way, adding explicit type arguments should give better results (and no CCE) - just as you already do for the invocation of "of".
 

> This occurs on v4.4.1 as well as Mars build N20141206-2000.

I can reproduce using 4.4.1 and 4.5M1, but all later versions of ecj accept the example. Could you please recheck? Also a reference to your exact version of ImmutableList might help.
Comment 3 Trejkaz pen name CLA 2014-12-09 17:17:53 EST
Alright, I retried on the same nightly it was previously happening on and now it isn't happening anymore. Same build, as far as I know the plugins didn't get updated either, and using the same version of Guava. So I have no idea what changed now. But at least this means it has been fixed.

I included IDEA in the comparison because they _do_ have their own parser and type checker, even if it isn't a _compiler_. It certainly isn't just using javac - if it were, I wouldn't have multiple tickets open with them about issues very similar to this one. ;)
Comment 4 Stephan Herrmann CLA 2014-12-09 18:30:33 EST
Sasi, can you find the change that fixed this between M1 & M2?