[ 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)