Problem overview
The program should print two lines:
Hey bro!
How are you doing?
The first line is supposed to come from println! inside greet_and_return. The second comes from mainFunction, which calls greet_and_return, stores the returned String in question and prints it. When the starter code runs, only How are you doing? appears, and the compiler adds a warning about an unreachable statement.
What goes wrong
The starter code puts the lines of greet_and_return in the wrong order:
fn greet_and_return() -> String {
return "How are you doing?".to_string();
println!("Hey bro!");
}
Rust runs the lines of a function from top to bottom. The first line is a return, which leaves the function immediately and gives the string to the caller. The println! below it is never executed, so Hey bro! is never printed. The compiler can see this, which is why it reports unreachable statement. The warning doesn't stop the build, but it tells you the line has no effect.
The fix does not need new code. The println! line and the return line are both correct, they only need to swap places.
Step by step
- Find the line that prints
Hey bro!. It is already insidegreet_and_return, so it just has to run while the function is still going. - Move it above the
return. Anything the function has to do must happen before the value is returned. - Keep the
returnas the last line, so the function still givesHow are you doing?to the caller. - Leave
mainFunctionalone. It already prints the returned value, which produces the second line.
The solution in Rust
fn greet_and_return() -> String {
println!("Hey bro!");
return "How are you doing?".to_string();
}
fn mainFunction() {
let question = greet_and_return();
println!("{}", question);
}
The order of events is now:
mainFunctioncallsgreet_and_return().- Inside it,
println!printsHey bro!. - The function returns the string
How are you doing?, andquestionreceives it. - Back in
mainFunction,println!("{}", question)prints it as the second line.
Notice that the two lines are printed by two different println! calls in two different functions. The first one runs before the function returns, and the second runs after.
Rust details that matter here
The final expression as a shortcut
At the end of a function, return is optional. A last expression without a semicolon is returned automatically:
fn greet_and_return() -> String {
println!("Hey bro!");
"How are you doing?".to_string()
}
This behaves exactly like the solution above. The lesson's version spells out return, which makes the moment of leaving the function easy to see.
Why the dead line compiles
The wrong version compiles because return already supplies the String that the signature promises. What follows it never runs, so the type of the unreachable line doesn't matter to the signature. It is only a warning, not an error, which is why the program ran and printed one line instead of failing outright.
Owned strings
A literal like "How are you doing?" has type &str. The function promises a String, an owned string, so to_string() converts the literal.
Common mistakes
- Putting the work after the return. Everything the function needs to do must come before the line that returns.
- Printing the second line inside the function too. The caller already prints the returned value, so doing it in the function would duplicate it.
- Ignoring compiler warnings. A message such as
unreachable statementpoints at the exact line that never runs.
Key takeaways
- Code runs from top to bottom, and
returnends the function immediately. - Side effects such as printing belong before the
return. - Rust warns about unreachable code, so read the warnings.
