Edit: Looks like for multithreaded code they suggest you use thread sanitiser, so in multithreaded code it doesn't enforce memory safety. At the same time, I don't see a history of memory safety issues with Swift compared to C and C++, I don't see this being a big deal in practice, particularly if you adopt the strict concurrency checking.
I use Swift at my job, and all I can say is anecdotally we've had a ton of problems with memory safety.
- Swift has a feature where you can unwrap a nullable which is basically just unusable, as it completely crashes the entire program if it fails, with no way for you to gracefully handle it or present a message to the user. And it's a massive footgun, since it has such convenient syntax that makes it seem like it should be used. But no, you have to avoid to like the plague.
- There are some Apple APIs where they just disregard their own types, and pass nil to your callback where the type says it's non nullable. This means if you access the var at all, crash.
- Concurrent access of dictionary, crash. And very hard to track down why as well since it can be very intermittent; in our case we were using an asynchronous dispatch queue instead of a sync one, so a single keyword. Oops!
- Stack overflow, crash.
- This isn't really Swift's fault, but in general every single macOS API is riddled with bugs and undocumented behavior. As a matter of fact, I would venture to say that almost every macOS API is virtually undocumented, either since there is literally no documentation or the existing documentation is just names of functions and occasionally an extremely out of date sample app.
So IMO it's about as memory safe as C. We're floating around the idea of just porting everything to Rust and moving on, haven't researched or committed to it yet though.
I don't see how any of what you said makes Swift memory unsafe. Memory safety is about security, not about whether or not the program crashes, in fact you want a crash as opposed to continuing on which could admit corruption.
From that article I linked:
If you have conflicting access to memory from within a single thread, Swift guarantees that you’ll get an error at either compile time or runtime.
Does any of what you said lead to a vulnerability that can be exploited?