You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am writing this here, because I feel like it belongs to unsafe-code-guidelines, I hope this is the right place to discuss it. It's more of a suggestion to put it in the guidelines than a real question.
Currently I see few problems with this concept.
Discoverability - ie. You don't know you need it unless you already know about it.
If there's a situation when you should use PhantomData<T> to signal that you own an allocation, compiler doesn't give you any warning, and there's very little information online about it. There's a great chance a lot of users never even heard about it, (at least I think).
It's not exactly clear what it does.
Docs + Nomicon say that it's needed for variance, which is more or less clear, but then it also says it's needed for drop check, which is not very well explained. Nomicon has a few paragraphs about that, but it's still unclear what exactly goes wrong if you don't specify PhantomData - it just "just leads to unsoundness" but why? I guess I'm just looking for a concrete example here.
It's unclear if you actually need it and how to use it
For example Docs and Nomicon only talk about use cases with generic types, so it's unclear if you should use it even for things that are not generic.
One specific problem I had is some simple wrapper around opened file from libc:
structMyFile{file:*mut libc::FILE}
There's a lot of questions about this code.
Is PhantomData<FILE> needed here?
Even when the struct is not generic?
Does it matter when this type is from libc? libc::FILE doesn't have a destructor, does it matter at all here?
This struct has a Drop impl that calls fclose . If I need PhantomData for drop check, why? Why is Drop impl not enough?
What goes wrong if I don't have PhantomData<FILE> field?
I think clarifying this example specifically would be great, because something like this will probably be the first experience with unsafe code for many users, given that a lot of Rust adopters have to interface with existing C/C++ code.
The text was updated successfully, but these errors were encountered:
libc::FILE doesn't impl Drop, so dropck doesn't matter for your example.
That said, the examples here are very bad. I regularly see people confused about how/when to use PhantomData, and the suggestion in the official docs
If your struct does not in fact own the data of type T, it is better to use a reference type, like PhantomData<&'a T> (ideally) or PhantomData<*const T> (if no lifetime applies), so as not to indicate ownership.
is very misleading. There are a number of alternatives here that are more appropriate for common PhantomData use cases before *const T, which will require manual Send/Sync impls.
So given that the variance aspect seems clear, on the technical level the biggest gap seems to be about dropck. And indeed dropck is rather confusing, but the lack of documentation is more of a Reference / Nomicon issue than a UCG issue -- which have already been filed:
I am writing this here, because I feel like it belongs to unsafe-code-guidelines, I hope this is the right place to discuss it. It's more of a suggestion to put it in the guidelines than a real question.
Currently I see few problems with this concept.
Discoverability - ie. You don't know you need it unless you already know about it.
If there's a situation when you should use
PhantomData<T>
to signal that you own an allocation, compiler doesn't give you any warning, and there's very little information online about it. There's a great chance a lot of users never even heard about it, (at least I think).It's not exactly clear what it does.
Docs + Nomicon say that it's needed for variance, which is more or less clear, but then it also says it's needed for drop check, which is not very well explained. Nomicon has a few paragraphs about that, but it's still unclear what exactly goes wrong if you don't specify PhantomData - it just "just leads to unsoundness" but why? I guess I'm just looking for a concrete example here.
It's unclear if you actually need it and how to use it
For example Docs and Nomicon only talk about use cases with generic types, so it's unclear if you should use it even for things that are not generic.
One specific problem I had is some simple wrapper around opened file from libc:
There's a lot of questions about this code.
Is
PhantomData<FILE>
needed here?Even when the struct is not generic?
Does it matter when this type is from libc?
libc::FILE
doesn't have a destructor, does it matter at all here?This struct has a
Drop
impl that callsfclose
. If I need PhantomData for drop check, why? Why is Drop impl not enough?What goes wrong if I don't have
PhantomData<FILE>
field?I think clarifying this example specifically would be great, because something like this will probably be the first experience with unsafe code for many users, given that a lot of Rust adopters have to interface with existing C/C++ code.
The text was updated successfully, but these errors were encountered: