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

Bug 492838

Summary: [1.8][compiler][inference] method not applicable for arguments, goes away on simple refactor to local variable (in an expression which javac 1.8 allows)
Product: [Eclipse Project] JDT Reporter: Michael Vorburger <mike>
Component: CoreAssignee: JDT-Core-Inbox <jdt-core-inbox>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: jarthana, stephan.herrmann
Version: 4.6   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Whiteboard: stalebug

Description Michael Vorburger CLA 2016-05-02 13:13:15 EDT
This is a similar rant to my earlier bug 490001, but with an interesting twist:

Neon Milestone 6 (4.6.0M6) Build id: 20160329-0659 chokes on the following generics, in a project using Java 8 level, which works in javac because there is mvn CLI build which digs this, and IDEA according to other users:

this.substatements = ImmutableList.copyOf(Collections2.transform(substatementsToBuild, StmtContextUtils.buildEffective()));

saying: The method transform(Collection<F>, Function<? super F,T>) in the type Collections2 is not applicable for the arguments (Collection<StatementContextBase<?,?,?>>, Function<StmtContext<?,?,? extends EffectiveStatement<?,?>>,EffectiveStatement<?,?>>)

If interested, you should be to reproduce this in a complete WS quite easily, by using my https://github.com/vorburger/opendaylight-eclipse-setup and provisioning (just) the yangtools project.  Check out current git revision 31d5ed0c664e8fbd793538c4e4546204847c779e just to be sure we're talking about the same thing, and the error shown above will appear in line 94 of org.opendaylight.yangtools.yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStatementBase.java

Stephan I recall your "javac is known to have long standing bugs in this area, and reverse engineering these bugs will get us nowhere. The goal in implementing a Java compiler is to be compliant with JLS." from bug 490001, BUT here is the interesting twist on this one:

If you mark "StmtContextUtils.buildEffective()" and do a Refactor > Extract Local Variable, it will turn the above into this below, and on this it doesn't choke anymore:

Function<StmtContext<?, ?, ? extends EffectiveStatement<?, ?>>, EffectiveStatement<?, ?>> buildEffective = StmtContextUtils.buildEffective();
this.substatements = ImmutableList.copyOf(Collections2.transform(substatementsToBuild, buildEffective));

My point being: If Refactoring "knows" about the correct (horrible...) generic here, shouldn't & couldn't the type inference that's underlying the generics stuff be smart enough to also dig this, without requiring factoring out to an explicit variable ?

If there are other open bugs about this / something related to this, do link.  I had a look around but there are so many open generic related bugs (wow!) that it's hard to see what is what.


PS: I'll just be honest and just admit that I do actually understand this scary horrible looking generic - it's part of an API of a product I'm trying to get my head around (and haven't yet..).  From the little I understand, there are perhaps way too many <?, ?, ?> instead of <? extends ...> all over here? Thoughts welcome. Addressing this, project wide, is probably a major undertaking. Be that as it may, it would still seem "nice" if Eclipse would handle this code which javac & IDEA do.
Comment 1 Michael Vorburger CLA 2016-05-02 13:18:05 EDT
> reproduce this in a complete WS quite easily (...)
> Check out current git revision 31d5ed0c664e8fbd793538c4e4546204847c779e 

careful, https://git.opendaylight.org/gerrit/#/c/38289/ will work around this.
Comment 2 Stephan Herrmann CLA 2016-05-02 16:34:04 EDT
(In reply to Michael Vorburger from comment #0)
> Stephan I recall your "javac is known to have long standing bugs in this
> area, and reverse engineering these bugs will get us nowhere. The goal in
> implementing a Java compiler is to be compliant with JLS." from bug 490001,

thanks for the quotation, so I don't have to repeat myself :)

> BUT here is the interesting twist on this one:
> 
> If you mark "StmtContextUtils.buildEffective()" and do a Refactor > Extract
> Local Variable, it will turn the above into this below, and on this it
> doesn't choke anymore:
> 
> Function<StmtContext<?, ?, ? extends EffectiveStatement<?, ?>>,
> EffectiveStatement<?, ?>> buildEffective = StmtContextUtils.buildEffective();
> this.substatements =
> ImmutableList.copyOf(Collections2.transform(substatementsToBuild,
> buildEffective));

This may not be your main point, but: It is a known effect of Java 8 target typing, that additional type hints from declaring an intermediate local variable can push inference towards the intended solution, where otherwise it fails.
 
> My point being: If Refactoring "knows" about the correct (horrible...)
> generic here, shouldn't & couldn't the type inference that's underlying the
> generics stuff be smart enough to also dig this, without requiring factoring
> out to an explicit variable ?

"could", yes, probably.

"should" is to be decided by JLS authors, not Eclipse committers.


This doesn't yet rule out that ecj has a bug here.
To prove a bug, it will require to demonstrate *how* exactly inference is supposed to find a valid solution based on JLS chap. 18. Unfortunately, such demonstration is a painfully complex task. Showing the opposite - that not finding a solution is correct - is even harder. Just saying ...
Comment 3 Eclipse Genie CLA 2020-04-25 18:27:08 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.