-
Notifications
You must be signed in to change notification settings - Fork 381
Reusing Rust type bindings / support for type aliases in the Rust section #1539
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
base: master
Are you sure you want to change the base?
Conversation
`syntax::parse::parse_items` is currently called from two places: from `macro/src/expand.rs` and from `gen/src/mod.rs`. (In the future it may be also called from a `syntax/test_support.rs` helper.) Before this commit, all those places had to destructure/interpret a `syntax::file::Module` into `content`, `namespace`, and `trusted`. After this commit, this destructuring/interpretation is deduplicated into `syntax::parse::parse_items`. This requires some minor gymnastics: * `gen/src/mod.rs` has to call `std::mem::take(&mut bridge.attrs)` instead of doing a partial destructuring and passing `bridge.attrs` directly. This is an extra complexity, but we already do the same thing in `macro/src/expand.rs` before this commit, so hopefully this is ok. * `fn parse_items` takes `&mut Module` rather than `Module` and "consumes" / `std::mem::take`s `module.content`, because `macro/src/expand.rs` needs to retain ownership of other `Module` fields. This also seems like an unfortunate extra complexity, but (again) before this commit we already do this for `bridge.attrs` in `macro/src/expand.rs`.
Before this commit `fn parse_apis` in `syntax/test_support.rs` would ignore the namespace in `#[cxx::bridge(namespace = "ignored")]`. In other words, the new test added in `syntax/namespace.rs` would fail before this commit. This commit fixes this. At a high-level this commit: * Moves two pieces of code from `gen/src/file.rs` into `syntax/...` to make them reusable from `syntax/test_support.rs`: - `fn find_cxx_bridge_attr` (moved into `syntax/attrs.rs`) - `Namespace::parse_attr` (moved into `syntax/namespace.rs`) * Reuses these pieces of code from `syntax/test_support.rs` * Renames `Namespace::parse_bridge_attr_namespace` to `Namespace::parse_stream` so that all 3 parse methods are named after their input: `parse_attr`, `parse_stream`, `parse_meta`. * Adds a `syntax/`-level unit test that verifies that the namespace is indeed getting correctly parsed and propagated
@@ -163,3 +163,46 @@ mod ffi { | |||
|
|||
Bounds on a lifetime (like `<'a, 'b: 'a>`) are not currently supported. Nor are | |||
type parameters or where-clauses. | |||
|
|||
## Reusing existing binding types |
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.
Reusing an existing defined pair of C++ and Rust type is already supported. I don't understand the distinction between the extern C++ type aliases which are already supported, and the extern Rust type aliases in this PR. What is the situation where it would be correct to write extern "Rust" { type T = path::to::U; }
and not extern "C++" { type T = path::to::U; }
?
verify | ||
verify | ||
} | ||
Lang::Rust => { |
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.
This is not sufficient for safety. Consider adding:
// inside extern "Rust"
type Any = crate::module::CrossModuleRustType;
fn repro(bad: &mut CrossModuleRustType) -> &mut Any;
...
fn repro(bad: &mut ffi::CrossModuleRustType) -> &mut ffi::Any {
bad
}
Nothing here enforces what type the C++ Any
is. We can make it anything:
namespace tests {
using Any = std::array<char, 1000>;
}
and arbitrarily stomp on memory.
repro(*r_boxed_cross_module_rust_type(123)).fill('?');
Running tests/test.rs (target/debug/deps/test-f2f5723622a08a56)
running 15 tests
free(): invalid next size (fast)
malloc(): corrupted top size
error: test failed, to rerun pass `--test test`
Caused by:
process didn't exit successfully: `target/debug/deps/test-f2f5723622a08a56` (signal: 6, SIGABRT: process abort signal)
PTAL?
This PR fixes https://crbug.com/433254489 (/cc @ShabbyX as FYI - IIUC they've patched this PR onto their local machine and verified that it does indeed unblock them).
The first commit fixes some existing code duplication and prevents more code duplication around how
fn syntax::parse_items
consumes asyntax::Module
. I think this commit is okay and moves things in a reasonable direction, but I acknowledge that adding more partial consumption/destructuring/taking is a bit icky. More discussion about this aspect of the changes can be found in a comment from a semi-internal review at anforowicz#2 (comment) and anforowicz#2 (comment).I also note that some existing variants of
syntax::Api
enum
have Rust and C++ versions - e.g.RustFunction
andCxxFunction
as well asRustType
andCxxType
. We could also do that for theTypeAlias
variant which this PR doesn't touch just yet. Please provide feedback on whether I should also submit an additional commit into this or a separate PR - see https://github.com/anforowicz/cxx/tree/api-rust-type-alias-separate-variant/cc @zetafunction who has kindly provided initial, semi-internal feedback at anforowicz#2