Rust path · Ownership · Topic 1 of 12

Cargo, crates and editions

Not started

Cargo is Rust's build system and package manager in one. cargo new makes a project, cargo build compiles it and its dependencies, cargo test runs the tests, cargo run builds and runs, and cargo add adds a dependency from crates.io. The compiler, rustc, works on one **crate** at a time: a tree of modules that compiles to a library or an executable. Cargo works out which crates to build, in which order, with which flags.

Why it matters: Every Rust project starts with Cargo. Knowing how it resolves versions, what Cargo.lock is for, and what an edition does saves you from confusing builds and failed upgrades.

  1. 1A crate is a compilation unit

    A binary crate builds an executable, a library crate builds something others depend on. A package (one Cargo.toml) holds one or more crates.

  2. 2Semver by default

    serde = "1.0" means any compatible 1.x from 1.0 up. Cargo picks the newest compatible version and records it in Cargo.lock.

  3. 3Editions are opt-in, per crate

    The edition key selects language rules (2015, 2018, 2021 or 2024). Crates of different editions link together freely.

  4. 4Debug and release profiles

    cargo build is fast to compile and slow to run; cargo build --release turns optimisations on. Benchmark only release builds.

1

How it works

The explanation, with examples you can run.

Cargo.toml and Cargo.lock

[package]name = "shop"version = "0.1.0"edition = "2024" [dependencies]serde = { version = "1.0", features = ["derive"] }tokio = { version = "1", features = ["full"] } [dev-dependencies]proptest = "1" [profile.release]lto = true
  • Version requirements are semver ranges. "1.0" means ^1.0: at least 1.0.0 and below 2.0.0. For 0.x versions the minor number counts as breaking, so "0.8.3" allows up to, not including, 0.9.0.
  • Cargo picks the newest version that satisfies everyone (unlike Go's minimal version selection) and writes the exact choice to Cargo.lock. Later builds reuse the lock until you run cargo update. With the 2024 edition the resolver also prefers versions whose declared rust-version your toolchain supports.
  • Two incompatible major versions of one crate can both appear in a build. That works, but their types are different types, which is a common source of puzzling "expected X, found X" errors.
  • Features are optional parts of a crate you switch on. Features are additive: if any crate in the graph enables one, every user of that crate gets it.

Profiles

cargo build uses the dev profile: no optimisation, debug assertions and integer overflow checks on. cargo build --release optimises, which can make code many times faster. Iterators, generics and other zero-cost abstractions only become zero-cost once the optimiser runs, so never measure performance in a debug build.

Editions

An edition is a set of language rules chosen per crate with the edition key. New editions come out every few years (2015, 2018, 2021, and 2024 with Rust 1.85) and may change syntax or defaults in ways that would otherwise break code. The rule that makes this work: crates of every edition interoperate, so each crate migrates when it is ready. cargo fix --edition applies most of the mechanical changes.

The 2024 edition, for example, requires unsafe extern blocks and #[unsafe(no_mangle)], changes how long temporaries in if let and at the end of a block live, makes impl Trait return types capture all lifetimes in scope by default, reserves the gen keyword, turns references to static mut into an error by default, and marks std::env::set_var as unsafe. cargo new picks the newest edition.

The rest of the toolbox

cargo fmt (rustfmt) formats code, cargo clippy adds hundreds of lints, cargo doc --open builds documentation for your crate and every dependency, and rustup installs and switches toolchains. A rust-toolchain.toml file pins the toolchain version for a project.

2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.Cargo.toml says rand = "0.8.3". Which versions can Cargo choose?
  2. 2.Your library uses the 2024 edition and depends on a crate written for 2018. What happens?
  3. 3.Should an application commit Cargo.lock?

0 of 3 right so far. Get all three to finish this topic.