Description
I tried this code:
use core::cell::Cell;
// use core::marker::PhantomData as PDOrBox;
struct PDOrBox<T> {
n: String,
m: core::mem::ManuallyDrop<T>
}
//use std::boxed::Box as PDOrBox;
struct Foo<'a> {
selfref: Cell<Option<&'a Foo<'a>>>,
}
impl<'a> Drop for Foo<'a> {
fn drop(&mut self) {
}
}
fn make_selfref<'a>(x: &'a PDOrBox<Foo<'a>>) {}
fn make_pdorbox<'a>() -> PDOrBox<Foo<'a>> {
unimplemented!()
}
fn main() {
let x = make_pdorbox();
make_selfref(&x);
}
use core::cell::Cell;
// use core::marker::PhantomData as PDOrBox;
struct PDOrBox<T> {
n: String,
m: core::marker::PhantomData<T>
}
//use std::boxed::Box as PDOrBox;
struct Foo<'a> {
selfref: Cell<Option<&'a Foo<'a>>>,
}
impl<'a> Drop for Foo<'a> {
fn drop(&mut self) {
}
}
fn make_selfref<'a>(x: &'a PDOrBox<Foo<'a>>) {}
fn make_pdorbox<'a>() -> PDOrBox<Foo<'a>> {
unimplemented!()
}
fn main() {
let x = make_pdorbox();
make_selfref(&x);
}
I expected to see this happen: These should behave identically.
Instead, this happened: Implementation details of parametric dropck, also known as may_dangle, which is an internal unstable feature, leak to stable, so one of these complies while the other doesn't.
We honestly, after a lot of discussion and reading a lot of RFCs related to dropck, think both of these should compile. A quick fix would be to treat PhantomData like ManuallyDrop when outside an explicitly Drop type, and fall back to the existing behaviour for may_dangle. A proper fix would be to change may_dangle to be non-parametric, but that's gonna require an (e)RFC :). (N.B.: ManuallyDrop is unsound with may_dangle, but that's already acknowledged by may_dangle being unsafe.)
Meta
rustc --version --verbose
:
playground, N/A
Backtrace
N/A