Scott Murphy Heiberg created GROOVY-12668:
---------------------------------------------

             Summary: SC calls the Closure method instead of the enclosing 
class method of the same name from a lambda
                 Key: GROOVY-12668
                 URL: https://issues.apache.org/jira/browse/GROOVY-12668
             Project: Groovy
          Issue Type: Bug
    Affects Versions: 5.0.8, 6.0.0, 7.0.0-alpha-1
            Reporter: Scott Murphy Heiberg


{code:groovy}
import groovy.transform.CompileStatic
import java.util.function.Supplier

@CompileStatic
class C {
    String getDelegate() { 'Cd' }
    String memoizeAtMost(int i) { 'C' + i }
    def m() {
        Supplier<Object> s = () -> getDelegate()
        Supplier<Object> t = () -> memoizeAtMost(2)
        [s.get(), t.get()]
    }
}
println new C().m()
{code}
*Actual* (5.0.8, 6.0.0, master): {{[C@6d1310f6, 
org.codehaus.groovy.runtime.memoize.Memoize$MemoizeFunction@3228d990]}}. The 
calls go to the lambda object's {{Closure.getDelegate()}} and 
{{Closure.memoizeAtMost(int)}}. With {{curry(1)}}, {{rcurry}} or {{ncurry}} 
declared in the class, compilation fails with "Reference to method is ambiguous 
... Closure#curry".

*Expected* (as in 4.0.33): {{[Cd, C2]}}. The enclosing class's methods are 
called, static ones included.

Since GROOVY-11386, the type checker looks up an implicit-this call in a 
closure or lambda on {{Closure}} before the owner and the delegate. A lambda in 
statically compiled code follows Java semantics, so the enclosing class should 
come first. A lambda in dynamic or @TypeChecked code is a closure at run time, 
where the closure's own methods do come first.

Verified: 5.0.8, 6.0.0 and master affected; 4.0.33 not affected.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to