---
title: "17.x Chapter 17 summary and quiz"
description: "Review of what lifetimes are, annotations on functions and structs, the elision rules, and the 'static lifetime, with a chapter quiz."
url: "https://learnrust.net/chapter-17/chapter-17-summary-and-quiz/"
last_updated: "2026-06-13"
---

# 17.x Chapter 17 summary and quiz

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](https://learnrust.net/chapter-17/what-lifetimes-are/)). 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](https://learnrust.net/chapter-17/lifetime-annotations-in-functions/)); 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](https://learnrust.net/chapter-17/lifetimes-in-structs/)), the IOU from lesson [10.8](https://learnrust.net/chapter-10/ownership-in-structs/); owned fields remain the simpler default.

You *don't* write lifetimes most of the time because of three **elision rules** ([17.4](https://learnrust.net/chapter-17/elision-rules/)): 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](https://learnrust.net/chapter-17/the-static-lifetime/)); 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?

<details class="solution">
<summary>Show solution</summary>

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."

</details>

**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)

<details class="solution">
<summary>Show solution</summary>

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.

</details>

**Question #3**

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

<details class="solution">
<summary>Show solution</summary>

`'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.

</details>

**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?

<details class="solution">
<summary>Show solution</summary>

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](https://learnrust.net/chapter-9/string-slices/)) 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.

</details>

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.

## Sitemap

See the full [sitemap](https://learnrust.net/sitemap.md) for all pages.
