2

I'd like to create a struct that holds a slice, and can return references to items in that slice. So far, I've been able to do this:

pub struct Stride<'a> {
    items: &'a [f32],
}

impl<'a> Iterator for Stride<'a> {
    type Item = &'a f32;
    fn next(&mut self) -> Option<&'a f32> {
        Some(&self.items[0])
    }
}

However, when I change the slice to be a mutable slice:

pub struct Stride<'a> {
    items: &'a mut [f32],
}

impl<'a> Iterator for Stride<'a> {
    type Item = &'a f32;
    fn next(&mut self) -> Option<&'a f32> {
        Some(&self.items[0])
    }
}

I get a compiler error:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
 --> src/lib.rs:8:15
  |
8 |         Some(&self.items[0])
  |               ^^^^^^^^^^^^^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 7:5...
 --> src/lib.rs:7:5
  |
7 | /     fn next(&mut self) -> Option<&'a f32> {
8 | |         Some(&self.items[0])
9 | |     }
  | |_____^
note: ...so that reference does not outlive borrowed content
 --> src/lib.rs:8:15
  |
8 |         Some(&self.items[0])
  |               ^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 5:6...
 --> src/lib.rs:5:6
  |
5 | impl<'a> Iterator for Stride<'a> {
  |      ^^
  = note: ...so that the expression is assignable:
          expected std::option::Option<&'a f32>
             found std::option::Option<&f32>

Why can't I hold this mutable slice and return references to the elements in that slice? I would like to go even further: returning mutable references to elements in this slice. Is this even possible?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
awelkie
  • 2,422
  • 1
  • 22
  • 32
  • I assume that you are asking this to explore how it would be implemented. If you wanted to do this in The Real World, you can just use [`iter_mut`](http://doc.rust-lang.org/std/slice/trait.SliceExt.html#tymethod.iter_mut) from the standard library. – Shepmaster Jan 10 '15 at 20:11

1 Answers1

3

Really, what you want to do is to create an iterator of mutable references. That has been answered before, with at least one example of how to do it.

The summary is that Rust cannot tell that you are not returning the same mutable reference more than once. If you did so, then you would have aliasing, which breaks Rust's rules. As an aside, your iterator as shown is unsafe because it will always return the first item! As a human smarter than Rust, you have to manually verify that you aren't breaking the safety rules and then use unsafe code to ignore the warnings. Something like mem::transmute is often used.

Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366