Rust error E0495 using split_at_mut in a closure - rust

I'm encountering an "error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements" with this simple function:
fn assign_split_at_mut<'a, 'b, T>(s: &'b mut &'a mut [T], mid: usize) -> &'a mut [T] {
let (x, y) = (*s: &'a mut [T]).split_at_mut(mid);
*s = y;
x
}
I wrote a playpen example including this unsafe variant of split_at_mut that does work.
fn assign_split_at_mut_unsafe<'a, T>(s: &mut &'a mut [T], mid: usize) -> &'a mut [T] {
let len = (*s: &'a mut [T]).len();
let ptr = (*s: &'a mut [T]).as_mut_ptr();
unsafe {
use std::slice::from_raw_parts_mut;
assert!(mid <= len);
*s: &'a mut [T] = from_raw_parts_mut(ptr.offset(mid as isize), len - mid);
from_raw_parts_mut(ptr, mid)
}
}
In fact, I want to write roughly this:
pub fn slice_header<'a>(&'static self, mut header: &'a mut [u8])
-> MyResult<HeaderRefs<'a>>
{
// ...
let take = |l: usize| -> &'a mut [u8] {
let (x,y) = header.split_at_mut(l);
header = y; x
};
let hr = HeaderRefs {
params: self,
alpha: array_mut_ref![take(32),0,32],
gamma: array_mut_ref![take(16),32,16],
beta: take(self.beta_length as usize),
surb_log: take(self.surblog_length as usize),
surb: take(self.surb_length()),
};
// ...
Ok(hr)
}
I believe it would work fine if I simply wrote out a bunch of
let (alpha,header) = header.split_at_mut(32);
let (gamma,header) = header.split_at_mut(16);
// ...
Maybe it'd work if I put them into an array. I cannot get it to work with a closure, which would look much cleaner.

This is a borrowing issue:
fn assign_split_at_mut<'a, 'b, T>(s: &'b mut &'a mut [T], mid: usize) -> &'a mut [T] {
let (x, y) = (*s: &'a mut [T]).split_at_mut(mid);
*s = y;
x
}
Specifically, split_at_mut borrows s, so you cannot also assign to s while it is borrowed.
To understand the issue, imagine that we were talking about vectors here, with s: &mut Vec<T>: you could first borrow a slice from the Vec and then use s to mutate it.
This is why Rust specifies that the whole access path is borrowed, not just the leaf.
Okay, so what now?
As mentioned by #nox, the solution is to "dance":
move the ownership of &'a mut [T] out of s to a local variable
borrow this local variable
assign to s
This way, the borrow checker is appeased since it knows that modifying s cannot affect the local variable and its borrows.
There are various ways to move the ownership out of &mut X depending on the situation, some common ways are:
std::mem::replace,
std::mem::swap,
Option::take if X is an Option,
...
In your case, replace is the simpler. And the solution provided by #nox is rather simple:
fn reserve<'heap, T>(heap: &mut &'heap mut [T], len: usize) -> &'heap mut [T] {
let tmp: &'heap mut [T] = ::std::mem::replace(&mut *heap, &mut []);
let (reserved, tmp) = tmp.split_at_mut(len);
*heap = tmp;
reserved
}

An IRC user nox provided a clean answer by using mem::replace to move the &mut [T] that needs mutation out of the way first :
fn reserve<'heap, T>(heap: &mut &'heap mut [T], len: usize) -> &'heap mut [T] {
let tmp: &'heap mut [T] = ::std::mem::replace(&mut *heap, &mut []);
let (reserved, tmp) = tmp.split_at_mut(len);
*heap = tmp;
reserved
}

Related

lifetime / borrow of nested structs error [duplicate]

This question already has an answer here:
How can I create my own data structure with an iterator that returns mutable references?
(1 answer)
Closed 6 months ago.
I'm having a lifetime issue when implementing an iterator on custom struct containing borrows of vecs.
I've been trying different solutions but can't fix it by myself (I'm still a beginner) and I want to understand what is going on.
here is a playground example of my issue, that should be simple enough.
This is the example :
struct SomeData;
struct CustomIterator<'a> {
pub vec: &'a mut Vec<SomeData>,
pub index: usize,
}
struct MultipleIterator<'a> {
iter1: CustomIterator<'a>,
iter2: CustomIterator<'a>,
}
impl<'a> Iterator for MultipleIterator<'a> {
type Item = (&'a mut SomeData, &'a mut SomeData);
fn next(&mut self) -> Option<Self::Item> {
Some((
match self.iter1.vec.get_mut(self.iter1.index) {
Some(mut data) => &mut data,
None => return None,
},
match self.iter2.vec.get_mut(self.iter2.index) {
Some(mut data) => &mut data,
None => return None,
}
))
}
}
I don't unerstand why I can't borrow out of the next function, since I am borrowing the struct anyway when calling next()
This is actually quite tricky to implement safely and requires a lot of care to do correctly.
First things first though:
match self.iter1.vec.get_mut(self.iter1.index) {
Some(mut data) => &mut data,
None => return None,
},
This is a problem because Vec::get_mut already returns a Option<&mut T>. So in the Some(mut data) arm, data already is a mutable reference. When you try to return &mut data, you're trying to return a &mut &mut T which doesn't work. Instead, just do this:
match self.iter1.vec.get_mut(self.iter1.index) {
Some(data) => data,
None => return None,
},
We can tidy this up even more with the ? operator which does the same thing. I'm gonna substitute SomeData for i32 from now on to demonstrate something later.
impl<'a> Iterator for MultipleIterator<'a> {
type Item = (&'a mut i32, &'a mut i32);
fn next(&mut self) -> Option<Self::Item> {
Some((
self.iter1.vec.get_mut(self.iter1.index)?,
self.iter2.vec.get_mut(self.iter2.index)?,
))
}
}
This still doesn't work and now we're getting to the core of the problem. The signature of next is
fn next(&mut self) -> Option<(&'a mut i32, &'a mut i32)>
which can be desugared to
fn next<'b>(&'b mut self) -> Option<(&'a mut i32, &'a mut i32)>
This means that the lifetime of &mut self ('b) is completely decoupled from the lifetime of the references we return ('a). Which makes total sense. If that wasn't the case, we couldn't do
let mut v = vec![1,2,3];
let mut iter = v.iter_mut();
let next1: &mut i32 = iter.next().unwrap();
let next2: &mut i32 = iter.next().unwrap();
because the lifetime of next1 would have to be the same lifetime of iter, i.e. that of v. But you can't have multiple mutable references to v at the same time, so next2 would be illegal.
So you're getting an error because Rust only knows that self is borrowed for 'b but you're telling it that you're returning a reference with lifetime 'a which it can't verify to be true.
And for good reason, because as it stands right now, your implementation isn't safe! Let's just throw caution to the wind and tell Rust that this is okay with unsafe:
impl<'a> Iterator for MultipleIterator<'a> {
type Item = (&'a mut i32, &'a mut i32);
fn next(&mut self) -> Option<Self::Item> {
unsafe {
Some((
&mut *(self.iter1.vec.get_mut(self.iter1.index)? as *mut _),
&mut *(self.iter2.vec.get_mut(self.iter2.index)? as *mut _),
))
}
}
}
It's not important what exactly this does, it basically just tells the compiler to shut up and trust me.
But now, we can do this:
let mut v1 = vec![1, 2, 3];
let mut v2 = vec![4, 5, 6];
let mut mi = MultipleIterator {
iter1: CustomIterator {
vec: &mut v1,
index: 0,
},
iter2: CustomIterator {
vec: &mut v2,
index: 0,
},
};
let next1 = mi.next().unwrap();
let next2 = mi.next().unwrap();
assert_eq!(next1, (&mut 1, &mut 4));
assert_eq!(next2, (&mut 1, &mut 4));
*next1.0 += 1;
assert_eq!(next1, (&mut 2, &mut 4));
assert_eq!(next2, (&mut 2, &mut 4));
We have broken Rust's most important rule: never have two mutable references to the same thing at once.
This can only be safe if your Iterator implementation can never return a mutable reference to something more than once. You could increment index each time, for example (although this still requires unsafe):
impl<'a> Iterator for MultipleIterator<'a> {
type Item = (&'a mut i32, &'a mut i32);
fn next(&mut self) -> Option<Self::Item> {
let next1 = self.iter1.vec.get_mut(self.iter1.index)?;
let next2 = self.iter2.vec.get_mut(self.iter2.index)?;
self.iter1.index += 1;
self.iter2.index += 1;
// SAFETY: this is safe because we will never return a reference
// to the same index more than once
unsafe { Some((&mut *(next1 as *mut _), &mut *(next2 as *mut _))) }
}
}
Here is an interesting related read from the nomicon; the "mutable slice" example being particularly relevant to your problem.

Lifetime conflicts when implementing IntoIterator to iterate over an inner collection [duplicate]

I am trying to create an mutable iterator for a vector of type: Vec<Vec<(K, V)>>
The iterator code:
pub struct IterMut<'a, K: 'a, V: 'a> {
iter: &'a mut Vec<Vec<(K, V)>>,
ix: usize,
inner_ix: usize,
}
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
#[inline]
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
while self.iter.len() < self.ix {
while self.iter[self.ix].len() < self.inner_ix {
self.inner_ix += 1;
let (ref k, ref mut v) = self.iter[self.ix][self.inner_ix];
return Some((&k, &mut v));
}
self.ix += 1;
}
return None;
}
}
The error I get is:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:16:42
|
16 | let (ref k, ref mut v) = self.iter[self.ix][self.inner_ix];
| ^^^^^^^^^^^^^^^^^^
|
help: consider using an explicit lifetime parameter as shown: fn next(&'a mut self) -> Option<(&'a K, &'a mut V)>
--> src/main.rs:11:5
|
11 | fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
| ^
Apparently I have lifetime problems, but I don't know how to tell the compiler that this should work.
Is this how you should implement the mutable iterator or is there a better way?
When debugging cryptic error messages, I've found it easier to try and isolate the issue as much as possible.
The first step is to break the expression into its essential constituents, let's start by splitting the indexing steps:
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
while self.iter.len() < self.ix {
while self.iter[self.ix].len() < self.inner_ix {
self.inner_ix += 1;
let outer: &'a mut Vec<_> = self.iter;
let inner: &'a mut Vec<_> = &mut outer[self.ix];
let (ref k, ref mut v) = inner[self.inner_ix];
return Some((&k, &mut v));
}
self.ix += 1;
}
return None;
}
The Index trait assumes that the lifetime of its output is linked to that of its receiver, so to get a 'a lifetime we need the receiver to have a &'a lifetime, and it propagates upward, leading to the above code.
However there's an issue here: let outer: &'a mut Vec<_> = self.iter; will not compile because mutable references are not Copy.
So, how does one get a mutable reference from a mutable reference (which must be possible since IndexMut gets a mutable reference)?
One uses re-borrowing: let outer: &'a mut Vec<_> = &mut *self.iter;.
And, oh:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> <anon>:16:45
|
16 | let outer: &'a mut Vec<_> = &mut *self.iter;
| ^^^^^^^^^^^^^^^
|
The reborrowed reference is not valid for 'a, it's valid only for the (unnamed) lifetime of self!
Why Rust? Why?
Because doing otherwise would be unsafe.
&mut T is guaranteed NOT to be aliasing, however your method could create aliasing references (if you forgot to advance the index):
#[inline]
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
let (ref k, ref mut v) = self.iter[self.ix][self.inner_ix];
return Some((&k, &mut v));
}
And even if you don't, there's not guarantee that you don't have a rewind method that would allow "stepping back".
TL;DR: You were about to step on a landmine, you were steered toward Stack Overflow instead ;)
Alright, but how do you implement the iterator!.
Well, using iterators, of course. As Shepmaster (briefly) answers, there is the equivalent in the standard library already in the guise of FlatMap. The trick is to use existing iterators for the nitty-gritty details!
Something like:
use std::slice::IterMut;
pub struct MyIterMut<'a, K: 'a, V: 'a> {
outer: IterMut<'a, Vec<(K, V)>>,
inner: IterMut<'a, (K, V)>,
}
Then you consume from inner as long as it provides items, and when empty you refill it from outer.
impl<'a, K, V> MyIterMut<'a, K, V> {
fn new(v: &'a mut Vec<Vec<(K, V)>>) -> MyIterMut<'a, K, V> {
let mut outer = v.iter_mut();
let inner = outer.next()
.map(|v| v.iter_mut())
.unwrap_or_else(|| (&mut []).iter_mut());
MyIterMut { outer: outer, inner: inner }
}
}
impl<'a, K, V> Iterator for MyIterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
#[inline]
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
loop {
match self.inner.next() {
Some(r) => return Some((&r.0, &mut r.1)),
None => (),
}
match self.outer.next() {
Some(v) => self.inner = v.iter_mut(),
None => return None,
}
}
}
}
A quick test case:
fn main() {
let mut v = vec![
vec![(1, "1"), (2, "2")],
vec![],
vec![(3, "3")]
];
let iter = MyIterMut::new(&mut v);
let c: Vec<_> = iter.collect();
println!("{:?}", c);
}
Prints:
[(1, "1"), (2, "2"), (3, "3")]
as expected, so it's not completely broken, but I wish I did not have to rely on the &[] is 'static trick (ie, that std::slice::IterMut implemented Default).
You've provided no reason that you are reimplementing the standard Iterator::flat_map, so I'd just use that and another map to remove the mutability you don't need:
fn main() {
let mut a: Vec<Vec<(u8, u8)>> = Default::default();
let c = a.iter_mut()
.flat_map(|x| x.iter_mut())
.map(|&mut (ref a, ref mut b)| (a, b))
.count();
println!("{}", c);
}
Once you have that, you can just return the iterator in one of the many ways.
#[derive(Debug, Default)]
struct Thing<K, V>(Vec<Vec<(K, V)>>);
impl<K, V> Thing<K, V> {
fn iter_mut<'a>(&'a mut self) -> Box<Iterator<Item = (&'a K, &'a mut V)> + 'a> {
Box::new(self.0
.iter_mut()
.flat_map(|x| x.iter_mut())
.map(|&mut (ref a, ref mut b)| (a, b)))
}
}
fn main() {
let mut a = Thing::<u8, u8>::default();
let c = a.iter_mut().count();
println!("{}", c);
}

Is it possible to create a wrapper around an &mut that acts like an &mut

The following code fails to compile because MutRef is not Copy. It can not be made copy because &'a mut i32 is not Copy. Is there any way give MutRef similar semantics to &'a mut i32?
The motivation for this is being able to package up a large set of function parameters into a struct so that they can be passed as a group instead of needing to be passed individually.
struct MutRef<'a> {
v: &'a mut i32
}
fn wrapper_use(s: MutRef) {
}
fn raw_use(s: &mut i32) {
}
fn raw_ref() {
let mut s: i32 = 9;
let q = &mut s;
raw_use(q);
raw_use(q);
}
fn wrapper() {
let mut s: i32 = 9;
let q = MutRef{ v: &mut s };
wrapper_use(q);
wrapper_use(q);
}
No.
The name for this feature is "implicit reborrowing" and it happens when you pass a &mut reference where the compiler expects a &mut reference of a possibly different lifetime. The compiler only implicitly reborrows when the actual type and the expected type are both &mut references. It does not work with generic arguments or structs that contain &mut references. There is no way in current Rust to make a custom type that can be implicitly reborrowed. There is an open issue about this limitation dating from 2015, but so far nobody has proposed any way to lift it.
You can always implement your own method to explicitly reborrow:
impl<'a> MutRef<'a> {
// equivalent to fn reborrow(&mut self) -> MutRef<'_>
fn reborrow<'b>(&'b mut self) -> MutRef<'b> {
MutRef {v: self.v}
}
}
fn wrapper() {
let mut s: i32 = 9;
let mut q = MutRef{ v: &mut s };
wrapper_use(q.reborrow()); // does not move q
wrapper_use(q); // moves q
}
See also
Why is the mutable reference not moved here?
Type inference and borrowing vs ownership transfer

Why can't Rust infer an appropriate lifetime for my trait method?

I've got a function take_head that takes two parameters: a slice, and the number of items in the "head" of the slice (the "head" being the first n items, and the "tail" being everything after the head). It splits the slice into two parts: the head, which it returns, and the tail, which it sets the parameter to. Here's the main function showing how it's used:
fn main() {
let mut strings = &mut ["a", "b", "c"][..];
println!("original: {:?}", strings);
// head should ["a"], and strings should be set to the tail (["b", "c"]).
let head = take_head(&mut strings, 1);
println!("head: {:?}", head); // Should print ["a"].
println!("tail: {:?}", strings); // Should print ["b", "c"].
}
If I implement take_head like so:
fn take_head<'a>(strings: &mut &'a mut [&'a str], n: usize) -> &'a mut [&'a str] {
let value = std::mem::replace(strings, &mut []);
let (head, tail) = value.split_at_mut(n);
*strings = tail;
println!("returning head: {:?}", head);
head
}
it works correctly and outputs:
original: ["a", "b", "c"]
returning head: ["a"]
head: ["a"]
tail: ["b", "c"]
However, if I implement take_head like this:
// Make a convenient trait for slices.
pub trait TakeFrontMut<T> {
fn take_front_mut(&mut self, n: usize) -> &mut [T];
}
impl<'a, T> TakeFrontMut <T> for &'a mut [T] {
fn take_front_mut(&mut self, n: usize) -> &mut [T] {
// It's the same code as before, just in a trait method.
let value = std::mem::replace(self, &mut []);
let (head, tail) = value.split_at_mut(n);
*self = tail;
return head;
}
}
fn take_head<'a>(strings: &mut &'a mut [&'a str], n: usize) -> &'a mut [&'a str] {
let head = strings.take_front_mut(n);
println!("returning head: {:?}", head);
head
}
It produces an error:
<anon>:15:24: 15:41 error: cannot infer an appropriate lifetime for autoref due to conflicting requirements [E0495]
<anon>:15 let head = strings.take_front_mut(n);
^~~~~~~~~~~~~~~~~
<anon>:14:1: 18:2 help: consider using an explicit lifetime parameter as shown: fn take_head<'a>(strings: &'a mut &'a mut [&'a str], n: usize)
-> &'a mut [&'a str]
<anon>:14 fn take_head<'a>(strings: &mut &'a mut [&'a str], n: usize) -> &'a mut [&'a str] {
<anon>:15 let head = strings.take_front_mut(n);
<anon>:16 println!("returning head: {:?}", head);
<anon>:17 head
<anon>:18 }
Question: Why does the second version produce an error? What's so different that the parser can't determine the appropriate lifetime? I don't understand why it's failing, and I'm not sure what these conflicting requirements are.
Yes, the take_head function is dumb, but it's the simplest MVCE I could make that still captures the same issue as my real code.
The signature of take_front_mut doesn't specify the correct lifetime for the return value. It should be &'a mut [T], because that's the lifetime of the slice you split. This also requires you to make a change on the trait itself.
pub trait TakeFrontMut<'a, T> {
fn take_front_mut(&mut self, n: usize) -> &'a mut [T];
}
impl<'a, T> TakeFrontMut<'a, T> for &'a mut [T] {
fn take_front_mut(&mut self, n: usize) -> &'a mut [T] {
let value = std::mem::replace(self, &mut []);
let (head, tail) = value.split_at_mut(n);
*self = tail;
return head;
}
}

How can I modify a slice that is a function parameter?

Parameters can be passed to functions and modified:
fn set_42(int: &mut i32) {
*int += 42;
}
fn main() {
let mut int = 0;
set_42(&mut int);
println!("{:?}", int);
}
Output:
42
Changing the code to use a slice fails with a whole bunch of errors:
fn pop_front(slice: &mut [i32]) {
*slice = &{slice}[1..];
}
fn main() {
let mut slice = &[0, 1, 2, 3][..];
pop_front(&mut slice);
println!("{:?}", slice);
}
Output:
error[E0308]: mismatched types
--> src/main.rs:2:14
|
2 | *slice = &{ slice }[1..];
| ^^^^^^^^^^^^^^^
| |
| expected slice `[i32]`, found `&[i32]`
| help: consider removing the borrow: `{ slice }[1..]`
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
--> src/main.rs:2:5
|
2 | *slice = &{ slice }[1..];
| ^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `[i32]`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: the left-hand-side of an assignment must have a statically known size
If we try using a mutable slice (which isn't what I really want; I don't want to modify the values within the slice, I just want to modify the slice itself so it covers a smaller range of elements) and a mutable parameter, it has no effect on the original slice:
fn pop_front(mut slice: &mut [i32]) {
slice = &mut {slice}[1..];
}
fn main() {
let mut slice = &mut [0, 1, 2, 3][..];
pop_front(&mut slice);
println!("{:?}", slice);
}
Output:
[0, 1, 2, 3]
Is there a way to modify a slice that's a function parameter? I don't want to modify the elements within the slice; I just want to modify the range of the slice itself so it becomes a smaller "sub-slice".
As others have said, the core idea here is to take a &mut &... [T] (where ... is mut or empty) and read/write to the internal slice. The other answers demonstrate it is possible for &mut &[T] in safe code, and possible for &mut &mut [T] with unsafe code, but they don't explain why there's the difference... and &mut &mut [T] is possible with safe code too.
In explicit-lifetime terms, the nested reference is something like &'a mut &'b ... [T] for some lifetimes 'a and 'b, and the goal here is to get a &'b ... [T], slice it and write that into the &'a mut.
For &'a mut &'b [T], this is easy: &[T] is copy, so writing *slice = &slice[1..] will effectively copy the &'b [T] out of the &mut and then, later, overwrite the existing value with the shorter one. The copy means that one literally gets a &'b [T] to operate with, and so there's no direct connection between that and the &'a mut, and hence it is legal to mutate. It is effectively something like
fn pop_front<'a, 'b>(slice: &'a mut &'b[i32]) {
// *slice = &slice[1..] behaves like
let value: &'b [i32] = *slice;
*slice = &value[1..]
}
(I've labelled the lifetimes and annotated the type to tie into my explanation, but this is not required for the code to work.)
For &'a mut &'b mut [T] things are a little trickier: &mut [T] cannot be copied: dereferencing won't copy, it will reborrow to give a &'a mut [T] i.e. the slice has a lifetime that is connected to the outer &'a mut, not the inner &'b mut [T]. This means the sliced reference has a shorter lifetime than the type it is trying to overwrite, so it's invalid to store the slice into that position. In other words:
fn pop_front<'a, 'b>(slice: &'a mut &'b mut [i32]) {
let value: &'a mut [i32] = &mut **slice;
*slice = &mut value[1..] // error
}
The way to do this safely for &'a mut &'b mut [T] is to get the internal slice out of the reference with that 'b lifetime. This requires keeping track of the "one owner" rule, doing no borrowing, and the best function for this sort of ownership manipulation is mem::replace. It allows us to extract the inner &'b mut [T] by swapping it with some placeholder, which we can then overwrite with the short version. The best/only placeholder is an empty array: writing &mut [] can be a &'c mut [X] for any type X and any lifetime 'c, since there's no data to store and so nothing needs initialisation, and no data will ever become invalid. In particular, it can be a &'b mut [T]:
fn pop_front<'a, 'b>(slice: &'a mut &'b mut [i32]) {
let value: &'b mut [i32] = mem::replace(slice, &mut []);
*slice = &mut value[1..]
}
Since &mut[T] implements Default, we can also use mem::take:
fn pop_front<'a, 'b>(slice: &'a mut &'b mut [i32]) {
let value: &'b mut [i32] = mem::take(slice);
*slice = &mut value[1..]
}
(As above, I've made things more explicit than necessary.)
See also:
Why can't I assign one dereference of a reference of a reference to another when the outer lifetimes differ?
Why does linking lifetimes matter only with mutable references?
How can I swap in a new value for a field in a mutable reference to a structure?
If you need to modify an immutable slice, see Cornstalks's answer.
You cannot modify a mutable slice in safe Rust. When you take a subslice of a mutable slice, you effectively borrow from the original slice. This means that the subslice must not outlive the original slice.
You want something that looks like this:
fn pop_front(slice: &mut &mut [i32]) {
*slice = &mut slice[1..];
}
but the subslice slice[1..] is only valid until the end of the function, and which point the borrow will end and the original slice (the slice parameter) will be usable again.
We can use some unsafe code to construct manually the slice we want:
use std::slice;
fn pop_front(slice: &mut &mut [i32]) {
let ptr = slice.as_mut_ptr();
let len = slice.len();
*slice = unsafe { slice::from_raw_parts_mut(ptr.offset(1), len - 1) };
}
fn main() {
let mut slice = &mut [0, 1, 2, 3][..];
pop_front(&mut slice);
println!("{:?}", slice);
}
playground
This program outputs:
[1, 2, 3]
Using part of Francis Gagné's answer (I didn't think of trying &mut &), I was able to get it working without using unsafe code:
fn pop_front(mut slice: &mut &[i32]) {
*slice = &slice[1..];
}
fn main() {
let mut slice = &[0, 1, 2, 3][..];
pop_front(&mut slice);
println!("{:?}", slice);
}
Output:
[1, 2, 3]

Resources