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

Refactor library to use type kinds for non-overlapping traits #2

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ObsidianMinor
Copy link
Collaborator

One of the things I don't really like about my current implementation is the approach to generic impls of non-overlapping types. The approach of "wrap the type in another type so we can write generic implementations" like recapn::field::Enum<Foo> or recapn::field::Struct<Bar> is just really annoying in practice since you have to import these types in order to access the trait implementation that is generic for those types. This forces me to make concessions like read_as_struct::<T>() which just calls read_as::<field::Struct<T>>() so you don't have to import the type.

This PR is an alternative approach that uses a trait with an associated type to make non-overlapping generic implementations. It works really great in all the ways you would expect! Now we don't need read_as_struct, you can just read_as::<T>() and it automatically selects the struct read implementation. You can have a list::Reader<Foo> and a list::Reader<Bar> and it will automatically be an enum, struct, or capability list based on the traits implemented by the types. Awesome!

But there's one small hinge that doesn't make this perfect: rust-analyzer doesn't understand it. RA will give you completions for structs that it can know the type for, but it can't give completions for accessors.
image

While it can figure out what you want from a read_as::<StructType>(), it doesn't know what the result of read_as::<List<StructType>>() is.
image

It gives errors saying you haven't implemented all match arms when you've definitely implemented all match arms. This is likely because it can't figure out what the types are supposed to be for some of said arms.
image

All in all, while it's great on the surface, since it doesn't work with the dev tools most people use I'm hesitant to go forward with it since it will make devex worse by getting rid of completions and type hints in many places where they currently exist today. Though I'm putting up the PR for comments and I'm hoping that one day RA can figure out what these types are. Then we can move forward with it since the experience will become better. Maybe someone with experience debugging RA will be able to use this too.

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.

1 participant