Status: Superseded by ADR-305 — its D1-D4 are D4-D7 there
Date: September 26, 2026
Target Version: Nikaia 0.0.201
Answers: the owner’s is the codebase compatible with Rust 1.94 and
Edition 2024’s stricter scoping at .await points, or do we need to change
them? 1.94 as the new minimum would be fine
Related: ADR-219 (the floor, which stays 1.88),
ADR-218 (the unsafe crates), ADR-298 (the names
the language below reserves)
Edition 2024 changes when some values are dropped. That matters at .await,
because a guard or borrow that lives past a pause is held for the whole pause
and makes a future !Send. There are two changes:
tail_expr_drop_order: the temporaries of a block’s tail expression are
dropped before the block’s locals, not after them.if_let_rescope: the scrutinee’s temporaries in if let … else are dropped
before the else branch, not at the end of the whole if.Both make values live shorter, never longer. So a program that compiled
under 2021 cannot start holding a lock across an .await because of them. What
can change is an order of Drop that someone relied on.
Rust 1.94.1’s migration lints (cargo fix --edition) were run over
crates/nikaia, crates/nikaia-std, crates/orchestrator and the six crates
under crates/unsafe/:
| lint | hits | verdict |
|---|---|---|
if_let_rescope |
0 | — |
tail_expr_drop_order |
10 | benign: each drops a temporary (a Result, an Option just taken, a poll’s return value) that holds no lock and has no Drop anyone observes. Three are in the runtime (net.rs accept, exec.rs poll and the task’s value.take()), none across an .await |
impl_trait_overcaptures |
1 | branch_values in the emitter, + use<'_> added |
edition_2024_expr_fragment_specifier |
1 | a diagnostics macro, now expr_2021 |
Then the edition was switched and the whole suite was run, including every
program the tests emit, compiled as 2024. Two things broke, both in the
emitted code and neither about .await:
extern "C" { … } has to be unsafe extern "C" { … };gen is a reserved word, so a Nikaia name gen has to reach Rust as r#gen.Clippy under 2024 also asks for let chains where two if let were nested. That
is style, applied with clippy --fix, and rustfmt’s 2024 style sorts imports
differently. Neither changes behaviour.
.await point needs a change.This is the answer to the question. The drop-order changes make temporaries live shorter. None of the ten places holds anything across a pause, and the suite, which runs the runtime’s async paths, passes unchanged.
This covers crates/nikaia, crates/nikaia-std, crates/orchestrator and
every crate under crates/unsafe/. The benchmark crates under benches/ stay
This covers every generated Cargo.toml, the grammar runner’s manifest, and the
tests’ rustc --edition. The emitter writes unsafe extern "C". gen joins
the emitter’s list of words the language below reserves, and the sweep in
tests/reserved_below.rs compiles it escaped in every position.
Edition 2024 needs Rust 1.85, and let chains need 1.88, which is already the
floor (ADR-219). Nothing measured needs 1.94, so raising the floor would lock
out 1.88 through 1.93 for nothing. scripts/check-floor.sh passes on 1.88.0
with everything on 2024.
All of it, in 0.0.201.