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

Support ADTs #10

Merged
merged 9 commits into from
Mar 18, 2018
Merged

Support ADTs #10

merged 9 commits into from
Mar 18, 2018

Conversation

harpocrates
Copy link
Owner

@harpocrates harpocrates commented Mar 14, 2018

Extend contexts support passing Haskell ADTs directly into Rust enums. The core insights are that

  • Storable lets us reorganize what exactly gets passed through the FFI. On the Rust side, we need to make that explicit by having an intermediate #[repr(C)] type and some conversions to and from that type.
  • These sorts of conversion shenanigans only work when we are passing the actual values through the FFI - functions and pointers won't work for this (another face of the same observation: the Storable instances for Ptr a and FunPtr a do not impose superclass Storable constraints)

When merged, this PR will go a long way to helping on #1.

  • Extend contexts to support intermediate Rust types.
  • Generate #[repr(C)] unions/structs corresponding to the derived Storable instances for ADTs
  • Generate enums corresponding to the ADTs
  • Generate Into/From trait impls for converting between the #[repr(C)] union/struct form and the enum form
  • Wrap all of this into a simple TH function
  • Update all of the documentation

Extend contexts to prepare for deriving via TH Rust structs/unions and enums
to match ADTs. All old examples still work.
It will need to be reused for deriving Rust types.
The Rust codegen that remains is the `impl`s.
Added support for generating the right pairs of `From<...> for ...`
impl's for the ADT case. There are still a handful of small TODOs
before this is testable though.
I've manually verified that the generated code compiles.
The one major hiccup: Haskell's FFI supports a very limited number of types.
Consequently, I'm shoving any other type into a pointer (alloca/with) and
passing the pointer instead. For complex return values, that means passing
in a pointer and assigning to that pointer.
Added a context for unboxed types too.
@harpocrates
Copy link
Owner Author

Couple points now that I've got an MVP:

  • every step of the codegen needs to be manually overridable
  • I need to generate an extra From impl for just the generic parameters (impl<T, T1: Into<T>> From<Option<T>> for Option<T1>)

@harpocrates
Copy link
Owner Author

Couple points now that I've got an MVP:

  • every step of the codegen needs to be manually overridable
  • I should support top-level reference types (by unsafely converting a pointer from a reference argument into a reference) - but only for types that require no conversion
  • I need to solve the issue around a missing (and impossible) From impl like impl<T, T1: Into<T>> From<MyStruct<T>> for MyStruct<T1>.
  • Better error messages (thread some Writer through?)

Replaced uses of 'Into' with a custom 'MarshalInto'. Obviously
this isn't great, but it does mean I can make the struct impl's I
want (without conflicting with some more general impl).
@harpocrates harpocrates merged commit 9fed344 into master Mar 18, 2018
@harpocrates harpocrates deleted the feature/adt-contexts branch March 18, 2018 22:54
@harpocrates harpocrates changed the title [WIP] Support ADTs Support ADTs Mar 18, 2018
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.

None yet

1 participant