If you encounter a case where the solution to a problem was PhantomData or Pin, and the compiler doesn't flat out tell you that, file a ticket.
> PhantomData
Usually when you want to give type some information it wouldn't normaly have. Like e.g. using it to store generic type signature for some kind of SQL builder. or to keep a lifetime that would otherwise be unbound.
> Pin
Just for self-referential structs. Since async relies on self-referential, it might also require it.
---
When to use it? When you either exhaust all other options or know enough to judge it worthwhile.
Macros are easier than GAT, maybe, there is a whole talk how serde goes crazy with macros.
PhantomData or Pin are hard to grasp, not as concept, rather to keep track when they are needed, many times it isn't clear that the way to fix some compilation error is to plug one of those types. A bit like having to do references to constant literals as well, another gotcha.