After cargo new, it's tempting to compile a single file directly with rustc src/main.rs. That isn't the same compiler setup. Cargo.toml says edition = "2024", and Cargo passes that to rustc for you; plain rustc on its own defaults to the 2015 edition. Code that is perfectly valid in your project, like calling u8::try_from, which the 2021 prelude brought into scope, fails to compile when you skip Cargo.
$ cargo new hello_rust && cd hello_rust
# src/main.rs:
# let level: i32 = 300;
# match u8::try_from(level) { Ok(v) => ..., Err(_) => println!("{} does not fit in a u8", level) }
$ cargo run
300 does not fit in a u8
$ rustc src/main.rs
error[E0599]: no function or associated item named `try_from` found for type `u8` in the current scope
= help: items from traits can only be used if the trait is in scope
help: trait `TryFrom` which provides `try_from` is implemented but not in scope; perhaps you want to import itrustup is the official installer and version manager for the Rust toolchain (the compiler rustc, and Cargo). Cargo is Rust’s combined build tool and package manager: it compiles projects, runs tests, manages dependencies declared in Cargo.toml, and publishes packages (called crates) to the central registry, crates.io.
Installing with rustup
rustup is installed via a shell script from rust-lang.org, and manages everything else — including keeping multiple toolchain versions side by side and switching per-project.
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ rustc --version
rustc 1.95.0 (59807616e 2026-04-14)
$ cargo --version
cargo 1.95.0 (f2d3ce0bd 2026-03-21)
# the toolchain these pages were verified on; a fresh install gives the
# current stable (1.99.0 as of October 2026), and `rustup update` upgradesCreating a project with Cargo
cargo new scaffolds a project with a Cargo.toml manifest and a src/main.rs entry point already wired up; cargo run compiles and runs in one step.
$ cargo new hello_rust
$ cd hello_rust
$ cargo run
Compiling hello_rust v0.1.0 (/path/to/hello_rust)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.42s
Running `target/debug/hello_rust`
Hello, world!That's the reason to let Cargo drive the compiler, as above: cargo run and cargo build read the edition from Cargo.toml (and the dependency list), while bare rustc knows nothing about the project. rustc --help says it directly: "The default is 2015". If you do need rustc by hand, pass the edition yourself:
$ rustc --edition 2024 src/main.rs && ./main
300 does not fit in a u8Cargo.toml and adding dependencies
Dependencies (crates) are declared in Cargo.toml under [dependencies], following semantic versioning; cargo add can add one from the command line directly. Cargo.lock, generated automatically, pins the exact resolved versions for reproducible builds — comparable to go.sum or package-lock.json.
[package]
name = "hello_rust"
version = "0.1.0"
edition = "2024"
[dependencies]
serde = "1.0"
tokio = { version = "1", features = ["full"] }