-
Notifications
You must be signed in to change notification settings - Fork 0
Arbitrary inner type in named impl key #4
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks plausible... just two questions.
/// that can be used as a **part** of monomorphized/instantiated thunk names | ||
/// (e.g. `cxxbridge1$box$org$rust$Struct$alloc`). | ||
/// | ||
/// Not all type names can be mangled at this point - `None` will be returned |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it's not yet implemented, or some cases are supposed to be handled elsewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I can expand this comment to explain better.
syntax/symbol.rs
Outdated
// [an injection](https://en.wikipedia.org/wiki/Injective_function). | ||
for c in self.0.chars() { | ||
match c { | ||
'_' => f.write_str("__")?, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this end up in symbol names used elsewhere? Or is it purely internal?
(I'm wondering if we need to worry since __
is traditionally reserved for the implementation in C++)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! IIRC this would end up being used as part of identifiers used in the generated Rust code. So, yes - using _u
as a substitution is probably safer.
This commit refactors `write_...` functions to enable formatting a C++ representation of a `Type` into any generic `impl std::fmt::Write` instead of only supporting formatting into an `OutFile`. This is then used to provide `fn stringify_type`. The new function is not used in this commit, but will become quite handy in a follow-up commit when `inner` type of generics/templates may not necessarily be a simple `std::fmt`-friendly `Type::Ident`. Without the refactored `write_...` APIs, the follow-up would have to split *single* `writeln!` invocations (such as the ones in `fn write_shared_ptr` or `fn write_cxx_vector`) into *multiple* ones - e.g. into: `write!` + `write_type` + `write!` + `write_type` + `writeln!`. The new function is a little bit redundant wrt the already existing `trait ToTypename`, but we can't replace that trait just yet: * The trait has slightly different semantics (formatting not the whole type represented by `self`, but only formatting the inner `T`). * The trait works with `Ident` rather than `Type` (this will change in the follow-up commit mentioned above).
Before this commit `NamedImplKey` could only represent the inner type as `rust: &'a Ident`. For example, it could represent `Vec<Foo>` but could not represent `Vec<Box<Foo>>` where the inner type (`Box<Foo>` in our example) is not a simple identifier. After this commit `NamedImplKey` is refactored to support an arbitrary inner type. Note that (to simplify and to minimize risks associated with this commit) this new ability is not actually used at this point - it is planned to be used in follow-up commits to incrementally relax generic type argument restrictions in `syntax/check.rs`. This commit is quite big, but it seems difficult to extract some changes to smaller, separate commits, because all of the changes stem from the refactoring of the `NamedImplKey`. At a high-level this commit contains the following changes: 1. `syntax/instantiate.rs`: Changing `pub rust: &'a Ident` field of `NamedImplKey` to `pub inner: &'a Type`. This is the main/root change in this commit. 2. `gen/src/write.rs`: supporting arbitrary inner types when writing C++ thunks exposing instantiations/monomorphizations of templates/generics supported by `cxx`. * This depends on `fn stringify_type` introduced in `gen/src/write.rs` in an earlier commit. * Handling arbitrary inner types *in general* means that we can delete `enum UniquePtr` which provided handling of two *specific* inner types. 3. `macro/src/expand.rs`: supporting arbitrary inner types when writing Rust thunks exposing instantiations/monomorphizations of templates/generics supported by `cxx`. * Using `#inner` instead of `#ident` may now (optionally) cover generic lifetime arguments. This is why this commit also changes `macro/src/generics.rs`. And this is why we can no longer need the `ty_generics` field from `struct Impl`. * One minor functional change here is changing the error messages so that references to type names are generated purely in the generated bindings, without depending on `fn display_namespaced`. 4. `syntax/mangle.rs`: supporting mangling of individual types. This helps to: * Support the (long-term, not-yet-realized) high-level goal of actually allowing and using arbitrary inner types * Deduplicate mangling code details that were somewhat duplicated in `macro/src/expand.rs` and `gen/src/write.rs`. 5. `syntax/types.rs`: Supporting arbitrary inner types in * `fn is_maybe_trivial` * `fn is_local` (this function supports an earlier refactoring that changed how `cxx` decides whether to provide an *implicit* impl of a given generic/template instantiation/monomorphization)
1c784bf
to
795da6d
Compare
Thanks for the feedback. Let me close this PR - I'll replace it with an upstream PR. |
@zetafunction, can you PTAL before I open a PR against the upstream repo?