Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
SoniEx2 opened this issue Oct 20, 2022 · 3 comments
Closed
Labels
C-bug Category: This is a bug. needs-triage-legacy Old issue that were never triaged. Remove this label once the issue has been sufficiently triaged.

Comments

@SoniEx2
Copy link
Contributor

SoniEx2 commented Oct 20, 2022

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

@SoniEx2 SoniEx2 added the C-bug Category: This is a bug. label Oct 20, 2022
@SoniEx2 SoniEx2 changed the title non-Drop types with drop glue leak parametric dropck on stable non-Drop types with drop glue leak may_dangle implementation details on stable Oct 22, 2022
@comex
Copy link
Contributor

comex commented Oct 23, 2022

(N.B.: ManuallyDrop is unsound with may_dangle, but that's already acknowledged by may_dangle being unsafe.)

What do you mean by unsound?

@SoniEx2
Copy link
Contributor Author

SoniEx2 commented Oct 23, 2022

/// Swallow dropck requirements of T while still dropping it, because
/// `ManuallyDrop` doesn't own `T` as far as dropck is concerned.
struct Wrapper<T>(ManuallyDrop<T>);

unsafe impl<#[may_dangle] T> Drop for Wrapper<T> {
  fn drop(&mut self) {
    unsafe {
      ManuallyDrop::drop(&mut self.0);
    }
  }
}

struct PrintOnDrop<'a>(&'a str);
impl<'a> Drop for PrintOnDrop<'a> {
  fn drop(&mut self) {
    println!("{}", self.0);
  }
}

fn main() {
  let s = String::from("hello");
  let pod_wrapper = Wrapper(ManuallyDrop::new(PrintOnDrop(&*s)));
  drop(s);
}

@ChrisDenton ChrisDenton added the needs-triage-legacy Old issue that were never triaged. Remove this label once the issue has been sufficiently triaged. label Jul 16, 2023
@Enselic
Copy link
Member

Enselic commented Jul 29, 2024

Triage: Thank you for taking the time to file an issue. Based on the discussion in #103413 it seems unlikely that a regular issue is going to be enough to make any changes. For that reason I propose that we close this, as it seems unlikely to lead anywhere at this point. Maybe you could consider writing an RFC for this.

@Enselic Enselic closed this as not planned Won't fix, can't repro, duplicate, stale Jul 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. needs-triage-legacy Old issue that were never triaged. Remove this label once the issue has been sufficiently triaged.
Projects
None yet
Development

No branches or pull requests

4 participants