diff --git a/src/gen_server.rs b/src/gen_server.rs index 73dd2fb..5d69bb3 100644 --- a/src/gen_server.rs +++ b/src/gen_server.rs @@ -301,7 +301,7 @@ pub trait GenServer: Send + 'static { /// full idle window (set via [`GenServerCtx::idle_after`] in `init`) without /// dispatching any message. The window resets automatically after this /// fires, so it acts as a steady idle detector. To shut down after one idle - /// period, call [`request_stop`](crate::scheduler::request_stop) here. + /// period, call [`request_stop`] here. /// Default: no-op. fn handle_idle(&mut self) {} @@ -814,7 +814,7 @@ impl GenServerBuilder { self } - /// Spawn the server under an explicit supervisor pid (via [`spawn_under`]) + /// Spawn the server under an explicit supervisor pid (via [`spawn_under`](crate::scheduler::spawn_under)) /// so it slots into the supervision tree. pub fn under(mut self, supervisor: Pid) -> Self { self.supervisor = Some(supervisor); @@ -1032,14 +1032,14 @@ pub fn shutdown(name: GenServerName) { } } -/// Spawn `state` as a server under the current actor (via [`spawn`]). Returns a +/// Spawn `state` as a server under the current actor (via [`spawn`](crate::scheduler::spawn)). Returns a /// [`GenServerRef`]. Shorthand for `GenServerBuilder::new(state).start()`. pub fn start(state: G) -> GenServerRef { GenServerBuilder::new(state).start() } /// Like [`start`], but spawns the server under an explicit supervisor pid (via -/// [`spawn_under`]) so it slots into the supervision tree. +/// [`spawn_under`](crate::scheduler::spawn_under)) so it slots into the supervision tree. pub fn start_under(supervisor: Pid, state: G) -> GenServerRef { GenServerBuilder::new(state).under(supervisor).start() } diff --git a/src/introspect.rs b/src/introspect.rs index ace3b26..0ecd1f7 100644 --- a/src/introspect.rs +++ b/src/introspect.rs @@ -191,8 +191,8 @@ pub struct ActorInfo { /// [`Stack::new`](crate::stack::Stack::new) rounds them. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct StackInfo { - /// Usable stack size ([`SpawnOpts::stack_reserve`] - /// (crate::SpawnOpts::stack_reserve) or the Config/default). + /// Usable stack size ([`SpawnOpts::stack_reserve`](crate::SpawnOpts::stack_reserve) + /// or the Config/default). pub reserve: usize, /// PROT_NONE guard below the usable region. pub guard: usize, diff --git a/src/lib.rs b/src/lib.rs index b48af52..7e54c70 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,15 @@ //! //! See `LOOM.md` for the design intent and the deferred-for-later list. +// Docs are part of the contract: broken/private intra-doc links fail `cargo doc`, +// and every doctest is compiled with `deny(warnings)` under `cargo test --doc`. +#![deny(rustdoc::broken_intra_doc_links)] +#![deny(rustdoc::private_intra_doc_links)] +#![deny(rustdoc::redundant_explicit_links)] +#![deny(rustdoc::invalid_codeblock_attributes)] +#![deny(rustdoc::invalid_rust_codeblocks)] +#![doc(test(attr(deny(warnings))))] + pub mod actor; pub mod causal; pub mod channel; diff --git a/src/pid.rs b/src/pid.rs index 96b3f21..729d67e 100644 --- a/src/pid.rs +++ b/src/pid.rs @@ -76,7 +76,7 @@ pub struct Pid { impl Pid { /// Build an untyped pid from raw numbers. The runtime mints identities - /// here; typing happens at typed-actor boundaries via [`Pid::from_raw`]. + /// here; typing happens at typed-actor boundaries via `Pid::from_raw`. #[inline] pub const fn new(index: u32, generation: u32) -> Self { Self { diff --git a/src/registry.rs b/src/registry.rs index 7c20b1d..24b1496 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -10,7 +10,7 @@ //! directly, without ever having been handed a `Pid`. //! //! ``` -//! use smarm::{channel, register, run, send, spawn, unregister, whereis, Name}; +//! use smarm::{channel, register, run, send, spawn, whereis, Name}; //! //! const COUNTER: Name = Name::new("counter"); //! diff --git a/src/run_queue.rs b/src/run_queue.rs index a2d1187..0ff932c 100644 --- a/src/run_queue.rs +++ b/src/run_queue.rs @@ -18,7 +18,7 @@ //! //! All variants are compiled unconditionally (so every build runs every //! variant's unit tests); the feature only picks which one the runtime uses -//! via the [`RunQueue`] alias. +//! via the `RunQueue` alias. //! //! # Contract (shared by all variants) //! diff --git a/src/runtime.rs b/src/runtime.rs index 231ea50..0970a77 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -76,7 +76,7 @@ //! time (`rq-mutex` / `rq-mpmc` / `rq-striped`). Queue ops require //! preemption disabled (debug-asserted there); when the mutex variant is in //! play it is the innermost lock — nothing else is acquired under it. -//! - Per-slot `cold` locks ([`RawMutex`], non-poisoning, guard enters +//! - Per-slot `cold` locks (`RawMutex`, non-poisoning, guard enters //! `NoPreempt`) guard the lifecycle collections. **Leaf rule: never hold //! two cold locks at once** — `finalize_actor`'s link cascade and `link()` //! lock peers one at a time (correctness arguments at the call sites). @@ -144,13 +144,13 @@ pub const DEFAULT_MAX_ACTORS: usize = 16_384; /// use smarm::runtime::Config; /// /// // Use all available CPUs (default): -/// let c = Config::default(); +/// let _all = Config::default(); /// /// // Exactly 4 scheduler threads: -/// let c = Config::exact(4); +/// let _four = Config::exact(4); /// /// // Between 2 and 8, clamped to available parallelism: -/// let c = Config::new(2, 8, None); +/// let _clamped = Config::new(2, 8, None); /// ``` #[derive(Clone, Debug)] pub struct Config { diff --git a/src/scheduler.rs b/src/scheduler.rs index 5e398d5..25f15de 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -263,6 +263,7 @@ impl Drop for JoinHandle { /// ``` /// use smarm::SpawnOpts; /// let opts = SpawnOpts { stack_reserve: Some(8 * 1024 * 1024), ..SpawnOpts::default() }; +/// assert_eq!(opts.stack_reserve, Some(8 * 1024 * 1024)); /// ``` /// /// Both sizes are page-rounded. The reserve is *virtual* (demand-paged): @@ -286,8 +287,8 @@ pub struct SpawnOpts { #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum SpawnError { - /// The fixed actor slab ([`Config::max_actors`] - /// (crate::runtime::Config::max_actors)) is full: every slot is claimed + /// The fixed actor slab ([`Config::max_actors`](crate::runtime::Config::max_actors)) + /// is full: every slot is claimed /// by a live actor. This is a routine overload condition, not an /// invariant violation — shed the unit of work (close the socket, /// return a 503) and try again once actors have died. @@ -371,7 +372,7 @@ pub fn spawn_under_with( } } -/// [`spawn`] and [`monitor`](crate::monitor) the child in one step, with no +/// [`spawn`] and [`monitor`](crate::monitor()) the child in one step, with no /// window in which the child can die unobserved. /// /// `spawn` followed by `monitor(h.pid())` races: on a multi-scheduler