The difference is the endorsement of the standard library content and the fact it's a single, trusted source.
If you look on lib.rs or crates.io, it's not hard to find several crates that do random number generation, but you must choose one of them. That's the potentially confusing part, as I explained.
Indeed. It's not the first time we see something like that: there's been Libz Blitz, an initiative to bring some 3rd-party crates at a similar level, and curated lists like stdx, blessed.rs, Awesome Rust... The problem is maintaining that in the long run. Maybe this idea would be more successful, who knows.
I believe that. What I like about the battery pack idea is that they are just crates, so there is nothing special to learn in order to use them. But someone has to create them!
BTrees are notably slower for the majority of tasks than the hashsets/maps. As far as I know it's usually hard to beat hash-maps in performance with anything else. So, unless you really need entries to be in order (which sometimes you need), or if you don't care that much about performance, BTrees perhaps should not be a go-by-default solution. Additionally, for some tasks B+ Trees are more preferable than B-Tress, which Std currently is not supporting either.
Besides this, the main problem here is that the 3rd part solutions are not standardized as common, widely used interface. For example, parking_lot considered by many as better alternative (and maybe still is) for Std's sync. But what happens if one day parking_lot becomes abandoned? Furthermore, if the public interfaces of my project expose references to types of the 3rd party crates, not only my internal implementation, but also my users became vendor-locked to that crate. Which in turn raises a problem of cross-crate public API compatibility.
The main feature of including theoretically separable Std things is to provide the minimal cross-crate interchanging interface with certain (typically more strong) guarantees on the long-term maintenance.
Of course, this "what happens if parking_lot becomes abandoned is a problem for std, too - what happens if std::sync becomes abandoned because everyone uses parking_lot instead?
You're implicitly saying that you expect std to be maintained forever, even if the things in std turn out to be bad ideas - but that's the same reason people expecting you to use community crates give for not putting things into std, because then they don't have to be maintained forever.
No, I don't expect Std to be maintained forever. Every project ends somewhere. But when it happens, in a distant future, perhaps Rust will cross the line of old age. And I don't expect any crate to outlast longer than Std.
Other crates could be maintained by the same organization that maintains std, not it's not really an argument for putting things in the same std crate.
Interestingly to me, many people in the Zig community have almost the opposite take on this topic. They put the responsibility for maintaining dependencies on the person using them: before you depend on something, you should be aware that you're committing yourself to fork and maintain it. This means that reducing dependencies becomes more important. Also, unlike Rust, there is nothing special about the way the compiler treats code in Zig's std library. So you're free to replace std completely without losing capability. So those who are unhappy with the std library have a way out of using it.
I don't know whether that's a good approach or not, but it makes me wonder. For example, is the code in Rust's std that is specially treated by the compiler, fairly isolated and well known? If not, this might be a good goal. Then if HashMap does not get special treatment, it can be obsoleted by a better alternative in a crate and there isn't a lot of harm done. Allowing for evolution is definitely an advantage.
Most of the really special stuff is in core, and they're mostly only special in that they provide a "lang item" (via attribute) and have an expected layout so the compiler can generate code for it.
There's some stuff like "built-in" operations like the pointer deref implementation only existing for type checking and the like, so the implementation in the library looks infinitely recursive, a bunch of magic macros, etc.
One of the biggest exceptions is Box, which is a Very Special Boy who gets all sorts of special treatment (partial assignment, borrow checking, etc), but I believe that's something that's being worked on not just to reduce the risk of miscompilation, but because lots of other types in std, let alone user types, would love to be able to access those special behaviors.
There's plenty of special stuff in the compiler itself (features) that (stable) std gets to take advantage of, like may_dangle (used by every collection).
So you can have code compile with the stdHashMap which fails borrow check with hashbrown (on stable), for example.
I guess it depends on if you read "code in std that's treated specially by the compiler" as "code that the compiler needs to be provided by std in a special way for the compiler to work" vs "stuff that because it's in std gets abilities that 'user' code doesn't"
I was talking more to the first, but yeah, there's a lot of the second too - I'm not sure how much of that is actually critical for what @jumpnbrownweasel is after, eg I think the relaxed orphan rules are needed to provide the exact interface the general crates interface uses, but if you just want any "standard" library with some updated interface I think the bar is quite a bit lower.
Ideally (to me) everything in std, that is possible given the design of Rust of course, should be doable in a crate. If that's a priority, it would mean not adding such features to std unless/until they can be used by crates as well. I'm guessing many of those things in std (that are not currently possible in crates) were done with the assumption that most everyone will use the std collections, etc, and therefore it is worth the special treatment by the compiler, at least temporarily.
But that's easy for me to say! Doing it is not a small thing and takes lots of time.
AIUI, the issue with std is that std is allowed to use unstable features, even on stable, mostly as a way to ensure that unstable features get testing from a group who's going to provide "experience reports" to the compiler team, and will cooperate with trying to find a fix for any problems found.
This leads to problems when std uses features that are useful, but don't have a good path to stabilization (e.g. specialization with its soundness hole) - you can't stop using it where it's useful without sacrificing performance, but equally, because it's not on the path to stable, it can't be used in crates that target stable right now.
But at least in theory, everything that's implemented in std (apart from "lang items") for a given toolchain version can be implemented on nightly (albeit that you may need to forward-port as the unstable features change on their path to stability), and also on a future stable version of Rust once the necessary unstable features are stabilized.