Instead of walking individual rust files and reading the AST from
those, we instead call
`RUSTC_BOOTSTRAP=1 cargo rustc --profile=check -- -Zunstable-options --pretty=expanded`
and let it create one giant lib.rs which we can parse as a whole.
This allows us to parse a post-macro crate, working with structs
and functions created inside macros just fine. It does require
handling a few things that we didn't previously, most notably Clone
via `impl ::core::clone::Clone` blocks instead of just looking for
`#![derive(Clone)]`.
This ends up resolving a few types slightly differently, resulting
in different bindings, but only in ways which don't impact the
runtime.
In general, it maps:
* Traits to a struct with a void* and a list of function pointers,
emulating what the compiler will do for a dyn trait anyway,
* Structs as a struct with a single opaque pointer to the
underlying type and a flag to indicate ownership. While this is
a bit less effecient than just a direct pointer, it neatly lets
us expose in the public interface the concept of ownership by
setting a flag in the generated struct.
* Unit enums as enums with each type copied over and conversion
functions,
* Non-unit enums have each field converted back and forth with a
type flag and a union across all the C-mapped fields.