I listed two things Rust doesn't handle well without unsafe code, doubly linked lists and multidimensional arrays. Here are examples of both from popular repositories with high download numbers:
- https://github.com/andelf/rust-adivon/blob/master/src/deque....
- https://github.com/andelf/rust-adivon/blob/master/src/queue....
These are all the doubly-linked list problem:
struct Node {
item: T,
next: Option>>,
prev: Rawlink>
}
Since this is templated code, it might be possible to break it by instantiating it on a type with unusual semantics.
- https://github.com/BurntSushi/aho-corasick/blob/master/src/f...
Looks like unsafe code for "performance reasons". But there are no comments near "unsafe", so it's hard to tell.
- https://github.com/SiegeLord/RustAlgebloat/blob/master/algeb...
Matrix math. "Unsafe" all over the place, and unsafeness is exported, allowing the caller to do unsafe things. This is an example of why I occasionally stress the need for multidimensional array support at the language level. If the compiler knew about multidimensional arrays, it could optimize the subscript checks for them, avoiding code such as this.
The unsafe version. The caller can store anywhere in memory.
fn unsafe_set_idx(&self, $mat: &T, v: f64)
{
let $self_ = self;
let (r, c) = $rc_expr;
unsafe
{ $mat.raw_set(r, c, v) }
}
Safe, but inefficient version. The compiler can't hoist those checks out of loops.
fn set_idx(&self, $mat: &T, v: f64)
{ let $self_ = self;
let (r, c) = $rc_expr;
assert!(r
This is the sort of thing that leads to exploits in code that reads things like JPEG files. Yet you can't do much better in Rust.
That's why doing multidimensional arrays in macros and templates isn't good enough.