@CompileStatic breaking vararg call resolution

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

@CompileStatic breaking vararg call resolution

Thibault Kruse
Hi,

I notice this, and I cannot decide whether it is a groovy bug or feature.
Using the 3 files below, running 'gradle run' gives me:
"Strings", but when I commentout @CompileStatic, I get "Classes".

Is that because for static compilation, the list of Arguments is
resolved as an Object[] Array, and Any(String... strings) is therefore
closer?

This bit me for Springs AnnotationConfigApplicationContext() constructor.

cheers,
  Thibault



build.gradle:
-----------------
apply plugin: 'groovy'

sourceCompatibility = 1.7
targetCompatibility = 1.7

repositories {jcenter()}
dependencies {
    compile('org.codehaus.groovy:groovy-all:2.2.2') { force = true }
}

task run(dependsOn: 'classes', type: JavaExec) {
    main = 'Starter'
    classpath = sourceSets.main.runtimeClasspath
}



src/main/groovy/Any.java
------------------------------------
public class Any {

    public Any(Class<?>... classes) {
        System.out.println("Classes");
    }

    public Any(String... strings) {
        System.out.println("Strings");
    }

}


src/main/groovy/Starter.groovy
------------------------------------------
import Any
import groovy.transform.CompileStatic

@CompileStatic
public class Starter {

    public static void main(String[] args) {
        new Any(List.class, Map.class)
    }

}

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: @CompileStatic breaking vararg call resolution

Dinko Srkoč
On 29 March 2014 00:31, Thibault Kruse <[hidden email]> wrote:
> Hi,
>
> I notice this, and I cannot decide whether it is a groovy bug or feature.

I would vote for a bug.

> Using the 3 files below, running 'gradle run' gives me:
> "Strings", but when I commentout @CompileStatic, I get "Classes".
>
> Is that because for static compilation, the list of Arguments is
> resolved as an Object[] Array, and Any(String... strings) is therefore
> closer?

My own only weak understanding is that the distance would be the same
i.e. the distance from `String[]` to `Object[]` is the same as from
`Class[]` to `Object[]` as both `String` and `Class` extend `Object`
and arrays are covariant.

I believe the example could be reduced to this:

    def foo(Class... cs) { "Classes" }
    def foo(String... ss) { "Strings" }

    @groovy.transform.CompileStatic
    def run()  { foo(List, Map) }

to which the compiler complains:

```
1 compilation error:

[Static type checking] - Cannot call
ConsoleScript14#foo(java.lang.String[]) with arguments
[java.lang.Class <java.util.List>, java.lang.Class <java.util.Map>]
 at line: 5, column: 14
```

Why would it want to call `foo(String[])`?

If the method was changed to accept, say, `Integer...`, the compiler
would still complain about not being able to call
`foo(java.lang.Integer[])`. If the array was replaced by any other
argument, e.g. `foo(String s)`, the compiler would finally choose
`foo(Class...)`.

Without static type checking everything works as expected.

Cheers,
Dinko

>
> This bit me for Springs AnnotationConfigApplicationContext() constructor.
>
> cheers,
>   Thibault
>
>
>
> build.gradle:
> -----------------
> apply plugin: 'groovy'
>
> sourceCompatibility = 1.7
> targetCompatibility = 1.7
>
> repositories {jcenter()}
> dependencies {
>     compile('org.codehaus.groovy:groovy-all:2.2.2') { force = true }
> }
>
> task run(dependsOn: 'classes', type: JavaExec) {
>     main = 'Starter'
>     classpath = sourceSets.main.runtimeClasspath
> }
>
>
>
> src/main/groovy/Any.java
> ------------------------------------
> public class Any {
>
>     public Any(Class<?>... classes) {
>         System.out.println("Classes");
>     }
>
>     public Any(String... strings) {
>         System.out.println("Strings");
>     }
>
> }
>
>
> src/main/groovy/Starter.groovy
> ------------------------------------------
> import Any
> import groovy.transform.CompileStatic
>
> @CompileStatic
> public class Starter {
>
>     public static void main(String[] args) {
>         new Any(List.class, Map.class)
>     }
>
> }
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: @CompileStatic breaking vararg call resolution

Thibault Kruse
Yes, I also notice that for non-Constructors it seems to behave differently.
Maybe it is ot distance, but auto-boxing or something similar?

On Sat, Mar 29, 2014 at 3:51 AM, Dinko Srkoč <[hidden email]> wrote:

> On 29 March 2014 00:31, Thibault Kruse <[hidden email]> wrote:
>> Hi,
>>
>> I notice this, and I cannot decide whether it is a groovy bug or feature.
>
> I would vote for a bug.
>
>> Using the 3 files below, running 'gradle run' gives me:
>> "Strings", but when I commentout @CompileStatic, I get "Classes".
>>
>> Is that because for static compilation, the list of Arguments is
>> resolved as an Object[] Array, and Any(String... strings) is therefore
>> closer?
>
> My own only weak understanding is that the distance would be the same
> i.e. the distance from `String[]` to `Object[]` is the same as from
> `Class[]` to `Object[]` as both `String` and `Class` extend `Object`
> and arrays are covariant.
>
> I believe the example could be reduced to this:
>
>     def foo(Class... cs) { "Classes" }
>     def foo(String... ss) { "Strings" }
>
>     @groovy.transform.CompileStatic
>     def run()  { foo(List, Map) }
>
> to which the compiler complains:
>
> ```
> 1 compilation error:
>
> [Static type checking] - Cannot call
> ConsoleScript14#foo(java.lang.String[]) with arguments
> [java.lang.Class <java.util.List>, java.lang.Class <java.util.Map>]
>  at line: 5, column: 14
> ```
>
> Why would it want to call `foo(String[])`?
>
> If the method was changed to accept, say, `Integer...`, the compiler
> would still complain about not being able to call
> `foo(java.lang.Integer[])`. If the array was replaced by any other
> argument, e.g. `foo(String s)`, the compiler would finally choose
> `foo(Class...)`.
>
> Without static type checking everything works as expected.
>
> Cheers,
> Dinko
>
>>
>> This bit me for Springs AnnotationConfigApplicationContext() constructor.
>>
>> cheers,
>>   Thibault
>>
>>
>>
>> build.gradle:
>> -----------------
>> apply plugin: 'groovy'
>>
>> sourceCompatibility = 1.7
>> targetCompatibility = 1.7
>>
>> repositories {jcenter()}
>> dependencies {
>>     compile('org.codehaus.groovy:groovy-all:2.2.2') { force = true }
>> }
>>
>> task run(dependsOn: 'classes', type: JavaExec) {
>>     main = 'Starter'
>>     classpath = sourceSets.main.runtimeClasspath
>> }
>>
>>
>>
>> src/main/groovy/Any.java
>> ------------------------------------
>> public class Any {
>>
>>     public Any(Class<?>... classes) {
>>         System.out.println("Classes");
>>     }
>>
>>     public Any(String... strings) {
>>         System.out.println("Strings");
>>     }
>>
>> }
>>
>>
>> src/main/groovy/Starter.groovy
>> ------------------------------------------
>> import Any
>> import groovy.transform.CompileStatic
>>
>> @CompileStatic
>> public class Starter {
>>
>>     public static void main(String[] args) {
>>         new Any(List.class, Map.class)
>>     }
>>
>> }
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>
>>     http://xircles.codehaus.org/manage_email
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: @CompileStatic breaking vararg call resolution

Andrey Bloschetsov
Hi all,

Indeed, this is unclear why the compiler tries to choose String[]
method. I think at least, there is should work the same logic as with
foo(null):

Groovy:[Static type checking] - Reference to method is ambiguous.
Cannot choose between [java.lang.Object Test#foo(java.lang.Class[]),
 java.lang.Object TestAny#foo(java.lang.Object[])]

I also vote for a bug.

2014-03-29 11:55 GMT+04:00 Thibault Kruse <[hidden email]>:

> Yes, I also notice that for non-Constructors it seems to behave differently.
> Maybe it is ot distance, but auto-boxing or something similar?
>
> On Sat, Mar 29, 2014 at 3:51 AM, Dinko Srkoč <[hidden email]> wrote:
>> On 29 March 2014 00:31, Thibault Kruse <[hidden email]> wrote:
>>> Hi,
>>>
>>> I notice this, and I cannot decide whether it is a groovy bug or feature.
>>
>> I would vote for a bug.
>>
>>> Using the 3 files below, running 'gradle run' gives me:
>>> "Strings", but when I commentout @CompileStatic, I get "Classes".
>>>
>>> Is that because for static compilation, the list of Arguments is
>>> resolved as an Object[] Array, and Any(String... strings) is therefore
>>> closer?
>>
>> My own only weak understanding is that the distance would be the same
>> i.e. the distance from `String[]` to `Object[]` is the same as from
>> `Class[]` to `Object[]` as both `String` and `Class` extend `Object`
>> and arrays are covariant.
>>
>> I believe the example could be reduced to this:
>>
>>     def foo(Class... cs) { "Classes" }
>>     def foo(String... ss) { "Strings" }
>>
>>     @groovy.transform.CompileStatic
>>     def run()  { foo(List, Map) }
>>
>> to which the compiler complains:
>>
>> ```
>> 1 compilation error:
>>
>> [Static type checking] - Cannot call
>> ConsoleScript14#foo(java.lang.String[]) with arguments
>> [java.lang.Class <java.util.List>, java.lang.Class <java.util.Map>]
>>  at line: 5, column: 14
>> ```
>>
>> Why would it want to call `foo(String[])`?
>>
>> If the method was changed to accept, say, `Integer...`, the compiler
>> would still complain about not being able to call
>> `foo(java.lang.Integer[])`. If the array was replaced by any other
>> argument, e.g. `foo(String s)`, the compiler would finally choose
>> `foo(Class...)`.
>>
>> Without static type checking everything works as expected.
>>
>> Cheers,
>> Dinko
>>
>>>
>>> This bit me for Springs AnnotationConfigApplicationContext() constructor.
>>>
>>> cheers,
>>>   Thibault
>>>
>>>
>>>
>>> build.gradle:
>>> -----------------
>>> apply plugin: 'groovy'
>>>
>>> sourceCompatibility = 1.7
>>> targetCompatibility = 1.7
>>>
>>> repositories {jcenter()}
>>> dependencies {
>>>     compile('org.codehaus.groovy:groovy-all:2.2.2') { force = true }
>>> }
>>>
>>> task run(dependsOn: 'classes', type: JavaExec) {
>>>     main = 'Starter'
>>>     classpath = sourceSets.main.runtimeClasspath
>>> }
>>>
>>>
>>>
>>> src/main/groovy/Any.java
>>> ------------------------------------
>>> public class Any {
>>>
>>>     public Any(Class<?>... classes) {
>>>         System.out.println("Classes");
>>>     }
>>>
>>>     public Any(String... strings) {
>>>         System.out.println("Strings");
>>>     }
>>>
>>> }
>>>
>>>
>>> src/main/groovy/Starter.groovy
>>> ------------------------------------------
>>> import Any
>>> import groovy.transform.CompileStatic
>>>
>>> @CompileStatic
>>> public class Starter {
>>>
>>>     public static void main(String[] args) {
>>>         new Any(List.class, Map.class)
>>>     }
>>>
>>> }
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe from this list, please visit:
>>>
>>>     http://xircles.codehaus.org/manage_email
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>
>>     http://xircles.codehaus.org/manage_email
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>



--
Andrey Bloschetsov

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: @CompileStatic breaking vararg call resolution

Cédric Champeau
Hi guys,

Sorry for the long delay, I'm just back from Greach today. But yes, it's
a bug, and it doesn't seem to occur on master. I didn't test with
2.2.3-SNAPSHOT though.

Cédric

Le 29/03/2014 10:04, Andrey Bloschetsov a écrit :

> Hi all,
>
> Indeed, this is unclear why the compiler tries to choose String[]
> method. I think at least, there is should work the same logic as with
> foo(null):
>
> Groovy:[Static type checking] - Reference to method is ambiguous.
> Cannot choose between [java.lang.Object Test#foo(java.lang.Class[]),
>   java.lang.Object TestAny#foo(java.lang.Object[])]
>
> I also vote for a bug.
>
> 2014-03-29 11:55 GMT+04:00 Thibault Kruse <[hidden email]>:
>> Yes, I also notice that for non-Constructors it seems to behave differently.
>> Maybe it is ot distance, but auto-boxing or something similar?
>>
>> On Sat, Mar 29, 2014 at 3:51 AM, Dinko Srkoč <[hidden email]> wrote:
>>> On 29 March 2014 00:31, Thibault Kruse <[hidden email]> wrote:
>>>> Hi,
>>>>
>>>> I notice this, and I cannot decide whether it is a groovy bug or feature.
>>> I would vote for a bug.
>>>
>>>> Using the 3 files below, running 'gradle run' gives me:
>>>> "Strings", but when I commentout @CompileStatic, I get "Classes".
>>>>
>>>> Is that because for static compilation, the list of Arguments is
>>>> resolved as an Object[] Array, and Any(String... strings) is therefore
>>>> closer?
>>> My own only weak understanding is that the distance would be the same
>>> i.e. the distance from `String[]` to `Object[]` is the same as from
>>> `Class[]` to `Object[]` as both `String` and `Class` extend `Object`
>>> and arrays are covariant.
>>>
>>> I believe the example could be reduced to this:
>>>
>>>      def foo(Class... cs) { "Classes" }
>>>      def foo(String... ss) { "Strings" }
>>>
>>>      @groovy.transform.CompileStatic
>>>      def run()  { foo(List, Map) }
>>>
>>> to which the compiler complains:
>>>
>>> ```
>>> 1 compilation error:
>>>
>>> [Static type checking] - Cannot call
>>> ConsoleScript14#foo(java.lang.String[]) with arguments
>>> [java.lang.Class <java.util.List>, java.lang.Class <java.util.Map>]
>>>   at line: 5, column: 14
>>> ```
>>>
>>> Why would it want to call `foo(String[])`?
>>>
>>> If the method was changed to accept, say, `Integer...`, the compiler
>>> would still complain about not being able to call
>>> `foo(java.lang.Integer[])`. If the array was replaced by any other
>>> argument, e.g. `foo(String s)`, the compiler would finally choose
>>> `foo(Class...)`.
>>>
>>> Without static type checking everything works as expected.
>>>
>>> Cheers,
>>> Dinko
>>>
>>>> This bit me for Springs AnnotationConfigApplicationContext() constructor.
>>>>
>>>> cheers,
>>>>    Thibault
>>>>
>>>>
>>>>
>>>> build.gradle:
>>>> -----------------
>>>> apply plugin: 'groovy'
>>>>
>>>> sourceCompatibility = 1.7
>>>> targetCompatibility = 1.7
>>>>
>>>> repositories {jcenter()}
>>>> dependencies {
>>>>      compile('org.codehaus.groovy:groovy-all:2.2.2') { force = true }
>>>> }
>>>>
>>>> task run(dependsOn: 'classes', type: JavaExec) {
>>>>      main = 'Starter'
>>>>      classpath = sourceSets.main.runtimeClasspath
>>>> }
>>>>
>>>>
>>>>
>>>> src/main/groovy/Any.java
>>>> ------------------------------------
>>>> public class Any {
>>>>
>>>>      public Any(Class<?>... classes) {
>>>>          System.out.println("Classes");
>>>>      }
>>>>
>>>>      public Any(String... strings) {
>>>>          System.out.println("Strings");
>>>>      }
>>>>
>>>> }
>>>>
>>>>
>>>> src/main/groovy/Starter.groovy
>>>> ------------------------------------------
>>>> import Any
>>>> import groovy.transform.CompileStatic
>>>>
>>>> @CompileStatic
>>>> public class Starter {
>>>>
>>>>      public static void main(String[] args) {
>>>>          new Any(List.class, Map.class)
>>>>      }
>>>>
>>>> }
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe from this list, please visit:
>>>>
>>>>      http://xircles.codehaus.org/manage_email
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe from this list, please visit:
>>>
>>>      http://xircles.codehaus.org/manage_email
>>>
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>
>>      http://xircles.codehaus.org/manage_email
>>
>>
>
>


--
Cédric Champeau
SpringSource - Pivotal
http://twitter.com/CedricChampeau
http://melix.github.io/blog
http://spring.io/ http://www.gopivotal.com/


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: @CompileStatic breaking vararg call resolution

Thibault Kruse
Opened at https://jira.codehaus.org/browse/GROOVY-6646, did not test
on master neither, though I think I used a fairly recent build.

On Mon, Mar 31, 2014 at 4:31 PM, Cédric Champeau
<[hidden email]> wrote:

> Hi guys,
>
> Sorry for the long delay, I'm just back from Greach today. But yes, it's a
> bug, and it doesn't seem to occur on master. I didn't test with
> 2.2.3-SNAPSHOT though.
>
> Cédric
>
> Le 29/03/2014 10:04, Andrey Bloschetsov a écrit :
>
>> Hi all,
>>
>> Indeed, this is unclear why the compiler tries to choose String[]
>> method. I think at least, there is should work the same logic as with
>> foo(null):
>>
>> Groovy:[Static type checking] - Reference to method is ambiguous.
>> Cannot choose between [java.lang.Object Test#foo(java.lang.Class[]),
>>   java.lang.Object TestAny#foo(java.lang.Object[])]
>>
>> I also vote for a bug.
>>
>> 2014-03-29 11:55 GMT+04:00 Thibault Kruse <[hidden email]>:
>>>
>>> Yes, I also notice that for non-Constructors it seems to behave
>>> differently.
>>> Maybe it is ot distance, but auto-boxing or something similar?
>>>
>>> On Sat, Mar 29, 2014 at 3:51 AM, Dinko Srkoč <[hidden email]>
>>> wrote:
>>>>
>>>> On 29 March 2014 00:31, Thibault Kruse <[hidden email]> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> I notice this, and I cannot decide whether it is a groovy bug or
>>>>> feature.
>>>>
>>>> I would vote for a bug.
>>>>
>>>>> Using the 3 files below, running 'gradle run' gives me:
>>>>> "Strings", but when I commentout @CompileStatic, I get "Classes".
>>>>>
>>>>> Is that because for static compilation, the list of Arguments is
>>>>> resolved as an Object[] Array, and Any(String... strings) is therefore
>>>>> closer?
>>>>
>>>> My own only weak understanding is that the distance would be the same
>>>> i.e. the distance from `String[]` to `Object[]` is the same as from
>>>> `Class[]` to `Object[]` as both `String` and `Class` extend `Object`
>>>> and arrays are covariant.
>>>>
>>>> I believe the example could be reduced to this:
>>>>
>>>>      def foo(Class... cs) { "Classes" }
>>>>      def foo(String... ss) { "Strings" }
>>>>
>>>>      @groovy.transform.CompileStatic
>>>>      def run()  { foo(List, Map) }
>>>>
>>>> to which the compiler complains:
>>>>
>>>> ```
>>>> 1 compilation error:
>>>>
>>>> [Static type checking] - Cannot call
>>>> ConsoleScript14#foo(java.lang.String[]) with arguments
>>>> [java.lang.Class <java.util.List>, java.lang.Class <java.util.Map>]
>>>>   at line: 5, column: 14
>>>> ```
>>>>
>>>> Why would it want to call `foo(String[])`?
>>>>
>>>> If the method was changed to accept, say, `Integer...`, the compiler
>>>> would still complain about not being able to call
>>>> `foo(java.lang.Integer[])`. If the array was replaced by any other
>>>> argument, e.g. `foo(String s)`, the compiler would finally choose
>>>> `foo(Class...)`.
>>>>
>>>> Without static type checking everything works as expected.
>>>>
>>>> Cheers,
>>>> Dinko
>>>>
>>>>> This bit me for Springs AnnotationConfigApplicationContext()
>>>>> constructor.
>>>>>
>>>>> cheers,
>>>>>    Thibault
>>>>>
>>>>>
>>>>>
>>>>> build.gradle:
>>>>> -----------------
>>>>> apply plugin: 'groovy'
>>>>>
>>>>> sourceCompatibility = 1.7
>>>>> targetCompatibility = 1.7
>>>>>
>>>>> repositories {jcenter()}
>>>>> dependencies {
>>>>>      compile('org.codehaus.groovy:groovy-all:2.2.2') { force = true }
>>>>> }
>>>>>
>>>>> task run(dependsOn: 'classes', type: JavaExec) {
>>>>>      main = 'Starter'
>>>>>      classpath = sourceSets.main.runtimeClasspath
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> src/main/groovy/Any.java
>>>>> ------------------------------------
>>>>> public class Any {
>>>>>
>>>>>      public Any(Class<?>... classes) {
>>>>>          System.out.println("Classes");
>>>>>      }
>>>>>
>>>>>      public Any(String... strings) {
>>>>>          System.out.println("Strings");
>>>>>      }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>> src/main/groovy/Starter.groovy
>>>>> ------------------------------------------
>>>>> import Any
>>>>> import groovy.transform.CompileStatic
>>>>>
>>>>> @CompileStatic
>>>>> public class Starter {
>>>>>
>>>>>      public static void main(String[] args) {
>>>>>          new Any(List.class, Map.class)
>>>>>      }
>>>>>
>>>>> }
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe from this list, please visit:
>>>>>
>>>>>      http://xircles.codehaus.org/manage_email
>>>>>
>>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe from this list, please visit:
>>>>
>>>>      http://xircles.codehaus.org/manage_email
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe from this list, please visit:
>>>
>>>      http://xircles.codehaus.org/manage_email
>>>
>>>
>>
>>
>
>
> --
> Cédric Champeau
> SpringSource - Pivotal
> http://twitter.com/CedricChampeau
> http://melix.github.io/blog
> http://spring.io/ http://www.gopivotal.com/
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email