A Brief Introduction to Rust

A language empowering everyone to build reliable and efficient software.
  • Introduction
  • Common Pitfalls
  • Unique Features
  • Ecosystem
  • Questions

What is Rust?

  • system programming language (like C++)
  • safe, concurrent and fast
  • compiled, without runtime
  • static strong typing

Show Me Some Code!


                        fn main() {
                            let mut sum: i64 = 0;
                            for i in 1..10 {
                                if i % 2 == 0 {
                                    sum += i;
                                }
                            }
                            println!("sum is {}", sum);
                        }
                    

                        fn main() {
                            let sum: i64 = (1..10).filter(|i| i % 2 == 0).sum();
                            println!("sum is {}", sum);
                        }
                    

Common Pitfalls

Overflows

int overflow, buffer over-read, buffer overflow...

Rust: runtime bound check

Memory Hazards

  • dangling pointers
  • memory leaks
  • double free
  • iterator invalidation
  • ...

Rust: Ownership + Borrowing (compiletime check)

Concurrency Hazards

data race

A data race is any unsynchronized, concurrent access to data involving a write

Rust: Ownership + Borrowing (compiletime check)

Rust Unique Features

  • ownership & borrowing
  • lifetimes
  • ⇒ memory safety
  • ⇒ thread safety

Ownership

Ownership Rules

  • Each value in Rust has a variable that's called its owner
  • There can only be one owner at a time.
  • When the owner goes out of scope, the value will be dropped.

Let's look at some book examples!

Owning the Book


                        struct Book;

                        fn john() {
                            let book = Book; // john owns the book
                        } // john destroys his book
                    

                        struct Book;

                        fn steve() {
                            let book = Book; // steve owns the book

                            sally(book); // steve gives the book to sally
                        }

                        fn sally(book) {
                            // sally owns the book
                        } // sally destroys her book
                    

Borrowing the Book


                        fn my() {
                            let mut book = Book;

                            spelling_corrector(&mut book);
                            // we must explicitly mention that we lend the book
                            // and we don't give it away

                            reader(&book);
                        }

                        fn spelling_corrector(book: &mut Book) {
                            // correct spelling in place
                        }

                        fn reader(book: &Book) {
                            // read a book
                        }
                    

Rust References

Borrowing values

  • At any given time, you may have:
    • either exactly one mutable reference (&mutT)
    • or one or more immutable references (&T)
  • References are guaranteed (by the compiler) to be valid

No Iterator Invalidation

No Iterator Invalidation


                        fn main() {
                            let mut v = vec![0; 2];
                            for _each in v.iter() {
                                v.push(1); // ?
                            }
                            println!("{:?}", v);
                        }
                    

                        error[E0502]: cannot borrow `v` as mutable because
                        it is also borrowed as immutable
                         --> src/main.rs:4:9
                          |
                        3 |     for _each in v.iter() {
                          |                  --------
                          |                  |
                          |                  immutable borrow occurs here
                          |                  immutable borrow later used here
                        4 |         v.push(1); // ?
                          |         ^^^^^^^^^ mutable borrow occurs here
                    

Lifetimes


                        {
                            let r;                // ---------+-- 'a
                            {                     //          |
                                let x = 5;        // -+-- 'b  |
                                r = &x;           //  |       |
                            }                     // -+       |
                            println!("r: {}", r); //          |
                        }                         // ---------+
                    

                        error[E0597]: `x` does not live long enough
                         --> src/main.rs:6:9
                          |
                        6 |         r = &x;
                          |         ^^^^^^ borrowed value does not live long enough
                        7 |     }
                          |     - `x` dropped here while still borrowed
                        8 |
                        9 |     println!("r: {}", r);
                          |                       - borrow later used here
                    

Lifetimes


                    {
                        let x = 5;            // ----------+-- 'b
                                              //           |
                        let r = &x;           // --+-- 'a  |
                                              //   |       |
                        println!("r: {}", r); //   |       |
                                              // --+       |
                    }                         // ----------+
                    

(correct)

The compiler checks references are valid w.r.t referenced values lifetimes

Thread Safety

Rust ownership thread-safety

Thread Safety


                    use std::thread;

                    fn main() {
                        let mut v = vec![];
                        thread::spawn(move || { // v is moved into closure
                            v.push(2);
                        });
                        v.push(3);
                    //  ^ value borrowed here after move
                    }
                    

Thread Safety

Sharing Data


                    use std::thread;
                    // A thread-safe reference-counting pointer
                    use std::sync::Arc;

                    fn main() {
                        let v = Arc::new(vec![1, 2, 3]);
                        let v2 = v.clone();
                        let child = thread::spawn(move || {
                            println!("{:?}", v2);
                        });
                        child.join().expect("child thread error");
                        println!("{:?}", v);
                    }
                    

(correct)

Thread Safety

Preventing Unsynchronized Writes


                        use std::sync::Arc;

                        fn main() {
                            let mut v = Arc::new(vec![1, 2, 3]);
                            v.push(42);
                        //  ^ cannot borrow data in an Arc as mutable
                        }
                    

Thread Safety

Allowing Concurrent Mutation


                    use std::thread;
                    use std::sync::{Arc, Mutex};

                    fn main() {
                        let v = Arc::new(Mutex::new(vec![1, 2, 3]));
                        let v2 = v.clone();
                        let child = thread::spawn(move || {
                            let mut vector = v2.lock().unwrap();
                            vector.push(4);
                        });
                        child.join().expect("child thread error");
                        println!("{}", v.lock().unwrap().len());
                    }
                    

(correct)

Rust Ecosystem

(Nov 2019)

Rust Tools

  • rustup
  • cargo
  • rustdoc
  • rustfmt
  • clippy
source: https://ashleygwilliams.github.io/gotober-2018/#54

Rust in Production

  • Google
    • Crosvm (Chrome OS VM Monitor) 116k Rust
    • Fuchsia (OS) 1153k C++, 1430k Rust
  • Dropbox
    • Rust-brotli (lossless compression) 108k Rust
  • Mozilla
    • Servo (Parallel Browser Engine) 278k Rust
  • Facebook
    • Custom Mercurial 3k Rust
    • Libra (Facebook Currency) 111k Rust
  • You?
Thank You
Questions?

References

these slides are made with reveal.js

Here be (owned) books (article by hauleth)

Fearless Concurrency with Rust (article by Aaron Turon)

Concurrency in Rust (conf by Alex Crichton)

Illustrations

rust on iron

gaston lagaffe

integer overflow

heartbleed

blaster worm

train wreck

train signals

ferrofluid

reading room

wallace and gromit

tight rope walking

marine ecosystem

cargo ship

ferris (rust unofficial mascot)