this is a weird definition for unsafe rust.
as many already said, there's no such thing as "purely safe" rust, after all, all code must be lowerered down to llvm, which doesn't have the rich type system as rust, thus you cannot have the same safety properties. for example, most of the intrinsics in core are unsafe, and these intrinsics are major building blocks of the language.
at some point, all rust code compiles down to a smaller set of primitives, and most of such primitives are unsafe, so you can't determine a function is safe or unsafe by it's internal implementation, you have to draw a line somewhere, and for all intents and purposes, the standard library (particularly, the core crate) IS this line. if an API is not marked unsafe, such as core::mem::replace, then it can be used in safe rust, it doesn't matter what's the internal implementation.
as a counter example, do you consider the dereference operator * (exclusing raw pointers, which are defined to be unsafe) safe or unsafe? it should be safe right? it's an operator, how can that be unsafe?
but, operators are syntax sugars of some lang-item traits, for example, deferencing a Vec (directly or indirectly, e.g. by calling the .iter() method, which is defined for slice types) invokes library functions in the standard library. by your logic, impl Deref for Vec {} uses an "auxiliary" unsafe function, so it must be unsafe!
on the other hand, if we agree operators are safe (except defererencing raw pointers), in theory, we could just introduce new syntax, for example, we could add an operator for core::mem::swap() or core::mem::replace(), so instead of calling swap(&mut x, &mut y), we can write something like x <-> y, but at the end of the day, they must still be lowered to the same IR, and generating the same machine code. so does the surface syntax really matter?
to me, unsafe is more about semantics. as long you use only safe API, it is safe rust. for example, transmute() is unsafe, ptr::copy_nonoverlapping() is unsafe, but mem::take() is NOT unsafe.
don't get me wrong, I'm not saying every data structure can be implemented completely in safe rust: they CANNOT (EDIT: not as cleanly as one may want, after all we have shared ownership, weak pointers and interior mutability anyway, but they are clunky).
I'm just saying, your reasoning about safety regarding (potential unsafe) internal implementations of otherwise totally safe APIs is a bit off.
EDIT:
I want to asnwer the title question in short: as long as you agree owning pointer types like Box and/or allocating containers like Vec are safe rust, then many recursive data structures can be implement in rust without problem.