What a name error is
Every name in a Rust program has to refer to something the compiler already knows about: a variable you declared, a function you defined, a macro from the standard library. When you write a name that matches none of them, the compiler can't continue. It reports cannot find and stops. Because Rust compiles the whole program before running any of it, a name error means nothing runs at all. No line before the mistake is executed or printed either.
Most name errors are typos. A few come from case (Rust names are case-sensitive) or from using a variable somewhere it isn't visible.
Two kinds of mistake: syntax and names
A syntax error means the code is not written in the shape the language allows, like a sentence that is missing a verb. A name error has perfectly valid shape, but one of the words is unknown. The compiler tells them apart in its message.
A string that opens with a single quote and closes with a double quote is a syntax problem. This line is rejected with error[E0765]: unterminated double quote string:
let greeting: &str = 'Hey there!";
Leaving out the ! and parentheses of a macro call is a syntax problem as well:
println "Hey";
The compiler reports expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"Hey"`. It lists what it would have accepted after println, and a string literal isn't on the list.
Misspelled macros and variables
The two name errors this lesson focuses on look alike but get different messages.
A misspelled macro
In Rust, println! is a macro, which is why its name ends with !. If you misspell it:
prntln!("Welcome!");
the compiler answers with error: cannot find macro `prntln` in this scope. It also looks for similar names, notes that println exists, and suggests the corrected line. Capital letters count too: Println! gets the same kind of message.
A misspelled variable
With a variable, the error carries a code, E0425:
let animal: &str = "parrot";
println!("{}", anmal);
The compiler says error[E0425]: cannot find value `anmal` in this scope, points at the exact spot, and adds a help line that a local variable named animal exists. A call to a function that doesn't exist is reported with the same code, as cannot find function.
Why the typos in the exercise matter
The lesson's program has one of each:
prntln!("Welcome!");
let weather: String = "sunny".to_string();
println!("{}", whether);
The first line misspells the macro. The last line prints whether, a perfectly good English word that is not the variable declared two lines above. The compiler can't know what you meant, so it reports cannot find value `whether` in this scope.
The program has two errors, and nothing prints until both are fixed. The compiler lists both in a single run, so fixing only one still leaves the other to stop the build.
Fixing it step by step
- Read the first message. It names the unknown word and the line it is on.
- Compare the name with its declaration. For a macro, check it against the standard one. For a variable, look at the
letline that introduced it. - Correct the spelling. Here,
prntln!becomesprintln!andwhetherbecomesweather. Leave the declaration alone: the variable's name is the right one, and the use was wrong. - Compile again. Fixing a name can occasionally expose an error that was hidden behind it, so run once more to confirm.
println!("Welcome!");
let weather: String = "sunny".to_string();
println!("{}", weather);
The corrected program prints:
Welcome!
sunny
Other ways to get a name error
- Case differences. With
let total = 5;, writingTotalorTOTALrefers to a different name. The compiler reportscannot find value `Total` in this scopeand suggeststotal. - Using a name before its declaration. In a function body, a variable exists only from its
letline onward. Printingcounton the line beforelet count = 3;is anE0425error. - Using a variable outside its block. A variable declared inside curly braces disappears at the closing brace. Printing it afterwards gives
cannot find value `inner` in this scope, and the compiler adds that a binding with that name is available in a different scope.
Key takeaways
- A name error means the compiler met a word it can't match to anything. It stops before running the program.
- A missing macro and a missing value are reported differently (
error: cannot find macroagainsterror[E0425]: cannot find value), but both mean the same thing: check the spelling. - The compiler often suggests the name it thinks you meant. Read that help text before changing anything.
- Rust names are case-sensitive, and a variable only exists after its declaration and inside its block.
