abi_stable/
lib.rs

1/*!
2
3For Rust-to-Rust ffi,
4with a focus on creating libraries loaded at program startup,
5and with load-time type-checking.
6
7This library allows defining Rust libraries that can be loaded at runtime,
8even if they were built with a different Rust version than the crate that depends on it.
9
10These are some usecases for this library:
11
12- Converting a Rust dependency tree from compiling statically into a single binary,
13    into one binary (and potentially) many dynamic libraries,
14    allowing separate re-compilation on changes.
15
16- Creating a plugin system (without support for unloading).
17
18# Features
19
20Currently this library has these features:
21
22- Features the [`sabi_trait`] attribute macro, for creating ffi-safe trait objects.
23
24- Ffi-safe equivalent of some trait objects with [`DynTrait`].
25
26- Provides ffi-safe alternatives/wrappers for many standard library types,
27    in the [`std_types`] module.
28
29- Provides ffi-safe wrappers for some types defined in external crates,
30    in the [`external_types`] module.
31
32- Provides the [`StableAbi`] trait for asserting that types are ffi-safe.
33
34- The [prefix types] feature for building extensible modules and vtables,
35without breaking ABI compatibility.
36
37- Supports ffi-safe [nonexhaustive enums], wrapped in [`NonExhaustive`].
38
39- Checking at load-time that the types in the dynamic library have the expected layout,
40    allowing for semver compatible changes while checking the layout of types.
41
42- Provides the [`StableAbi` derive] macro
43    to both assert that the type is ffi compatible,
44    and to get the layout of the type at load-time to check that it is still compatible.
45
46# Examples
47
48For **examples** of using `abi_stable` you can look at [the readme example],
49or for the crates in the examples directory in the repository for this crate.
50This crate also has examples in the docs for most features.
51
52To run the example crates you'll generally have to build the `*_impl` crate,
53then run the `*_user` crate (all `*_user` crates should have a help message and a readme.md).
54
55
56# Minimum Rust version
57
58This crate support Rust back to 1.61.0
59
60You can manually enable support for Rust past 1.61.0 with the `rust_*_*` cargo features.
61
62# Crate Features
63
64These are default cargo features that enable optional crates :
65
66- "channels":
67    Depends on `crossbeam-channel`,
68    wrapping channels from it for ffi in `abi_stable::external_types::crossbeam_channel` .
69
70- "serde_json":
71    Depends on `serde_json`,
72    providing ffi-safe equivalents of
73    `&serde_json::value::RawValue` and `Box<serde_json::value::RawValue>`,
74    in `abi_stable::external_types::serde_json` .
75
76
77To disable the default features use:
78```text
79[dependencies.abi_stable]
80version = "<current_version>"
81default-features = false
82features = [  ]
83```
84enabling the features you need in the `features` array.
85
86### Manually enabled
87
88These are crate features to manually enable support for newer language features:
89
90- "rust_1_64": Turns many functions for converting types to slices into const fns.
91
92- "rust_latest_stable":
93Enables the "rust_1_*" features for all the stable releases.
94
95# Glossary
96
97`interface crate`: the crate that declares the public functions, types, and traits that
98are necessary to load a library at runtime.
99
100`ìmplementation crate`: A crate that implements all the functions in a interface crate.
101
102`user crate`: A crate that depends on an `interface crate` and
103loads 1 or more `ìmplementation crate`s for it.
104
105`module`: refers to a struct of function pointers and other static values.
106The root module of a library implements the [`RootModule`] trait.
107These are declared in the `interface crate`,exported in the `implementation crate`,
108and loaded in the `user crate`.
109
110# Rust-to-Rust FFI types.
111
112Types must implement [`StableAbi`] to be safely passed through the FFI boundary,
113which can be done using the [`StableAbi` derive] macro.
114
115For how to evolve dynamically loaded libraries you can look at the [library_evolution] module.
116
117These are the kinds of types passed through FFI:
118
119- Value kind:<br>
120    This is the default kind when deriving StableAbi.
121    The layout of these types must not change in a minor versions.
122
123- [Nonexhaustive enums] :<br>
124    Enums wrapped inside [`NonExhaustive`],
125    which can add variants in minor versions of the library.
126
127- [Trait objects] :<br>
128    Trait object-like types generated using the [`sabi_trait`] attribute macro,
129    which erase the type of the value they wrap,implements the methods of the trait,
130    and can only be unwrapped back to the original type in the dynamic library/binary
131    that created it.
132
133- Opaque kind:<br>
134    Types wrapped in [`DynTrait`],
135    whose layout can change in any version of the library,
136    and can only be unwrapped back to the original type in the dynamic library/binary
137    that created it.
138
139- [Prefix types] :<br>
140    Types only accessible through some custom pointer types,
141    most commonly vtables and modules,
142    which can be extended in minor versions while staying ABI compatible,
143    by adding fields at the end.
144
145# Extra documentation
146
147- [Unsafe code guidelines] :<br>
148    Describes how to write unsafe code ,relating to this library.
149
150- [Troubleshooting] :<br>
151    Some problems and their solutions.
152
153# Macros (derive and attribute)
154
155- [`sabi_trait`] attribute macro:<br>
156    For generating ffi-safe trait objects.
157
158- [`StableAbi` derive] :<br>
159    For asserting abi-stability of a type,
160    and obtaining the layout of the type at runtime.
161
162- [Nonexhaustive enums] :<br>
163    Details for how to declare nonexhaustive enums.
164
165- [Prefix types] \(using the StableAbi derive macro):<br>
166    The way that *vtables* and *modules* are implemented,
167    allowing extending them in minor versions of a library.
168
169[`std_types`]: ./std_types/index.html
170[`external_types`]: ./external_types/index.html
171[prefix types]: ./docs/prefix_types/index.html
172[Prefix types]: ./docs/prefix_types/index.html
173[nonexhaustive enums]: ./docs/sabi_nonexhaustive/index.html
174[Nonexhaustive enums]: ./docs/sabi_nonexhaustive/index.html
175[library_evolution]: ./docs/library_evolution/index.html
176[`NonExhaustive`]: ./nonexhaustive_enum/struct.NonExhaustive.html
177
178[the readme example]:
179https://github.com/rodrimati1992/abi_stable_crates/blob/master/readme.md#readme_example
180
181[`RootModule`]: ./library/trait.RootModule.html
182[`StableAbi`]: ./abi_stability/stable_abi_trait/trait.StableAbi.html
183[`sabi_trait`]: ./attr.sabi_trait.html
184[Trait objects]: ./attr.sabi_trait.html
185[`StableAbi` derive]: ./derive.StableAbi.html
186[`DynTrait`]: ./struct.DynTrait.html
187[Troubleshooting]: ./docs/troubleshooting/index.html
188[Unsafe code guidelines]: ./docs/unsafe_code_guidelines/index.html
189
190*/
191
192// `improper_ctypes` is way too noisy of a lint,
193// every single warning was a false positive.
194// the true positives are caught by the StableAbi trait.
195#![allow(improper_ctypes)]
196#![allow(improper_ctypes_definitions)]
197#![allow(non_camel_case_types)]
198#![deny(unused_must_use)]
199#![warn(rust_2018_idioms)]
200#![allow(clippy::needless_doctest_main)]
201#![allow(clippy::bool_assert_comparison)]
202#![allow(clippy::zero_prefixed_literal)]
203#![allow(clippy::type_complexity)]
204#![allow(clippy::ptr_offset_with_cast)]
205#![allow(clippy::assertions_on_constants)]
206#![deny(missing_docs)]
207#![deny(clippy::missing_safety_doc)]
208// #![deny(clippy::missing_const_for_fn)]
209#![deny(unsafe_op_in_unsafe_fn)]
210#![cfg_attr(feature = "docsrs", feature(doc_cfg))]
211
212#[macro_use]
213extern crate serde_derive;
214
215#[macro_use(StableAbi)]
216extern crate abi_stable_derive;
217
218extern crate self as abi_stable;
219
220include! {"./proc_macro_reexports/get_static_equivalent.rs"}
221include! {"./proc_macro_reexports/export_root_module.rs"}
222include! {"./proc_macro_reexports/sabi_extern_fn.rs"}
223include! {"./proc_macro_reexports/sabi_trait_attribute.rs"}
224include! {"./proc_macro_reexports/stable_abi_derive.rs"}
225
226#[doc(no_inline)]
227pub use abi_stable::sabi_types::{RMut, RRef};
228
229use abi_stable_derive::impl_InterfaceType;
230
231#[doc(hidden)]
232pub use abi_stable_derive::get_root_module_static;
233
234#[macro_use]
235mod impls;
236
237#[macro_use]
238mod internal_macros;
239
240#[macro_use]
241mod macros;
242
243#[cfg(test)]
244#[macro_use]
245mod test_macros;
246
247#[allow(missing_docs)]
248#[cfg(feature = "testing")]
249#[macro_use]
250pub mod test_utils;
251
252#[cfg(test)]
253mod misc_tests;
254
255#[macro_use]
256pub mod utils;
257
258#[macro_use]
259pub mod const_utils;
260
261#[macro_use]
262pub mod traits;
263
264pub mod for_examples;
265
266#[macro_use]
267pub mod abi_stability;
268#[macro_use]
269pub mod erased_types;
270pub mod external_types;
271#[macro_use]
272pub mod library;
273pub mod inline_storage;
274pub mod marker_type;
275mod multikey_map;
276pub mod nonexhaustive_enum;
277pub mod pointer_trait;
278pub mod prefix_type;
279pub mod type_layout;
280
281#[doc(hidden)]
282pub mod derive_macro_reexports;
283
284// `pmr` is what I call "private" reexport for macros in newer crates.
285#[doc(hidden)]
286pub use self::derive_macro_reexports as pmr;
287
288pub mod sabi_types;
289pub mod std_types;
290
291pub mod reflection;
292pub mod type_level;
293
294pub mod docs;
295
296pub mod sabi_trait;
297
298/// The header used to identify the version number of abi_stable
299/// that a dynamic libraries uses.
300pub static LIB_HEADER: library::AbiHeader = library::AbiHeader::VALUE;
301
302/// Miscelaneous items re-exported from core_extensions.
303pub mod reexports {
304    pub use core_extensions::{
305        type_level_bool::{False, True},
306        utils::transmute_ignore_size,
307        SelfOps,
308    };
309}
310
311#[doc(hidden)]
312pub const ABI_STABLE_VERSION: sabi_types::VersionStrings = package_version_strings!();
313
314/*
315I am using this static as the `identity` of this dynamic library/executable,
316this assumes that private static variables don't get merged between
317Rust dynamic libraries that have a different global allocator.
318
319If the address of this is the same among dynamic libraries that have *different*
320allocators,please create an issue for this.
321*/
322use std::sync::atomic::AtomicUsize;
323static EXECUTABLE_IDENTITY: AtomicUsize = AtomicUsize::new(1);
324
325#[doc(inline)]
326pub use crate::{
327    abi_stability::StableAbi,
328    erased_types::{dyn_trait::DynTrait, InterfaceType},
329};
330
331#[doc(hidden)]
332pub mod globals {
333    use crate::{
334        abi_stability::abi_checking::check_layout_compatibility_for_ffi,
335        sabi_types::LateStaticRef,
336        std_types::{RBoxError, RResult},
337        type_layout::TypeLayout,
338        utils::leak_value,
339    };
340
341    #[repr(C)]
342    #[derive(StableAbi)]
343    // #[sabi(debug_print)]
344    pub struct Globals {
345        pub layout_checking:
346            extern "C" fn(&'static TypeLayout, &'static TypeLayout) -> RResult<(), RBoxError>,
347    }
348
349    impl Globals {
350        pub fn new() -> &'static Self {
351            leak_value(Globals {
352                layout_checking: check_layout_compatibility_for_ffi,
353            })
354        }
355    }
356
357    pub(crate) static GLOBALS: LateStaticRef<&Globals> = LateStaticRef::new();
358
359    #[inline(never)]
360    pub fn initialized_globals() -> &'static Globals {
361        GLOBALS.init(Globals::new)
362    }
363
364    #[inline(never)]
365    pub extern "C" fn initialize_globals_with(globs: &'static Globals) {
366        GLOBALS.init(|| globs);
367    }
368}
369
370#[cfg(all(test, not(feature = "testing")))]
371compile_error! { "tests must be run with the \"testing\" feature" }
372
373#[cfg(miri)]
374extern "Rust" {
375    /// Miri-provided extern function to mark the block `ptr` points to as a "root"
376    /// for some static memory. This memory and everything reachable by it is not
377    /// considered leaking even if it still exists when the program terminates.
378    ///
379    /// `ptr` has to point to the beginning of an allocated block.
380    fn miri_static_root(ptr: *const u8);
381}
382
383// Removed readme testing, now the readme code is tested with actual crates.
384// #[cfg(doctest)]
385// #[doc = include_str!("../../readme.md")]
386// pub struct ReadmeTest;