Repository: dtolnay/cxx (language: rust)

Issue:
tests/ffi: strange error with a function returning Vec<Buffer>
The error triggers a warning for the Buffer field in Array that was already there but somehow silent.

    cargo:warning=.../out/cxxbridge/sources/tests/ffi/lib.rs.cc:1387:45:
        error: static assertion failed: type tests::Buffer should be trivially
               move constructible and trivially destructible in C++ to be used
               as a field of `Array` or vector element in Vec<Buffer> in Rust
    cargo:warning= 1387 |     ::rust::IsRelocatable<::tests::Buffer>::value,

- Here the [failing pipeline log](https://github.com/dtolnay/cxx/actions/runs/3081009896/jobs/4979054704#step:7:57) for the error above (first commit c858291a9ff62bcbd123363407cd73e05ab1a46a).
- The "fix" is not complete either, the plain Buffer struct code does not pass the tests on windows: [msvc pipeline logs](https://github.com/dtolnay/cxx/actions/runs/3081012199/jobs/4979060118#step:7:59) (second commit d0537c91e56e570b880046be092c4068739cb41c)


Discussion / hints:
Long story short, I'd like to use a trivial struct inside a `Vec`, but it did not work. I had to wrap it inside a struct as a field to have it work.

```rust
struct Foo {
   data: Vec<TrivialData>
}
```

does not link, missing `Vec` constructor.

```rust
struct DataWrapper {    // <--- shared
   d: TrivialData
}

struct Foo {
   data: Vec<DataWrapper>
}
```

So I dived into the code to understand if that case was covered, tried to add a test and found a strange error.
I'd like to help, either adding support for the use case or improving the error or the documentation or the tests, feel free to suggest some direction and I'll have a look in my spare time. Thanks anyway!

Fix patch:
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 982fb3caf..dddec7a55 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -472,10 +472,10 @@ fn check_trivial_extern_type(out: &mut OutFile, alias: &TypeAlias, reasons: &[Tr
     writeln!(out, "static_assert(");
     if reasons
         .iter()
-        .all(|r| matches!(r, TrivialReason::StructField(_)))
+        .all(|r| matches!(r, TrivialReason::StructField(_) | TrivialReason::VecElement))
     {
-        // If the type is only used as a struct field and not as by-value
-        // function argument or any other use, then C array of trivially
+        // If the type is only used as a struct field or Vec element, not as
+        // by-value function argument or return value, then C array of trivially
         // relocatable type is also permissible.
         //
         //     --- means something sane:


Test patch: