use std::marker::PhantomData;
struct Struct1(u32);
impl Struct1 {
fn new() -> Self { Self(0) }
fn take_mut(&mut self) {
println!("{}", self.0);
}
}
struct Struct2<'a>(PhantomData<&'a ()>);
impl<'a> Struct2<'a> {
fn from_first(_: &'a Struct1) -> Struct2<'a> {
Struct2(PhantomData)
}
}
fn main() {
let mut first = Struct1::new();
let second = Struct2::from_first(&first);
// if this line is commented out, the code compiles
first.take_mut();
// EDIT: updated after first two comments
std::mem::drop(second);
std::mem::drop(first);
}
Intention of this code is to define drop order of Struct1 and Struct2 by using lifetimes. However, it seems that borrow checker doesn't let the code compile even though there is no actual borrow inside Struct1.
Lifetimes are done with a purely syntactic analysis. And because you are telling Rust that Struct2 may hold references into Struct1 (by tying their lifetimes together), it's invalid for you to call take_mut while that phantom borrow is active.