Repository: dtolnay/cxx (language: rust)

Issue:
Reuse of shared structs containing String
It seems I am still getting something wrong about https://github.com/dtolnay/cxx/issues/297. [Here](https://github.com/alexeyr/tokenizers/commit/2c7c484a871f2cece61518d153ad91f7d020a3b2) I am trying to reuse a shared struct instead of declaring it the second time and get

```
  running: "E:\\VisualStudio\\VC\\Tools\\MSVC\\14.26.28801\\bin\\HostX64\\x64\\cl.exe" "-nologo" "-MD" "-Z7" "-Brepro" "-I" "E:\\MyProgramming\\tokenizers\\bindings\\cpp\\target\\debug\\build\\tokenizers-cpp-348e1825e6b8d85d\\out\\cxxbridge\\include" "-I" "E:\\MyProgramming\\tokenizers\\bindings\\cpp\\target\\debug\\build\\tokenizers-cpp-348e1825e6b8d85d\\out\\cxxbridge\\crate" "-I" "." "-I" "target/cxxbridge/tokenizers-cpp" "-I" "thirdparty" "-W4" "/std:c++14" "/EHsc" "-FoE:\\MyProgramming\\tokenizers\\bindings\\cpp\\target\\debug\\build\\tokenizers-cpp-348e1825e6b8d85d\\out\\cxxbridge\\sources\\tokenizers-cpp\\tokenizers-cpp\\processors.rs.o" "-c" "E:\\MyProgramming\\tokenizers\\bindings\\cpp\\target\\debug\\build\\tokenizers-cpp-348e1825e6b8d85d\\out\\cxxbridge\\sources\\tokenizers-cpp\\tokenizers-cpp\\processors.rs.cc"
  processors.rs.cc
  E:\MyProgramming\tokenizers\bindings\cpp\target\cxxbridge\tokenizers-cpp\tokenizers-cpp/processors.rs.h(198): error C2338: type ::huggingface::tokenizers::ffi::KVStringU32 marked as Trivial in Rust is not trivially move constructible and trivially destructible in C++     
  E:\MyProgramming\tokenizers\bindings\cpp\target\debug\build\tokenizers-cpp-348e1825e6b8d85d\out\cxxbridge\sources\tokenizers-cpp\tokenizers-cpp\processors.rs.cc(251): error C2338: type ::huggingface::tokenizers::ffi::KVStringU32 marked as Trivial in Rust is not trivially 
move constructible and trivially destructible in C++
  exit code: 2

  --- stderr

  CXX include path:
    E:\MyProgramming\tokenizers\bindings\cpp\target\debug\build\tokenizers-cpp-348e1825e6b8d85d\out\cxxbridge\include
    E:\MyProgramming\tokenizers\bindings\cpp\target\debug\build\tokenizers-cpp-348e1825e6b8d85d\out\cxxbridge\crate
```

The only potentially significant difference from #465 that I can see on my own is that I `include!("tokenizers-cpp/models.h");` and not `.rs.h`; but trying to change that adds a lot more errors and doesn't fix this one.

Hopefully the commit introducing the error is small enough; if not, I can try to create a smaller case reproducing it.


Discussion / hints:
Ah, the problem is that it contains a `String`, and is never actually passed by value in `models`, but only in `processors` . Is that right?
It looks like the problem can be fixed by adding 

```
template <>
struct IsRelocatable<MyStruct> : std::true_type {};
```

If I understand `IsRelocatable`, this should be safe, and can be generated for any shared struct containing `String`; and for shared structs containing `Vec<SomethingElse>`,

```
template <>
struct IsRelocatable<MyStruct> : IsRelocatable<SomethingElse>::value {};
```

(approximately). If this is correct, I can make a pull request.

Fix patch:
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 851b95373..cae93578b 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -233,9 +233,7 @@ fn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct, methods: &[&Extern
         writeln!(out, "{};", field.ident);
     }
 
-    if !methods.is_empty() || operator_eq || operator_ord {
-        writeln!(out);
-    }
+    writeln!(out);
 
     for method in methods {
         write!(out, "  ");
@@ -281,6 +279,9 @@ fn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct, methods: &[&Extern
         );
     }
 
+    out.include.type_traits = true;
+    writeln!(out, "  using IsRelocatable = ::std::true_type;");
+
     writeln!(out, "}};");
     writeln!(out, "#endif // {}", guard);
 }


Test patch: