GROOVY-12289: Switch expressions with duplicate case labels compile under @TypeChecked but fail under @CompileStatic - #2826
Conversation
…nder @TypeChecked but fail under @CompileStatic
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #2826 +/- ##
==================================================
+ Coverage 70.2594% 70.2651% +0.0057%
- Complexity 36274 36283 +9
==================================================
Files 1569 1569
Lines 133723 133725 +2
Branches 24637 24638 +1
==================================================
+ Hits 93953 93962 +9
+ Misses 31257 31249 -8
- Partials 8513 8514 +1
🚀 New features to boost your workflow:
|
✅ All tests passed ✅🏷️ Commit: 7dedae9 Learn more about TestLens at testlens.app/docs. |
There was a problem hiding this comment.
Pull request overview
This PR addresses GROOVY-12289 by making duplicate constant case labels in switch expressions consistently rejected by the static type checker (so @TypeChecked and @CompileStatic fail the same way), while preserving dynamic “first match wins” behavior when type checking is explicitly bypassed (e.g., TypeCheckingMode.SKIP or a type-checking extension).
Changes:
- Add a static type checking pass that detects duplicate constant case labels (int-family, String, enum constants) in switch expressions and reports a consistent STC error.
- Update the static switch-expression bytecode writer to treat duplicates (when type checking is bypassed) as a reason to skip intrinsic switch optimizations and fall back to sequential dispatch.
- Add regression tests covering dynamic semantics, STC/SC error reporting, skip-mode fallback behavior, and an extension-based “escape hatch”.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/test/groovy/org/codehaus/groovy/classgen/Jep361SwitchExpressionTest.groovy | Adds coverage for duplicate-label behavior across dynamic, @TypeChecked, and @CompileStatic. |
| src/test/groovy/org/codehaus/groovy/classgen/asm/sc/SwitchExpressionStaticCompileTest.groovy | Updates expected error messaging and adds a skip-mode fallback test for sequential dispatch semantics. |
| src/test/groovy/groovy/transform/stc/TypeCheckingExtensionsTest.groovy | Adds a test demonstrating a type-checking extension can opt a DSL method out of the duplicate-label error. |
| src/test-resources/groovy/transform/stc/Groovy12289Extension.groovy | Introduces the STC extension used by the new escape-hatch test. |
| src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java | Implements duplicate constant label detection during STC for switch expressions. |
| src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesSwitchExpressionWriter.java | Removes late duplicate-label hard error and instead skips optimizer to allow sequential dispatch when checking is bypassed. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| Object key = (enumType != null && enumType.isEnum()) ? enumConstantName(label, enumType) : null; | ||
| if (key == null) key = intConstant(label); | ||
| if (key == null) key = stringConstant(label); | ||
| if (key != null && !seen.add(key)) { |
See: https://issues.apache.org/jira/browse/GROOVY-12289