Bug 432603 - [compile][1.7] ecj reports an Error while javac doesn't
Summary: [compile][1.7] ecj reports an Error while javac doesn't
Status: VERIFIED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.3.2   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 4.4 RC1   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords: test
Depends on:
Blocks:
 
Reported: 2014-04-11 05:35 EDT by Jakub Gruszka CLA
Modified: 2015-06-30 09:10 EDT (History)
5 users (show)

See Also:


Attachments
Maven project (164 bytes, application/zip)
2014-04-11 05:41 EDT, Jakub Gruszka CLA
no flags Details
Eclipse screenshot (155.97 KB, image/png)
2014-04-11 05:42 EDT, Jakub Gruszka CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Gruszka CLA 2014-04-11 05:35:58 EDT
Problem has been reported and discussed on Stackoverflow:

http://stackoverflow.com/questions/23006777/eclipse-fails-to-compile-generic-code-but-mvn-compile-works

In general ECJ reports and error where Javac does not and code runs succefully without any problems.

{code}
package testit;

import java.util.Map;
import java.util.Map.Entry;

import com.google.common.base.Optional;

public class Test {

    private static final Object NO_VALUE = new Object();

    public void method(Map<String, ?> map) {
        for (Entry<String, ?> entry : map.entrySet()) {
            Optional.fromNullable(entry.getValue()).or(NO_VALUE);
//                                                  ^^ error here
        }
    }
}
{code}
Comment 1 Jakub Gruszka CLA 2014-04-11 05:41:51 EDT
Created attachment 241877 [details]
Maven project
Comment 2 Jakub Gruszka CLA 2014-04-11 05:42:11 EDT
Created attachment 241878 [details]
Eclipse screenshot
Comment 3 Stephan Herrmann CLA 2014-04-11 13:23:22 EDT
Let's see which one is correct...

My initial understanding is:

 - Type of entry.getValue() is "capture#2-of ?"
 - Type of fromNullable(..) is "Optional<capture#2-of ?>"
 - Parameter of or(..) is "capture#2-of ?"
 - Object is not compatible with any capture

This would mean ecj is right, the bug is in javac.

I'll try to find a matching bug in their system (or a corresponding discussion in our bugzilla).

Note specifically, that the dot before "or" separates the inference for fromNullable(..) from the trailing method invocation, i.e., the type of NO_VALUE does not have any influence on the inferred type for fromNullable(..).
Comment 4 Jakub Gruszka CLA 2014-05-01 16:52:27 EDT
In my opinion a good point in the discussion have made Eugene on stackoverflow:

"@JensSchauder a small search revealed this: 15.12.2.8 Any remaining type variables that have not yet been inferred are then inferred to have type Object –  Eugene Apr 11 at 8:49"

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.8

I've tested :

jdk1.6.0_45
jdk1.7.0_51
jdk1.8.0
OpenJDK 1.7.0_51

all them succefully compile the code while ecj doesn't. As a Developer I would like ECJ does not correct the JDK.
Comment 5 Stephan Herrmann CLA 2014-05-01 18:58:13 EDT
> In my opinion a good point in the discussion have made Eugene on stackoverflow:

The question is a bit more complex than that :)

To get an idea about the status of javac in this field have a look at https://bugs.openjdk.java.net/browse/JDK-8016207

The bottom line is: if type checking involves captures (like in comment 0) then javac cannot be much relied on. That javac bug has been open for some time already.

Note that this current bug is still targeted 4.4 so I'll try to find the time to clarify what exactly is going on before the Luna release.
Comment 6 Stephan Herrmann CLA 2014-05-13 17:03:25 EDT
(In reply to Jakub Gruszka from comment #4)
> In my opinion a good point in the discussion have made Eugene on
> stackoverflow:
> 
> "@JensSchauder a small search revealed this: 15.12.2.8 Any remaining type
> variables that have not yet been inferred are then inferred to have type
> Object –  Eugene Apr 11 at 8:49"
> 
> http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.8

This line doesn't apply for the following reason:

Type inference starts by resolving this expression:

  Optional.fromNullable(entry.getValue())

In this expression all elements can be typed as stated above:

  entry :            Entry<String, capture#2-of ?>
  entry.getValue:    capture#2-of ?
  fromNullable(..) : (capture#2-of ?) -> Optional<capture#2-of ?>

In short: T is inferred to be "capture#2-of ?". Inference succeeds.


Only after all these have been decided, does resolution proceed to inspect the .or(..) method call. No reason to fill in un-inferred inference variables with "Object".


With a receiver of type Optional<capture#2-of ?>, we have these three overloads of "or":

  Optional<capture#2-of ?> or(Optional<? extends capture#2-of ?>)
  capture#2-of ? or(Supplier<? extends capture#2-of ?> supplier)
  capture#2-of ? or(capture#2-of ? defaultValue)

None of these methods is applicable for an argument of type Object.
ecj arbitrarily picks the first method for error reporting:

"The method or(Optional<? extends capture#2-of ?>) in the type Optional<capture#2-of ?> is not applicable for the arguments (Object)"


The difference between ecj and javac is most certainly covered by the mentioned javac bug: https://bugs.openjdk.java.net/browse/JDK-8016207


As mentioned in that bug, a future update of the JLS may possibly adopt parts of the current javac behavior. Until such a spec update is released, the only reliable point of reference for ecj is the JLS. In this specification I see no reason for changing the behavior of ecj in this regard.

BTW, the canonical fix (no cast needed) is:

   Optional.<Object>fromNullable(entry.getValue()).or(NO_VALUE);
Comment 7 Stephan Herrmann CLA 2014-05-13 17:11:27 EDT
I've released regression tests (negative and positive) via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=460d5bedc49ffdc3e78c2a4574461c7301168e97

That's all we can do here.
Comment 8 Jakub Gruszka CLA 2014-05-14 03:04:02 EDT
Thanks for the effort on the research as well for providing a constructive answer.
Comment 9 shankha banerjee CLA 2014-05-19 03:00:16 EDT
Verified for Luna 4.4 RC1.
Comment 10 Stephan Herrmann CLA 2015-06-30 09:10:14 EDT
Despite the related https://bugs.openjdk.java.net/browse/JDK-8039214 being fixed, javac9 still accepts the program. OTOH, https://bugs.openjdk.java.net/browse/JDK-8016207 is still unresolved ...