Skip to content
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

What to do with duplicate types in variants? #9

Open
Expurple opened this issue Apr 7, 2024 · 1 comment
Open

What to do with duplicate types in variants? #9

Expurple opened this issue Apr 7, 2024 · 1 comment

Comments

@Expurple
Copy link
Contributor

Expurple commented Apr 7, 2024

Currently, instantiations of OneOf with duplicated variants like OneOf<(bool, bool)> typecheck:

fn this_code_compiles() -> OneOf<(bool, bool)> {
    unimplemented!()
}

but their constructors don't*, so there's no way to construct and actually use instances of these types.

The user experience can be refined and guided in one of two ways:

  • Stay isomorphic to enums and allow constructing instances of these types in unambiguous ways. Maybe, using something like OneOf::from_enum?
  • Explicitly limit ourselves to type sets, document this and adjust the implementation so that the example above doesn't compile.

Having the first option may be useful for some people, while others may find the code confusing. I can imagine easier interoperability with regular enums as one of the use cases.

The second option is how anonymous unions usually work in other languages (at least in Python).

I expect this topic to be discussed here for a while before landing on a decision.


* OneOf::<(bool, bool)>::new(true) rightfully causes the error below. I wonder if it's already possible to follow the compiler suggestion and fix the error by adding some obscure annotation in place of ... in OneOf::<(bool, bool)>::new::<bool, ...>(true).

error[E0283]: type annotations needed
   --> tests/usability.rs:13:5
    |
13  |     OneOf::<(bool, bool)>::new(true)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Index` declared on the associated function `new`
    |
    = note: multiple `impl`s satisfying `Cons<bool, Cons<bool, terrors::End>>: terrors::type_set::Contains<bool, _>` found in the `terrors` crate:
            - impl<T, Index, Head, Tail> terrors::type_set::Contains<T, Cons<Index, ()>> for Cons<Head, Tail>
              where Tail: terrors::type_set::Contains<T, Index>;
            - impl<T, Tail> terrors::type_set::Contains<T, terrors::End> for Cons<T, Tail>;
note: required by a bound in `OneOf::<E>::new`
   --> /home/dima/code/oss/terrors/src/one_of.rs:109:22
    |
106 |     pub fn new<T, Index>(t: T) -> OneOf<E>
    |            --- required by a bound in this associated function
...
109 |         E::Variants: Contains<T, Index>,
    |                      ^^^^^^^^^^^^^^^^^^ required by this bound in `OneOf::<E>::new`
help: consider specifying the generic arguments
    |
13  |     OneOf::<(bool, bool)>::new::<bool, Index>(true)
    |                               +++++++++++++++

Attempting to broaden OneOf::<(bool,)> into OneOf::<(bool, bool)> causes a similar error.

@dan-da
Copy link

dan-da commented Nov 30, 2024

I'm just discovering this crate and haven't tried it out yet so take with a grain of salt...

But I like the sound of OneOf::from_enum and better enum interop. Since I work with existing crates that have a lot of enum error types, typically created with thiserror.

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

No branches or pull requests

2 participants