RUST DISTILLED:
AN EXPRESSIVE TOWER OF LANGUAGES
Aaron Weiss, Daniel Patterson, Amal Ahmed Northeastern University and Inria Paris
Rust is a systems programming language that runs blazingly fast, - - PowerPoint PPT Presentation
AN EXPRESSIVE TOWER OF LANGUAGES
Aaron Weiss, Daniel Patterson, Amal Ahmed Northeastern University and Inria Paris
Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. – the official Rust website
Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. – the official Rust website systems programming
Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. – the official Rust website blazingly fast
Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. – the official Rust website prevents segfaults, guarantees thread safety.
Memory safety without garbage collection Abstraction without overhead Concurrency without data races Stability without stagnation
Hack without fear.
... BUT HOW?
... BUT HOW? Ownership x y z
identifiers "own" values
... BUT HOW? Borrowing x y z &x
references "borrow" values
Ownership x y z
identifiers "own" values
A PROGRAM IN RUST
extern crate irc; use irc:;client:;prelude:;*; fn main() -? irc:;error:;Result<()> { let config = Config {../}; let mut reactor = IrcReactor:;new()?; let client = reactor.prepare_client_and_connect(&config)?; client.identify()?; reactor.register_client_with_handler(client, |client, message| { print!("{}", message); Ok(()) }); reactor.run()?; }
A PROGRAM IN RUST
extern crate irc; use irc:;client:;prelude:;*; fn main() -? irc:;error:;Result<()> { let config = Config {../}; let mut reactor = IrcReactor:;new()?; let client = reactor.prepare_client_and_connect(&config)?; client.identify()?; reactor.register_client_with_handler(client, |client, message| { print!("{}", message); Ok(()) }); reactor.run()?; }
A PROGRAM IN RUST
extern crate irc; use irc:;client:;prelude:;*; fn main() -? irc:;error:;Result<()> { let config = Config {../}; let mut reactor = IrcReactor:;new()?; let client = reactor.prepare_client_and_connect(&config)?; client.identify()?; reactor.register_client_with_handler(client, |client, message| { print!("{}", message); Ok(()) }); reactor.run()?; }
A PROGRAM IN RUST
extern crate irc; use irc:;client:;prelude:;*; fn main() -? irc:;error:;Result<()> { let config = Config {../}; let mut reactor = IrcReactor:;new()?; let client = reactor.prepare_client_and_connect(&config)?; client.identify()?; reactor.register_client_with_handler(client, |client, message| { print!("{}", message); Ok(()) }); reactor.run()?; }
A PROGRAM IN RUST
extern crate irc; use irc:;client:;prelude:;*; fn main() -? irc:;error:;Result<()> { let config = Config {../}; let mut reactor = IrcReactor:;new()?; let client = reactor.prepare_client_and_connect(&config)?; client.identify()?; reactor.register_client_with_handler(client, |client, message| { print!("{}", message); Ok(()) }); reactor.run()?; }
A PROGRAM IN RUST
extern crate irc; use irc:;client:;prelude:;*; fn main() -? irc:;error:;Result<()> { let config = Config {../}; let mut reactor = IrcReactor:;new()?; let client = reactor.prepare_client_and_connect(&config)?; client.identify()?; reactor.register_client_with_handler(client, |client, message| { print!("{}", message); Ok(()) }); reactor.run()?; }
A PROGRAM IN RUST
extern crate irc; use irc:;client:;prelude:;*; fn main() -? irc:;error:;Result<()> { let config = Config {../}; let mut reactor = IrcReactor:;new()?; let client = reactor.prepare_client_and_connect(&config)?; client.identify()?; reactor.register_client_with_handler(client, |client, message| { print!("{}", message); Ok(()) }); reactor.run()?; } &config
A PROGRAM IN RUST
extern crate irc; use irc:;client:;prelude:;*; fn main() -? irc:;error:;Result<()> { let config = Config {../}; let mut reactor = IrcReactor:;new()?; let client = reactor.prepare_client_and_connect(&config)?; client.identify()?; reactor.register_client_with_handler(client, |client, message| { print!("{}", message); Ok(()) }); reactor.run()?; } client
THE CURRENT STATE OF AFFAIRS
THE CURRENT STATE OF AFFAIRS
interprocedural static analysis with ad-hoc constraint solving
RUST
THE CURRENT STATE OF AFFAIRS
interprocedural static analysis with ad-hoc constraint solving
RUST RUSTBELT (JUNG, JOURDAN, KREBBERS, AND DREYER, POPL '18)
formal language specified in Iris but low-level, in a CPS-style.
CAPABILITIES FOR OWNERSHIP x y z
CAPABILITIES FOR OWNERSHIP x y z capabilities guard the use of identifiers
BORROWS BREAK CAPABILITIES INTO FRACTIONS x y z
BORROWS BREAK CAPABILITIES INTO FRACTIONS x y z &x
BORROWS BREAK CAPABILITIES INTO FRACTIONS x y z &x
BORROWS BREAK CAPABILITIES INTO FRACTIONS x y z &x
&mut z
BORROWS BREAK CAPABILITIES INTO FRACTIONS x y z &x
&mut z
MOVES TAKE THE CAPABILITY AND THE HOLE x y z &x
&mut z
MOVES TAKE THE CAPABILITY AND THE HOLE x y z &x
&mut z
w
WE CALL REFERENCE SITES LOANS
extern crate irc; use irc:;client:;prelude:;*; fn main() -? irc:;error:;Result<()> { let config = Config {../}; let mut reactor = IrcReactor:;new()?; let client = reactor.prepare_client_and_connect(&config)?; client.identify()?; reactor.register_client_with_handler(client, |client, message| { print!("{}", message); Ok(()) }); reactor.run()?; } &config
a loan
WHAT ABOUT LIFETIMES?
WHAT ABOUT LIFETIMES? x : u32
WHAT ABOUT LIFETIMES? x : u32 &x : &'x u32
WHAT ABOUT LIFETIMES?
To keep type-checking tractable, regions correspond to sets of loans.
x : u32 &x : &'x u32
TYPE CHECKING
TYPE CHECKING
Σ
global context
TYPE CHECKING
Σ; Δ
global context type variable context
TYPE CHECKING
Σ; Δ; Γ
global context type variable context variable context
TYPE CHECKING
Σ; Δ; Γ; L
global context type variable context variable context loan context
TYPE CHECKING
Σ; Δ; Γ; L; P
global context type variable context variable context loan context region context
TYPE CHECKING
Σ; Δ; Γ; L; P ⊢ e
global context type variable context variable context loan context region context
TYPE CHECKING
Σ; Δ; Γ; L; P ⊢ e: τ
global context type variable context variable context loan context region context
TYPE CHECKING
Σ; Δ; Γ; L; P ⊢ e: τ ⇒ ε
global context type variable context variable context loan context region context
TYPING BORROWS Γ, x :f τ; L; P ⊢ &'
a x :
Σ; Δ;
TYPING BORROWS f ≠ 0 Γ, x :f τ; L; P ⊢ &'
a x :
Σ; Δ;
TYPING BORROWS f ≠ 0 Γ, x :f τ; L; P ⊢ &'
a x : &{ ' a } τ
Σ; Δ;
TYPING BORROWS f ≠ 0 Γ, x :f τ; L; P ⊢ &'
a x :
⇒ borrow imm x as '
a
&{ ' a } τ
Σ; Δ;
TYPING BRANCHING Σ; Δ; Γ; L; P ⊢ if { } else { } e1 e2 e3 : Σ; Δ;
TYPING BRANCHING Σ; Δ; Γ; L; P ⊢ if { } else { } e1 e2 e3 : Σ; Δ; Σ; Δ; Γ; L; P ⊢ e1 : bool ⇒ ε1 Σ; Δ;
TYPING BRANCHING Σ; Δ; Γ; L; P ⊢ if { } else { } e1 e2 e3 : Σ; Δ; Σ; Δ; ε1(Γ); ε1(L); ε1(P) ⊢ e2 : τ2 ⇒ ε2 Σ; Δ; Σ; Δ; Γ; L; P ⊢ e1 : bool ⇒ ε1 Σ; Δ;
TYPING BRANCHING Σ; Δ; Γ; L; P ⊢ if { } else { } e1 e2 e3 : Σ; Δ; Σ; Δ; ε1(Γ); ε1(L); ε1(P) ⊢ e2 : τ2 ⇒ ε2 Σ; Δ; Σ; Δ; ε1(Γ); ε1(L); ε1(P) ⊢ e3 : τ3 ⇒ ε3 Σ; Δ; Σ; Δ; Γ; L; P ⊢ e1 : bool ⇒ ε1 Σ; Δ;
TYPING BRANCHING Σ; Δ; Γ; L; P ⊢ if { } else { } e1 e2 e3 : τ2 ∼ τ3 ⇒ τ Σ; Δ; Σ; Δ; ε1(Γ); ε1(L); ε1(P) ⊢ e2 : τ2 ⇒ ε2 Σ; Δ; Σ; Δ; ε1(Γ); ε1(L); ε1(P) ⊢ e3 : τ3 ⇒ ε3 Σ; Δ; Σ; Δ; Γ; L; P ⊢ e1 : bool ⇒ ε1 Σ; Δ;
TYPING BRANCHING Σ; Δ; Γ; L; P ⊢ if { } else { } e1 e2 e3 : τ2 ∼ τ3 ⇒ τ τ Σ; Δ; Σ; Δ; ε1(Γ); ε1(L); ε1(P) ⊢ e2 : τ2 ⇒ ε2 Σ; Δ; Σ; Δ; ε1(Γ); ε1(L); ε1(P) ⊢ e3 : τ3 ⇒ ε3 Σ; Δ; Σ; Δ; Γ; L; P ⊢ e1 : bool ⇒ ε1 Σ; Δ;
TYPING BRANCHING Σ; Δ; Γ; L; P ⊢ if { } else { } e1 e2 e3 : τ2 ∼ τ3 ⇒ τ τ ⇒ ε1, ε2, ε3 Σ; Δ; Σ; Δ; ε1(Γ); ε1(L); ε1(P) ⊢ e2 : τ2 ⇒ ε2 Σ; Δ; Σ; Δ; ε1(Γ); ε1(L); ε1(P) ⊢ e3 : τ3 ⇒ ε3 Σ; Δ; Σ; Δ; Γ; L; P ⊢ e1 : bool ⇒ ε1 Σ; Δ;
WE MODEL...
WE MODEL...
struct Point { x: u32, y: u32 }
WE MODEL...
struct Point { x: u32, y: u32 } enum Option<T> { Some(T), None }
WE MODEL...
struct Point { x: u32, y: u32 } enum Option<T> { Some(T), None } if { } else { }
e1 e2 e3
WE MODEL...
struct Point { x: u32, y: u32 } enum Option<T> { Some(T), None } if { } else { }
e1 e2 e3
|x: u32| { x + x }
WE MODEL...
struct Point { x: u32, y: u32 } enum Option<T> { Some(T), None } if { } else { }
e1 e2 e3
|x: u32| { x + x } match opt { Some(x) =? x, None =? 42, }
WE DO NOT MODEL...
WE DO NOT MODEL...
trait Read { ../ }
WE DO NOT MODEL...
trait Read { ../ } Box:;new(Counter:;new()).count()⇝ Box:;new(Counter:;new()).deref().count()
WE DO NOT MODEL...
trait Read { ../ } Box:;new(Counter:;new()).count()⇝ Box:;new(Counter:;new()).deref().count() (&foo).frobnicate() ⇝ let tmp = &foo; tmp.frobnicate()
A TOWER OF LANGUAGES
A TOWER OF LANGUAGES
Oxide0
"safe" Rust
A TOWER OF LANGUAGES
Oxide0 Oxide1
Heap Allocation "safe" Rust
A TOWER OF LANGUAGES
Oxide0 Oxide1 Oxide2
Shared Memory Heap Allocation "safe" Rust
A TOWER OF LANGUAGES
Oxide0 Oxide1 Oxide2 Oxide3
Interior Mutability Shared Memory Heap Allocation "safe" Rust
A TOWER OF LANGUAGES
Oxide0 Oxide1 Oxide2 Oxide3
Interior Mutability Shared Memory Heap Allocation "safe" Rust
AN EXPRESSIVE TOWER OF EXPRESSIVE POWER
Expressive power is rooted in observational equivalence.
e1 e2
(Felleisen '90)
AN EXPRESSIVE TOWER OF EXPRESSIVE POWER
Each new abstraction raises the expressive power by adding functionality that cannot be observed in lower levels
Expressive power is rooted in observational equivalence.
e1 e2
(Felleisen '90)
AN EXPRESSIVE TOWER OF EXPRESSIVE POWER
Each new abstraction raises the expressive power by adding functionality that cannot be observed in lower levels
Expressive power is rooted in observational equivalence.
e1 e2
∀
C
,
(Felleisen '90)
C C
AN EXPRESSIVE TOWER OF EXPRESSIVE POWER
Each new abstraction raises the expressive power by adding functionality that cannot be observed in lower levels
Expressive power is rooted in observational equivalence.
e1 e2
∀
C
,
(Felleisen '90)
C C
AN EXPRESSIVE TOWER OF EXPRESSIVE POWER
Each new abstraction raises the expressive power by adding functionality that cannot be observed in lower levels
Expressive power is rooted in observational equivalence.
e1 e2
⇓ ⇓
∀
C
,
(Felleisen '90)
v C C
AN EXPRESSIVE TOWER OF EXPRESSIVE POWER
Each new abstraction raises the expressive power by adding functionality that cannot be observed in lower levels
Expressive power is rooted in observational equivalence.
e1 e2
⇓ ⇓
v
∀
C
,
=
(Felleisen '90)
NEXT STEPS
NEXT STEPS
ελλάδα
⊢
γεια
⊢
More formalization...
NEXT STEPS
ελλάδα
⊢
γεια
⊢
More formalization...
Rust-to-Oxide Compiler
Rust Oxide
A RUSTY FUTURE
A RUSTY FUTURE
Language Extensions
A RUSTY FUTURE
Language Extensions
Rust OCaml
Safe Interoperability
Gallina
A RUSTY FUTURE
Language Extensions
Rust OCaml
Safe Interoperability
Gallina
U n s a f e C
e G u i d e l i n e s
What unsafe code is safe to write?
TAKEAWAYS x y z &x
&mut z
w
TAKEAWAYS x y z &x
&mut z
w
Ownership with fractional capabilities
TAKEAWAYS x y z &x
&mut z
w
Moves never return their capability Ownership with fractional capabilities
TAKEAWAYS x y z &x
&mut z
w
Moves never return their capability Ownership with fractional capabilities 'x R e g i
s a r e s e t s
l
n s