gen_statem: GenStatem* type prefix + cleanup
- rename StatemRef/StatemCallError/StatemSendError -> GenStatem*
- move the inline unit test out of src; consolidate the Switch coverage
onto a single macro-driven harness in tests/gen_statem.rs
- drop the redundant hand-written Switch test machine and the two
untracked rejected-direction probes (succ_enums, typed_edges)
- rename examples statem_{fused,macro}.rs -> gen_statem_{fused,macro}.rs
- strip RFC/chunk/spike provenance and fix the mislabeled "throwaway"
example header and dead cross-references
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
//! SPIKE (throwaway) — RFC 017 "fused" approach.
|
||||
//! The hand-written **expansion target** of the `gen_statem!` macro: the same
|
||||
//! machine as `examples/gen_statem_macro.rs`, written out in full so the
|
||||
//! primitives can be judged standing on their own. The macro generates exactly
|
||||
//! this shape; nothing here needs the macro to be correct or safe.
|
||||
//!
|
||||
//! This is the hand-written *expansion target* of the eventual `statem!` macro,
|
||||
//! written out in full so the primitives can be judged standing on their own.
|
||||
//! A macro would generate exactly this from a `transitions { … }` block; nothing
|
||||
//! here needs the macro to be correct or safe.
|
||||
//!
|
||||
//! The design, as settled over the prior iterations:
|
||||
//! The design:
|
||||
//!
|
||||
//! * States and events are real enums. An invalid state is unrepresentable;
|
||||
//! there are no bitflags, no `u32` superpositions, no unsafe unions.
|
||||
@@ -27,18 +25,18 @@
|
||||
//! wired in is dead code — and dead_code is denied below, making an orphan
|
||||
//! handler a compile error.
|
||||
//!
|
||||
//! * Drops onto the committed `Machine` / `Resolution` / `Cx` primitives with
|
||||
//! no change to `src/statem.rs`.
|
||||
//! * Drops onto the `Machine` / `Resolution` / `Cx` primitives with no change
|
||||
//! to `src/gen_statem.rs`.
|
||||
//!
|
||||
//! Default build is clean and runs. A BREAK-CASE MENU at the bottom documents
|
||||
//! how to make each of the four guarantees fire.
|
||||
//!
|
||||
//! Run: `cargo run --example statem_fused`
|
||||
//! Run: `cargo run --example gen_statem_fused`
|
||||
|
||||
#![deny(dead_code, unreachable_patterns)]
|
||||
|
||||
use smarm::run;
|
||||
use smarm::gen_statem::{spawn, Cx, Machine, Reply, Resolution, StatemRef};
|
||||
use smarm::gen_statem::{spawn, Cx, Machine, Reply, Resolution, GenStatemRef};
|
||||
|
||||
// === user types ============================================================
|
||||
|
||||
@@ -114,7 +112,7 @@ struct DoorSm {
|
||||
}
|
||||
|
||||
impl DoorSm {
|
||||
fn start(init: Door) -> StatemRef<DoorSm> {
|
||||
fn start(init: Door) -> GenStatemRef<DoorSm> {
|
||||
spawn(DoorSm {
|
||||
state: init,
|
||||
data: Data { enters: 0, pushes: 0 },
|
||||
@@ -184,7 +182,7 @@ impl Machine for DoorSm {
|
||||
self.state = s; // sole writer of the state cell
|
||||
self.enter(cx);
|
||||
}
|
||||
Resolution::Postpone => unreachable!("postpone lands in chunk 3"),
|
||||
Resolution::Postpone => unreachable!("postpone is not generated yet"),
|
||||
Resolution::Unhandled => cx.on_unhandled(),
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
//! RFC 017 — the **same** machine as `examples/statem_fused.rs`, written through
|
||||
//! the `gen_statem!` macro. Diff this file against that one to see exactly what
|
||||
//! the macro buys: every `// ===` section there that was boilerplate (the `Ev`
|
||||
//! The **same** machine as `examples/gen_statem_fused.rs`, written through the
|
||||
//! `gen_statem!` macro. Diff this file against that one to see exactly what the
|
||||
//! macro buys: every `// ===` section there that was boilerplate (the `Ev`
|
||||
//! enum, the `DoorSm` struct, `start`, the whole `Machine` impl, the `enter`
|
||||
//! dispatch, the stay/transition apply-tail) collapses into the invocation
|
||||
//! below. What stays hand-written is what carries meaning: the four types, the
|
||||
//! per-state successor enum, and the handler fns.
|
||||
//!
|
||||
//! The point of the exercise is that the macro is *pure sugar*: the four
|
||||
//! compile-time guarantees the fused spike demonstrates are properties of the
|
||||
//! emitted code, not of the macro, so they survive expansion unchanged. The
|
||||
//! compile-time guarantees the hand-written form demonstrates are properties of
|
||||
//! the emitted code, not of the macro, so they survive expansion unchanged. The
|
||||
//! BREAK-CASE MENU at the bottom is the same four cases, re-expressed against
|
||||
//! the macro surface — flip any one on and the compiler fires identically.
|
||||
//!
|
||||
//! Run: `cargo run --example statem_macro`
|
||||
//! Run: `cargo run --example gen_statem_macro`
|
||||
|
||||
#![deny(dead_code)] // guarantee #3 (orphan handlers); the macro denies the
|
||||
// dispatch's own unreachable_patterns internally.
|
||||
@@ -21,7 +21,7 @@ use smarm::gen_statem;
|
||||
use smarm::run;
|
||||
use smarm::gen_statem::Reply;
|
||||
|
||||
// === user types (identical to statem_fused.rs) =============================
|
||||
// === user types (identical to gen_statem_fused.rs) =========================
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
enum Door {
|
||||
@@ -91,7 +91,7 @@ gen_statem! {
|
||||
|
||||
// You name the bindings the bodies use; the macro can't lend you its own
|
||||
// `self`/`cx` across macro hygiene. `data` = &mut Data, `prev` = current
|
||||
// state tag, `cx` = context handle (unused in chunk 1).
|
||||
// state tag, `cx` = context handle (unused here).
|
||||
context(data, prev, cx);
|
||||
|
||||
enter {
|
||||
@@ -145,7 +145,7 @@ fn main() {
|
||||
|
||||
// ===========================================================================
|
||||
// BREAK-CASE MENU — the four guarantees, through the macro. Each fires exactly
|
||||
// as it does in the hand-written statem_fused.rs.
|
||||
// as it does in the hand-written gen_statem_fused.rs.
|
||||
//
|
||||
// 1. ORPHAN HANDLER (dead_code -> error):
|
||||
// add `fn on_slam(_d: &mut Data) {}` and don't reference it.
|
||||
@@ -157,8 +157,8 @@ fn main() {
|
||||
// NOTE: this example is a separate crate from `smarm`, so rustc's
|
||||
// in_external_macro rule SILENCES this lint here even though the macro
|
||||
// denies it — the duplicate compiles. The guarantee is real only for
|
||||
// machines defined inside the smarm crate (see the unit test in
|
||||
// src/statem.rs). This is the documented macro_rules! limitation.
|
||||
// machines defined inside the `smarm` crate itself. This is the documented
|
||||
// macro_rules! limitation.
|
||||
//
|
||||
// 3. MISSING PAIR (non-exhaustive match, E0004):
|
||||
// delete the `cast Cast::Push | Cast::Pull | Cast::Lock => unhandled,`
|
||||
Reference in New Issue
Block a user