Improving support for cross-bridge type aliases of Rust types. #1606
+74
−10
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR improves docs (to explain that the type alias has to go into a
extern "C++"
section, and to point out the need to use#[derive(ExternType)]
).This commit also fixes errors that would be reported if a type alias for a Rust type would be used as a
&mut T
parameter. The fixes boil down to ensuring that the Rust type is recognized as Rust-movable. More details can be found in the PR discussion.Description of changes in
macro/src/expand.rs
16e2620 has introduced support for
#[derive(ExternType)]
inextern “Rust”
section. I don’t understand why this commit usedtype Kind = ::cxx::kind::Opaque
rather thankind::Trivial
.Docs for
cxx::kind::Opaque
say that “an opaque type [...] cannot be passed or held by value within Rust” because “Rust’s move semantics are such that every move is equivalent to a memcpy” (which is “incompatible in general with C++’s constructor-based move semantics”).Docs for
cxx::kind::Trivial
say that this is “a type with trivial move constructor and no destructor, which can therefore be owned and moved around in Rust code without requiring indirection”.Based on
tests/ui/rust_pinned.rs
(and the corresponding expected error message in the.stderr
file here I assume thatcxx
does not allowextern “Rust” { type RustType; }
for!Unpin
types. So this would mean that all Rust types supported bycxx
can be moved bymemcpy
.Therefore it seems okay to change
macro/src/[expand.rs](http://expand.rs/)
to emittype Kind = ::cxx::kind::Trivial
Without the change in
macro/src/expand.rs
, the new tests would result in the following error:Description of changes in
gen/src/write.rs
Currently C++ bindings for
extern “Rust”
types do not mark the bindings as relocatable (in thecxx::IsRelocatable<T>
sense).The doc comment of
cxx::IsRelocatable
says this is an assertion that the type “is soundly relocatable by Rust”.We already established above that all Rust types supported by
cxx
can be moved bymemcpy
. Therefore from that perspective it seems okay to start emittingusing IsRelocatable = ::std::true_type
inside the struct/bindings emitted for Rust types byfn write_opaque_type
ingen/src/[write.rs](http://write.rs/)
.Emitting a new public member carries a risk that its name may conflict/clash with another, preexisting member. So from that perspective, it may be safer to directly specialize
cxx::IsRelocatable
. OTOH, the Rust naming guidelines reserve UpperCamelCase to types, traits, enum variants, and type parameters - this means that a clash withIsRelocatable
seems unlikely.Without the change in
gen/src/write.rs
, the new tests would result in the following error:/cc @ShabbyX