DEV Community

Ramdai Bista
Ramdai Bista

Posted on Originally published at devtoolsreview.com

We Tested 5 AI Coding Tools Against Rust's Borrow Checker — Here's What Compiled

Disclosure: This article contains affiliate links. We may earn a commission at no extra cost to you. It never changes our rankings — we only make money if we point you to the tool that's actually right for you.

Rust is a bad language to fake your way through with an LLM. Python forgives a wrong guess — code "looks right," runs, and you fix the type error later. Rust doesn't negotiate: it's correct or it's a compile error, and the gap between "almost right" and "right" is frequently a single &, mut, or lifetime annotation.

So instead of asking which AI coding tool "feels" best for Rust, we measured something falsifiable: how often does each tool's suggestion actually compile on the first try.

What we ran

Five tools — Cursor, GitHub Copilot, Windsurf, Tabnine, and Claude Code — against four real project types: a clap-based CLI, an axum async web server with database pooling and JWT auth, a systems library with unsafe blocks and FFI via bindgen, and a wasm-bindgen WebAssembly module. Same codebase, same Rust 1.77 toolchain, three weeks, tracked whether each suggestion compiled without edits.

The numbers

Compile-on-first-try rate across all four projects:

  • Cursor: 72%
  • Copilot: 58%
  • Windsurf: 51%
  • Tabnine: 44%

Claude Code doesn't fit this metric cleanly — it's a task-based terminal agent, not inline autocomplete — but on a harder test (15 real borrow-checker errors, fix-and-explain), it correctly resolved 14. Cursor fixed 11 but couldn't always explain why. Copilot fixed 9.

Where the gap actually shows up

Ownership, not syntax, is what separates these tools. On mutable-borrow detection specifically, Cursor correctly identified when &mut was required about 85% of the time versus Copilot's 70%. Windsurf's failure mode was the opposite of what you'd expect — not under-cautious, but reflexively inserting .clone() to dodge borrow errors it couldn't resolve, which compiles but teaches exactly the wrong habit.

For unsafe code and FFI, Claude Code was the standout: it documented safety invariants in comments (something none of the inline tools did unprompted), handled raw pointer round-trips correctly, and in one bindgen-wrapped C library test, was the only tool to add a correct Drop implementation preventing a memory leak nobody asked it to look for.

The advanced-type-system test — implementing a typestate builder pattern with phantom types and zero-sized types for compile-time state checking — only Claude Code got fully right. Cursor's attempt had a gap in the type transitions. Everyone else produced incomplete implementations.

The honest tradeoffs

Cursor's weakness is over-suggestion: unnecessary trait bounds, derives you won't use, and in multi-lifetime generic code it sometimes produces something that compiles but is more restrictive than it needs to be. Claude Code has no inline completions at all — most Rust developers who use it pair it with an editor-based tool for daily typing and save Claude Code for the lifetime error they don't understand.

Full breakdown

The complete writeup has the per-category breakdown (async/tokio, cargo integration, trait implementations, no_std/embedded), the testing methodology in full, and pricing for each tool.

Top comments (0)