Open mamins1376 opened 9 months ago
Note that Drain::as_mut_slice
and Drain::keep_rest
(which currenty exists unstably) cannot both exist soundly, since Drain<'_, T>
is covariant in T. Otherwise, you could do something like this (playground link):
#![feature(drain_keep_rest)]
use std::vec::Drain;
fn evil(iter: Drain<'_, &'static str>, local: &str) {
// rebind for lifetime coercion
let mut iter = iter;
iter.as_mut_slice()[0] = local;
iter.keep_rest();
}
fn main() {
let mut static_strs: Vec<&'static str> = vec!["hello", "my", "friend"];
let local = String::from("evil");
let iter = static_strs.drain(1..2);
evil(iter, &local);
drop(local);
dbg!(static_strs); // use-after-free
}
Since
Vec::drain()
in a sense owns the selected range of vector items, it makes sense to be able to hand out a mutable slice pointing to them. This can happen throughAsMut
trait andvec::Drain::as_mut_slice()
, as it is already the case for a immutable slice.