Change:
I need to give a Rust slice to a C API that will return an opaque handle (that actually contains a pointer to the slice), and the slice must outlive the handle. nicely suggested using for this, but the description of phantom data (and its RFC) for me is so far removed from my mental model/terminology of the problem, that it . "…tell the compiler about fake fields" — fake field doesn't sound like a thing I want to create. I'm not sure if a fake field is an actual Rust concept. I'm hoping it's a different way of saying a "pointer that Rust isn't keeping track of". "inform the compiler that one or more instances of the type T could be dropped" — but does it actually drop anything? I want to prevent value from being dropped, so this confuses me. The RFC is even worse, since it uses type variance terminology which is so confusing, that the most comprehensible description of them on Wikipedia is a 3D cube! !
allows you to describe that a type acts as if it stores a value of type , e.g. maybe one is having to use opaque pointers or otherwise disguise the fact that there is a contained in the value, or need to have a lifetime without having an actual reference to attach it to. This is what is meant by "fake field": a field doesn't actually store any data, but it behaves as if it does. If you have a lifetime, and the type is acting like a reference, then (or ) is the recommended approach. It's hard to be more specific without knowing your exact use-case, though. In any case, the major motivation for is to avoiding having to think in terms of co*variance, and instead just think of what the intended "storage" of a type is. The RFC is meant to serve as a technical reference to describe the behaviour unambiguously. I definitely agree that the current docs are not as helpful as they could be.
I see you've used lifetime as part of 's type. In my code I've used and got confusing error messages. That bit in the documentation would help a lot! (just saying is very unhelpful) BTW: the first paragraph in your comment is already clearer to me than the documentation :)
The example seems relevant. A previous example was referenced at the though I think rustbyexample is clearer. Note that the syntax of this example has changed recently. That didn't used to be required. If indeed what you need is something similar, you should flag it on rustbyexample for a more practical example. I was only aware of using phantom types in for use cases like unit system manipulation and such. If you can provide the gist of what other things they can be used for I can probably shoehorn it into an rustbyexample example(s) (there's IRC if I get stuck). Though I don't know when I'd get to it.
is designed as a low-level building block to enable certain types of unsafe code to be written safely. The relationship to phantom types (as used for dimensional analysis etc.) is the name (almost-coincidence) and the fact that the language doesn't allow type parameters to be left completely unused (meaning a phantom type has to be mentioned, e.g, in , to let the code compile). Almost instances of phantom types for dimensional analysis won't care about the precise variance (unlike unsafe/low-level code) and so just need to make the compiler shut up. :)
great that you've made progress!
Okay. The distinction between them is definitely unclear then too (in the docs).
If it's just to make the compiler shut up, then it's a good indication that the old default was better (not needing PhantomData for most unused type parameters).
I sympathize. PhantomData and PhantomFn are Byzantine to me as well, and I'm hitting several issues in rlibc because of them.
, because unused parameter did absolutely nothing, even when I used a parameter with the same name a method. I don't mind having a marker, I just needed to learn how to use it.
To be clear, it is just the use of 'unused' type parameters for dimensional analysis/tagging where the details of the precise used aren't so important. It is extremely important for data structures building on (or otherwise not using their lifetime/type parameters directly internally) to get their uses correct, as they are actually informing the compiler of information necessary for safety. There has been a regular stream of bugs/problems discovered in types in this repo due to the old default not helping with code. (I imagine that many external libs with data structures have had to insert 's since the change... meaning they were likely incorrect too.)

Discussion:
#[stable(feature = "rust1", since = "1.0.0")] pub trait PhantomFn<A:?Sized,R:?Sized=()> { } <del> /// `PhantomData` is a way to tell the compiler about fake fields. /// Phantom data is required whenever type parameters are not used. /// The idea is that if the compiler encounters a `PhantomData<T>` /// instance, it will behave *as if* an instance of the type `T` were /// present for the purpose of various automatic analyses. </del> <ins> /// `PhantomData<T>` allows you to describe that a type acts as if it stores a value of type `T`, /// even though it does not. This allows you to inform the compiler about certain safety properties /// of your code. /// /// Though they both have scary names, `PhantomData<T>` and "phantom types" are unrelated. 👻👻👻 </ins> /// /// # Examples /// /// When handling external resources over a foreign function interface, `PhantomData<T>` can <del> /// prevent mismatches by enforcing types in the method implementations, although the struct /// doesn't actually contain values of the resource type. </del> <ins> /// prevent mismatches by enforcing types in the method implementations: </ins> /// /// ``` /// # trait ResType { fn foo(&self); };

/// commonly necessary if the structure is using an unsafe pointer /// like `*mut T` whose referent may be dropped when the type is /// dropped, as a `*mut T` is otherwise not treated as owned. <del> /// /// FIXME. Better documentation and examples of common patterns needed /// here! For now, please see [RFC 738][738] for more information. /// /// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md </del> #[lang="phantom_data"] #[stable(feature = "rust1", since = "1.0.0")] pub struct PhantomData<T:?Sized>;