Skip to content

Instantly share code, notes, and snippets.

@jpastuszek
Forked from rust-play/playground.rs
Last active May 7, 2020 12:22
Show Gist options
  • Save jpastuszek/0471b276e6ec4fe187c4731b1581a303 to your computer and use it in GitHub Desktop.
Save jpastuszek/0471b276e6ec4fe187c4731b1581a303 to your computer and use it in GitHub Desktop.
Drop and pahntom ref unsound drop order
use std::marker::PhantomData;
struct Connection(u32);
impl Connection {
fn statement(&self) -> Statement {
Statement(Raii(self.0), PhantomData)
}
}
impl Drop for Connection {
fn drop(&mut self) {
println!("dropping Connection({})", self.0)
}
}
struct Raii(u32);
impl Drop for Raii {
fn drop(&mut self) {
println!("dropping Raii({})", self.0)
}
}
struct Statement<'c>(Raii, PhantomData<&'c u32>);
/* this should not be required because Raii implements Drop but this would prevent bad example from compiling.
impl Drop for Statement<'_> {
fn drop(&mut self) { }
}
*/
struct Foo<'c>(&'c Connection, Statement<'c>);
impl<'c> Foo<'c> {
fn new(connection: &'c Connection) -> Foo<'c> {
Foo(connection, connection.statement())
}
fn mu(&mut self) -> u32 {
((self.1).0).0
}
}
fn main() {
let c = || {
let connection = Connection(7);
/*
dropping Raii(42)
dropping Connection(42)
Err(Some(42))
*/
let mut foo = Foo::new(&connection);
foo.mu()
};
println!("{:?}", c());
let c = || {
let connection = Connection(42);
/*
dropping Connection(42)
dropping Raii(42)
Err(Some(42))
*/
// This should not compile: `foo` dropped here while still borrowed
Foo::new(&connection).mu()
};
println!("{:?}", c());
}
@jpastuszek
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment