jamesfredley commented on PR #15557:
URL: https://github.com/apache/grails-core/pull/15557#issuecomment-4819691235

   ### Deep-dive: the `withDelegate` trait-static problem is GROOVY-12106, and 
it is still broken on `5.0.7-SNAPSHOT`
   
   I dug into why the GraphQL sub-traits cannot call the inherited 
`ExecutesClosures.withDelegate` static, since it is the one thing keeping the 
inline-duplication workaround in this PR.
   
   **Standalone reproducer:** 
https://github.com/jamesfredley/groovy-12106-repro (pure Groovy + Gradle, 
`./gradlew compileGroovy` fails on `5.0.7-SNAPSHOT`).
   
   #### Root cause
   Under `@CompileStatic`, when a child trait `extends` a parent trait and 
calls an inherited `static` helper, STC **misroutes** the call to the *child* 
trait's helper with a synthetic `$self`:
   
   ```
   Cannot find matching method 
Arguable$Trait$Helper#withDelegate(java.lang.Class, groovy.lang.Closure, 
SimpleArgument)
   ```
   
   The decisive trigger (found by bisection): **an argument whose static type 
is a proper subtype of the declared parameter type.** With 
`withDelegate(Closure, Object)`, calling it with a `CustomArgument`/`Field` 
(subtypes of `Object`) fails; calling it with an exact `Object` resolves fine. 
`@DelegatesTo`, a stateful trait field, and the presence of an implementer were 
all ruled out as necessary - only the subtype argument is required to reproduce 
the minimal case.
   
   This is exactly why 
**[GROOVY-12106](https://issues.apache.org/jira/browse/GROOVY-12106)** (which I 
filed) was closed **Resolved / Cannot Reproduce**: a naive minimal repro passes 
exact-typed arguments and compiles. The subtype case still fails on the current 
`GROOVY_5_0_X` tip - the repo above demonstrates it and I think the issue 
should be reopened with it.
   
   #### What does NOT fix it
   - `@groovy.transform.Virtual` (the replacement for the removed `@Anchored`): 
only restores per-implementer override dispatch for same-trait / 
implementing-class calls; it does not make a child trait resolve an inherited 
parent-trait static. Adding it does not change the failure.
   - Casting the argument to the exact parameter type (`withDelegate(closure, 
(Object) argument)`) fixes the *minimal* case, but in the full 
`grails-data-graphql-core` module it is **still not sufficient** (the real 
traits then fail with `Arguable#withDelegate(Closure, Object)` not found). So a 
cast is not a usable workaround for this PR.
   
   #### Conclusion for this PR
   The inline-duplication workaround already on this branch stays as the only 
reliable option until the Groovy STC fix lands. Once GROOVY-12106 is genuinely 
fixed in a `5.0.7-SNAPSHOT` build, the inlined blocks in `Arguable` / 
`ComplexTyped` can be deleted and replaced with a plain `withDelegate(closure, 
argument)` call. I left `// GROOVY-12106` markers on the inlined blocks so they 
are easy to find and remove later.
   
   #### Also fixed: the related `Validateable.defaultNullable()` CI failure
   The same finalized Groovy 5 trait-static model broke the *other* direction. 
After the `5.0.7-SNAPSHOT` switch, `ValidateableTraitSpec` had 2 failures 
(constraints nullable-by-default when overridden; overridden-`defaultNullable` 
properties not accessed during validation). Root cause: `Validateable`'s trait 
body calls `this.defaultNullable()`, and under the new **declarer-bound** 
default a plain trait static returns the trait's own `false` instead of an 
implementing class's override. Fix: annotate `Validateable.defaultNullable()` 
with `@groovy.transform.Virtual` (the matrix-documented "Grails 
`Validateable.defaultNullable`" use case) so the override is seen by trait-body 
calls. `:grails-validation:test` + `:grails-validation:codeStyle` now pass. 
External callers are unaffected (reflective static invocation / compile-time 
boolean).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to