Is PhantomData needed without generics?

Taking the "this compiles and runs fine" example of PhantomData and dropck confusion - #2 by Yandros, and reducing its "type genericity" to a lifetime genericy, we still get a UAF when not using PhantomData:

In summary, there are three usages of PhantomData:

  • removing auto-traits, such as Send, Sync, Unpin (or Freeze). This does not require generics, so this is a clear case where usage of PhantomData would be "needed" (until, if ever, negative impls get stabilized).

  • removing accidental co[ntra]variance (in some way, one could perceive variance as a form of auto-traits, but for generic types / type constructors). But contraty to auto-traits, variance makes no sense outside of a generic context / type constructors. Thus, without generics, no variance whatsoever, and thus no need for that usage of PhantomData

  • "expressing ownership" (c.f., the linked post). The only case where that is useful, AFAIK, is when using the unsafe #[may_dangle] unstable feature (definitely the Rust feature with the most scary name, safety-wise :sweat_smile:). And given that such (terrifying) attribute can only be applied to a generic parameter, then the answer seems to go in your direction.

That being said, some people may consider that a type like &str is not generic (we know what it is: a reference to a str!), or at least not truly generic (contrary to something like <T> / Option<T>; etc.). But such genericy suffices to bring variance questions, as well as "ownership expressiveness" questions, as I showed at the beginning.

1 Like