Skip to content

Conversation

anforowicz
Copy link
Owner

@zetafunction, can you PTAL before I open a PR against the upstream repo?

Copy link

@zetafunction zetafunction left a 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

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?

Copy link
Owner Author

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("__")?,

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++)

Copy link
Owner Author

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)
@anforowicz anforowicz force-pushed the arbitrary-inner-type-in-named-impl-key branch from 1c784bf to 795da6d Compare September 29, 2025 18:38
@anforowicz
Copy link
Owner Author

Thanks for the feedback. Let me close this PR - I'll replace it with an upstream PR.

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.

2 participants