-
Notifications
You must be signed in to change notification settings - Fork 13k
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
PhantomData<T> no longer dropck? #70841
Comments
It fails to compile with the 2015 edition on 1.31, so it's probably caused by NLL. I suspect the issue is something like: |
Adding an unrelated field that has a destructor makes the error appear again |
Regression from 1.36: https://rust.godbolt.org/z/hnEi6A |
Assigning |
Should this error, though, if *no |
We definitely need to check into this, but I think @eddyb is correct that the special role of |
Injected between +nightly-2019-04-22 and +nightly-2019-04-23
So current guess is that this was fallout from PR #59114 |
And I have now confirmed that if you enable edition=2018, you will see this behavior going all the way back to Rust version 1.31.0 (i.e. back when we first deployed stable support for the 2018 edition).
So now I just want to confirm the running hypothesis that this is logical according to NLL. |
At this point I agree with the logic put forth by @eddyb and @nikomatsakis up above: There is no destructor operating on the type that holds the I do worry a little bit about the user's mental model for this case, however. The claim " More specifically, here is the current text from the std library docs for
So, it seems at the very least we have a documentation bug to resolve here... |
Does The way I understand it, and if I'm right, that's a solution for the documentation, is that, when there is no field containing an actual
So I think the simpler phrasing w.r.t. the
So, back to the OP, the question is: could / should the case |
Yes. First of all, it is also relevant for variance. For example: struct MyBox<T>(NonNull<T>);
// Mirror `Box` API, including `Drop`. This is unsound because of the lack of |
Could you provide an example of an implementation being unsound that does not use The following (case struct MyBox<T>(ptr::NonNull<T>);
/// Mirror `Box` API, including `Drop`.
impl<T> Drop for MyBox<T> {
fn drop (self: &'_ mut Self)
{
// ...
}
}
fn main ()
{
let (my_box, s): (MyBox<&'_ String>, String);
s = String::from("hi");
let at_s = &s;
let at_s_ptr = ptr::NonNull::from(Box::leak(Box::new(at_s)));
my_box = MyBox(at_s_ptr);
} The way I see it,
So, without step |
Hm... okay things don't work entirely as I thought they would. To rephrase what you said, a I still have an idea for a counterexample but it's getting tricky: a type not having |
Yeah that actually sounds like an interesting and potentially useful data structure (a "view" into untyped memory responsible for calling destructors on it before handing it back). Beyond the soundness issue, I also don't like this because it makes the rules more complicated. "treat PhantomData like T during structural recursion" is a simple rule that applies to other "auto traits" (to the extent that inherent drop impls are auto trait implementations), and I was hoping to use it for dropck as well. |
Are you sure dropck isn't using that rule, though? Your own example demonstrates that dropck works field-by-field. Isn't it just doing that here, too? (EDIT: Hm okay, in the original example replacing Arguably, dropck needs a special case for |
Or special case
|
@RalfJung I think I have managed to implement what you were talking about: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=22b7c3d56e8cadceb49210b51fdb3255
|
@danielhenrymantilla Yeah, something like that is what I was imagining... though your code still has I am not sure why |
@RalfJung I'm still confused about:
From my understanding of dropck, considering If it construct
If you want to construct a ub from the former, it is equivalent to finding a But I tried to construct such a And I'm not sure how this violates dropck:
|
Wow this is an ancient thread, and I lost all context. Could you link to the context where I said that?
Also I recently opened #103413, does that help?
|
Re-reading the thread above, it seems to be about the same fundamental question as #102810. Curious. My PR fixes the documentation paragraph that @pnkfelix quoted above
They also wrote
which is still true and would require pretty fundamental changes to NLL at this point. |
I know I'm just curious how the following code causes ub, and how it violates dropck rules:
|
Oh, I will note that :D.
But as the example in #103413 (comment), |
Yeah I read that thread after this one.^^ The summary is "it's complicated, hopefully we'll figure it out in #103413". Let's not re-post everything in two spots. :) |
PhantomData: fix documentation wrt interaction with dropck As far as I could find out, the `PhantomData`-dropck interaction *only* affects code using `may_dangle`. The documentation in the standard library has not been updated for 8 years and thus stems from a time when Rust still used "parametric dropck", before [RFC 1238](https://rust-lang.github.io/rfcs/1238-nonparametric-dropck.html). Back then what the docs said was correct, but with `may_dangle` dropck it stopped being entirely accurate and these days, with NLL, it is actively misleading. Fixes rust-lang/rust#102810 Fixes rust-lang/rust#70841 Cc `@nikomatsakis` I hope what I am saying here is right.^^
PhantomData: fix documentation wrt interaction with dropck As far as I could find out, the `PhantomData`-dropck interaction *only* affects code using `may_dangle`. The documentation in the standard library has not been updated for 8 years and thus stems from a time when Rust still used "parametric dropck", before [RFC 1238](https://rust-lang.github.io/rfcs/1238-nonparametric-dropck.html). Back then what the docs said was correct, but with `may_dangle` dropck it stopped being entirely accurate and these days, with NLL, it is actively misleading. Fixes rust-lang/rust#102810 Fixes rust-lang/rust#70841 Cc `@nikomatsakis` I hope what I am saying here is right.^^
PhantomData: fix documentation wrt interaction with dropck As far as I could find out, the `PhantomData`-dropck interaction *only* affects code using `may_dangle`. The documentation in the standard library has not been updated for 8 years and thus stems from a time when Rust still used "parametric dropck", before [RFC 1238](https://rust-lang.github.io/rfcs/1238-nonparametric-dropck.html). Back then what the docs said was correct, but with `may_dangle` dropck it stopped being entirely accurate and these days, with NLL, it is actively misleading. Fixes rust-lang/rust#102810 Fixes rust-lang/rust#70841 Cc `@nikomatsakis` I hope what I am saying here is right.^^
PhantomData: fix documentation wrt interaction with dropck As far as I could find out, the `PhantomData`-dropck interaction *only* affects code using `may_dangle`. The documentation in the standard library has not been updated for 8 years and thus stems from a time when Rust still used "parametric dropck", before [RFC 1238](https://rust-lang.github.io/rfcs/1238-nonparametric-dropck.html). Back then what the docs said was correct, but with `may_dangle` dropck it stopped being entirely accurate and these days, with NLL, it is actively misleading. Fixes rust-lang/rust#102810 Fixes rust-lang/rust#70841 Cc `@nikomatsakis` I hope what I am saying here is right.^^
Consider this code:
Playground
I believe it should not compile (by failing dropcheck). It, however, compiles and runs on 1.42 and 1.31. On 1.24 it indeed fails as I expect.
The equivalent code, where
PhantomData<T>
is replaced withT
rightfully fails to compiles: Playground. So, dropchk somehow observes the difference betweenT
andPhantomData<T>
?Either I misunderstand how
PhantomData<T>
is supposed to work, or this is a stable-to-stable regression and a soundless hole.The text was updated successfully, but these errors were encountered: