Share
Embed
A hammer you can only hold by the handle
Presented at RustFest Zürich (http://zurich.rustfest.eu)
Rust’s type system provides tools to ensure safe memory management, and safe concurrent access to data. What if we used those same tools to encode and enforce other API constraints?
We can leverage affine types (non-Clone structs) to enforce that a user performs a series of operations in a certain order; or we can use structs as tokens representing the user’s ability to perform certain actions. And everything’s checked at compile time.
We’ll see how these techniques let us encode complex API constraints, and make them self-documenting by preventing disallowed behaviour at compile time.
Andrea Lattuada
September 30, 2017
Transcript
126 slides
-
A HAMMER YOU CAN ONLY HOLD BY THE HANDLE ANDREA
LATTUADA @UTAAL SYSTEMS GROUP, DEPT. OF COMPUTER SCIENCE ETH ZÜRICH -
OWNERSHIP (LINEAR / AFFINE TYPES) fn use_name(name: String) { }
fn main() { let name = String::from(“Andrea”); use_name(name); println!("{}", name); } -
OWNERSHIP (LINEAR / AFFINE TYPES) fn use_name(name: String) { }
fn main() { let name = String::from(“Andrea”); use_name(name); println!("{}", name); } error[E0382]: use of moved value: `name` ---- value moved here ^^^^ value used here after move -
OWNERSHIP (LINEAR / AFFINE TYPES) fn use_name(name: String) { }
fn main() { let name = String::from(“Andrea”); use_name(name); println!("{}", name); } error[E0382]: use of moved value: `name` ---- value moved here ^^^^ value used here after move -
OWNERSHIP (LINEAR / AFFINE TYPES) fn use_name(name: String) { }
fn main() { let name = String::from(“Andrea”); use_name(name); println!("{}", name); } error[E0382]: use of moved value: `name` ---- value moved here ^^^^ value used here after move -
OWNERSHIP (LINEAR / AFFINE TYPES) fn use_name(name: String) { }
fn main() { let name = String::from(“Andrea”); use_name(name); println!("{}", name); } error[E0382]: use of moved value: `name` ---- value moved here ^^^^ value used here after move -
DROP fn main() { let a = get_number(); if a
> 3 { let data = vec![3, 4, 8]; } println!("{}", data); } -
DROP fn main() { let a = get_number(); if a
> 3 { let data = vec![3, 4, 8]; } println!("{}", data); } `data` dropped here -
#[derive(Clone)] pub struct Letter { text: String, } pub struct
Envelope { letter: Option<Letter>, } pub struct PickupLorryHandle { done: bool, // references to lorry's resources } -
#[derive(Clone)] pub struct Letter { text: String, } pub struct
Envelope { letter: Option<Letter>, } pub struct PickupLorryHandle { done: bool, // references to lorry's resources } -
#[derive(Clone)] pub struct Letter { text: String, } pub struct
Envelope { letter: Option<Letter>, } pub struct PickupLorryHandle { done: bool, // references to lorry's resources } -
#[derive(Clone)] pub struct Letter { text: String, } pub struct
Envelope { letter: Option<Letter>, } pub struct PickupLorryHandle { done: bool, // references to lorry's resources } -
#[derive(Clone)] pub struct Letter { text: String, } impl Letter
{ pub fn new(text: String) -> Self { Letter { text: text } } } -
pub struct Envelope { letter: Option<Letter>, } impl Envelope {
pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } pub fn buy_prestamped_envelope() -> Envelope { Envelope { letter: None } } -
pub struct Envelope { letter: Option<Letter>, } impl Envelope {
pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } pub fn buy_prestamped_envelope() -> Envelope { Envelope { letter: None } } -
pub struct Envelope { letter: Option<Letter>, } impl Envelope {
pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } pub fn buy_prestamped_envelope() -> Envelope { Envelope { letter: None } } -
pub struct PickupLorryHandle { done: bool, // references to lorry's
resources } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: &Envelope) { /* give letter */ } pub fn done(&mut self) { self.done = true; println!("sent"); } } pub fn order_pickup() -> PickupLorryHandle { PickupLorryHandle { done: false, /* other handles */ } } -
pub struct PickupLorryHandle { done: bool, // references to lorry's
resources } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: &Envelope) { /* give letter */ } pub fn done(&mut self) { self.done = true; println!("sent"); } } pub fn order_pickup() -> PickupLorryHandle { PickupLorryHandle { done: false, /* other handles */ } } -
pub struct PickupLorryHandle { done: bool, // references to lorry's
resources } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: &Envelope) { /* give letter */ } pub fn done(&mut self) { self.done = true; println!("sent"); } } pub fn order_pickup() -> PickupLorryHandle { PickupLorryHandle { done: false, /* other handles */ } } -
pub struct PickupLorryHandle { done: bool, // references to lorry's
resources } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: &Envelope) { /* give letter */ } pub fn done(&mut self) { self.done = true; println!("sent"); } } pub fn order_pickup() -> PickupLorryHandle { PickupLorryHandle { done: false, /* other handles */ } } -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); } -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); } -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); } -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); } -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); } -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); } -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut rustfest_envelope = buy_prestamped_envelope(); rustfest_envelope.wrap(&rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(&rustfest_envelope); lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(&rustfest_letter); lorry.pickup(&e); } lorry.done(); } #[derive(Clone)] pub struct Letter { text: String, } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); #[derive(Clone)] pub struct Letter { text: String, } impl Envelope { pub fn wrap(&mut self, letter: Letter) { self.letter = Some(letter); } } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); } lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let mut
envelopes = vec![ buy_prestamped_envelope(), buy_prestamped_envelope()]; let mut lorry = order_pickup(); for e in envelopes.iter_mut() { e.wrap(rustfest_letter); lorry.pickup(&e); } lorry.done(); } error[E0382]: use of moved value: `rustfest_letter` ^^^^^^^^^^^^^^^ value moved here in previous iteration of loop -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); impl Envelope { pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); impl Envelope { pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } assert!(self.letter.is_none()); -
// in a separate module fn main() { let rustfest_letter
= Letter::new(String::from("Dear RustFest")); let mut envelope = buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); impl Envelope { pub fn wrap(&mut self, letter: &Letter) { self.letter = Some(letter.clone()); } } panic assert!(self.letter.is_none()); -
pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:
Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } } -
pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:
Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } } -
pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:
Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } } -
pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:
Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } } -
pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:
Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } } -
pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:
Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } } -
pub struct EmptyEnvelope { } pub struct ClosedEnvelope { letter:
Letter, } impl EmptyEnvelope { pub fn wrap(self, letter: Letter) -> ClosedEnvelope { ClosedEnvelope { letter: letter } } } impl PickupLorryHandle { pub fn pickup(&mut self, envelope: ClosedEnvelope) { /* give letter */ } pub fn buy_prestamped_envelope() -> EmptyEnvelope { EmptyEnvelope { } } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(envelope); lorry.done(); } error[E0308]: mismatched types = note: expected type `ClosedEnvelope` found type `EmptyEnvelope` = help: here are some functions which might fulfill your needs: - .wrap(...) ^^^^^^^^ expected struct `ClosedEnvelope`, found struct `EmptyEnvelope` -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); let closed_envelope = envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); let closed_envelope = envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); let closed_envelope = envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); let closed_envelope = envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); lorry.done(); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let eth_letter = Letter::new(String::from("Dear ETH")); let closed_envelope = envelope.wrap(eth_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); lorry.done(); } error[E0382]: use of moved value: `envelope` -------- value moved here ^^^^^^^^ value used here after move -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); } -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); } impl Drop for PickupLorryHandle { fn drop(&mut self) { println!("sent"); } } impl PickupLorryHandle { pub fn done(self) { } … -
fn main() { let rustfest_letter = Letter::new(String::from("Dear RustFest")); let envelope
= buy_prestamped_envelope(); let closed_envelope = envelope.wrap(rustfest_letter); let mut lorry = order_pickup(); lorry.pickup(closed_envelope); } `lorry` dropped here impl Drop for PickupLorryHandle { fn drop(&mut self) { println!("sent"); } } impl PickupLorryHandle { pub fn done(self) { } … -
pub struct HttpResponseWritingHeaders { /* connection, … */ } pub
struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ } -
pub struct HttpResponseWritingHeaders { /* connection, … */ } pub
struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ } -
pub struct HttpResponseWritingHeaders { /* connection, … */ } pub
struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ } -
pub struct HttpResponseWritingHeaders { /* connection, … */ } pub
struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ } -
pub struct HttpResponseWritingHeaders { /* connection, … */ } pub
struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ } -
pub struct HttpResponseWritingHeaders { /* connection, … */ } pub
struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ } -
pub struct HttpResponseWritingHeaders { /* connection, … */ } pub
struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ } -
pub struct HttpResponseWritingHeaders { /* connection, … */ } pub
struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ } -
pub struct HttpResponseWritingHeaders { /* connection, … */ } pub
struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ } -
pub struct HttpResponseWritingHeaders { /* connection, … */ } pub
struct HttpResponseWritingBody { /* ... */ } pub fn start_response() -> HttpResponseWritingHeaders { /* ... */ } impl HttpResponseWritingHeaders { fn header(&mut self, header: Header) { /* ... */ } fn body(self) -> HttpResponseWritingBody { /* ... */ } } impl HttpResponseWritingBody { fn write(&mut self, chunk: Chunk) { /* ... */ } fn cease(self) { } } impl Drop for HttpResponseWritingBody { /* ... */ } -
/// The capability to send data with a certain timestamp
on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time -
/// The capability to send data with a certain timestamp
on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time -
/// The capability to send data with a certain timestamp
on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time -
/// The capability to send data with a certain timestamp
on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time -
/// The capability to send data with a certain timestamp
on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time -
/// The capability to send data with a certain timestamp
on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time -
/// The capability to send data with a certain timestamp
on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time -
/// The capability to send data with a certain timestamp
on a dataflow edge. pub struct Capability<T: Timestamp> { time: T, internal: Rc<RefCell<ChangeBatch<T>>>, } impl<T: Timestamp> Clone for Capability<T> { fn clone(&self) -> Capability<T> { // … update self.internal … } } impl<T: Timestamp> Drop for Capability<T> { fn drop(&mut self) { // … update self.internal … } } pub fn session(&mut self, cap: &Capability<T>) -> Handle time -
MY GROUP IS LOOKING FOR SOFTWARE ENGINEERS AND PHD STUDENTS
WE WORK WITH RUST HTTPS://WWW.SYSTEMS.ETHZ.CH ANDREA LATTUADA @UTAAL ON TWITTER, GITHUB [email protected] FRANK MCSHERRY, TIMELY DATAFLOW HTTPS://GITHUB.COM/FRANKMCSHERRY/TIMELY-DATAFLOW ANDREA LATTUADA, PROGRAMMABLE SCHEDULING IN A STREAM PROCESSING SYSTEM HTTPS://WWW.RESEARCH-COLLECTION.ETHZ.CH/HANDLE/20.500.11850/155664