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

Bug 428307

Summary: [1.8][compiler] Compiler fails to compile AnnotatedElement
Product: [Eclipse Project] JDT Reporter: Srikanth Sankaran <srikanth_sankaran>
Component: CoreAssignee: Stephan Herrmann <stephan.herrmann>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: jarthana, noopur_gupta
Version: 4.4   
Target Milestone: BETA J8   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Bug Depends on:    
Bug Blocks: 427787    

Description Srikanth Sankaran CLA 2014-02-16 16:41:45 EST
We get an error: 

The method getDirectlyAndIndirectlyPresent(Map<Class<? extends Annotation>,Annotation>, Class<A>) in the type AnnotationSupport is not applicable for the arguments (Map<Class<capture#9-of ? extends Annotation>,Annotation>, Class<T>)
Comment 1 Srikanth Sankaran CLA 2014-02-16 16:43:16 EST
Thanks for taking a look, I'll tackle https://bugs.eclipse.org/bugs/show_bug.cgi?id=428261 and once these are taken care of, Jay can devise some ways to package
and test.
Comment 2 Stephan Herrmann CLA 2014-02-17 20:04:20 EST
First thing tomorrow :)
Comment 3 Stephan Herrmann CLA 2014-02-18 04:48:38 EST
Minimal repro:

//----
import java.util.*;
import java.util.function.Function;
import java.util.stream.*;

interface Bar {
	Class<? extends Bar> type();
}
public class X {
 
    <T extends Bar> T[] test(Class<T> barClass, Stream<Bar> bars) {
        return get(bars.
                    collect(Collectors.toMap(Bar::type,
                                             Function.identity(),
                                             ((first,second) -> first),
                                             HashMap::new)),
                            barClass);
    }
    
    <A extends Bar> A[] get(Map<Class<? extends Bar>,Bar> m, Class<A> c) {
    	return null;
    }
}
//----
Comment 4 Stephan Herrmann CLA 2014-02-18 07:05:53 EST
This is an interesting case: trouble occurred at this constraint:

⟨bars.collect(Collectors.toMap(..)) → java.util.Map<java.lang.Class<? extends Bar>,Bar>⟩

Here the spec (18.2.1) clearly says:

"A constraint formula of the form ⟨Expression → T⟩ is reduced as follows:
If T is a proper type, the constraint reduces to true if the expression is compatible in a loose invocation context with T (5), and false otherwise."

Problem was: after applicability inference the inner ("toMap") has type
   Map<Class<capture#3-of ? extends Bar>,Bar>
which is *not* compatible with its non-captured variant. Bummer!

First guess: maybe compatibility should be checked after finishing inner inference. This indeed fixes the immediate issue, but then we ended up comparing an unsubstituted type variable (U, declared by toMap) with its inference solution Bar and again incompatibility was detected.

The solution is to include inner inference into the current inference. Interestingly, a few bullets down in 18.2.1 we have "the constraint reduces to the bound set B3 ...", which exactly solves the problem.

Even more interestingly, the initial "If T is a proper type" is separated from the other bullet by a chain of "Otherwise, if .., Otherwise". I conclude that javac is interpreting this "Otherwise" in a non-exclusive way. Which is extremely interesting, as also the case reported in [1] can be explained using a non-exclusive interpretation of "Otherwise".

Test & fix released via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=b0e8687830f97b9ddeb50b010730e5d2fdfd5916


[1] http://mail.openjdk.java.net/pipermail/lambda-spec-experts/2014-February/000507.html
Comment 5 Noopur Gupta CLA 2014-02-21 02:38:53 EST
Verified as working for Eclipse + Java 8 RC1 using Kepler SR2(RC4) +   
Eclipse Java Development Tools Patch for Java 8 Support (BETA)	
1.0.0.v20140220-2054