Hacker News new | ask | show | jobs
by yazaddaruvala 3701 days ago
My Cargo wish list!

1. Like every enterprise build system I've ever gotten to use, I wish Cargo would manage the compiler version as well.

2. The compiler forces me to mark `unsafe` functions/blocks to use unsafe code. Why does Cargo not force me to mark `unsafe` dependencies to use unsafe code?[0]

[0] Only dependencies that explicitly use `unsafe` should need to be marked in my Cargo.toml. eg. Iron doesn't use `unsafe`, but Mio does. Iron depends on Hyper depends on Mio. If I have a dependence on Iron, I really want to be able to mark `#[unsafe_deep_dep] mio`, or else my build fails.

2 comments

At the fundamental level, the machine is unsafe. This means that if unsafe were transitive, all code would need to be marked unsafe. Use a String? Your crate needs to be marked unsafe.
We agree. I think there was a bit of misunderstanding. I don't think transitive unsafe is appropriate.

Only crates which use `unsafe` explicitly should need to be whitelisted.

Fun Example: I need to depend on Iron. Iron boasts in its README that it doesn't use `unsafe`. Cool.

However, Iron depends on Hyper. Hyper is complicated, it needs to use `unsafe`, I can understand that. Hyper is also used by a lot of people, I trust it, and whitelist Hyper. My build passes, I know only `std` and Hyper use `unsafe`.

Why is this helpful?

Hasn't happened yet but @reem, being human, adds an `unsafe`[0] and lets Iron's README go out of date. It happens. However, as a user, I don't like to trust documentation, and I don't like to trust other developers[1]. When I update to this version of Iron, I'd rather my builds now failed. Then I can decide if this escalation of responsibility is appropriate.

This is especially true in an enterprise context where teams of new hires do whatever it takes to push features, and "accidentally" push some really unsafe code to a deep dependency[2].

[0] Lets pretend this `unsafe` was actually used in production code: https://github.com/iron/iron/commit/ba4d197030067d4347134c2e...

[1] Hence my other preferences for type checking, core reviews, and tests.

[2] Not everything is manually catchable in code reviews. Sometimes its 3am. Sometimes whoever it was, was really new and the CR is 14 pages long and needs to be deployed Thursday! Sometimes a reviewer is just having an off-day. It happens.

Another really cool thing is:

Even slightly discouraging the use of unsafe via Cargo will push crate owners to find already trusted "miro-crates" which abstract their usage of unsafe. Imagine something akin to left-pad existed solely to abstract unsafe. Most crates already use it, so most teams already whitelist it. Using finding and using a micro-crate might mean less friction for users to add your dependency into their application.

Benefits:

1. Smaller the crate, smaller the surface area, better the audit-ability.

2. The more people using the same crate, the less probable there is a bug.

3. If a relatively small crate exists, solely for its abstraction of `unsafe`, and it is relatively popular, then that could be a good indicator for moving that logic into `std`.

> 1. Like every enterprise build system I've ever gotten to use, I wish Cargo would manage the compiler version as well.

With rustup.rs becoming official, it's a much better way to handle compiler versions since it handles cargo versions as well and allows the two to be coupled together. This allows for tighter integration between cargo and rustc as well as making testing of new versions of cargo significantly easier (i.e. there's no permutation matrix of whether cargo A.B.C works flawlessly with rustc X.Y.Z)

To me, as a user (rather than, as a dev), I don't really care about the "Single Responsibility Principle", and the difference between Rustup and Cargo seems artificial.

They are both binaries I need to install that help me manage my Rust application's dependencies. The only arguable difference is that Rustup manages "build dependencies" where Cargo manages "code dependencies". However, the tools I've used, managed both those concepts, and did so seamlessly (I wish I could share more).

Meanwhile, I don't believe Rustup.toml currently exists (I'd love to be corrected). Since other people like the difference between Cargo and Rustup, I'm happy to change my Wishlist 1.

1. I wish Rustup had a Rustup.toml file, such that my git repo could manage the currently used version of rustc. Primarily for consistency across teams, and seamless transition when I `cd ../<other_application> && cargo build`.

Rustup supports your wish with "rustup override".