blob: 7b72c2bba46712af71d8f914726e7b745cef38f5 [file] [edit]
// 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
// IWYU pragma: private, include "support/annotations.h"
#ifndef THIRD_PARTY_CRUBIT_SUPPORT_ANNOTATIONS_H_
#define THIRD_PARTY_CRUBIT_SUPPORT_ANNOTATIONS_H_
#include "support/annotations_internal.h"
// Marks a function or type as requiring Rust binding.
//
// If Crubit fails to generate bindings for a function or type annotated with
// `CRUBIT_MUST_BIND`, bindings generation for the entire target will fail
// with a hard error.
//
// This can be useful when developing C++ API surfaces that are intended to be
// used from Rust, as it produces a clear error message when a function is
// missing bindings.
//
// For example, this C++ header will silently not produce bindings for
// `foo` because overloads are not supported.
//
// ```c++
// void foo();
// void foo(int x);
// void bar();
// ```
//
// This default behavior allows `bar` to still receive bindings.
//
// By contrast, this C++ header will fail at binding generation time with an
// error message describing that overloads are not supported:
//
// ```c++
// CRUBIT_MUST_BIND void foo();
// void foo(int x);
// void bar();
// ```
//
// The annotation can also be applied to a type:
//
// ```c++
// struct CRUBIT_MUST_BIND Foo {
// int x;
// };
// ```
#define CRUBIT_MUST_BIND CRUBIT_INTERNAL_ANNOTATE("crubit_must_bind")
// Prevents a function or type from receiving Rust bindings.
//
// Use of this annotation should be avoided where-possible as usage of it can
// prevent Rust from accessing useful C++ functionality.
//
// Declarations using this annotation must be registered in the
// `do_not_bind_allowlist` or bindings generation will fail with a hard error.
#define CRUBIT_DO_NOT_BIND CRUBIT_INTERNAL_ANNOTATE("crubit_do_not_bind")
// By default, crubit.rs will infer Rust safety based on the types of the
// function's parameters. This annotation can be used to override that
// inference.
#define CRUBIT_OVERRIDE_UNSAFE(function_is_unsafe) \
CRUBIT_INTERNAL_ANNOTATE("crubit_override_unsafe", function_is_unsafe)
// This annotation configures a user-defined rust name for a C++ declaration.
// If the user-defined rust name conflicts with an existing name, bindings for
// both the annotated decl and the conflicting decl will fail, and be treated as
// overloads.
//
// For example, this C++ header:
//
// ```c++
// CRUBIT_RUST_NAME("foo")
// int bar() { return 42; }
// ```
//
// Becomes this Rust interface:
//
// ```rust
// pub fn foo() -> i32; // returns 42
// ```
//
// There's a special case for operators: when an operator symbol is given, for
// example `CRUBIT_RUST_NAME("!")`, the function is mapped to the corresponding
// Rust operator trait, in this case `core::ops::Not`.
//
// ```c++
// CRUBIT_RUST_NAME("!")
// MyInt operator~(MyInt x);
// ```
//
// ```rust
// impl core::ops::Not for MyInt {
// type Output = Self;
//
// fn not(self) -> Self::Output { /* calls operator~ */ }
// }
// ```
#define CRUBIT_RUST_NAME(crubit_rust_name) \
CRUBIT_INTERNAL_ANNOTATE("crubit_rust_name", crubit_rust_name)
// This annotation is used to mark a function as `unsafe` to Rust callers.
//
// For example, this C++ header:
//
// ```c++
// CRUBIT_UNSAFE
// int foo() { return 42; }
// ```
//
// Becomes this Rust interface:
//
// ```rust
// pub unsafe fn foo() -> i32; // returns 42
// ```
//
// By default, crubit.rs will infer Rust safety based on the types of the
// function's parameters. This annotation can be used to override that
// inference.
#define CRUBIT_UNSAFE CRUBIT_OVERRIDE_UNSAFE(true)
// This annotation is used to mark a function as `safe` to Rust callers
// regardless of the types of the function's parameters.
//
// For example, this C++ header:
//
// ```c++
// CRUBIT_UNSAFE_MARK_SAFE
// uint64_t foo(uint64_t* unsafe_ptr) { return 42; }
// ```
//
// Becomes this Rust interface:
//
// ```rust
// pub fn foo(*mut u64) -> u64; // returns 42
// ```
//
// By default, crubit.rs will infer Rust safety based on the types of the
// function's parameters. This annotation can be used to override that
// inference.
#define CRUBIT_UNSAFE_MARK_SAFE CRUBIT_OVERRIDE_UNSAFE(false)
// Overrides the `Debug` binding generation for a struct, class, or union.
//
// By default, Crubit generates a custom `Debug` implementation for all concrete
// structs/classes and all unions, but not abstract structs/classes. Use
// `CRUBIT_OVERRIDE_DEBUG` to opt-out (or opt-in for abstract types).
//
// Unlike Rust's `derive(Debug)`, does not require all fields to `impl Debug`.
// However, only guaranteed to be exhaustive if all the following hold:
// * The type is a struct or class, not a union.
// * Every field is supported, named, and implements `Debug`, including
// non-generic Rust types that implement `Debug`.
// * The type has no bases.
#define CRUBIT_OVERRIDE_DEBUG(should_bind) \
CRUBIT_INTERNAL_ANNOTATE("crubit_override_debug", should_bind)
// Marks a type as deriving a trait.
//
// This can be applied to a struct, class, or enum.
//
// For example, this C++ header:
//
// ```c++
// struct CRUBIT_TRAIT_DERIVE("Clone") MyStruct {
// bool enable_foo;
// };
// ```
//
// Becomes this Rust interface:
//
// ```rust
// #[derive(..., Clone)]
// pub struct MyStruct {
// enable_foo: bool,
// }
// ```
//
// TODO(b/475834520): Deriving `Debug` will be deprecated in favor of the
// default behavior. To opt out of the default `Debug` implementation, use
// `CRUBIT_OVERRIDE_DEBUG(false)`.
#define CRUBIT_TRAIT_DERIVE(...) \
CRUBIT_INTERNAL_ANNOTATE("crubit_internal_trait_derive" __VA_OPT__(, ) \
__VA_ARGS__)
// Marks a type as unsafely implementing one or more marker traits.
//
// This can be applied to a struct, class, or enum.
//
// For example, this C++ header:
//
// ```c++
// struct
// CRUBIT_UNSAFE_IMPL("Send", "Sync") MyStruct {
// bool enable_foo;
// };
// ```
//
// Becomes this Rust interface:
//
// ```rust
// pub struct MyStruct {
// enable_foo: bool,
// }
//
// unsafe impl Send for MyStruct {}
// unsafe impl Sync for MyStruct {}
// ```
#define CRUBIT_UNSAFE_IMPL(...) \
CRUBIT_INTERNAL_ANNOTATE("crubit_internal_unsafe_impl" __VA_OPT__(, ) \
__VA_ARGS__)
// Marks a type as bridging to a Rust type.
//
// # Warning
//
// Composable bridging on user-defined types is still highly experimental.
//
// # Usage
//
// * rust_name: The name of the Rust type.
// * abi_rust: The Crubit ABI of the Rust type.
// * abi_cpp: The Crubit ABI of the C++ type.
// * label_hint: (Optional) The target that owns the Rust type.
// Format: "//package:target" or a short-form like
// "@abseil-cpp//absl/status".
//
// From absl::StatusOr:
//
// ```c++
// #include "absl/status/status.h" # from
// @abseil-cpp//absl/status:status
//
// template <typename T>
// class
// CRUBIT_BRIDGE("::status::absl::StatusOr", "::status::absl::StatusOrAbi",
// "::crubit::StatusOrAbi", "@abseil-cpp//absl/status:status")
// StatusOr;
// ```
#define CRUBIT_BRIDGE_3(rust_name, abi_rust, abi_cpp) \
CRUBIT_INTERNAL_ANNOTATE("crubit_bridge_rust_name", rust_name) \
CRUBIT_INTERNAL_ANNOTATE("crubit_bridge_abi_rust", abi_rust) \
CRUBIT_INTERNAL_ANNOTATE("crubit_bridge_abi_cpp", abi_cpp)
#define CRUBIT_BRIDGE_4(rust_name, abi_rust, abi_cpp, label_hint) \
CRUBIT_BRIDGE_3(rust_name, abi_rust, abi_cpp) \
CRUBIT_INTERNAL_ANNOTATE("crubit_bridge_label_hint", label_hint)
#define CRUBIT_BRIDGE_GET_MACRO(_1, _2, _3, _4, NAME, ...) NAME
#define CRUBIT_BRIDGE(...) \
CRUBIT_BRIDGE_GET_MACRO(__VA_ARGS__, CRUBIT_BRIDGE_4, \
CRUBIT_BRIDGE_3)(__VA_ARGS__)
// Prevents Crubit from interpreting one or more named attributes on this
// declaration.
//
// ```c++
// // example.h
// // SAFETY: `my_attribute` does not affect ABI.
// struct CRUBIT_UNSAFE_IGNORE_ATTR("my_attr") [[my_attr]] MyStruct {};
// ```
#define CRUBIT_UNSAFE_IGNORE_ATTR(...) \
CRUBIT_INTERNAL_ANNOTATE("crubit_unsafe_ignore_attr" __VA_OPT__(, ) \
__VA_ARGS__)
// The CRUBIT_OWNED_POINTER AND CRUBIT_OWNED_POINTEE annotations work together
// to map conventionally "owned" C++ pointer usages to a Rust type that provides
// Rust-style ownership wrapping a raw pointer.
//
// Think carefully before using these annotations. These annotations exist to
// support existing APIs that use raw pointers directly, and can not be
// modified; if your API can be improved to avoid dealing with raw pointers (for
// example, by using the managed C++ pointer types that crubit supports) that's
// almost certainly the preferable solution.
//
// Types annotated with `CRUBIT_OWNED_PTR` indicate a transfer of ownership: for
// example, in the return position, they indicate that the function is passing
// ownership of the pointed-to object to the caller. Similarly, in a parameter
// position, the callee receiving ownership of the pointed-to object.
//
// The annotation is only meaningful on pointer types. When a pointer is
// annotated with `CRUBIT_OWNED_PTR`, the pointee type must also be annotated
// with `CRUBIT_OWNED_PTR_TYPE`, indicating the Rust type that will manage the
// ownership of the object in Rust bindings.
//
// The annotation pair is meant to associate Rust types that simply contain a
// pointer to the associated C++ type.
//
// For example:
//
// ```c++
// struct CRUBIT_OWNED_POINTEE("WrapperTypeName") MyType;
//
// MyType* CRUBIT_OWNED_POINTER ReturnOwnedPtr() { ... }
// void AcceptOwnedPtr(MyType* CRUBIT_OWNED_POINTER owned_ptr) { ... }
// ```
//
// This will generate a Rust struct called `WrapperTypeName` that simply
// contains a pointer to the underlying object. This type will be used in
// positions that are annotated with `CRUBIT_OWNED_POINTER`.
//
// You can optionally specify a custom drop method name as a second argument:
// `CRUBIT_OWNED_POINTEE("WrapperTypeName", "DropMethodName")`. If omitted, it
// defaults to `DropImpl`.
#define CRUBIT_OWNED_POINTER \
CRUBIT_INTERNAL_ANNOTATE_TYPE("crubit_owned_pointer")
#define CRUBIT_OWNED_POINTEE(name, ...) \
CRUBIT_INTERNAL_ANNOTATE("crubit_owned_pointee", \
name __VA_OPT__(, ) __VA_ARGS__)
// Overrides the `Display` binding detection for a type to true or false.
//
// If detected: binds to Rust's `Display` trait, preferring `AbslStringify` over
// `std::ostream&` `operator<<` but requiring either.
//
// By default, infers a type `T`'s formatability based on one of:
// * `template <typename Sink> void AbslStringify(Sink&, const T&)`
// * `template <typename Sink> void AbslStringify(Sink&, T)`
// * `std::ostream& operator<<(std::ostream&, const T&)`
// * `std::ostream& operator<<(std::ostream&, T)`
// * This annotation on `T`'s bases
//
// in any of the following:
// * `T`'s namespace
// * `T`'s friends
// * `T`'s bases' namespace and friends
//
// and recurses on the bases of `T`. e.g., if `T` inherits from `B`, then
// looks for both `AbslStringify(Sink&, T)` and `AbslStringify(Sink&, B)` in
// `B`.
//
// However, default inference does *not* handle all cases, including:
// * Other function or function template signatures e.g.,
// ```c++
// template <typename Sink, typename T>
// void AbslStringify(Sink&, const Foo<T>&);
//
// template <typename T>
// struct Bar {
// template <
// typename U = T,
// typename = std::enable_if_t<absl::HasOstreamOperator<U>::value>>
// friend std::ostream& operator<<(std::ostream&, const Bar&);
// };
//
// template <typename T>
// struct Baz {
// friend std::ostream& operator<<(std::ostream&, const Bar&)
// requires(absl::HasOstreamOperator<T>::value);
// };
//
// struct Qux {
// template <typename T, typename Traits>
// friend std::basic_ostream<T, Traits>& operator<<(
// std::basic_ostream<T, Traits>&, const Qux&);
// };
// ```
// * Formattable but non-public bases
// * Deleted functions
#define CRUBIT_OVERRIDE_DISPLAY(should_bind) \
CRUBIT_INTERNAL_ANNOTATE("crubit_override_display", should_bind)
// Marks a type as thread-safe for Rust interop.
//
// This is an unsafe operation. Only use this annotation on thread-safe types
// which are never created as `const`, or else which mark all fields that can
// be mutated as `mutable`, even if those fields can only be mutated from a
// non-const method.
//
// Types annotated with `CRUBIT_THREAD_SAFE` will:
//
// * Implement `Send + Sync` in Rust
// * Have their internal representation wrapped in `UnsafeCell`, allowing
// non-const C++ methods to be called via shared references (`&self`)
//
// This annotation is appropriate for types that internally synchronize
// access (e.g., types with mutexes, atomics, or other synchronization
// primitives). However, it places strong requirements on the type's C++ users
// and/or the C++ type owner: either the type must never be created as a top
// level `const` object, or else all mutating operations must be made valid on a
// `const` object, by marking all mutated fields as `mutable`.
//
// Example:
//
// ```c++
// class CRUBIT_THREAD_SAFE ThreadSafeCounter {
// public:
// void Increment(); // Can be called via mut T*.
// int Get() const; // Can also be called via &self
// private:
// mutable std::atomic<int> count_;
// };
// ```
//
// See crubit.rs/cpp/cookbook#thread_safety
//
#define CRUBIT_THREAD_SAFE CRUBIT_INTERNAL_ANNOTATE("crubit_thread_safe")
// Marks a template or template instance as always instantiated.
//
// Example:
// ```c++
// using MyInst CRUBIT_ALWAYS_INSTANTIATE = MyTemplate<int>;
// ```
#define CRUBIT_ALWAYS_INSTANTIATE \
CRUBIT_INTERNAL_ANNOTATE("crubit_always_instantiate")
// Creates a uniquely-named using declaration that aliases `tp`, annotated with
// `CRUBIT_ALWAYS_INSTANTIATE`.
//
// Example:
// ```c++
// CRUBIT_BIND_INSTANTIATION(MyTemplate<int>);
// ```
#define CRUBIT_BIND_INSTANTIATION(tp...) \
namespace { \
using CRUBIT_INTERNAL_EXPAND_AND_CONCAT( \
crubit_bind_instantiation_, __COUNTER__) CRUBIT_ALWAYS_INSTANTIATE = tp; \
}
// Suppresses the warning on types defined in the `srcs` of a
// `rust_api_from_cpp` target that will not receive C++ bindings.
#define CRUBIT_ALLOW_UNBINDABLE_TYPE \
CRUBIT_INTERNAL_ANNOTATE("crubit_allow_unbindable_type")
#endif // THIRD_PARTY_CRUBIT_SUPPORT_ANNOTATIONS_H_