I've been conducting an extensive evaluation of Claude Code's capabilities for Rust development, specifically within the context of building internal tooling for CRM data pipelines. A persistent and concerning pattern has emerged during my structured testing: the assistant has a marked tendency to suggest the use of `unsafe` blocks in scenarios where safe, idiomatic Rust alternatives are not only available but are preferable for maintainable production code. This directly impacts risk assessment for any development project reliant on its suggestions.
My primary use case involves generating Rust code for high-integrity data transformation and API client libraries, where memory safety and auditability are non-negotiable requirements. The problematic suggestions typically appear in contexts like:
* Direct pointer manipulation or dereferencing when working with FFI stubs or certain data structures.
* Proposals for performance optimizations that bypass Rust's borrow checker, often prematurely.
* Handling of raw bytes or certain standard library functions that have safe wrappers.
To mitigate this and steer Claude Code toward generating exclusively safe Rust, I have developed a multi-layered prompt engineering strategy that has yielded a significant improvement in output quality. The core principle is to establish an unambigious, non-negotiable contract before any code generation begins.
**Essential Pre-Prompt Directive Framework:**
```
You are an expert Rust developer committed to writing safe, idiomatic, and production-ready code. For this entire session, adhere strictly to the following rules:
1. Under no circumstances use the `unsafe` keyword. If a task seems to require unsafe code, you must find and implement a safe alternative using the standard library or crates from the Rust ecosystem.
2. Prioritize clarity and correctness over micro-optimizations. Do not suggest performance changes that would compromise memory safety.
3. If I request an operation that is inherently unsafe (e.g., a specific FFI call), you must first explain the safe abstraction pattern (e.g., using `libc` crate, safe wrappers) before providing any implementation.
4. Always prefer using `Vec`, slices, iterators, and checked methods over pointer arithmetic or manual memory management.
```
Furthermore, I have found it critical to provide explicit, positive instructions within the specific task prompt itself. For example, instead of "write a function to parse this byte buffer," I now use:
"Write a function to parse this byte buffer. Use only safe Rust constructs. Utilize the `byteorder` crate or standard library methods like `from_le_bytes` for any necessary conversions. Assume the buffer is a `&[u8]` slice."
This combination of a strong foundational policy followed by task-specific reinforcement has virtually eliminated unwanted `unsafe` suggestions in my recent tests. It forces the model to reason within a constrained, safe solution space, which aligns perfectly with the philosophy of the language itself. For teams integrating Claude Code into their Rust workflow, I would consider establishing and sharing a standardized "Safe Rust" prompt template as a mandatory first step in any coding session.
You had me at "extensive evaluation." How many prompts are we talking here? Structured testing against what baseline? The vendor's own claims or a real open source model?
The unsafe suggestions are a symptom. The root cause is Anthropic training on a lot of C/C++ code and calling it "Rust." Their evals don't punish them for it. I'd bet your "mitigation" prompt is just a band-aid that'll fail on edge cases.
Prove it
I tried Claude Code for a small Rust project last week, just porting a CSV parser. Same pattern. It wanted to use unsafe for a simple transmute where I could have just used `from_le_bytes`. My prompt engineering didn't help much either. Did you try adding a specific line like "only suggest unsafe if you can prove no safe alternative exists" or is that too vague to work?