Skip to content

Commit 67d797b

Browse files
committed
Add lifetimes to RFC
1 parent d317332 commit 67d797b

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

text/0000-linked-list-cursors.md

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,22 +132,22 @@ pub fn cursor_mut(&mut self) -> CursorMut<T>;
132132
These would provide the following interface:
133133

134134
``` rust
135-
impl<T> Cursor<T> {
135+
impl<'list, T> Cursor<'list, T> {
136136
/// Move to the subsequent element of the list if it exists or the empty
137137
/// element
138138
pub fn move_next(&mut self);
139139
/// Move to the previous element of the list
140140
pub fn move_prev(&mut self);
141141

142142
/// Get the current element
143-
pub fn current(&self) -> Option<&T>;
143+
pub fn current(&self) -> Option<&'list T>;
144144
/// Get the following element
145-
pub fn peek(&self) -> Option<&T>;
145+
pub fn peek(&self) -> Option<&'list T>;
146146
/// Get the previous element
147-
pub fn peek_before(&self) -> Option<&T>;
147+
pub fn peek_before(&self) -> Option<&'list T>;
148148
}
149149

150-
impl<T> CursorMut<T> {
150+
impl<'list T> CursorMut<'list, T> {
151151
/// Move to the subsequent element of the list if it exists or the empty
152152
/// element
153153
pub fn move_next(&mut self);
@@ -162,7 +162,7 @@ impl<T> CursorMut<T> {
162162
pub fn peek_before(&mut self) -> Option<&mut T>;
163163

164164
/// Get an immutable cursor at the current element
165-
pub fn as_cursor(&self) -> Cursor<T>;
165+
pub fn as_cursor<'cm>(&'cm self) -> Cursor<'cm, T>;
166166

167167
// Now the list editing operations
168168

@@ -190,6 +190,30 @@ impl<T> CursorMut<T> {
190190
pub fn split_before(self) -> LinkedList<T>;
191191
}
192192
```
193+
One should closely consider the lifetimes in this interface. Both `Cursor` and
194+
`CursorMut` operate on data in their `LinkedList`. This is why, they both hold
195+
the annotation of `'list`.
196+
197+
The lifetime elision for their constructors is correct as
198+
```
199+
pub fn cursor(&self) -> Cursor<T>
200+
```
201+
becomes
202+
```
203+
pub fn cursor<'list>(&'list self) -> Cursor<'list, T>
204+
```
205+
which is what we would expect. (the same goes for `CursorMut`).
206+
207+
Since `Cursor` cannot mutate its list, `current`, `peek` and `peek_before` all
208+
live as long as `'list`. However, in `CursorMut` we must be careful to make
209+
these methods borrow. Otherwise, one could produce multiple mutable references
210+
to the same element.
211+
212+
The only other lifetime annotation is with `as_cursor`. In this case, the
213+
returned `Cursor` must borrow its generating `CursorMut`. Otherwise, it would be
214+
possible to achieve a mutable and immutable reference to the same element at
215+
once.
216+
193217
One question that arises from this interface is what happens if `move_next` is
194218
called when a cursor is on the last element of the list, or is empty (or
195219
`move_prev` and the beginning). A simple way to solve this is to make cursors

0 commit comments

Comments
 (0)