error[E0277]: the trait bound `&mut T: EndExt` is not satisfied
--> src/tests/help_me.rs:39:5
|
39 | worker_in_deeper(sub_a.as_mut_slice(), b);
| ^^^^^^^^^^^^^^^^ the trait `EndExt` is not implemented for `&mut T`
|
= help: the trait `EndExt` is implemented for `Ends`
note: required by a bound in `worker_in_deeper`
--> src/tests/help_me.rs:42:24
|
42 | fn worker_in_deeper<T: EndExt>(a: &mut [T], b:&T) {
| ^^^^^^ required by this bound in `worker_in_deeper`
In the above situation, can I convert &mut [&mut T] into &mut [T]?
To elaborate on @drewtato's answer, the reason you can't turn a &mut [&mut T] into a &mut [T] is because a &mut [T] is a reference to a single slice of contiguous T's, whereas a &mut [&mut T] is a bunch of references to slices of T's, where each of those slices could be placed anywhere in memory.
If you really wanted everything to be in a single slice, you would need to copy all the T's into something like a Vec<T> so the elements are guaranteed to be next to each other.
However, you can turn something like a &mut [&mut T] into an iterator quite easily if all you need is to access each element in turn.
Yes, for exactly the same reason. If you want to move things around in memory so they are contiguous, you'll need to make a temporary copy or new allocation (depending on where the original &[&T] came from).
There are some unsafe tricks that you might be able to use in the really niche case that the values being referred to are already contiguous (e.g. because they came from slice::chunks()), but it's quite nuanced (the term is "pointer provenance") and will probably be UB unless you really know what you are doing.