[
https://issues.apache.org/jira/browse/GROOVY-10905?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17678000#comment-17678000
]
ASF GitHub Bot commented on GROOVY-10905:
-----------------------------------------
paulk-asert merged PR #1846:
URL: https://github.com/apache/groovy/pull/1846
> 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.x
>
>
> 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)