The Rust backend renders every []T parameter as Vec<T> — by value, without mut — and then emits buf[i] = x into it.
Measured on master
- 189 specs declare a slice parameter; 174 parse.
- 23 of those emit Rust that index-assigns into a slice parameter.
- 0 of the 23 compile. Not one.
- Corpus-wide,
E0382 (use of moved value) plus E0596 (cannot borrow as mutable) appear in 33 files, 143 diagnostics.
Instrument: rustc --edition 2021 --crate-type lib --crate-name g --emit=metadata over the emitted Rust of all 650 specs, with a control that accepts a valid file and rejects an invalid one. The --crate-name is load-bearing: without it rustc derives the crate name from the filename, rejects the . in .t27, and nothing is ever compiled — an earlier run of this measurement read 0 for every binary for that reason alone.
Two defects, not one
- It does not compile.
pub fn byte_to_trits(byte: u8, trits: Vec<i32>, len: usize) then trits[i] = ... is E0382/E0596.
- Even if it compiled, it would be wrong. The writes would land in a moved copy and the caller would see nothing. That is the more serious half, because a plausible future fix — adding
mut to the binding — makes it compile and leaves it silently wrong.
The other backends do not have this problem: the C backend passes a pointer and the Verilog backend gives the caller its writes, so the Rust column was the one disagreeing with the rest. For a project whose stated property is cross-target agreement, that is the shape that matters.
The chain, which a per-function scan cannot see
char_to_trits never assigns into its own trits — it hands it to byte_to_trits, which does. Marking only the direct writers gives the caller a Vec<i32> and the callee a &mut [i32], and the call between them is E0308: expected &mut [i32], found Vec<i32>. The marking has to reach a fixpoint over calls.
Separately: .len on a slice
Thirteen files newly report error[E0615]: attempted to take value of method len once they get far enough to be type-checked — while ((i < DEQUE_MAX_SIZE) && (i < data.len)). The emitted line is byte-identical to what master emits; those files simply died earlier before. Rust exposes length as a method, data.len(). The Zig backend documents the mirror-image of this at its own .len site (Zig exposes it as a field). Filed here as a separate defect rather than folded into the parameter change.
The Rust backend renders every
[]Tparameter asVec<T>— by value, withoutmut— and then emitsbuf[i] = xinto it.Measured on master
E0382(use of moved value) plusE0596(cannot borrow as mutable) appear in 33 files, 143 diagnostics.Instrument:
rustc --edition 2021 --crate-type lib --crate-name g --emit=metadataover the emitted Rust of all 650 specs, with a control that accepts a valid file and rejects an invalid one. The--crate-nameis load-bearing: without it rustc derives the crate name from the filename, rejects the.in.t27, and nothing is ever compiled — an earlier run of this measurement read 0 for every binary for that reason alone.Two defects, not one
pub fn byte_to_trits(byte: u8, trits: Vec<i32>, len: usize)thentrits[i] = ...is E0382/E0596.mutto the binding — makes it compile and leaves it silently wrong.The other backends do not have this problem: the C backend passes a pointer and the Verilog backend gives the caller its writes, so the Rust column was the one disagreeing with the rest. For a project whose stated property is cross-target agreement, that is the shape that matters.
The chain, which a per-function scan cannot see
char_to_tritsnever assigns into its owntrits— it hands it tobyte_to_trits, which does. Marking only the direct writers gives the caller aVec<i32>and the callee a&mut [i32], and the call between them isE0308: expected &mut [i32], found Vec<i32>. The marking has to reach a fixpoint over calls.Separately:
.lenon a sliceThirteen files newly report
error[E0615]: attempted to take value of method lenonce they get far enough to be type-checked —while ((i < DEQUE_MAX_SIZE) && (i < data.len)). The emitted line is byte-identical to what master emits; those files simply died earlier before. Rust exposes length as a method,data.len(). The Zig backend documents the mirror-image of this at its own.lensite (Zig exposes it as a field). Filed here as a separate defect rather than folded into the parameter change.