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.
This commit is contained in:
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.cache/
|
||||
.claude/
|
||||
*.log
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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/<hostname>
|
||||
nix flake update fenix
|
||||
sudo nixos-rebuild switch --flake '.#<hostname>'
|
||||
```
|
||||
|
||||
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 = "<manifest-hash>"; # 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
|
||||
};
|
||||
```
|
||||
@@ -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
|
||||
```
|
||||
Reference in New Issue
Block a user