Uploaded image for project: 'Clover'
  1. Clover
  2. CLOV-1371

Javac compilation fails for type-casted lambda expression instrumented by Clover

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Medium Medium
    • 3.2.0
    • 3.2.0
    • Instrumentation
    • None

      A following code:

      Object o = (Runnable) () -> System.out.println("lambda expression with class cast");
      ((Runnable)o).run();
      

      is being instrumented by Clover as follows:

      Object o = (Runnable) RECORDER.lambdaInc(111, () -> System.out.println("lambda expression with class cast"));
      ((Runnable)o).run();
      

      As a result javac is unable to compile such code - it cannot infer proper type from the context:

      error: incompatible types: cannot infer type-variable(s) I,T
      (argument mismatch; Object is not a functional interface)
      where I,T are type-variables:
      I extends Object declared in method <I,T>lambdaInc(int,T)
      T extends I declared in method <I,T>lambdaInc(int,T)

      Workaround:

      Change lambda from expression to block:

      Object o = (Runnable) () -> { System.out.println("lambda expression with class cast"); };
      

      or

      Remove class cast:

      Runnable o =  () -> System.out.println("lambda expression with class cast");
      

      Possible fix:

      Wrap class cast inside lambdaInc():

      Object o = RECORDER.lambdaInc(111, (Runnable)  () -> System.out.println("lambda expression with class cast"));
      

            [CLOV-1371] Javac compilation fails for type-casted lambda expression instrumented by Clover

            It affects method references too:

            private interface Printer<T> {
                    T print();
            }
            
            void foo() {
              Object oo = (Runnable) () -> System.out.println("lambdaWithCastExpression cast a lambda one-liner");
              ((Runnable)oo).run();
            }
            
            void hoo() {
              Object oo = (Printer<String>)String::new;
              String s = ((Printer<String>)oo).print();
            }
            

            Marek Parfianowicz added a comment - It affects method references too: private interface Printer<T> { T print(); } void foo() { Object oo = ( Runnable ) () -> System .out.println( "lambdaWithCastExpression cast a lambda one-liner" ); (( Runnable )oo).run(); } void hoo() { Object oo = (Printer< String >) String :: new ; String s = ((Printer< String >)oo).print(); }

            Few samples from JDK8:

            return (Comparator<T> & Serializable) (c1, c2) -> ...
            
            (PrivilegedAction<Boolean>) () -> Boolean.getBoolean(TRIPWIRE_PROPERTY)
            
            return (Comparator<Map.Entry<K, V>> & Serializable) (e1, e2) -> ...
            
            (PrivilegedAction<Boolean>) () -> Boolean.getBoolean(TRIPWIRE_PROPERTY)
            

            Marek Parfianowicz added a comment - Few samples from JDK8: return (Comparator<T> & Serializable) (c1, c2) -> ... (PrivilegedAction< Boolean >) () -> Boolean .getBoolean(TRIPWIRE_PROPERTY) return (Comparator<Map.Entry<K, V>> & Serializable) (e1, e2) -> ... (PrivilegedAction< Boolean >) () -> Boolean .getBoolean(TRIPWIRE_PROPERTY)

              mparfianowicz Marek Parfianowicz
              mparfianowicz Marek Parfianowicz
              Affected customers:
              0 This affects my team
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved: