Rust
Unsafe guidelines
Learn unsafe Rust writing guidelines and a checklist.
Unsafe guidelines
An API is sound if no undefined behaviour can occur however safe code uses it. Rules when writing unsafe code: next to every unsafe block, write a // SAFETY: comment explaining why it's safe; document the contract of unsafe fns with # Safety; enforce the contract at runtime with assert! where possible; and run the tests under Miri:
$ rustup +nightly component add miri
$ cargo +nightly miri test # catches unaligned access, use-after-free, data races
Lints help too: #![deny(unsafe_op_in_unsafe_fn)], clippy::undocumented_unsafe_blocks.
A sound wrapper
Once the contract is checked and a safe result is returned on failure, the function containing unsafe stays safe:
fn ilk_iki(v: &[i32]) -> Option<(i32, i32)> {
if v.len() < 2 {
return None;
}
// SAFETY: v.len() >= 2 was checked above.
unsafe { Some((*v.get_unchecked(0), *v.get_unchecked(1))) }
}
In this example unsafe isn't actually needed (v.get(..2) would do); unsafe should be used only when there's a measured gain.
Exercise Sound access
Write the ilk_iki function above with a // SAFETY: comment. Print the results for [4, 5, 6] and [9] with {:?}, separated by a space.
Show example solution
fn ilk_iki(v: &[i32]) -> Option<(i32, i32)> {
if v.len() < 2 {
return None;
}
// SAFETY: yukarıda v.len() >= 2 olduğu denetlendi.
unsafe { Some((*v.get_unchecked(0), *v.get_unchecked(1))) }
}
fn main() {
println!("{:?} {:?}", ilk_iki(&[4, 5, 6]), ilk_iki(&[9]));
}
Test yourself
-
If an unsafe block inside a safe function can produce UB on wrong input, what is the function?
- Safe
- Acceptable
- Unsound; it must either check the input or be an unsafe fn
- Sound
Show answer
Unsound; it must either check the input or be an unsafe fn — A safe signature is the promise "whatever input you call it with, there's no UB".
-
Justification comment
// ____: yukarıda v.len() >= 2 olduğu denetlendi.
unsafe { *v.get_unchecked(1) }
Show answer
// SAFETY: yukarıda v.len() >= 2 olduğu denetlendi.
unsafe { *v.get_unchecked(1) }
-
Concept and meaning
- Sound
- UB impossible from safe code
- Miri
- Interpreter catching UB
- // SAFETY:
- Justification
- # Safety
- Contract documentation
Next lesson: Summary - Build tools