@@ -21,14 +21,35 @@ where
2121}
2222```
2323
24- In this example we have a trait that borrows some inner data element of type ` V `
25- from an outer type ` T ` , through an intermediate type ` U ` . The compiler is unable
26- to prove that the livetime of ` U ` is long enough to support the reference. To
27- fix the issue we can explicitly add lifetime specifiers to the ` NestedBorrowMut `
28- trait, which link the lifetimes of the various data types and allow the code to
29- compile.
30-
31- Working implementation of the ` NestedBorrowMut ` trait:
24+ Why doesn't this code compile? The problem has to do with Rust's rules for
25+ lifetime elision in functions (Chapter 10.3 in the Rust book). One of the
26+ inputs is a reference to ` self ` , so the compiler attempts to assign the
27+ the same lifetime to the ` &mut self ` input and ` &mut V ` output to the
28+ ` nested_borrow_mut() ` function. The problem is that there is no way for the
29+ compiler to directly figure out how these two lifetimes are related in the
30+ implementation of the function. We're implementing the ` NextedBorrowMut `
31+ trait for a type ` T ` , so the ` &mut self ` reference has the lifetime of ` T ` .
32+ We know that ` T ` implements the ` BorrowMut ` trait returning a reference to ` U ` ,
33+ and that ` U ` implements the ` BorrowMut ` trait returning a reference to ` V ` .
34+ The key is that we have not told the compiler that those two ` U ` lifetimes
35+ are the same: for all it knows, we could be that the first ` BorrowMut ` trait
36+ on ` T ` works with a lifetime ` 'a ` and the second ` BorrowMut ` trait on ` U `
37+ works on a lifetime ` 'b ` .
38+
39+ The fix here is to add explicit lifetime annotations that tell the compiler
40+ that the lifetime of the output is in fact the same as the lifetime of the
41+ input (` self ` ). There are three references involved, to objects of type ` T `
42+ (` self ` ), ` U ` (the intermediate type), and ` V ` (the return type). In the
43+ working code below, we see that all have been given the same lifetime ` 'a ` :
44+ - ` &'a mut self ` in the function argument list for ` T `
45+ - ` U: BorrowMut<V> + 'a ` in the trait bounds for ` U `
46+ - ` &'a mut V ` in the function return for ` V ` .
47+
48+ The compiler can the check that the implementation of the
49+ ` nested_borrow_mut() ` function satisfies these lifetimes. There are two
50+ functions being called inside of ` nested_borrow_mut() ` , both of which are
51+ the ` borrow_mut() ` function, which promises that the output lifetime is
52+ the same as the input lifetime (see lifetime elision rules), which checks out.
3253
3354```
3455use std::borrow::BorrowMut;
0 commit comments