Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-10807

STC seems to lose type information through method references

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.0.12, 3.0.13, 4.0.6
    • 3.0.14, 4.0.7
    • Static compilation
    • None

    Description

      This compiles in Groovy 3.0.11, but it does not compile in Groovy 3.0.12 or 3.0.13.

      
      import groovy.transform.CompileStatic
      
      @CompileStatic
      abstract class NoticeRenderer {
          private static final Comparator<String> COMPARATOR = Comparator<String>.comparing(NoticeRenderer::getComponentDisplayName)
         
          public static String getComponentDisplayName(String component) {
              return component;
          }
      } 
      

      The error is

      Failed to find the expected method[getComponentDisplayName(java.lang.Object)] in the type[NoticeRenderer] at line: 5, column: 79

      I think something is going sideways when inferring the types to comparing.

      Removing the type bound on the Comparator doesn't change the error.

      private static final Comparator<String> COMPARATOR = Comparator.comparing(NoticeRenderer::getComponentDisplayName)

      The type bound could be on the method itself. This produces the same error.

      private static final Comparator<String> COMPARATOR = Comparator.<String>comparing(NoticeRenderer::getComponentDisplayName)

      But comparing actually has two type parameters, so it's a little weird that the above doesn't complain. Specifying both type parameters still produces the same error.

      private static final Comparator<String> COMPARATOR = Comparator.<String, String>comparing(NoticeRenderer::getComponentDisplayName)

      If I mistakenly put the type bounds on Comparator, I don't expect this to work, but it produces BUG! output:
      private static final Comparator<String> COMPARATOR = Comparator<String, String>.comparing(NoticeRenderer::getComponentDisplayName)

      BUG! exception in phase 'instruction selection' in source unit 'ConsoleScript34' Expected earlier checking to detect generics parameter arity mismatch

      Expected: java.util.Comparator<T>

      Supplied: java.util.Comparator<java.lang.String,java.lang.String>

      In Java, you don't need the type information at all:

      private static final Comparator<String> COMPARATOR = Comparator.comparing(NoticeRenderer::getComponentDisplayName);

      If you wanted to be verbose in Java, you could specify the bounds:

      private static final Comparator<String> COMPARATOR = Comparator.<String, String>comparing(NoticeRenderer::getComponentDisplayName);

      As a workaround...
      If I avoid the use of the method reference, I can make something pass the static compiler:

      private static final Comparator<String> COMPARATOR = Comparator.<String>comparing( { String it -> getComponentDisplayName(it) })

      I need both the type bound on comparing and the type of the parameter.

      Attachments

        Activity

          People

            emilles Eric Milles
            big-guy Sterling Greene
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: