> For crates where you don’t need or want new features, bug fixes etc, you could consider pinning their versions.
It seems to me that you should _always_ pin your dependency versions. I'd go so far as to say that build tools shouldn't even have an option to automatically pull the latest - "version" should be a required field for all dependencies (and, ideally, that gets decorated with a hash after the first download).
Yes this means you might miss out on security fixes that you'd otherwise get automatically. But having the code that you run & ship change absent your intention just feels like a bizarre default approach.
This is exactly why cargo uses a lock file that does pin your dependencies as described for binary crates, but does not use the same mechanism for libraries. https://doc.rust-lang.org/cargo/faq.html#why-do-binaries-hav...
Crate C depends on them both. It now can't bring in updates to A until B does, and when B updates that's a breaking change, so it better bump its major version.
Take a look at this trick, for example, for foundational crates updating their major version: https://github.com/dtolnay/semver-trick
Now imagine that being an issue every single patch update.