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

Eric Milles resolved GROOVY-10905.
----------------------------------
    Fix Version/s: 5.0.0-alpha-1
                       (was: 5.x)
       Resolution: Fixed

https://github.com/apache/groovy/commit/e29b9288ee10d6ebe0443722294021f64371fbad

> Improve matching implicit arg closures to SAM types
> ---------------------------------------------------
>
>                 Key: GROOVY-10905
>                 URL: https://issues.apache.org/jira/browse/GROOVY-10905
>             Project: Groovy
>          Issue Type: Improvement
>            Reporter: Paul King
>            Assignee: Paul King
>            Priority: Major
>             Fix For: 5.0.0-alpha-1
>
>
> When matching Closures to SAM types, we have special treatment for Closures 
> without a formal parameter section. Such Closures may have 0 or 1 arguments, 
> e.g.:
> {code}
> foo { println 42 } // zero-arg case
> bar { println 'arg:' + it } // one-arg case
> {code}
> Our current matching says that because of this ambiguity, we know nothing 
> about the number of parameters, but this assumption is throwing away 
> information: the fact that we are expecting 0 or 1 args. I'd like to propose 
> for Groovy 5 that we match 0 or 1-arg SAMs more closely that say a 2-arg SAM 
> for such a Closure.
> The impact of this is that there will be less ambiguity errors (or 
> conversely, less places where we need to cast to get the correct method). It 
> obviously doesn't help if there are both 0 and 1-arg options available, where 
> casting would still be required.
> Example where 1 and 2-arg variants exist:
> {code}
> def method1(IntUnaryOperator unary) { '1a' }
> def method1(IntBinaryOperator binary) { '1b' }
> // unchanged behavior
> assert method1{ x -> } == '1a'    // explicit 1 arg
> assert method1{ x, y -> } == '1b'    // explicit 2 args
> assert method1({ } as IntUnaryOperator) == '1a'    // explicit cast for 
> implicit arg
> assert method1({ } as IntBinaryOperator) == '1b'    // explicit cast for 
> implicit arg
> // "method1{ -> }" would remain ambiguous
> // proposed change: implicit arg will match Unary over Binary since Unary is 
> the only match for 0 or 1 args
> assert method1{ } == '1a' // currently fails with Ambiguous method overloading
> {code}
> Example where 0 and 2-arg variants exist:
> {code}
> def method2(IntSupplier supplier) { '2a' }
> def method2(IntBinaryOperator binary) { '2b' }
> // unchanged behavior
> assert method2{ -> } == '2a'
> assert method2{ x, y -> } == '2b'
> assert method2({ } as IntSupplier) == '2a'
> assert method2({ } as IntBinaryOperator) == '2b'
> // "method2{ a -> }" would remain Ambiguous
> // proposed change: implicit arg will match Supplier over Binary since Unary 
> is the only match for 0 or 1 args
> assert method2{} == '2a' // currently fails with Ambiguous method overloading
> {code}
> Example where 0 and 1-arg variants exist:
> {code}
> def method3(IntSupplier supplier) { '3a' }
> def method3(IntUnaryOperator unary) { '3b' }
> assert method3{ -> } == '3a'
> assert method3{ x -> } == '3b'
> assert method3({ } as IntSupplier) == '3a'
> assert method3({ } as IntUnaryOperator) == '3b'
> // "method3{ }" will remain Ambiguous since "0 or 1" matches both; error 
> message is unchanged
> {code}
> Example where 0, 1 and 2-arg variants exist:
> {code}
> def method4(IntSupplier supplier) { '4a' }
> def method4(IntUnaryOperator unary) { '4b' }
> def method4(IntBinaryOperator binary) { '4c'  }
> assert method4{ -> } == '4a'
> assert method4{ x -> } == '4b'
> assert method4{ x, y -> } == '4c'
> assert method4({ } as IntSupplier) == '4a'
> assert method4({ } as IntUnaryOperator) == '4b'
> assert method4({ } as IntBinaryOperator) == '4c'
> // "method4{ }" will remain Ambiguous but error message will change from:
> //    Ambiguous method overloading [...] due to overlapping prototypes 
> between:
> //    [interface java.util.function.IntBinaryOperator]
> //    [interface java.util.function.IntSupplier]
> //    [interface java.util.function.IntUnaryOperator]
> // to:
> //    Ambiguous method overloading [...] due to overlapping prototypes 
> between:
> //    [interface java.util.function.IntSupplier]
> //    [interface java.util.function.IntUnaryOperator]
> // Since 0 or 1 variants will match closer than higher parameter numbers
> {code}



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

Reply via email to