[08]entry 8 of 29
crement
this entry is written twice, in full
- 1.in brief
C-style ++/-- for Rust (published crate)
- 2.in general
All four increment/decrement forms for Rust, delivered against the language’s better judgement.
- 3.in particular
n++, ++n, n--, --n with zero unsafe and zero runtime overhead beyond a single += / -=.
- 1.in brief
a published add-on giving Rust the ++ and -- operators
- 2.in general
All four ways of adding or subtracting one, delivered against the language’s better judgement.
- 3.in particular
Add one before or after, subtract one before or after, with nothing unsafe and no cost beyond the addition itself.
context
crement adds all four C-style increment/decrement variants to Rust1 via declarative macros. Add crement = "0.1" and use crement!(n++), or the named aliases post_inc!, pre_inc!, post_dec!, pre_dec!.
the interesting part
- 1.
Postfix forms capture the old value via Clone::clone; the compiler erases this to a register move for any Copy type, so there is no real overhead
- 2.
Internal temporaries use Span::mixed_site() hygiene: invisible to surrounding code, no shadowing
- 3.
The ++ / -- tokens are distinguished from separate operators by their Joint spacing in the token stream, matching C semantics
- 4.
Clean compile errors when a type is neither Copy nor Clone
outcome
Stable Rust1 has no specialization, so a single blanket impl<T: Clone> covers both paths and lets LLVM optimize. MSRV 1.71, MIT, published on crates.io. A small surface done exactly right.
A second published crate: small, sharp, and correct down to token spacing and macro hygiene.
context
Many languages let you write "add one to this" as two characters, and in two positions, depending on whether you want the value before or after the addition. Rust has none of them. This adds all four, as a package anyone can install in one line.
the interesting part
- 1.
The forms that hand back the old value have to copy it first. For any simple number the compiler reduces that copy to nothing at all, so the convenience costs nothing.
- 2.
The temporary values it creates internally are invisible to your own code, so they cannot collide with a variable you already have of the same name.
- 3.
Two plus signs written together mean something different from two written apart, and the difference is only the space between them. It reads that spacing to tell them apart, which is exactly how the older languages do it.
- 4.
A type that cannot be copied gets a clear explanation rather than a wall of compiler noise.
outcome
Rust cannot yet write two different implementations and let the compiler pick the better one, so a single implementation covers both paths and the optimiser sorts out the difference. A stated oldest supported compiler, a permissive licence, and published for anyone to install. A small surface, done exactly right.
A second published package: small, sharp, and correct all the way down to the spacing between two characters.