Support linking Rust code into a C++ binary

This is based on a version of my upstream PR:
https://github.com/bazelbuild/rules_rust/pull/1350

Change-Id: Ica7097c10666d2e0017336cf7d81420605238493
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
diff --git a/build_tests/BUILD b/build_tests/BUILD
index 29a1275..24fdad8 100644
--- a/build_tests/BUILD
+++ b/build_tests/BUILD
@@ -178,3 +178,16 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [":ts_test"],
 )
+
+rust_library(
+    name = "rust_in_cc_rs",
+    srcs = ["rust_in_cc.rs"],
+    target_compatible_with = ["@platforms//os:linux"],
+)
+
+cc_test(
+    name = "rust_in_cc",
+    srcs = ["rust_in_cc.cc"],
+    target_compatible_with = ["@platforms//os:linux"],
+    deps = [":rust_in_cc_rs"],
+)
diff --git a/build_tests/rust_in_cc.cc b/build_tests/rust_in_cc.cc
new file mode 100644
index 0000000..9c13b1b
--- /dev/null
+++ b/build_tests/rust_in_cc.cc
@@ -0,0 +1,19 @@
+// A very minimal rust_library linked into a cc_binary to make sure we still get
+// the allocator symbols linked in.
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern "C" int32_t rust_return5();
+
+extern "C" uint8_t c_return5() { return 5; }
+
+extern "C" void c_take5(uint8_t *) {}
+
+int main() {
+  const int rust_result = rust_return5();
+  printf("Rust says: %d\n", rust_result);
+  if (rust_result != 5) {
+    return 1;
+  }
+}
diff --git a/build_tests/rust_in_cc.rs b/build_tests/rust_in_cc.rs
new file mode 100644
index 0000000..0810609
--- /dev/null
+++ b/build_tests/rust_in_cc.rs
@@ -0,0 +1,19 @@
+extern "C" {
+    fn c_return5() -> u8;
+    fn c_take5(x: *mut u8);
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn rust_return5() -> i32 {
+    let layout = std::alloc::Layout::from_size_align(1, 1).unwrap();
+    let a = std::alloc::alloc(layout);
+    *a = c_return5();
+    // Do something so the compiler can't optimize out the alloc+free pair, which would invalidate
+    // this test.
+    if *a != 5 {
+        c_take5(a);
+    } else {
+        std::alloc::dealloc(a, layout);
+    }
+    5
+}