[ 
https://issues.apache.org/jira/browse/GROOVY-12574?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18135228#comment-18135228
 ] 

ASF GitHub Bot commented on GROOVY-12574:
-----------------------------------------

daniellansun commented on PR #3106:
URL: https://github.com/apache/groovy/pull/3106#issuecomment-6525889933

   Friendly ping: this PR is approved and CI is green. If there are no 
objections within 72 hours, this PR will be merged. Thanks!




> An outer class method called from an inner class runs on the wrong enclosing 
> instance
> -------------------------------------------------------------------------------------
>
>                 Key: GROOVY-12574
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12574
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler, Static compilation
>    Affects Versions: 4.0.33, 5.0.8, 6.0.0
>            Reporter: Scott Murphy Heiberg
>            Priority: Major
>
> An implicit-this call from an inner class to a method of an enclosing class 
> can run on the wrong instance.
> A closure in a field initializer of an inner class of a {{@CompileStatic}} 
> class fails in each {{@CompileDynamic}} constructor:
> {code:groovy}
> import groovy.transform.*
> @CompileStatic
> class Outer {
>     String pub() { 'pub' }
>     class Inner {
>         String v = { -> pub() }()
>         @CompileDynamic Inner() {}
>     }
>     String test() { new Inner().v }
> }
> new Outer().test() // GroovyCastException: Cannot cast object 
> 'Outer$Inner@...' with class 'Outer$Inner' to class 'Outer'
> {code}
> The static compiler gives the call a method target, and the dynamic 
> invocation writer, which writes the initializer into the {{@CompileDynamic}} 
> constructor, keeps the closure's this object as the receiver. Lambdas, nested 
> closures, private methods, interface default methods and trait methods fail 
> the same way, as does a {{@CompileStatic}} inner class of a dynamic class.
> A method that an intermediate enclosing class inherits is called on the wrong 
> instance:
> {code:groovy}
> import groovy.transform.*
> class Base { String base() { 'base' } }
> @CompileStatic
> class Outer {
>     class Mid extends Base {
>         class Inner { String m() { base() } }
>     }
>     String test() { def mid = new Mid(); new Mid.Inner(mid).m() }
> }
> new Outer().test() // VerifyError: Bad type on operand stack ... 
> Outer$Mid$Inner.m()
> {code}
> Both writers load {{DeclaringClass.this}}, which walks the enclosing 
> instances until it reaches the declaring class itself. When {{Outer}} extends 
> {{Base}} too, {{base()}} runs on the {{Outer}} instance; dynamic Groovy and 
> Java use the {{Mid}} instance. Property reads through an inherited getter 
> behave the same.
> Expected: the innermost enclosing instance whose class extends or implements 
> the declaring class, as the static writer already uses inside closures.
> PR: https://github.com/apache/groovy/pull/3106



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

Reply via email to