Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

C++ bindings for Rust use declarations

Crubit supports use declarations for functions and types, mapping them to equivalent using declarations in C++.

Limitations:

  • The use declaration must refer to a function or type.
    • If it refers to a function, it must not rename the function.
  • The use declaration must import exactly one entity per name. For example, pub use m::x; is supported if x refers to a function, or to a type, but not if it refers to both a function and a type.

Example

Given the following Rust crate:

// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

pub mod module {
    pub fn function() {}
    #[derive(Default)]
    pub struct Type {
        pub x: i32,
    }
}

pub use module::function;
pub use module::Type;

Crubit will generate the following bindings:

// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// Automatically @generated C++ bindings for the following Rust crate:
// example_crate_golden
// Features: custom_ffi_types, non_unpin_ctor, std_unique_ptr, std_vector,
// supported

// clang-format off
#ifndef THIRD_PARTY_CRUBIT_EXAMPLES_RUST_USE_DECLARATION_EXAMPLE_CRATE_GOLDEN
#define THIRD_PARTY_CRUBIT_EXAMPLES_RUST_USE_DECLARATION_EXAMPLE_CRATE_GOLDEN

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
#include "support/annotations_internal.h"
#include "support/internal/slot.h"

#include <cstddef>
#include <cstdint>
#include <type_traits>

namespace example_crate {

// Generated from:
// examples/rust/use_declaration/example.rs;l=8
struct CRUBIT_INTERNAL_RUST_TYPE(":: example_crate_golden :: Type") alignas(4)
    [[clang::trivial_abi]] Type final {
 public:
  // Default::default
  Type();

  // No custom `Drop` impl and no custom "drop glue" required
  ~Type() = default;
  Type(Type&&) = default;
  Type& operator=(Type&&) = default;

  // `example_crate_golden::Type` doesn't implement the `Clone` trait
  Type(const Type&) = delete;
  Type& operator=(const Type&) = delete;
  Type(::crubit::UnsafeRelocateTag, Type&& value) {
    memcpy(this, &value, sizeof(value));
  }
  union {
    // Generated from:
    // examples/rust/use_declaration/example.rs;l=9
    std::int32_t x;
  };

 private:
  static void __crubit_field_offset_assertions();
};

// Generated from:
// examples/rust/use_declaration/example.rs;l=6
void function();

namespace module {
using Type CRUBIT_INTERNAL_RUST_TYPE(":: example_crate_golden :: Type") =
    ::example_crate::Type;
}

static_assert(
    sizeof(Type) == 4,
    "Verify that ADT layout didn't change since this header got generated");
static_assert(
    alignof(Type) == 4,
    "Verify that ADT layout didn't change since this header got generated");
namespace __crubit_internal {
extern "C" void __crubit_thunk_default(::example_crate::Type* __ret_ptr);
}
inline Type::Type() { __crubit_internal::__crubit_thunk_default(this); }
static_assert(std::is_trivially_destructible_v<Type>);
static_assert(std::is_trivially_move_constructible_v<Type>);
static_assert(std::is_trivially_move_assignable_v<Type>);
inline void Type::__crubit_field_offset_assertions() {
  static_assert(0 == offsetof(Type, x));
}

namespace module {
using ::example_crate::function;
}

namespace __crubit_internal {
extern "C" void __crubit_thunk_function();
}
inline void function() { return __crubit_internal::__crubit_thunk_function(); }

}  // namespace example_crate
#pragma clang diagnostic pop
#endif  // THIRD_PARTY_CRUBIT_EXAMPLES_RUST_USE_DECLARATION_EXAMPLE_CRATE_GOLDEN