Skip to content

non-Drop types with drop glue leak may_dangle implementation details on stable #103318

@SoniEx2

Description

@SoniEx2

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);
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ef62faa188b41fd69f1561da05605db6

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);
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2c6e1a61081f093bab2b882e9ea676ae

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions