Languages & compilers
Rust to .NET
Compile Rust to .NET and compare managed execution with native output.
Recorded result
Explore the exampleWhy I’m interested
A compiler backend connects ecosystems at a deeper level than an API wrapper. Translating Rust into .NET brings Rust values and operations into a managed runtime, where libraries and platform services follow a different set of rules. I'm interested in that boundary: what the compiler emits, how the runtime executes it, and where compatibility work belongs.
Progress
My local fork work covers compiler and linker behavior, nightly compatibility, and release checks. The installed SDK compiled a Rust function to a .NET assembly and produced four results equal to native Rust. The recording uses cargo-dotnet 0.0.1 and nightly-2026-06-17. FractalFir supplies the upstream translation backend.
One function on .NET
Follow the function from source to compiler output, then compare its execution results.
The source function
The Rust-to-.NET backend compiles this function into a managed program. The recorded program returns the same four results as native Rust.
Input
#[inline(never)]
fn add_one(x: i32) -> i32 { x + 1 }
fn main() { for x in [-2, 0, 7, 41] { println!("{} -> {}", x, add_one(x)); } }
Result
cargo dotnet run ./fixture --offline
[profile.release]
overflow-checks = trueA generated managed assembly
The backend emitted a PE assembly for .NET 10. The fixture enables overflow checks. Its four inputs stay within the Int32 range.
Input
fn add_one(_1: i32) -> i32 {
debug x => _1;
let mut _0: i32;
let mut _2: (i32, bool);
bb0: {
_2 = AddWithOverflow(copy _1, const 1_i32);
assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _1, const 1_i32) -> [success: bb1, unwind continue];
}
bb1: {
_0 = move (_2.0: i32);
return;
}
}
Result
Artifact: portfolia-add-one.dll
Runtime: .NET 10
SDK: cargo-dotnet 0.0.1
Toolchain: nightly-2026-06-17
SHA-256: b99899d5ba09a3792577b9d5a7a0c9ede44499411e6773c49b937b8d4166ff45Four native reference inputs
The managed program produced these four lines. Its output matches the native Rust reference byte for byte.
- Cases
- 4
- Reference comparison
- Equal
Input
-2 -> -1
0 -> 1
7 -> 8
41 -> 42
Result
-2 -> -1
0 -> 1
7 -> 8
41 -> 42
The recorded run uses cargo-dotnet 0.0.1 and nightly-2026-06-17. It compares four inputs within the Int32 range. The next run builds from the newer source checkout. FractalFir authors rustc_codegen_clr.
What comes next
Repeat the same inputs with a build from the newer source checkout and compare the assembly and execution results.
Implementation and credits
How does the same Rust function behave on native and managed runtimes?
A four-input run through the installed Rust-to-.NET SDK compares managed output with native Rust.
Inspect the Rust source, generated assembly identity, and execution results.
The Rust compiler backend produces the managed assembly. Rust exports the recorded comparison.
FractalFir authors rustc_codegen_clr. My local fork covers compiler, linker, compatibility, and acceptance work.