From 45b364cd67d8156cb47a51bee1086027115c9d00 Mon Sep 17 00:00:00 2001 From: Rodrigo Rejala Date: Thu, 21 May 2026 23:44:11 -0300 Subject: [PATCH] fix(rust-patterns-book): make Lifetime Branding example compile Use RefCell for interior mutability so alloc takes &self instead of &mut self, resolving the borrow checker conflict between alloc and get. Fixes #102 --- ...04-phantomdata-types-that-carry-no-data.md | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/rust-patterns-book/src/ch04-phantomdata-types-that-carry-no-data.md b/rust-patterns-book/src/ch04-phantomdata-types-that-carry-no-data.md index 2bc6ac0..3f1ac92 100644 --- a/rust-patterns-book/src/ch04-phantomdata-types-that-carry-no-data.md +++ b/rust-patterns-book/src/ch04-phantomdata-types-that-carry-no-data.md @@ -46,6 +46,7 @@ struct Slice<'a, T> { Use `PhantomData` to prevent mixing values from different "sessions" or "contexts": ```rust +use std::cell::RefCell; use std::marker::PhantomData; /// A handle that's valid only within a specific arena's lifetime @@ -55,33 +56,35 @@ struct ArenaHandle<'arena> { } struct Arena { - data: Vec, + data: RefCell>, } impl Arena { fn new() -> Self { - Arena { data: Vec::new() } + Arena { data: RefCell::new(Vec::new()) } } /// Allocate a string and return a branded handle - fn alloc<'a>(&'a mut self, value: String) -> ArenaHandle<'a> { - let index = self.data.len(); - self.data.push(value); + fn alloc(&self, value: String) -> ArenaHandle<'_> { + let mut data = self.data.borrow_mut(); + let index = data.len(); + data.push(value); ArenaHandle { index, _brand: PhantomData } } /// Look up by handle — only accepts handles from THIS arena - fn get<'a>(&'a self, handle: ArenaHandle<'a>) -> &'a str { - &self.data[handle.index] + fn get<'a>(&'a self, handle: ArenaHandle<'a>) -> String { + let data = self.data.borrow(); + data[handle.index].clone() } } fn main() { - let mut arena1 = Arena::new(); + let arena1 = Arena::new(); let handle1 = arena1.alloc("hello".to_string()); // Can't use handle1 with a different arena — lifetimes won't match - // let mut arena2 = Arena::new(); + // let arena2 = Arena::new(); // arena2.get(handle1); // ❌ Lifetime mismatch println!("{}", arena1.get(handle1)); // ✅