Lesson 0001 · Rust Book chapters 1–9 · no new material, pure retrieval
Your learn-* folders prove you worked through variables, functions, control flow, ownership, borrowing, slices, structs, enums, modules, collections, and error handling. This lesson does not re-teach any of it. It tests what is still retrievable — that is the only kind of "knowing" that helps in an interview or on the job.
How to take this. For each question, think of your answer before revealing it. Grading yourself honestly matters more than "winning" — this diagnostic decides which lessons get built next. Multiple-choice ones grade themselves; short-answer ones ask you to self-grade after reading the answer.
Variables — ch03.1
This code:
let x = 5;
x = 6;
println!("{x}");
Does it compile? If not, what's the fix?
No — cannot assign twice to immutable variable. Rust variables are immutable by default; fix by declaring let mut x = 5;.
let s1 = String::from("hello");
let s2 = s1;
println!("{s1}");
Does it compile? Why or why not?
No. String owns heap data and is not Copy, so let s2 = s1;moves ownership from s1 to s2. Using s1 afterward is a compile error: "borrow of moved value."
What's the real difference between calling panic! and returning Err(...) from a function whose signature returns Result?
panic! unwinds and stops the program right there — unrecoverable. Returning Err hands the failure back to the caller, who decides what to do — recoverable. Libraries should almost always prefer Result.
Why must a match expression cover every variant of an enum?
The compiler enforces exhaustiveness — every possible value must be handled, or it's a compile error. Use _ as a catch-all arm when you don't care about the rest.
Does the last expression in a function body need a return keyword to become the return value? What one character must you drop from that line for it to count as an expression, not a statement?
No return needed. Drop the trailing semicolon — a line ending in ; is a statement (no value); without it, it's an expression whose value becomes the function's return value.
In your restauran project you called crate::front_of_house::hosting::add_to_waitlist(). What does the pub keyword do to hosting and to add_to_waitlist? What breaks if you remove it?
pub makes an item visible outside its parent module. Everything is private by default, so removing pub from either the module or the function makes it inaccessible from eat_at_restaurant's call site — a compile error ("module/function is private").
Name the trait that lets simple stack-only types like i32 get duplicated instead of moved on assignment.
The Copy trait. Types with a known, fixed size that live entirely on the stack (integers, bools, chars, tuples of Copy types, …) can implement it, so assignment copies instead of moving.
Why do most struct methods take &self (borrowed) instead of self (owned)?
Taking self by value would move the instance into the method, consuming it — the caller couldn't use it afterward. &self borrows it, so the instance survives the call.
What does .entry(v) return, and what does .or_insert(0) do whether v is a new key or an existing one?
.entry(v) returns an Entry enum for that key. .or_insert(0) inserts 0 only if the key is missing, and in both cases returns a mutable reference to the value — so *x += 1 works whether it's brand-new or already there.
? propagates the error immediately: the enclosing function returns that Err right away instead of continuing — the function's return type must be a compatible Result.
True or false: at any single point, Rust allows either one mutable reference OR any number of immutable references to the same data, never a mix. Why does this rule exist?
True. It's enforced at compile time by the borrow checker, and it exists to rule out data races and "reader sees a half-written value" bugs without needing a garbage collector or runtime lock.