Last active
January 12, 2022 00:14
-
-
Save XrXr/3b25a08c3206f1e76d6e59cbb97a6fff to your computer and use it in GitHub Desktop.
Rust non-lexical lifetimes https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html#non-lexical-lifetimes
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
// Borrowing 101. Easy to see that the borrows don't overlap | |
// because everything is explicit and has a mapping to a | |
// lexical range in the source. | |
#[derive(Debug)] | |
struct NotCopy; | |
fn main() { | |
// owner (can move the value if it wants, responsible for calling destructor) | |
let mut obj = NotCopy {}; | |
let immutable_borrow = &obj; | |
let mutable_borrow = &mut obj; | |
dbg!(mutable_borrow); | |
// Uncomment this to get a borrow checker error. | |
// dbg!(immutable_borrow); | |
} |
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
// Borrowing 501. How long a borrow lasts is not strictly a lexical | |
// construct. Note that Rust references behave more similar to | |
// C pointers than C++ references. | |
#[derive(Debug)] | |
struct NotCopy<'a> { | |
num: i8, | |
/// References are always valid. For self reference we need | |
/// an initial state that doesn't have the reference so we | |
/// wrap it in Option. | |
/// | |
/// The borrow lasts for an arbitrary lifetime of 'a. We | |
/// are at the declaration site so we don't have information | |
/// as to exactly how long that is, merely a variable for now. | |
borrow_slot: Option<&'a i8>, | |
} | |
fn main() { | |
// owner (can move the value if it wants, responsible for calling destructor) | |
let obj = NotCopy { | |
num: 0, | |
borrow_slot: None, | |
}; | |
// move it, just for fun. | |
let mut same_obj = obj; | |
// Can't use obj anymore, cause it moved to same_obj. | |
// The following causes a compile error | |
// dbg!(obj); | |
// Make the struct borrow from itself (!!) | |
// This fills in the 'a lifetime variable declared in the struct. How long does | |
// the borrow lasts? As long as the lifetime of the ownership in this case | |
// because the struct borrows from itself. | |
same_obj.borrow_slot = Some(&same_obj.num); | |
// The point: unlike in lexical.rs, the immutable borrow (the `&`) from line above | |
// lasts for _longer_ than the line it is on. | |
// | |
// Because there is still a borrow outstanding, we can't move same_obj | |
// anymore. | |
// let _illegal_move = same_obj; | |
// We can't move it, but we can still borrow it. | |
dbg!(&same_obj); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment