Diamonds: cyclic inference error

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Oct 15 07:50:40 PDT 2012


On 15/10/12 15:21, Aleksey Shipilev wrote:
> Hi guys, and Maurizio specifically :)
>
> This is the test which fails to compile with current lambda/lambda:
>
> ------------- 8< -------------------------------------------------------
>
> public class NoiseSampleTest {
>
>      @Test
>      public void testL() {
>          Map<String, Map<String, Counter>> map =
>                  new ComputeTreeMap<>(
> 			(s) -> new ComputeTreeMap<>(
> 				(x) -> new Counter()
> 			)
> 		);
>
>          Assert.assertEquals(1, map.get("foo").get("bar").inc());
>          Assert.assertEquals(2, map.get("foo").get("bar").inc());
>      }
>
>      public static class ComputeTreeMap<K, V> extends TreeMap<K,V> {
>
>          public ComputeTreeMap(Mapper<K, V> map) {
>              // do nothing
>          }
>
>          @Override
>          public V get(Object key) {
>              throw new UnsupportedOperationException();
>          }
>      }
>
>      public static class Counter {
>          private int count = 0;
>          public int inc() {
>              return ++count;
>          }
>      }
> }
>
> -------------- 8< ----------------------------------------------------
>
> javac says:
> com/oracle/lambda/NoiseSampleTest.java:[16,16] error: cannot infer type
> arguments for ComputeTreeMap<>
> [ERROR]  cyclic inference - cannot infer target type for given
> lambda/method reference expression
>
> ...and if I write out the explicit type arguments within the diamond,
> the test compiles well. Is this a spec-ed behavior, or just a bug?
This is the spec'd behavior, yes. You are passing an implicit lambda to 
a method where the target type contains inference variables (because of 
diamond). Which means javac doesn't know what the lambda parameter types 
should be inferred to. Javac would try to delay type-checking of the 
lambda expression as much as possible (to see if other inference 
constraints can be derived from remaining argument expression) - but in 
this case there's no additional arguments. Either you specify the type 
of the diamond, or you specify the explicit lambda parameter type.

Maurizio
>
> -Aleksey.
>



More information about the lambda-dev mailing list