Cursed Rust
Rust is a language with a lot of features. Sometimes those features have rough edges. Sometimes those rough edges are funny. Let's look at some.
Copy
and Clone
can diverge
#[derive(Debug)]
struct OhNo(u32);
impl Clone for OhNo {
fn clone(&self) -> Self {
OhNo(self.0 + 1)
}
}
impl Copy for OhNo { }
fn main() {
let oh = OhNo(3);
dbg!(oh.clone());
dbg!(oh);
}
Even worse, according to the docs, this isn't even a logic error, unlike inconsistent implementations of PartialOrd
and Ord
Really long place expression
a place expression is an expression you can take the address of.
turns out if
statements are place expressions. this is so obscure that not even the reference knows this, despite it being true since rust 1.0
fn main() {
let arr = [10, 20];
let arr_ref = &if true {
arr[0]
} else {
arr[1]
};
dbg!(arr_ref)
}
krate vs crate_
t-compiler says to use krate
, t-style says to use crate_
sidenote: how many of you have actually read the style guide? how many actually know that it exists?
Rust has reference variables! kinda..
use std::cell::Cell;
fn main() {
let x = Cell::new(1);
let ref y = x;
x.set(2);
let ref z = x;
assert_eq!(y, z);
}
This is mostly just silly.
&*
is actually useful
previous entries are here because they are weird and obscure. &*
is here because it is actually useful and meaningful, despite the fact that it would be a very silly no-op in most languages.
- invoking
Deref
without importing the trait - reborrowing a mutable reference as shared
- turning raw pointers into references