We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Ownership II: Borrowing and the Borrow Checker step 4 of 24
How to read a borrow-check diagnostic
Fix summarize so it appends a summary and returns the original first word.
pub fn summarize(words: &mut Vec<String>) -> String
Append exactly one new String of the form total=N, where N is the
vector's length before the append. Return an owned copy of the first
word's text as it was on entry, or an empty String if the vector was empty.
Preserve all existing elements and their order.
[] -> return ""; vector becomes ["total=0"]
["a"] -> return "a"; vector becomes ["a", "total=1"]
["a", "bb"] -> return "a"; vector becomes ["a", "bb", "total=2"]
["", "x"] -> return ""; vector becomes ["", "x", "total=2"]
An existing string such as total=9 is ordinary input. Do not parse it
or exclude it from the count. The new String contains no newline character.
Read the three locations together
The starter creates a reference into words, pushes another element, then reads through the earlier reference:
let first = &words[0];
words.push(format!("total={}", words.len()));
first.to_string()
Rust reports E0502, with annotations identifying these three locations:
| Location | Role in the conflict |
|---|---|
| &words[0] | creates a shared borrow of an element |
| words.push(...) | needs mutable access to the vector |
| first.to_string() | uses the earlier borrow after the push |
All three matter. The final use explains why the shared borrow must remain valid across the mutation. A push can reallocate the vector and move its String elements, so retaining a reference to an element across that call would be unsafe. Even if capacity happens to be sufficient, Vec::push's mutable-access contract does not permit this overlapping borrow.
To investigate a similar error, identify what was borrowed, find the later use that keeps it needed, then examine the operation that conflicts with it. rustc --explain E0502 provides another example of the same error class.
Save the result before changing the vector
The required return type is String, so the result can own its text instead of borrowing the vector. Build that owned result before pushing.
One approach starts with an empty String. If words.first() returns a reference, copy its text into the result with push_str. After that read, the reference is no longer needed, and the vector can be mutated.
This handles empty input without indexing. first returns None on an empty vector. Checked indexing or an explicit empty check can also be safe; unconditionally reading words[0] cannot. first is the direct way to express the intent here.
A block can make the order clear, but its closing brace is not a command to end every borrow. If a reference escapes the block and is used later, its borrow must still be valid for that use. Conversely, a reference's borrow can end before its variable's enclosing scope when no later use requires it. See non-lexical lifetimes.
Choose a fix that preserves the task
Reordering accesses or borrowing separate fields can solve other borrow conflicts. Here, narrowing first to one element does not allow pushing while that element reference remains in use: the vector still owns it. Computing the owned result first preserves both required operations.
Copying the entire Vec<String> would do unnecessary work. A single clone of that vector is not inherently quadratic; it copies all its strings, while this function only needs the first string's text. push_str also copies text, so describe the benefit as copying only what is needed.
The starter's push expression can use words.len() as its argument while calling push on words. That short read is not the error shown here; the reference used after push is the conflict. Keep the original length in the summary, whether you compute it inline or store it beforehand.
Check both outputs
Verify the returned String and the mutated vector. A fix that merely makes the borrow error disappear can still mishandle empty input, count the new summary element, or alter an existing word.
The submission must compile, match both outputs and pass Clippy with warnings denied.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.