Skip to content

Add rust 1.99, expand tokio and reqwest versions - #16

Merged
wfchandler merged 18 commits into
mainfrom
wc/add-rust-1-99
Oct 8, 2026
Merged

wfchandler merged 18 commits into
mainfrom
wc/add-rust-1-99

Conversation

@wfchandler

Copy link
Copy Markdown
Collaborator

Build with rust 1.99.0, and add it as the primary toolchain for fixtures to build with. Expand tokio coverage to all existing versions past the floor, and cover the latest reqwest as well.

Fix a race condition in task launch in the fixtures.

wfchandler and others added 18 commits October 7, 2026 14:32
The reviewed checksums of tokio's src/macros/select.rs, all five
revisions from 1.47.0 through 1.53.1, and of tracing 0.1.40's
src/instrument.rs differ from the real files by a few nibbles each,
transposed or dropped when the arrays were copied by hand. Nothing
noticed, because a checksum is only compared with a line table's and
rustc's DWARF 4 output carries none.

Replace each with the md5 of the file as the registry ships it. The
interval.rs checksums and tracing's 0.1.42 one were already right.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tokio state protocols, the acquire owners, the layout families
and the rustc conventions are reviewed for whole minors, so a patch
released into a reviewed minor afterwards counts as reviewed without
anyone reading it. tokio 1.51.5 and 1.53.2 are such patches,
backporting fixes into batch_semaphore.rs, the mpsc block list and
notify.rs among others. The select! and Interval::tick reviews name
patches but share the hole: one span from 1.47.0 to 1.53.1 holds
1.51.5.

Record every review's releases as spans of patches. tokio and rustc
get one span per minor, shared as TOKIO_RELEASES and RUSTC_RELEASES,
each ending at the matrix's pin for that minor; other crates keep the
one span they had. A release between two spans is outside: its rules
decline, and extraction warns and refuses unless allowed, naming what
was read of its minor ("tokio 1.51.5 is newer than the supported
version range: 1.51.0-1.51.4").

Each state protocol and the owners map now list the md5 of every
revision of the files they read across those releases. The std
adapter, Pending, refcount and futex conventions list those of the
rust-src files they read. Four tokio revisions shipped only in
releases the matrix never pinned (chan.rs, list.rs, rwlock.rs and
bounded.rs, across 1.47.0-1.47.4, 1.51.0-1.51.2 and 1.52.0-1.52.2);
each was read and differs only in code the reviews do not rely on.

`tokio-info reviewed --toolchain` now reports a bare-minor channel
such as "1.98" as unplaceable, like `stable`: rustup resolves it to
whatever patch is newest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reviews record the checksums of the files they read, but nothing
compares them with the real sources: the select! and tracing ones
were wrong unnoticed, and a span could be raised past a release whose
files changed.

Each matrix cell now hashes every file a review names, at every crate
release its lockfile pins inside the review's releases and in its
toolchain's rust-src. A file matching no listed revision fails the
cell. A test that needs no build holds each tokio and rustc span to
the matrix's newest pin in that minor, so a release is onboarded and
reviewed in one change. matrix.sh installs rust-src with every
toolchain, and the onboarding skill reads the files before `add`.
md-5 joins the dev-dependencies for the hashing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
matrix.sh update skips patches to the floor's and primary's tokio
minors, whose pins advance by hand, and checks only Rust's stable
channel. Once stable moves past a listed minor, that minor's point
releases go unreported: 1.98.1 never appeared, though omicron builds
with it.

Report both. A floor or primary patch is reported with how to advance
the pin, and each listed Rust minor is checked against its own
channel's newest patch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A review's spans hold a pre-release as if it were the release of the
same number, so a nightly or beta rustc counts as the stable one and
a crate's release candidate as the final release. Neither is the code
any review read, yet neither is warned of or refused.

Cover no pre-release. Placed in semver order, a nightly of 1.98.0
falls after the 1.97 span and is warned of against it, like an
unread patch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every crate review but tokio's covers one range of releases, so a
patch backported into an older minor after the review counts as
reviewed: a hyper 1.8.2 released now would fall inside 1.6.0-1.10.1.
The rustls session and hashbrown table reviews record no checksums,
so nothing can show their files unchanged.

Give each review one span per minor, ending at the newest release of
that minor it read, so a later patch to any minor is unreviewed until
read. List every revision of the files the rustls and hashbrown
reviews read, across all 23 and 20 releases in their ranges. Every
release was checked against what each doc claims: the members and
flag assignments rustls's routes and readings rely on are unchanged
throughout, and hashbrown's tables, buckets and control bytes are as
described, with the allocator move the doc names. The hashbrown doc
now names src/control/tag.rs, where is_full lives from 0.15.2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The source check holds each review only at the releases the matrix
cells build: the newest patch of each tokio minor and the listed
toolchains. Every other release inside a review's spans is vouched
for by checksums nothing checks.

Check every one. The matrix run lists each crate's releases inside a
review's spans from the crates.io index, and every rustc patch inside
its spans, and hashes each file the review read in each. Sources come
from cargo's registry or an installed toolchain's rust-src where
present, and are otherwise fetched once into fixtures/sources: 478
releases, about 30 seconds the first time and one after. The per-cell
check it replaces is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tokio 1.52.0 moved the blocking pool's queue out of its Shared into a
ShardedQueue on its Inner: sixteen shards, each a mutex-guarded
VecDeque, a spawn picking one at random. 1.52.1 reverted it after
spawn_blocking was found to hang. Built and extracted, 1.52.0's pool
has no Shared.queue for the walk to bind, so its queued spawn_blocking
cells cannot be listed, though the 1.52 span counts 1.52.0 as
reviewed. A runtime that hangs spawn_blocking is exactly what hansei
exists to examine.

Families select by minor, so none can cover a single patch, and a
versioned row falls back to the highest family below the target, so
an entry for 1.52.0 would serve every later release. Select families
from a table of patch-level ranges, in which a family may appear more
than once, and fall back along each family's lineage instead: 1.52.0
is v1_52_0, a branch of v1_49 that 1.52.1 returns to and v1_53 does
not descend from. A family entry with no route now records its walk
absent by the version, and WalkRoot::EndOfAny roots a row at whichever
of several roles bound, so one set of ring rows reads the pool's one
queue or each shard's.

v1_52_0 declares the shards and each shard's queue, and the reader
reads every ring the pool keeps. 1.52.0 is pinned in the matrix beside
1.52.4, with a span of its own in the reviewed releases and its own
cell, where every walk binds and Shared.queue is absent by the family.
Every other cell and extraction golden gains the two shard rows,
absent, and Shared.queue notes which family's entry it took. Versions
outside the reviews are placed against their own minor's span ("tokio
1.53.2 is newer than ... 1.53.0-1.53.1"), and rustc's warning names
its direction as tokio's does, so a nightly reads as older than its
minor's span. The bundle format moves to 105.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The matrix builds only the newest patch of each minor, or of each
family within one, so a layout an earlier patch moves goes unseen,
though the reviews claim every release in their spans.

HANSEI_MATRIX_ALL=1 adds a cell for every reviewed patch the matrix
does not pin: each tokio patch on the primary toolchain, with a
lockfile derived from the primary one as `matrix.sh add` derives a
pinned one, and each rustc patch with the primary tokio. Each is held
to its span's pinned cell's walk, formats and summary goldens.
Versions, declaration lines and rustc's varying order of dyn
associated-type bindings are normalized first. A format the pin
attaches is required of the patch only for a type the patch's build
declares. A cell that cannot build fails rather than skips. Every
reviewed tokio patch from 1.47.0 through 1.53.0, and rustc 1.97.0 and
1.98.0, matches its pin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1.51.5 backports three fixes into files the tokio protocols were read
from: batch_semaphore sets an Acquire's `queued` before assigning it
permits or linking it, and zeroes its counter on an immediate grant,
so a future dropped mid-poll returns what it holds; the io driver
keeps a registration whose OS deregister failed; and the mpsc block
list compares wrapping indices. None changes what a returned poll
leaves behind, so each protocol's reading holds.

Extend the 1.51 span to 1.51.5, add the new revisions' checksums,
and note each change in its protocol's doc. Pin 1.51.5 in place of
1.51.4: its cell's walk, formats and summary goldens match 1.51.4's,
and its semantics differ only in the order a Ready's delegators are
listed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1.53.2 carries 1.51.5's three fixes into 1.53, batch_semaphore's line
for line, and passes the poll's Context to the trace hook: join,
sleep, io registration, mpsc and oneshot call `trace_leaf(cx)`, and
Notified's `poll_notified` takes the Context in place of its waker.
A bounded OwnedPermit's `send` forgets the permit before sending.
None touches a state a protocol reads.

Extend the 1.53 span to 1.53.2, add the new revisions' checksums,
note the changes in the protocols' docs, and move the tests' unread
1.53 patch to 1.53.3. Pin 1.53.2 in place of 1.53.1, which moves the
latest role's three cells. Their walk, formats and summary goldens
match 1.53.1's. In semantics, async_trace_leaf now awaits a PollFn
over a fn pointer rather than a closure, and under rustc 1.98.1 that
PollFn's poll is inlined, as is the unix connect_addr one in the
stable cell; neither has a rule. The TokioCoop rule is listed later,
renumbering those after it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rust 1.99.0's coroutine variant naming and layout rules, its vtable
entries, and the Arc, Rc, Box and Pin definitions and Future impls
read the same as 1.98's; futex.rs changes only the path it imports
the futex functions from, and future.rs and pending.rs are
unchanged.

Add 1.99.0 to the rustc reviews with checksums for the four library
files that changed, and add it as a secondary toolchain, which
builds the floor, primary and latest tokio cells under it. Their
walk and summary goldens match 1.98.1's. In formats, rustc now lists
a dyn's associated types by name and names the stdio buffers under
alloc::io; nothing matches on either. In semantics, coroutine
suspend states keep fewer anonymous temporaries, so __awaitee
offsets shrink, and a few poll impls and task entries move by
inlining and emission order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The workspace toolchain (rust-toolchain.toml) must equal the matrix's
primary, and a testrun test fails while they differ. Nothing hansei
reads depends on the compiler that built it, so advancing one forces
the other: hansei cannot move to a new release without moving the
fixtures, and with them every golden, off the toolchain deployed
targets are built with.

Drop the test and let the two advance separately. CI installed the
fixtures' toolchain only because rust-toolchain.toml named it; add
fixture-toolchain.sh, which installs the matrix's primary, and call
it from every job that builds fixtures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Build hansei with Rust 1.99.0. The fixtures stay on 1.98.1. Clippy
1.99 flags one needless borrow of a closure passed by value; drop it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1.99.0 replaces 1.98.1 as the primary, so the fixtures build with it:
the full tokio axis and the no-unstable and ct-only cells move to
1.99.0, and 1.98.1 keeps the floor, primary and latest cells a
secondary toolchain builds. regen.sh, the extraction golden test and
exegesis's testlib build name the new primary with it.

The extraction goldens do not change. The new matrix cells differ
from the 1.98.1 cells they replace only as 1.99.0's secondary cells
did: a dyn's associated types listed by name, and the stdio buffers
named under alloc::io. The core goldens change by the floor build's
directory name, std's boxed.rs line numbers, frames 1.99 no longer
inlines in two stacks, one bundle type id, and in http-conns three
tasks' canonical ids. Those three tie on everything the canonical
order compares but their vtable symbol, which names the crate that
instantiated it with a hash each compiler release changes; under
1.99.0, reqwest's connection task sorts after the fixture's own
client's two.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review-drift job reports a release outside the reviews, and a
toolchain the matrix does not build, but nothing says when omicron
moves to a newer tokio or rustc minor than the matrix's primary pin.
The primary is what the fresh-core suites and extraction goldens run,
so it should follow the newest omicron runs, and it advances by hand.

Open one issue per omicron minor newer than the primary's, for tokio
and for rustc, and close it once the primary reaches that minor. A
newer patch within the primary's minor is left to the existing
findings, since the primary is the newest reviewed patch of its minor.
A dry run now reads the real issue lists, so it prints what a run
would open and close.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
omicron's main now locks reqwest 0.13.5, past the cookie layer's
review (through 0.13.4) and the pending request's (through 0.13.2),
so an extraction from a current omicron build refuses.

Read both in each release. The cookie layer's ResponseFuture is
unchanged, and 0.13.5's poll reads the store and URL through the
projection rather than cloning them first, still polling only the
inner future. PendingRequest, Pending and both Future impls are
byte-identical across all three; client.rs moves only in the builder,
the connector and proxy header handling. Extend both spans to 0.13.5
with each new revision's checksum.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
blocking-pool's acceptance test fails in about half of its runs in
the tokio 1.52.0 cell: its queued spawn_blocking cells, and the task
awaiting one of them, have finished by the time the core is taken. A
multi-thread runtime launches each worker as a task on its blocking
pool, and 1.52.0 shards that pool's queue, so a pool thread that
starts late can pop a cell main queued meanwhile and run it before
its worker. Every other release keeps one FIFO queue, where the
launch tasks come first.

Build the runtime in run_builder, wait until each worker has parked
once, which it does only from inside its run loop, and only then run
main, whose type is unchanged. Of 40 captures of that cell, 22 came
up short before and none after. The oxide_tokio_rt::run_builder
frame leaves the main thread's stack in simple-await's trace goldens,
and nine matrix cells' semantics reports move by one PollFn's poll
symbols and the order of two task entries, as the new code shifts
inlining and emission order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wfchandler
wfchandler merged commit 1ea59e8 into main Oct 8, 2026
5 checks passed
@wfchandler
wfchandler deleted the wc/add-rust-1-99 branch October 8, 2026 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant