-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Weird borrowck issues with &mut &mut [u8] #11361
Comments
It is possible to do something like the following in safe Rust: #![feature(collections)]
fn main() {
let mut line = [0u8; 512];
{
let mut buf = &mut line[..];
/// reslice is essentially equivalent to `*buf = &mut buf[len..];`.
fn reslice(buf: &mut &mut [u8], len: usize) {
let tmp = std::mem::replace(buf, &mut []);
std::mem::replace(buf, &mut tmp[len..]);
}
fn append(buf: &mut &mut [u8], v: &[u8]) {
let len = buf.clone_from_slice(v);
reslice(buf, len);
}
append(&mut buf, b"test");
append(&mut buf, b"foo");
}
assert_eq!(&line[..7], b"testfoo");
} The error message you get if you try to write
|
With a slight modification to @eefriedman 's example ( When trying to do the |
This issue boils down to the following, I think. fn append(buf: &mut &mut [u8]) {
*buf = &mut buf[..];
} |
OK, so, it's only been like 3 years since the initial issue report. Sheesh. Let me explain a bit what is going on. I don't see an obvious fix at the moment. First off, it's worth noting that while the original code does not compile, this variant (which uses a shared slice inside) does:
The reason for this is explained in my NLL-RFC draft, in particular when discussing Reborrow constraints and the notion of supporting prefixes. When we do If we adjust to |
Triage: NLL does not fix this. |
Issue incorrectly auto-closed. A commit in the subtree update of rust-analyzer "Fixes rust-lang/rust-analyzer#11361" but GitHub misinterpreted it as this issue #11361. |
Is this related? |
I ran into some bizarre borrowck issues when trying to write a function that would modify a
&mut &mut [u8]
. The goal here was to make it simple to shove data into a[u8, ..512]
by virtue of copying data into the corresponding&mut [u8]
and then modifying the slice. I tried three different approaches, and they all had issues. The various errors are commented into the source.(All 3 approaches require
use std::vdc::MutableCloneableVector
)The first approach tried to define a function
append(buf: &mut &mut [u8], v: &[u8])
that would copy the data intobuf
and then modify*buf
to contain the new slice. This ran into an odd lifetime error where it thinks that I can't say*buf = buf.mut_slice_from(len)
. It claims the lifetime ofbuf
is too short, but I don't see why that matters. I'm actually re-slicing*buf
, and putting the result back into the same location that held the original slice, so I would expect it to have the same lifetime and, therefore, be valid.The second approach was to give both levels of indirection the same lifetime, e.g.
append<'a>(&'a mut &'a mut [u8], v: &[u8])
to try and squelch the error. This didn't work because I wasn't allowed to reassign back to*buf
, as it consideredbuf.mut_slice_from(len)
to borrow it. I assume the borrow check is tied to the lifetime, which is shared at both levels, so borrowck thinksbuf
is borrowed when it's really*buf
that's borrowed.Curiously, it also decided I couldn't use
&mut buf
twice in the calling code, as it seemed to think it was already borrowed.The third approach was to ditch
&mut &mut [u8]
entirely and try capturingbuf
in a closure instead. This gave some odd errors. First off, it kept referencing(*buf)[]
, and I don't know what it meant by that. Also, the first error here indicates that a borrow on a later line was blocking a borrow on an earlier line, which is quite bizarre. How canbuf
have been borrowed already when the later line is, well, later? It also considered the same reference tobuf
to consist of multiple mutable borrows.In the end, I couldn't figure out any way to accomplish what I wanted. It seems to me the first approach should have worked.
/cc @nikomatsakis
The text was updated successfully, but these errors were encountered: