Skip to content

jextract/jni: Fix enums with unconvertible cases#755

Merged
ktoso merged 4 commits into
swiftlang:mainfrom
sidepelican:genericenum_typealias
May 19, 2026
Merged

jextract/jni: Fix enums with unconvertible cases#755
ktoso merged 4 commits into
swiftlang:mainfrom
sidepelican:genericenum_typealias

Conversation

@sidepelican
Copy link
Copy Markdown
Contributor

Currently, defining a generic enum like the one below leads to a Java compilation error:

public enum GenericEnumWithValue<T> {
  case some(T)
  case none
}
GenericEnumWithValue.java:86: error: the switch expression does not cover all possible input values
    return switch (this.getDiscriminator()) {
           ^

This occurs because some(T) contains a unsupported generic parameter and it is skipped.
The Java switch expression becomes non-exhaustive, leading to the build failure.

In cases where a getCase method cannot be fully generated due to unsupported generic parameters.
Instead of producing uncompilable code, the generator now provides a dummy implementation instead.

@sidepelican sidepelican requested a review from ktoso as a code owner May 15, 2026 07:22
@ktoso ktoso closed this May 18, 2026
@ktoso ktoso reopened this May 18, 2026
"""
// This is unavailable because it contains unsupported cases.
private Case getCase() {
return null;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably throw an exception instead or just a stray null like that

let allCasesCanBeTranslated = decl.cases.allSatisfy({
translatedEnumCase(for: $0) != nil
})
if !allCasesCanBeTranslated {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand -- wouldn't we want to just fail if we're in the not imported case in thew switch below?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either way works for me.

I implemented it this way because I thought it would be more user-friendly to make the function unavailable from the start, rather than causing a runtime error.
This is because users can still use alternatives like getAsNone instead of getCase to work around it.

I'm happy to change it to whichever you prefer.
Which would you prefer: throwing an exception for unsupported cases in the switch, or omitting the function entirely?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, if I read this correctly we'd make the entire getCase unavailable if any of the cases is not supported; but perhaps someone wants to use an enum with only a bunch of cases that were supported. So I think the dynamic may be ok... though we should emit warnings about the missed cases and maybe even some comments in source?

Copy link
Copy Markdown
Collaborator

@ktoso ktoso May 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So yeah, the throw variant: and we'd throw with some message that the case was not extracted because e.g. ... "type ... was not extracted"?

@ktoso ktoso merged commit 06556a5 into swiftlang:main May 19, 2026
73 checks passed
@sidepelican sidepelican deleted the genericenum_typealias branch May 19, 2026 00:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants