Anatomy of a rustc error message
Rust has two kinds of failure, and they look nothing alike. A compile error comes from rustc before your program exists: no binary is produced and nothing runs. A panic happens while the program runs: it prints a message, unwinds the thread and exits with code 101. Most of your time as a beginner is spent on the first kind, and the good news is that rustc error messages are among the most helpful of any compiler. They are worth reading slowly, top to bottom.
Compile error
- Starts with
error[E0xxx]: - Points at a file, line and column with an arrow
--> - No program is built, so nothing runs at all
- Usually ends with a
help:suggestion you can apply - Fix: change the code until
cargo checkis clean
Runtime panic
- Starts with
thread 'main' (id) panicked at - Gives the file:line:col where the panic fired
- Code before that line already ran and printed
- Set
RUST_BACKTRACE=1to see the call chain - Fix: handle the
None/Error the bad input the panic reveals
Here is a real diagnostic with every part labelled. The code borrows names[0], then pushes onto names while that borrow is still needed.
error[E0502]: cannot borrow `names` as mutable because it is also borrowed as immutable
--> main.rs:4:5
|
3 | let first = &names[0];
| ----- immutable borrow occurs here
4 | names.push(String::from("ben"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
5 | println!("{}", first);
| ----- immutable borrow later used hereThe full output ends with For more information about this error, try `rustc --explain E0502`.
- 1The headline
error[E0502]is the error code; the sentence after it is the rule you broke. Search the code, not the sentence: codes never change wording. - 2The location
--> main.rs:4:5is file, line, column of the primary problem. Editors make it clickable. - 3The primary span
The
^^^^underline marks where the rule was actually broken (line 4, the push). - 4Secondary spans
The
-----underlines tell the story around it: where the conflicting borrow started (line 3) and where it is still used (line 5). Read them in line order to see the conflict unfold. - 5note: and help:
A
note:adds context (often pointing into another function or the standard library). Ahelp:is a suggestion, frequently with a patch where+marks added text and~a changed line. Treat it as a strong hint, not gospel: it fixes the symptom the compiler sees, which is not always your design problem.
Every error code has a long explanation with a broken example and a fixed one, available offline:
$ rustc --explain E0499
A variable was borrowed as mutable more than once.
Erroneous code example:
```
let mut i = 0;
let mut x = &mut i;
let mut a = &mut i;
x;
// error: cannot borrow `i` as mutable more than once at a time
```
Please note that in Rust, you can either have many immutable references, or one
mutable reference. ...The same text lives online in the Rust error codes index. When you see several errors at once, fix the first one and recompile: later errors are often knock-on effects.
warning: (unused variable, unused Result, unreachable code) still produces a binary. Many real bugs show up first as a warning, such as a Result you forgot to check. Aim for zero warnings; CI pipelines often enforce it with RUSTFLAGS="-D warnings".