-
-
Save jpastuszek/0471b276e6ec4fe187c4731b1581a303 to your computer and use it in GitHub Desktop.
Drop and pahntom ref unsound drop order
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Explanation about temp at the end of expression:
https://www.reddit.com/r/rust/comments/6dynjz/psa_temporaries_in_final_expression_in_block_live/