1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
//! [![github]](https://github.com/dtolnay/linkme) [![crates-io]](https://crates.io/crates/linkme) [![docs-rs]](https://docs.rs/linkme)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! <br>
//!
//! **A library for safe cross-platform linker shenanigans.**
//!
//! <br>
//!
//! # Platform support
//!
//! | Component | Linux | macOS | Windows | FreeBSD | illumos | Other...<sup>†</sup> |
//! |:---|:---:|:---:|:---:|:---:|:---:|:---:|
//! | Distributed slice | 💚 | 💚 | 💚 | 💚 | 💚 | |
//!
//! <br>***<sup>†</sup>*** We welcome PRs adding support for any platforms not
//! listed here.
//!
//! <br>
//!
//! # Distributed slice
//!
//! A distributed slice is a collection of static elements that are gathered
//! into a contiguous section of the binary by the linker. Slice elements may be
//! defined individually from anywhere in the dependency graph of the final
//! binary.
//!
//! Refer to [`linkme::DistributedSlice`][DistributedSlice] for complete details
//! of the API. The basic idea is as follows.
//!
//! A static distributed slice is declared by writing `#[distributed_slice]` on
//! a static item whose type is `[T]` for some type `T`.
//!
//! ```
//! # #![cfg_attr(feature = "used_linker", feature(used_with_arg))]
//! #
//! # struct Bencher;
//! #
//! use linkme::distributed_slice;
//!
//! #[distributed_slice]
//! pub static BENCHMARKS: [fn(&mut Bencher)];
//! ```
//!
//! Slice elements may be registered into a distributed slice by a
//! `#[distributed_slice(...)]` attribute in which the path to the distributed
//! slice is given in the parentheses. The initializer is required to be a const
//! expression.
//!
//! ```
//! # #![cfg_attr(feature = "used_linker", feature(used_with_arg))]
//! #
//! # mod other_crate {
//! # use linkme::distributed_slice;
//! #
//! # pub struct Bencher;
//! #
//! # #[distributed_slice]
//! # pub static BENCHMARKS: [fn(&mut Bencher)];
//! # }
//! #
//! # use other_crate::Bencher;
//! #
//! use linkme::distributed_slice;
//! use other_crate::BENCHMARKS;
//!
//! #[distributed_slice(BENCHMARKS)]
//! static BENCH_DESERIALIZE: fn(&mut Bencher) = bench_deserialize;
//!
//! fn bench_deserialize(b: &mut Bencher) {
//! /* ... */
//! }
//! ```
//!
//! The distributed slice behaves in all ways like `&'static [T]`.
//!
//! ```no_run
//! # #![cfg_attr(feature = "used_linker", feature(used_with_arg))]
//! #
//! # use linkme::distributed_slice;
//! #
//! # struct Bencher;
//! #
//! # #[distributed_slice]
//! # static BENCHMARKS: [fn(&mut Bencher)];
//! #
//! fn main() {
//! // Iterate the elements.
//! for bench in BENCHMARKS {
//! /* ... */
//! }
//!
//! // Index into the elements.
//! let first = BENCHMARKS[0];
//!
//! // Slice the elements.
//! let except_first = &BENCHMARKS[1..];
//!
//! // Invoke methods on the underlying slice.
//! let len = BENCHMARKS.len();
//! }
//! ```
//!
//! <br>
//!
//! <details>
//! <summary>Workaround for buggy IDEs</summary>
//!
//! JetBrains's Rust IDE uses an outdated Rust parser that treats distributed
//! slice declarations as invalid syntax, despite being supported in stable
//! rustc for over 3.5 years.
//! See <https://youtrack.jetbrains.com/issue/RUST-12953>.
//!
//! If you hit this, you can work around it by adding a dummy initializer
//! expression to the slice.
//!
//! ```
//! # #![cfg_attr(feature = "used_linker", feature(used_with_arg))]
//! #
//! # use linkme::distributed_slice;
//! #
//! # struct Bencher;
//! #
//! #[distributed_slice]
//! pub static BENCHMARKS: [fn(&mut Bencher)] = [..];
//! #
//! # const _: &str = stringify! {
//! ^^^^^^
//! # };
//! ```
//! </details>
#![no_std]
#![doc(html_root_url = "https://docs.rs/linkme/0.3.26")]
#![deny(unsafe_op_in_unsafe_fn)]
#![allow(
clippy::doc_markdown,
clippy::empty_enum,
clippy::expl_impl_clone_on_copy,
clippy::manual_assert,
clippy::missing_panics_doc,
clippy::missing_safety_doc,
clippy::must_use_candidate,
clippy::unused_self
)]
mod distributed_slice;
// Not public API.
#[doc(hidden)]
#[path = "private.rs"]
pub mod __private;
pub use linkme_impl::*;
pub use crate::distributed_slice::DistributedSlice;