fn parse(s: Stream) -> Result<Ast, ParseError> { unimplemented!(); }
result errors
pub enum Result<T, E> { Ok(T), Err(E), } return Ok(Ast { ... }) return Err(ParseError::new())
enums generics
enum ParseError { Io(io::Error), UnexpectedCharacter, IntError { cause: ParseIntError, position: Pos }, }
enums errors error-hierarchy
match err { Io(io) => connection.close(), UnexpectedCharacter => println!("bad char"), }
match non-exhaustive
error[E0004]: non-exhaustive patterns: `IntError { .. }` not covered --> src/main.rs:14:11 | 6 | / enum ParseError { 7 | | Io(io::Error), 8 | | UnexpectedCharacter, 9 | | IntError { cause: ParseIntError, | | -------- not covered 10 | | position: Pos }, 11 | | } | |_- `ParseError` defined here ... 14 | match err { | ^^^ pattern `IntError { .. }` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
rustc-error
match err { Io(io) => connection.close(), UnexpectedCharacter => println!("bad char"), IntError { cause, .. } => println!("bad int: {}", cause), }
match structural-match unused-fields
let (new_state, action) = match (msg, state) { (Ping, Leader { .. }) => // re-elect (Ping, _) => // follow (Pong, me @ Leader { .. }) => // count (Pong, _) => // re-elect (Vote(id), Starting { .. }) => // vote (Vote(id), Electing {epoch, mut votes_for_me, deadline, needed_votes}) => // check (Vote(_), me @ Voted { .. }) | (Vote(_), me @ Leader { .. }) | (Vote(_), me @ Follower { .. }) => // discard };
let Config { host: a_host, port: a_port, listen_queue: _, } = a; let Config { host: b_host, port: b_port, .. } = b; return a_host == b_host && a_port == b_port;
unpacking exhaustiveness pattern-matching
#[non_exhaustive] enum ParseError { Io(io::Error), UnexpectedCharacter, IntError { cause: ParseIntError, position: Pos }, }
forward-compatibility semver
match err { Io(io) => connection.close(), _ => println!("error: {}", err), }
non-exhaustive catch-all
enum ParseError { Io(io::Error), Lexer(Box<dyn Error>), Parser(Box<dyn Error>), }
errors dynamic exhaustive boxing efficiency
pub struct ParserError { internal: InternalError, } enum InternalError { Io(...), Lexer(...), }
visibility forward-compatibility semver
pub struct ParserError(InternalError); pub(crate) enum InternalError { Io(...), Lexer(...), }
new-type visibility
pub struct UpstreamName(Arc<str>); pub struct DownstreamName(Arc<str>); struct Server { up: Map<UpstreamName, Upstream>, down: Map<DownstreamName, Downstream>, }
new-type arc interning validation
#[derive(Clone)] pub struct Percentile(u16); impl TryFrom for Percentile {...} impl Into for Percentile {...} fn get(perc: Percentile) -> Value { return self.percentiles[perc.0]; }
new-type validation performance ints conversion
pub struct Token { level: u8, slot: u32 } fn create_timeout() -> Token { } fn clear_timeout(tok: Token) { }
new-type token-pattern single-use linear-types
let (tx, rx) = channel::oneshot(); thread::spawn(move || { rx.send(1); });
single-use linear-types move threading
error[E0382]: use of moved value: `tx` --> src/main.rs:23:9 | 22 | tx.send(1); | -- value moved here 23 | tx.send(2); | ^^ value used here after move | = note: move occurs because `tx` has type `Sender`, which does not implement the `Copy` trait
linear-types move rustc-error
for (&key, _) in &map { if key.start_with("x") { map.remove(&key); } }
borrow-checker ownership
error[E0502]: cannot borrow `m` as mutable because \ it is also borrowed as immutable --> src/main.rs:7:13 | 5 | for (&key, _) in &map { | --- | | | immutable borrow occurs here | immutable borrow later used here 6 | if key.starts_with("x") { 7 | map.remove(&key); | ^^^^^^^^^^^^^^^^ mutable borrow occurs here
borrow-checker rustc-error
for (&key, _) in &map { if key.start_with("x") { map.remove(&key); break; } }
borrow-checker ownership nll
let x = HashMap::new(); x.insert("key1", v1); x.insert("key2", v2); let shared = Arc::new(x); thread1_channel.send(shared.clone()); thread2_channel.send(shared.clone());
mutability shared-state
let shared = Arc::new(Mutex::new(x)); thread::spawn(move || { let x: MutexGuard<HashMap<_, _>>; x = shared.lock() x.insert("x"); })
mutability shared-mutable-state raii lifetime
let gil = Python::acquire_gil(); let py = gil.python(); let dic1 = PyDict::new(py); dic1.set_item(py, "key1", PyInt::new(py, 1000))?;
python token-pattern lifetime
let a = HashMap::new(); a.insert("x", 1); let b = HashMap::new(); b.insert("key1", a); # a is moved # a.insert() -- is error b.get_mut("key1").insert("y", 2);
recursive-mutability
let a = TcpStream::connect("localhost:1234"); a.write(b"test"); a.read(&mut buf);
sharing sockets
let mut a = BufStream::new( TcpStream::connect("localhost:1234")); a.write(text); a.write(b"\n"); a.read_line(&mut buf);
sharing buffering mutation
let a = BufStream::new( TcpSocket::connect("localhost:1234")); let (mut tx, mut rx) = a.split(); thread::spawn(move || { # rx.write() -- no such method rx.read_line(&mut buf); }) tx.write(text); tx.write(b"\n");
sharing buffering mutation