I have noticed that AtomicPtr, despite being just a way to atomically set a pointer (the address not the value being pointed to), is Send + Sync, therefore providing a Send + Sync *mut T.
*mut T is explicitly !Send + !Sync, because it is possible to cause race conditions with *mut T.
This is still entirely true for AtomicPtr.
So why is AtomicPtr Send + Sync?
Edit: The moment i created the thread i see another one from 2015. AtomicPtr used to be !Send + !Sync.
An alternative question:
You can't cause UB sending a *mut T (or &*mut T) without unsafe somewhere else (relatedly: *mut T are Copy). So why make them !Send and !Sync?
Answer: While this can't cause UB on its own, its very hard to get correct and the compiler can't really help you do so. Therefore they are !Send and !Sync as a sort of non-negotiable lint to try to force you to write some unsafe specifically considering the Send/Sync requirements.
(At least, that was the original reasoning as I recall it.)
This still holds true for AtomicPtr, which is why it was !Send + !Sync, so why is it Send + Sync now?
Because otherwise it's relatively useless as an atomic; you couldn't share it between threads without, say, making a wrapper around AtomicPtr that does implement Send and/or Sync.
And I think it's safe to say that anyone using AtomicPtr<T> and writing unsafe code is probably going to think about threadsafety much more than the average person using *mut T.
I didn't find any evidence that was actually the case (but pre-1.0 discussion is hard to find, and auto-traits were in flux when the type was being fleshed out, so I'd welcome any citation).
E.g.