17.xChapter 17 summary and quiz

Last updated June 13, 2026

A short chapter on something that sounds scary and mostly isn't. Review, then a quiz.

Quick review

A lifetime is the span during which a reference is valid, derived from how long the borrowed value lives (17.1). The borrow checker has tracked lifetimes since chapter 9 to enforce "references must be valid"; this chapter just makes them writable. The single most important fact: a lifetime annotation describes a relationship, it never extends a lifetime.

You write a lifetime by hand in two situations. Functions returning a reference with multiple reference inputs need <'a>(x: &'a str, y: &'a str) -> &'a str to say which inputs the output borrows from (17.2); the longest example fails without it because the output could come from either input. Structs holding references need a lifetime parameter (struct Excerpt<'a> { text: &'a str }) declaring that the struct can't outlive its borrowed data (17.3), the IOU from lesson 10.8; owned fields remain the simpler default.

You don't write lifetimes most of the time because of three elision rules (17.4): each reference parameter gets its own input lifetime; one input lifetime is assigned to all outputs; and &self's lifetime is assigned to all outputs. These cover "one reference in, one out" and "method borrowing self" completely, which is most functions, so first_word needs no annotation while longest (two inputs) does. Finally, 'static is the whole-program lifetime of string literals (their bytes live in the binary), the one specific lifetime you name (17.5); adding 'static to silence a borrow error is a trap, because it demands data live forever rather than making it do so. The real fixes are owning the data or restructuring so it outlives the borrow.

Quiz time

Question #1

Does a lifetime annotation make a value live longer? What does it actually do?

Show solution

No. A lifetime annotation describes a relationship between references that already exists, so the compiler can check it; it never extends how long any value lives. If data doesn't actually live long enough, the program is still refused. The fix is owned data or restructuring, never "annotate harder."

Question #2

Using the elision rules, which of these need an explicit lifetime annotation?

a) fn id(s: &str) -> &str b) fn pick(a: &str, b: &str) -> &str c) fn name(&self) -> &str (a method)

Show solution

a) No: one input lifetime, rule 2 assigns it to the output. b) Yes: two input lifetimes, rule 2 doesn't apply and there's no &self, so the output lifetime is undetermined and you must annotate. c) No: rule 3 assigns &self's lifetime to the output.

Question #3

Why is let r: &'static str = &local_string; refused, and what should you do instead?

Show solution

'static requires the borrowed data to live for the entire program, but a local String is dropped at the end of its scope, so it isn't 'static, and the annotation just produces "does not live long enough." Instead, use the owned String directly (don't borrow it as 'static), or restructure so the data genuinely lives long enough. Reserve 'static for data that truly lives forever, like string literals and constants.

Question #4

A short exercise (no code required, just reasoning). You're writing fn longest_word(text: &str) -> &str that returns the longest word in a single input string. Does it need a lifetime annotation? Why?

Show solution

No annotation needed. It has exactly one reference input (text), so elision rule 2 assigns that input's lifetime to the returned &str: the output clearly borrows from text, the only thing it could borrow from. This is the same reason first_word (lesson 9.7) needed no annotation. Only when there are two or more reference inputs that the output might come from (like longest taking two strings) does elision fail and an explicit 'a become necessary.

Lifetimes complete the core type system: ownership (8), borrowing (9), generics (15), traits (16), and now lifetimes (17). Chapter 18 cashes all of it out on the data structures you'll actually reach for daily, Vec, String examined as real UTF-8, and HashMap, where every concept from the last ten chapters shows up in code you'll write constantly.