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
My current understanding of PhantomData<T> is: You need it if your struct "contains/owns" a T, even though there is no field to reflect that fact.
But neither the nomicon nor the rust docs of PhantomData seem to confirm this:
If PhantomData truly indicated containment to the compiler, why does the Drain impl for the example vec use a lifetime bound for T?
pubstructDrain<'a,T:'a>{vec:PhantomData<&'a mutVec<T>>,// this should imply `T: 'a`iter:RawValIter<T>,}
In the past, you needed T: 'a, but that has since been removed by rfc2093.
Instead, the presence of a &'a T field indicates that T: 'a.
So if PhantomData behaved like a field of the same type, the lifetime bound should not be necessary, because it is inferred transitively, all the way from RawVec.
"This also in turn requires the annotation T: 'a, indicating that any references in T are valid over the lifetime 'a."
What makes it even more confusing is that there is a pretty consistent pattern: The nomicon, the rust docs, and the rust std source code use T: 'a when implementing reference-like types, but not for owning types like Vec.
Is T: 'a ever required if PhantomData is used?
I think it would be great if the nomicon could provide a definite answer to this question. And if PhantomData obsoletes T: 'a, it would be very useful to include some info about this being a thing of the past.
The text was updated successfully, but these errors were encountered:
I got curious about this and tried out a few examples in the playground. To me it seems that you are right @leddoo that T: 'a is no longer required to be spelled out. But I ran into a curious example that I wanted to share about PhantomData, references and ownership:
use std::marker::PhantomData;#[derive(Debug)]structSlice<'a,T>{ptr:*constT,phantom:PhantomData<&'a T>,}fnmain(){// This works because T: 'a is implied, thus 'scoped: 'scoped, which is true{let my_string = String::from("Meow");let borrow = &my_string;// borrow: &'scoped Stringlet s = Slice{ptr:&borrow,phantom:PhantomData};// ptr: &'scoped &'scoped Stringdbg!(s.ptr);}// As expected, the following does not compile:// T: 'a is implied -> 'scoped: 'outer, which is not true// let s = {// let my_string = String::from("Meow");// let borrow = &my_string; // borrow: &'scoped String// Slice{ptr: &borrow, phantom: PhantomData} // ptr: &'outer &'scoped String// };// dbg!(s.ptr);// The following example is a little surprising. It compiles fine.let s = {let my_string = String::from("Meow");Slice{ptr:&my_string,phantom:PhantomData}// I guess// ptr: &'outer String// but who owns `my_string`?};dbg!(s);// Debug info:// s = Slice {// ptr: 0x00007ffe557fad20,// phantom: PhantomData<&alloc::string::String>,// }}
My current understanding of
PhantomData<T>
is: You need it if your struct "contains/owns" aT
, even though there is no field to reflect that fact.But neither the nomicon nor the rust docs of PhantomData seem to confirm this:
If PhantomData truly indicated containment to the compiler, why does the
Drain
impl for the example vec use a lifetime bound for T?In the past, you needed
T: 'a
, but that has since been removed by rfc2093.Instead, the presence of a
&'a T
field indicates thatT: 'a
.So if PhantomData behaved like a field of the same type, the lifetime bound should not be necessary, because it is inferred transitively, all the way from RawVec.
The PhantomData docs explicitly state that
T: 'a
is required:"This also in turn requires the annotation T: 'a, indicating that any references in T are valid over the lifetime 'a."
What makes it even more confusing is that there is a pretty consistent pattern: The nomicon, the rust docs, and the rust std source code use
T: 'a
when implementing reference-like types, but not for owning types like Vec.Is
T: 'a
ever required if PhantomData is used?I think it would be great if the nomicon could provide a definite answer to this question. And if PhantomData obsoletes
T: 'a
, it would be very useful to include some info about this being a thing of the past.The text was updated successfully, but these errors were encountered: