Yes and no. That is, they're "auto traits"; they get implemented automatically for anything that can safely implement them. They only don't get implemented for things like raw pointers, or structs that contain raw pointers, and then they're unsafe to implement.
Is that by design, necessity or compiler/language deficiencies? I'm curious if this is something the language hopes to improve on over time in the name of fearless concurrency or it's simply not possible.
I think this statement from the grandparent post might have been misleading:
> If you're looking for concurrent code that doesn't use `unsafe` you won't find any.
The Rust standard library provides a bunch of concurrency primitives. You can write 100% safe Rust code use these primitives to do things concurrently, and Rust guarantees that your resulting program is free of a specific category of bugs: memory errors, data races, etc. No other mainstream language gives you this combination of concurrency safety and efficiency.
The implementation of the concurrency primitives, however, often includes assembly, or C, or unsafe Rust code, which the Rust compiler can't provide guarantees for. We have to rely on humans for that. This is the norm for almost all programming languages.
Ideally, yes, it would be nice if the safe subset of Rust were powerful enough to implement efficient concurrency primitives, but that would add a TON of complexity to the type system.
People are generally ok with the Rust standard library using assembly, C, or unsafe Rust, because even though it can be tricky to write this kind of code correctly, the standard library is maintained by Rust experts who take every change seriously.
People tend to worry more about third party libraries because, on average, the authors are not Rust language experts and may not understand the subtleties.
Yes, by "concurrent code" I meant relatively low level concurrency primitives/data structures not, for example, a web server which happens to use multiple threads. I probably should have been clearer, but I thought it would be clear from the context as the code GGGP was criticizing for using too much `unsafe` is a perfect example of the former.
exactly this.
i understand that it's necessary to have raw/unsafe/whatever-is-the-name code when you interact with the outside world, or to implement building blocks of the language. that's not my problem.
my problem is when you look at something innocent-looking third-party library like a http-header-parsing library, and it contains unsafe-blocks. again, i understand it will give it a boost of performance. it's just not the tradeoff i would take personally.
[EDIT]: clarified that i mean third-party libraries.
I don't like the "unsafe for me, but not for thee" attitude where "third-party" code is held to a different standard than the compiler/stdlib code. This attitude is especially strange to me when it doesn't distinguish between something relatively high level like your example of parsing http headers, and something quite low level like the concurrent data structure implementation we're discussing here.
Stepping back from concurrency for a second, you can't even implement `RefCell<T>` without `unsafe`. Any method that takes `&self` and performs "interior mutation" is unsafe to implement.
Not sure whether you would consider that to be by "design", "necesity", or a "compiler/language deficiency".
In principle it could perhaps be enforced by the compiler, but it would be very difficult. Whether something is memory-safe to Sync or Send across threads can depend on things like platform-specific atomic operations, thread-local storage, how panics and stack unwinds proceed, etc. Sounds like a nightmare for the compiler to make guarantees about. Maybe when compiling for a specific version of a specific OS, but to do it at the language level would be an incredible feat, and might make the language unusably complex.
Unless you require your programs to be formally verified or use dependent linear types, the best you can do is an effect system, STM and GC. There is no panacea.