Skip to content

quasar: fix the zeropod resolution and lint the crates in CI - #125

Merged
mikemaccana merged 3 commits into
mainfrom
claude/quasar-lint-and-zeropod-pin
Aug 20, 2026
Merged

quasar: fix the zeropod resolution and lint the crates in CI#125
mikemaccana merged 3 commits into
mainfrom
claude/quasar-lint-and-zeropod-pin

Conversation

@mikemaccana

Copy link
Copy Markdown
Collaborator

Independent of the Anchor v2 work. Touches only Quasar crates and .github/workflows/quasar.yml.

42 of the 56 Quasar crates do not compile

quasar-lang at the pinned rev asks for zeropod = "0.3.3" and wincode = "0.4". zeropod 0.3.4 moved to wincode 0.5, so a caret range resolves to a zeropod whose PodU16, PodU32 and PodU64 implement wincode 0.5's SchemaWrite, while the macros in quasar-lang name wincode 0.4's. Every u16/u32/u64 instruction argument then fails with the trait bound PodU64: SchemaWrite<...> is not satisfied, and rustc adds there are multiple different versions of crate wincode in the dependency graph.

No lockfile is committed for these crates and CI regenerates one before building, so the resolution is live: a project builds or does not depending on what zeropod has published, not on anything in this repository.

lending, perpetual-futures and prop-amm already carried the zeropod = "=0.3.3" pin with a comment explaining exactly this. The other 53 did not. Same pin, same comment, applied everywhere.

Nothing has ever linted them

Each Quasar crate declares its own [workspace], because quasar build runs cargo metadata --locked against a per-project lockfile. They therefore cannot be members of the root workspace, and the repository-wide Rust Lint workflow only ever sees members. The Quasar workflow builds and tests them but never lints them.

51 of 56 had formatting diffs and 42 had clippy findings. Most fixes were mechanical. Three were not:

  • Account structs reported fields as never read, because mod instructions; kept the structs crate-private even though their fields were pub. The modules are pub now, which is what most of the Anchor examples already do and what a client needs to name the accounts.
  • MAX_URI_LEN in cutils was named by two comments and enforced by nothing. The String<256, 2> bound is what actually caps the URI, so the constant is gone and the comments say so.
  • handle_init_mint took ten arguments. The three extension authorities and the three metadata fields are now MintAuthorities and MintMetadata.

A new lint job runs the same two commands the repository-wide job runs. It walks Cargo manifests naming quasar-lang rather than reusing the build job's project list, which is directories named exactly quasar and so misses tokens/quasar-metadata, a vendored library three examples depend on. Linting needs neither the Quasar CLI nor platform-tools and does not vary by Solana version, so it runs once rather than once per matrix entry, and reports every failing crate rather than stopping at the first.

Verification

Ran against this branch, not the branch it was extracted from: all 56 crates pass cargo fmt --check and cargo clippy -- -D warnings. Main gained funding-rate tests in finance/perpetual-futures/quasar after the original work, and those were unformatted; this branch formats them too.

The build and test path was verified with the Quasar CLI installed at the pinned rev, running the workflow's own sequence of quasar build then cargo test per project: 197 tests pass.


Generated by Claude Code

claude added 3 commits August 19, 2026 22:56
`quasar-lang` at the pinned rev asks for `zeropod = "0.3.3"` and
`wincode = "0.4"`. zeropod 0.3.4 moved to wincode 0.5, so a caret range
resolves to a zeropod whose `PodU16`, `PodU32` and `PodU64` implement
wincode 0.5's `SchemaWrite`, while the macros in quasar-lang name wincode
0.4's. Every u16/u32/u64 instruction argument then fails to compile with
"the trait bound `PodU64: SchemaWrite<...>` is not satisfied", and rustc
adds "there are multiple different versions of crate `wincode` in the
dependency graph".

No lockfile is committed for these crates and CI regenerates one before
building, so the resolution is live: a project builds or does not depending
on what zeropod has published, not on anything in this repository.

lending, perpetual-futures and prop-amm already carried this pin. The other
53 did not, and 42 of them did not compile. Same pin, same comment, applied
everywhere.

(cherry picked from commit 6444919)
None of these crates has ever been formatted or linted: they each declare
their own `[workspace]`, and the repository-wide jobs only see members of the
root workspace. 51 of 56 had formatting diffs and 42 had clippy findings.

Formatting is `cargo fmt` with the repository's own rustfmt.toml, which they
pick up already by sitting under it.

The lint fixes:

- Account structs reported fields as never read, because `mod instructions;`
  kept the structs crate-private even though their fields were `pub`. The
  modules are `pub` now, which is what the majority of the Anchor examples
  already do and what a client needs to name the accounts.
- Needless borrows of `.address()`, which returns a reference already.
- `for i in 0..n { views[k + i] = src[i].clone() }` over account views, which
  is `clone_from_slice` on the corresponding subslice.
- `&[signer.clone()]` where `core::slice::from_ref(&signer)` does not clone.
- `(b'0'..=b'9').contains(&byte)` is `byte.is_ascii_digit()`.
- Redundant field names, a useless `u16` conversion, a manual `div_ceil`, a
  manual `!RangeInclusive::contains`, and a doc comment separated from its
  item by a blank line.
- `MAX_URI_LEN` in cutils was named only by two comments and enforced by
  nothing; the `String<256, 2>` bound is what actually caps the URI, so the
  constant is gone and the comments say so.
- `handle_init_mint` took ten arguments. The three extension authorities and
  the three metadata fields are now `MintAuthorities` and `MintMetadata`.

All Quasar projects build with `quasar build` and pass `cargo test`: 197
tests across 56 crates.

(cherry picked from commit dcee536)
The `Rust Lint` workflow runs `cargo fmt --check` and `cargo clippy` from the
repository root, which only ever sees members of the root workspace. Every
Quasar crate declares its own `[workspace]`, because `quasar build` runs
`cargo metadata --locked` against a per-project lockfile, so they cannot be
members and that workflow has never seen them. The Quasar workflow builds and
tests them but does not lint them.

This adds a `lint` job running the same two commands the repository-wide job
runs, including the `diverging_sub_expression` allowance.

It walks Cargo manifests that name `quasar-lang` rather than reusing
`build-and-test`'s project list, which is directories named exactly `quasar`.
That list misses `tokens/quasar-metadata`, a vendored library three of the
examples depend on. Linting is a host build needing neither the Quasar CLI nor
platform-tools, and does not vary by Solana version, so it runs once rather
than once per matrix entry. It reports every failing crate rather than
stopping at the first.
@mikemaccana
mikemaccana merged commit e48fbf7 into main Aug 20, 2026
41 checks passed
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.

2 participants