The general rule would be runtime divergence could...
# groovy
p
The general rule would be runtime divergence could be expected (good to document), compile-time is generally a bug. There are obvious ways to make it happen (never a good idea), e.g. create a type checking extension that "ignores some error about missing type info" and proceeds. Two places AI just found where Groovy itself breaks the rule (I'll investigate these separately):
1. Duplicate case labels in a switch expression (both int and String reproduce): @TypeChecked compiles fine (dynamically legal — first match wins, second is dead code), but @CompileStatic fails with "Duplicate case label"
2. @CompileStatic on a constructor inside a non-statically-compiled class that has fields, properties, or instance initializers → "Cannot statically compile constructor implicitly including non-static elements…"
AI Advice for framework code:
If this is happening in third-party framework code, the usual cause is an AST transform or type-checking extension rather than your code. Check whether the framework applies transforms that generate/rewrite code after type checking — the static compiler needs each call annotated with its resolved target (DIRECT_METHOD_CALL_TARGET / INFERRED_TYPE node metadata), and code injected post-STC won't have it, so it compiles fine dynamically and under @TypeChecked but fails under @CompileStatic. Errors like "Target method … hasn't been set", or VerifyErrors only under static compilation, are the tell. If the framework ships a type-checking extension, it should be using makeDynamic() (or resolving real method targets) for the calls it vouches for.