JDK-8173176 : javac inference failure when using implicit lambdas or inexact method references
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u60,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86_64
  • Submitted: 2017-01-22
  • Updated: 2017-02-03
  • Resolved: 2017-02-03
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux pamela 4.4.0-59-lowlatency #80-Ubuntu SMP PREEMPT Fri Jan 6 21:04:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
Impossible to compile the attached code => the error is
RunTransformation.java:41: error: method unmodifiableSet in class Collections cannot be applied to given types;
		final Set<String> transformerCodes = Collections.unmodifiableSet(mediaProcessAbstractFactories.stream()
		                                                ^
  required: Set<? extends T>
  found: Collection<String>
  reason: cannot infer type-variable(s) E
    (actual and formal argument lists differ in length)
  where T,E are type-variables:
    T extends Object declared in method <T>unmodifiableSet(Set<? extends T>)
    E extends Object declared in class TreeSet


REGRESSION.  Last worked in version 8u102

ADDITIONAL REGRESSION INFORMATION: 
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
javac RunTransformation.java

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
RunTransformation.class and RunTransformation$MyClass.class created
ACTUAL -
no compiling

ERROR MESSAGES/STACK TRACES THAT OCCUR :
error: method unmodifiableSet in class Collections cannot be applied to given types;
		final Set<String> transformerCodes = Collections.unmodifiableSet(mediaProcessAbstractFactories.stream()
		                                                ^
  required: Set<? extends T>
  found: Collection<String>
  reason: cannot infer type-variable(s) E
    (actual and formal argument lists differ in length)
  where T,E are type-variables:
    T extends Object declared in method <T>unmodifiableSet(Set<? extends T>)
    E extends Object declared in class TreeSet


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.*;

import java.util.stream.Collectors;

/**
 * @author Marian
 *
 */
public final class RunTransformation {
	public static void main(final String... args) {
		List<MyClass> mediaProcessAbstractFactories = createMediaProcessAbstractFactoryList ();
		final Set<String> transformerCodes = Collections.unmodifiableSet(mediaProcessAbstractFactories.stream()
                .flatMap(mpaf -> mpaf.getCodes().stream())
                .collect(Collectors.toCollection(TreeSet::new)));
		System.out.println ("transformerCodes size = " + transformerCodes.size());
	}

	private static List<MyClass> createMediaProcessAbstractFactoryList() {
		return Arrays.asList(new MyClass (1), new MyClass (2));
	}

	private static final class MyClass {
		private final Set<String> codes = new HashSet<>();
		MyClass (int nbc) {
			for (int i = 0; i < nbc; i++) {
				codes.add(String.valueOf(i));
			}
		}
	
		Set<String> getCodes() {
			return codes;
		}
		
	}
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
cast:
final Set<String> transformerCodes = Collections.unmodifiableSet((Set<String>)mediaProcessAbstractFactories.stream()
                .flatMap(mpaf -> mpaf.getCodes().stream())
                .collect(Collectors.toCollection(TreeSet::new)));


Comments
import java.util.function.*; abstract class Test { void m() { List<String> stringSet = id(toCollection(s -> new ArrayList<>())); } static <U> List<U> id(List<? extends U> l) { return null; } static <C extends Collection<String>> C toCollection(Function<String, C> collectionFactory) { return null; } }
25-01-2017

another test case: import java.util.*; import java.util.stream.*; class JDK8173176 { public void test(Stream<String> strings) { Set<String> s = Collections.unmodifiableSet(strings.collect(Collectors.toCollection(TreeSet::new))); } }
24-01-2017

reduced test case: import java.util.*; import java.util.stream.Collectors; class RunTransformation { public static void main(final String... args) { List<MyClass> mediaProcessAbstractFactories = createMediaProcessAbstractFactoryList (); final Set<String> transformerCodes = Collections.unmodifiableSet(mediaProcessAbstractFactories.stream() .flatMap(mpaf -> mpaf.getCodes().stream()) .collect(Collectors.toCollection(TreeSet::new))); } private static List<MyClass> createMediaProcessAbstractFactoryList() { return null; } private static final class MyClass { Set<String> getCodes() { return null; } } }
23-01-2017

the change was introduced by JDK-8069545
23-01-2017

The code compiles fine till 8u52 and from 8u60 it starts prompting compile time error, 8u52 - Pass 8u60 - Fail 8u121 - Fail 9 ea b52 - Pass 9 ea b53 - Fail 9 ea b152 - Fail
23-01-2017