#[extern_trait]
Generate an opaque type for a trait to forward to a foreign implementation.
Example
use extern_trait;
// In crate A
/// A Hello trait.
/// # Safety
/// See [`extern_trait`].
pub unsafe
let v = new;
v.hello;
// In crate B
;
unsafe
This will generate the following code (adapted):
// In crate A
// #[extern_trait(HelloProxy)]
/// A Hello trait.
/// # Safety
/// See [`extern_trait`].
pub unsafe
/// A proxy type for [`Hello`].
pub , *const );
unsafe
// In crate B
;
// #[extern_trait]
unsafe
const _: = ;
const _: = ;
Supertraits
An #[extern_trait] may have supertraits to forward more trait implementations. The currently supported traits are:
Send/SyncAsRef- TODO: support more
use extern_trait;
unsafe
Restrictions
For the trait:
- It may not have generics.
- It may only contain methods, not associated types or constants.
- Its methods have to be compatible with FFI, i.e. no
const/async/type parameters/const parameters - If
Selftype appears in any location (including the method receiver), it has to be one of the following forms:Self/&Self/&mut Self/*const Self/*mut Self.- Currently
Selfcan not be used as parameter type, but maybe supported in the future.
- Currently
For the implementor: The type must be able to pass through two general registers in calling conventions. That basically requires the following things:
- Smaller than two general registers (e.g. <= 16 bytes on 64-bit architectures)
- Do not use floating point registers unless using soft-float ABI
#[extern_trait] automatically checked the first requirement, but there are no way to check the second one. So #[extern_trait] is required to be unsafe and implementor must guarantee that their type satisfy all the requirements.
This also require the ABI to be able to pass value in two general registers, so not all architectures and platforms are supported.
- TODO: support table
Credits
This crate is heavily inspired by crate_interface, as the original starting point was to solve the problem that crate_interface cannot pass opaque types.