-
Notifications
You must be signed in to change notification settings - Fork 233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enum/error types are ambiguous #2034
Comments
The builtin bindings all generate subtly different code for enums and errors. Whether a name is treated as an error or an enum is determined by whether it's actually used as an error. Kotlin, for example, uses a different base class in each scenario.
For the existing bindings, this would not be an error - it's just a param. For it to be considered an error, it would need to be used as a How often does it happen that you have an object you want treated as an error even though it never appears as an error? |
I understand this part. What I'm wondering is if there are plans to support using an enum both as "enum" and "error" in the same uniffi package. |
Well it kinda is - these types are represented as enums, but are used as errors. Even before #1590, errors were represented as enums plus a kind of flag to indicate whether it was used as an error or not - which is roughly the same situation as now, except that flag is inferred. Maybe I'm confused by the reference to #1590 - I guess I don't understand how that changed the fundamental properties here other than the possibility that an error isn't automatically flagged. |
To follow up further, errors can now also be interfaces, etc - so an object is capable of being both an "object" and "error" in the same package, in the same way enums are. In other words, the fact a type is an error is in addition to the type of the object. Many bindings need to use this flag to change the fundamental characteristics of the underlying type (ie, using a different base class, for example), but the objects are still generally able to be used as both. |
My confusion rises from your saying that errors are implemented as enums. In Kotlin, "flat" enums are implemented as |
Right - what I mean is that in the "component interface", most errors are represented as However, for all bindings, errors are implemented differently than enums - ie, all bindings have Part of the justification for #1590 was to allow errors to also be represented as
I'm still struggling with that distinction, because IIUC all bindings generate different things for enums vs errors - as you note above, Kotlin generates different types for errors vs enums, so it effectively treats them as different types. But the fact errors can now also be interfaces means the current implementation is likely to remain, but we are obviously open to making the lives easier for bindings where we can. Given your example of Kotlin above, maybe it might help if we talk in terms of Kotlin? What would it mean to 'support using an enum both as "enum" and "error" in the same uniffi package.' in Kotlin terms? |
Right now the above proc macros generate the following bindings.
When I'm talking about distinct types, I mean that
|
I guess the actual reason I'm bringing up this discussion, is because the removal of dedicated |
I do see how this isn't ideal - but apart from convenience I still don't see how this is fundamentally different than before #1590. For example, part of the inconvenience could be addressed by changing the CI - eg, The other inconvenience of checking
whereas now you need:
but it still seems like the fundamental capabilities are the same, just how the checks are made are different. When taking "interfaces as errors" into account, every In other words, I still fail to see what fundamental differences there are between now and #1590 - I see how the checks that need to be made are different, but the total number of final end-states seems the same to me. And assuming "interfaces as errors" is a good thing, something had to change here - you'd either need to say "here's an error object, is it an interface or enum?" or "here's an enum/interface object, is it an error?" I'm sorry for being slow and I hope it's clear I'm not disagreeing with you, I'm just struggling to understand the actual problem (other than the fact that errors can now be a number of types means dealing with errors is less convenient) |
Thanks for the discussion. If enums/errors in UDL (and proc macros) remains as "distinct" types, i.e. an enum is either an enum or an error, but not both, then there is no ambiguity. Closing this issue. |
#1590 puts code generators into an awkard position, NordSecurity/uniffi-bindgen-go#48.
error
type is removed, but its not clear what the final use cases for enum-error-object should be. Can errors be referenced as regular types, i.e. function arguments, return values, struct members? Iferror
type does not exist, then a reference toerror
may be ambiguous depending on bindings implementation, and the aforementioned use case is not possible.If we look at generated Go code,
error
andenum
types are not interchangeable.enum
is represented in a straightfoward enum manner, whereaserror
is implemented to support various Goerror
paradigms.UDL
Go enum
Go error
Given these 2 distinct generate types, a reference to
RequestError
becomes ambiguous. DoesRequestError
refer to "error" or "enum" implementation?UDL
Go
The text was updated successfully, but these errors were encountered: