There are a couple open bugs related to STC handling of closure shared variables. When a shared variable is assigned a value within the closure, the assigned type is not included in the inferred type outside the closure/lambda and this leads to some problems.
If this behavior is changed to save the LUB(A,B) as the inferred type of "x", as is suggested in 9516 and seems required by 9344, the second pass checks for method calls will be replaced by no matching method errors. That is "Cannot find matching method java.lang.Object#something(). Please check if the declared type is correct and if the method exists." will replace "A closure shared variable [x] has been assigned with various types and the method [charAt(int)] does not exist in the lowest upper bound...". Is this an acceptable change in STC behavior? @groovy.transform.CompileStatic void test() { def x = new A(); { -> x = new B() } // may also be called immediately x.something() // current STC infers typeof(x) == A } I think it was done this way because you could define the closure but not call it (like above). Or call it asynchronously: @groovy.transform.CompileStatic void test() { def x = new A(); Thread.start { -> x = new B() } x.something() // current STC infers typeof(x) == A } https://issues.apache.org/jira/browse/GROOVY-9516 https://issues.apache.org/jira/browse/GROOVY-9344 https://issues.apache.org/jira/browse/GROOVY-5874 This e-mail is for the sole use of the intended recipient and contains information that may be privileged and/or confidential. If you are not an intended recipient, please notify the sender by return e-mail and delete this e-mail and any attachments. Certain required legal entity disclosures can be accessed on our website: https://www.thomsonreuters.com/en/resources/disclosures.html