Vibe Engines
YouTube

Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path

Learn RustChapter 1: Hello

Lesson 1.5 · 9 min

Reading what the compiler says

You are going to see a lot of compiler errors, and that is good news: every one of them is a mistake caught before your program ran. This lesson takes one message apart piece by piece, so the next time the compiler refuses your code you know exactly where to look and what it is asking for.

Adds to ChatterboxNothing new: you learn to read and fix compiler errors.

Compiler errors you will meet E0308

Mistakes are normal. Where they show up is not.

Everyone who writes programs makes mistakes all day: a missing quote, a name spelled two ways, a value of the wrong kind. The question is never whether you will make them, but who finds them.

In many languages the answer is "the program, while it runs": it gets halfway through and stops, perhaps in front of the person using it. In Rust, most mistakes are found earlier, by the compiler, before anything runs at all. It reads your whole program, and if something does not add up it refuses to build it and writes you a message saying what is wrong, where, and often how to fix it.

That message looks alarming the first time, with arrows and symbols and a code in brackets. It is actually very regular: the same few parts, in the same order, every time. Start with a mistake you will certainly make. What happens here?

PredictThe banner, without its quotes
fn main() {
println!("{} v{}", Chatterbox, "0.1");
}

Does this compile — and if it does, does it run?

  • It compiles and runs
  • Compile error E0425
  • Compile error E0308
Reveal the answer

It does not compile: E0425. Without quotes, Chatterbox is no longer a piece of text. It is a name, and the compiler goes looking for something called Chatterbox. Nothing in the program has that name, so it stops with E0425, "cannot find value". Quotes are what tell the compiler "this is text, take it as it is".

error[E0425]: cannot find value `Chatterbox` in this scope
 --> src/main.rs:2:24
  |
2 |     println!("{} v{}", Chatterbox, "0.1");
  |                        ^^^^^^^^^^ not found in this scope

The parts of a message

Look at the message from that predict, line by line. Every error the compiler prints has this shape.

You seeIt means
error[E0425]This is an error, so the program was not built. E0425 is the error's ID: every kind of mistake has its own number, and the same mistake always gets the same one.
cannot find value `Chatterbox` in this scopeThe headline: what went wrong, in one sentence. The backticks mark a piece of your code.
--> src/main.rs:2:24Where: the file, then the line number, then the column (how many characters from the left edge, counting from 1). Line 2, character 24 is exactly where Chatterbox starts.
2 | and your codeThe line itself, copied out with its number in the margin, so you do not have to go and find it.
^^^^^^^^^^The underline sits under the exact characters that are wrong. Words next to it, here not found in this scope, are the compiler talking about that spot.
help: and note:Extra lines that some messages carry. A help line suggests a fix, often showing the corrected line with + marks under what it would add, or as a pair of lines: - for the line as it is, + for the line as it could be. A note gives a fact that explains the error.
For more information about this error, try `rustc --explain E0425`.The last line: a command that prints a longer explanation of this error, with examples.

So read a message in this order: the headline for what, the arrow for where, the underline for exactly which characters, then any help line for what to try. Some messages also underline a second place with dashes, -----, instead of carets. Carets mark the spot that broke; dashes mark a place that explains why, such as where something was first made.

Typos: E0425

A program is full of names: main, banner, and soon names you invent yourself. The compiler matches them letter by letter, capitals included. It does not guess that baner was probably meant to be banner. But it does notice how close the two are, and says so.

Compiler CoachThe compiler, translated

This is the exact output of the real compiler. Toggle the English, then pick a fix and see what actually happens.

fn banner() -> String {
format!("{} v{}", "Chatterbox", "0.1")
}
 
fn main() {
println!("{}", baner());
}
error[E0425]: cannot find function `baner` in this scope
 --> src/main.rs:6:20
  |
1 | fn banner() -> String {
  | --------------------- similarly named function `banner` defined here
...
6 |     println!("{}", baner());
  |                    ^^^^^
  |
help: a function with a similar name exists
  |
6 |     println!("{}", banner());
  |                       +

E0425 in the compiler error atlas →

  1. cannot find function `baner` in this scope: line 6 asks for a function called baner, and no function has that name. (A scope is the part of the program where a name can be seen; for now, read it as "anywhere here".)
  2. The dashes under line 1 point at a function the compiler did find, banner, with the words similarly named function `banner` defined here. That is the compiler noticing the near miss.
  3. help: a function with a similar name exists shows line 6 again with the fix already made, and a + under the one letter it would add.
  4. It is the same error ID as the missing quotes above. Both mean the same thing: you used a name, and nothing in the program is called that.

Fixes that were compiled for real

  • Spell it the way the function is spelled — compiles. Add the missing <code>n</code>. This is exactly the change the help line showed.
  • Trap: fix the spelling but add a capital — still E0425. <code>Banner</code> and <code>banner</code> are different names to the compiler. Every letter has to match, including whether it is a capital.

The wrong kind of value: E0308

Every value in Rust has a kind, called its type: a piece of text, a whole number, true or false. The compiler checks that each value is the type the code around it expects. When it is not, you get E0308, mismatched types, and it always reads the same way: expected the type your code promised, found the type you actually gave.

Here is the most common case for a beginner. In the exercise of lesson 1.3, -> String promised that a function hands back a String. Quoted text looks like it should do, but it is a different type of text, so it does not.

Compiler CoachThe compiler, translated

This is the exact output of the real compiler. Toggle the English, then pick a fix and see what actually happens.

fn banner() -> String {
"Chatterbox v0.1"
}
 
fn main() {
println!("{}", banner());
}
error[E0308]: mismatched types
 --> src/main.rs:2:5
  |
1 | fn banner() -> String {
  |                ------ expected `String` because of return type
2 |     "Chatterbox v0.1"
  |     ^^^^^^^^^^^^^^^^^ expected `String`, found `&str`
  |
help: try using a conversion method
  |
2 |     "Chatterbox v0.1".to_string()
  |                      ++++++++++++

E0308 in the compiler error atlas →

  1. mismatched types: a value is not the type the code around it needs.
  2. expected `String` because of return type, under the dashes on line 1: the promise. -> String said this function hands back a String.
  3. expected `String`, found `&str`, under the carets on line 2: what you gave instead. Quoted text is a &str, a view of text that is baked into the program. A String is text the program owns and can grow. Chapter 2 is where the two get a lesson of their own.
  4. help: try using a conversion method suggests adding .to_string(), which turns the quoted text into a String. That dot form arrives in chapter 2; the two fixes below do the same job with things you have already seen.

Fixes that were compiled for real

  • Make a String from the quoted text — compiles. <code>String::from(…)</code> makes a new <code>String</code> holding a copy of the quoted text. The <code>::</code> in the middle is the path separator: <code>String::from</code> is the <code>from</code> that belongs to <code>String</code>. Now the value matches the promise.
  • Build it with format! — compiles. <code>format!</code> always hands back a <code>String</code>, which is why lesson 1.3 used it for text a function returns.
  • Trap: the right type, with a semicolon after it — still E0308. Still E0308, but now it says it found <code>()</code>, Rust's word for "nothing". The semicolon turned the last line into a step that produces no value. The next lesson explains exactly why.

Habits that make errors easy

  • Fix the first error first. One slip can confuse the compiler about the lines after it, so a single missing quote may produce several messages. Fix the top one, build again, and often the rest disappear. (The list is not always in line order: the compiler checks every name before it checks any types, so an E0425 further down can come before an E0308 near the top.)
  • Go to the line, then look one line up. The arrow points where the compiler noticed the problem. A missing bracket or quote is sometimes on the line before.
  • Read the help line before you change anything. It is often the exact fix. When it is not, it still tells you what the compiler was expecting.
  • Build often. cargo check from lesson 1.2 answers in a moment. Three new lines with one mistake are easy; forty new lines with five are not.
  • Look the ID up. rustc --explain E0308, typed in a terminal, prints a longer explanation with examples. This course also keeps an atlas of every error it shows you, each with a plain-words reading.

You will also meet warnings. A warning starts with warning: instead of error, and the program still builds: the compiler has spotted something that is allowed but probably not what you meant, like a name you made and never used. Read them too. They are cheap advice.

Try itYour turn: three mistakes, three messages

These are two of Chatterbox's opening lines, but someone typed them in a hurry and the program does not compile. Press Run, read the first message, fix the line it points at, and run again until it builds and the hidden tests pass. Do not rewrite the program: each fix is small.

These are two of Chatterbox's opening lines, but someone typed them in a hurry and the program does not compile. Press Run, read the first message, fix the line it points at, and run again until it builds and the hidden tests pass. Do not rewrite the program: each fix is small.

// Chatterbox's opening lines, typed in a hurry.
 
fn banner() -> String {
"Chatterbox v0.1"
}
 
fn tagline() -> String {
format!("{} answers every message.", Chatterbox)
}
 
fn main() {
println!("{}", banner());
println!("{}", tag_line());
}

Hidden tests (3): the_tagline the_banner the_bot_name_keeps_its_capital

This exercise runs real Rust in your browser through the official Rust Playground, so it needs JavaScript.

Self-check

Say it out loud, then reveal

Self-checkRetrieval beats re-reading
In <code>--&gt; src/main.rs:6:20</code>, what do the three parts tell you?Reveal
The file (src/main.rs), the line (6) and the column (20 characters from the left edge, counting from 1).
What is the difference between the <code>^^^</code> marks and the <code>---</code> marks under a line?Reveal
Carets mark the exact characters that are wrong. Dashes mark a related place that explains the error, such as where something was defined.
How do you read "expected String, found &amp;str"?Reveal
The code promised a String (expected), and the value actually given was a &str (found).
A program shows five errors. Which do you fix first, and why?Reveal
The first one. A single slip can cause the messages after it, so fixing the top one and building again often clears the rest.
Your Chatterbox so far: v0.1 (after lesson 1.4)
Chatterbox v0.1 after lesson 1.4: the whole program
src/main.rs
// Chatterbox: a small chat program, built one lesson at a time.
fn main() {
// The banner says who we are and which version this is.
println!("{} v{}", "Chatterbox", "0.1");
// Each {} is a hole. The values after the text fill the holes, in order.
println!("Hi {}! I'm {}.", "Sam", "Chatterbox");
println!("Type a message and I will answer.");
}

Download this version (zip)Unzip, then cargo run inside the folder.

That is lesson 1.5. Tick it off so the course remembers where you are.

Next: 1.6 Functions →

Questions people ask

What does error E0425 mean in Rust?

E0425 means the compiler cannot find a name you used: cannot find value or cannot find function. Usually the name is misspelled, has the wrong capital letter, or is a word that should have been in quotes.

What does mismatched types mean in Rust?

It is error E0308. A value is a different type from the one the code expects. The message says what was expected, which is what the code promised, and what was found, which is what you actually gave.

How do I read a Rust compiler error?

Read the headline for what went wrong, the arrow line for the file, line and column, the caret underline for the exact characters, and any help line for a suggested fix. Fix the first error first, then build again.

Are Rust compiler errors bad?

No. Each one is a mistake caught before the program ran, so it never reaches a user. Rust messages usually point at the exact spot and often suggest the fix.

How do I get more detail about a Rust error code?

Type rustc --explain followed by the code, for example rustc --explain E0308, in a terminal. It prints a longer explanation with examples. The same text is in the online Rust error codes index.

Learn Rust by building a chat app · Lesson 1.5 · every compiler message above is real output from rustc 1.99.0 (b940084d7 2026-09-28) (edition 2024) · Vibe Engines · 2026