From dcf3a897d1c4818b6d421de2e2f2544ea7448869 Mon Sep 17 00:00:00 2001 From: Oleks Date: Mon, 1 Jun 2026 11:28:48 +0300 Subject: [PATCH] Initial commit: rust-craft plugin Rust-on-NixOS knowledge plugin. Relocates plugin.json into .claude-plugin/ so it loads as a proper plugin, and adds README/LICENSE/.gitignore for distribution. Skill rust-nix-toolchain (Cranelift vs LLVM codegen, fenix nightly pins, cargo/clippy gates) with cranelift-limitations reference. --- .claude-plugin/plugin.json | 21 +++ .gitignore | 3 + CLAUDE.md | 7 + LICENSE | 21 +++ README.md | 23 +++ skills/rust-nix-toolchain/SKILL.md | 138 ++++++++++++++++++ .../references/cranelift-limitations.md | 66 +++++++++ 7 files changed, 279 insertions(+) create mode 100644 .claude-plugin/plugin.json create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 skills/rust-nix-toolchain/SKILL.md create mode 100644 skills/rust-nix-toolchain/references/cranelift-limitations.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..055c73a --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,21 @@ +{ + "name": "rust-craft", + "version": "1.0.0", + "description": "Rust development on NixOS — toolchain management (fenix nightly pins), codegen backends (Cranelift vs LLVM), clippy/cargo quality-gate workflows, and common pitfalls.", + "author": { + "name": "oleks", + "email": "plugins@oleks.space" + }, + "repository": "https://claude-plugins.oleks.space/plugins/rust-craft.git", + "license": "MIT", + "keywords": [ + "rust", + "nixos", + "fenix", + "cranelift", + "llvm", + "clippy", + "cargo", + "toolchain" + ] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8cc0620 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.cache/ +.claude/ +*.log diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..eb4de44 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,7 @@ +# rust-craft Plugin + +Rust development knowledge for NixOS environments — toolchain management, codegen backends, and common pitfalls. + +## Skills + +- **rust-nix-toolchain**: Cranelift vs LLVM codegen backend issues, NixOS fenix toolchain management, cargo quality gate patterns diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..67d98b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Oleks Kuksenko + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..09ee788 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# claude-plugin-rust-craft + +Claude Code plugin — Rust development knowledge for NixOS environments: toolchain management, codegen backends, and common pitfalls. + +## Installation + +Add to your Claude Code plugin list or install from the [plugin registry](https://claude-plugins.oleks.space): + +``` +claude plugin add https://claude-plugins.oleks.space/plugins/rust-craft.git +``` + +## Usage + +Skills from this plugin are automatically available in Claude Code conversations when installed. + +## Skills + +- **rust-nix-toolchain** — Cranelift vs LLVM codegen backend issues (`asm!`/`global_asm!` sym operands, wasmtime-fiber failures, "cargo test fails but cargo check works"), NixOS fenix nightly toolchain pins, and cargo/clippy quality-gate patterns. See `skills/rust-nix-toolchain/references/cranelift-limitations.md`. + +## License + +MIT diff --git a/skills/rust-nix-toolchain/SKILL.md b/skills/rust-nix-toolchain/SKILL.md new file mode 100644 index 0000000..2b7a47d --- /dev/null +++ b/skills/rust-nix-toolchain/SKILL.md @@ -0,0 +1,138 @@ +--- +name: rust-nix-toolchain +description: >- + This skill should be used when the user encounters + "asm! and global_asm! sym operands are not yet supported", + "wasmtime-fiber" compilation failures, + "cargo test fails but cargo check works", + "cranelift codegen backend" issues, + "update Rust nightly on NixOS", + "fenix toolchain pin", + or mentions Rust codegen backend problems on NixOS. + Covers the Cranelift vs LLVM codegen backend split, + NixOS fenix toolchain management, and common + Rust nightly pitfalls. +--- + +# Rust Nightly Toolchain on NixOS + +## Cranelift vs LLVM Codegen Backend + +NixOS dev setups commonly use `codegen-backend = "cranelift"` in `~/.cargo/config.toml` for faster dev builds. **Cranelift does NOT support `global_asm! { sym }` operands.** This causes `wasmtime-fiber` and other crates using `global_asm!` with `sym` to fail. + +### Symptom + +``` +error: asm! and global_asm! sym operands are not yet supported + --> wasmtime-fiber-28.0.1/src/stackswitch/x86_64.rs +``` + +### Why `cargo check` works but `cargo test` fails + +- `cargo check` / `cargo clippy` only verify types and borrow checking — **no codegen** +- `cargo test` / `cargo build` invoke the codegen backend, hitting the Cranelift limitation +- This makes the error appear only at test/build time, not during linting + +### Fix: Override codegen backend for tests + +```bash +# One-shot: force LLVM for this test run +CARGO_PROFILE_DEV_CODEGEN_BACKEND=llvm cargo test --lib + +# Or permanently in the project's .cargo/config.toml: +# [profile.dev] +# codegen-backend = "llvm" +``` + +### Where the Cranelift backend is configured + +Check `~/.cargo/config.toml`: + +```toml +[profile.dev] +codegen-backend = "cranelift" # faster codegen for dev builds + +[unstable] +codegen-backend = true +``` + +This is a **user-level** config that affects all projects. Project-level `.cargo/config.toml` can override it. + +## NixOS Fenix Toolchain Management + +### How the Rust nightly is pinned + +On NixOS with fenix, the Rust nightly version is determined by: + +1. **`flake.nix`** declares fenix input: `fenix.url = "github:nix-community/fenix"` +2. **`flake.lock`** pins a specific fenix commit, which bundles nightly manifests +3. **NixOS module** (e.g. `nixos/rust-dev.nix`) selects components: + +```nix +rust-nightly = fenix.packages.${pkgs.stdenv.hostPlatform.system}.complete.withComponents [ + "cargo" "clippy" "rustc" "rustfmt" + "rust-src" "rust-analyzer" + "rustc-codegen-cranelift-preview" +]; +``` + +### Updating the nightly + +```bash +cd ~/projects/servers/ +nix flake update fenix +sudo nixos-rebuild switch --flake '.#' +``` + +This pulls the latest fenix commit which includes the most recent nightly. + +### Pinning a specific nightly date + +Replace `complete.withComponents` with `toolchainOf`: + +```nix +rust-nightly = fenix.packages.${system}.toolchainOf { + channel = "nightly"; + date = "2026-03-15"; + sha256 = ""; # required for pure evaluation +}.withComponents [ "cargo" "clippy" "rustc" "rustfmt" "rust-src" ]; +``` + +## Cargo Quality Gate + +Standard Rust quality gate sequence: + +```bash +# 1. Format +cargo fmt + +# 2. Lint (zero warnings required) +cargo clippy --all --benches --tests --examples --all-features + +# 3. Test (use LLVM if Cranelift is default) +CARGO_PROFILE_DEV_CODEGEN_BACKEND=llvm cargo test --lib +``` + +### Common clippy patterns + +| Warning | Fix | +|---------|-----| +| `collapsible_match` / `collapsible_if` | Merge nested `if` into match guard: `Variant if condition => { ... }` | +| `new_without_default` | Add `impl Default for T { fn default() -> Self { Self::new() } }` | +| `let_unit_value` | Remove `let _ =` from expressions returning `()` | +| `unnecessary_sort_by` | Use `sort_by_key(|x| Reverse(x.field))` instead of `sort_by(|a, b| b.field.cmp(&a.field))` | +| `derivable_impls` | Replace manual `impl Default` with `#[derive(Default)]` | +| `manual_map` | Replace `if let Some(x) = opt { Some(f(x)) } else { None }` with `opt.map(f)` | +| `useless_conversion` | Remove redundant `.into_iter()` on values already implementing `IntoIterator` | + +### Feature-gated fields in tests + +When a struct has `#[cfg(feature = "...")]` fields, tests compiled with `--all-features` must include those fields: + +```rust +let cfg = MyConfig { + normal_field: value, + #[cfg(feature = "discord")] + discord: None, // must be present when feature is active +}; +``` diff --git a/skills/rust-nix-toolchain/references/cranelift-limitations.md b/skills/rust-nix-toolchain/references/cranelift-limitations.md new file mode 100644 index 0000000..030bd07 --- /dev/null +++ b/skills/rust-nix-toolchain/references/cranelift-limitations.md @@ -0,0 +1,66 @@ +# Cranelift Codegen Backend Limitations + +## Background + +The Cranelift codegen backend (`rustc-codegen-cranelift-preview`) is an alternative to LLVM for Rust compilation. It's significantly faster for debug builds but has feature gaps. + +## Known Unsupported Features + +### `global_asm!` with `sym` operands + +**Status**: Not supported as of March 2026 + +The error originates in `compiler/rustc_codegen_cranelift/src/global_asm.rs` in the rust-lang/rust repo. When Cranelift encounters a `GlobalAsmOperandRef::SymFn` operand, it emits: + +``` +error: asm! and global_asm! sym operands are not yet supported +``` + +**Affected crates** (non-exhaustive): +- `wasmtime-fiber` (all versions, including v42+) — uses `global_asm!` with `sym` for fiber context switching +- Any crate using `global_asm!` with function symbol references + +**Source**: [rust-lang/rust global_asm.rs](https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_cranelift/src/global_asm.rs) + +### Diagnostic confusion + +The error message says "not yet supported" which looks like a Rust nightly regression. It's NOT — it's a Cranelift limitation that has existed since the backend was introduced. The confusion arises because: + +1. `cargo check` and `cargo clippy` don't invoke codegen → no error +2. `cargo build` / `cargo test` invoke codegen → Cranelift fails +3. The error message doesn't mention Cranelift, so it looks like a rustc bug + +## Workarounds + +### Per-invocation override + +```bash +CARGO_PROFILE_DEV_CODEGEN_BACKEND=llvm cargo test +CARGO_PROFILE_DEV_CODEGEN_BACKEND=llvm cargo build +``` + +### Per-project override + +Create `.cargo/config.toml` in the project: + +```toml +[profile.dev] +codegen-backend = "llvm" +``` + +### Selective override (keep Cranelift for most builds) + +Use LLVM only for test profile: + +```toml +[profile.test] +codegen-backend = "llvm" +``` + +## Detection + +If `cargo check` passes but `cargo test` fails with `global_asm!` errors, check: + +```bash +grep -r "codegen-backend" ~/.cargo/config.toml .cargo/config.toml 2>/dev/null +```