You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Sterling Greene (Jira)" <ji...@apache.org> on 2022/11/01 22:51:00 UTC

[jira] [Updated] (GROOVY-10807) STC seems to lose type information through method references

     [ https://issues.apache.org/jira/browse/GROOVY-10807?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Sterling Greene updated GROOVY-10807:
-------------------------------------
    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.

  was:
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.


> STC seems to lose type information through method references
> ------------------------------------------------------------
>
>                 Key: GROOVY-10807
>                 URL: https://issues.apache.org/jira/browse/GROOVY-10807
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static compilation
>    Affects Versions: 3.0.12, 3.0.13
>            Reporter: Sterling Greene
>            Priority: Major
>
> 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.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)