-
Notifications
You must be signed in to change notification settings - Fork 14
.map_unchecked_mut() is unsound for self-referential types #9
Copy link
Copy link
Closed
Description
Hi! I’ve recently created a similar crate, but without dynamic dispatch and with automatic size calculation and Send/Sync inference, and found a problem with using .map_unchecked_mut() in .poll().
This line:
https://github.com/microsoft/stackfuture/blob/ae58939/src/lib.rs#L207
causes a retag of the whole byte array, invalidating all internal references inside of a future. To prevent this, you should directly transmute Pin<&mut MaybeUninit[u8; _]> instead of mapping.
This is a simple testcase that fails under Miri (adapted from futures-rs test suite):
use futures::{
channel::mpsc,
executor::block_on,
sink::SinkExt as _,
stream::{Stream, StreamExt as _},
};
use stackfuture::StackFuture;
use std::thread;
#[test]
fn stress_drop_sender() {
const ITER: usize = if cfg!(miri) { 100 } else { 10000 };
fn list() -> impl Stream<Item = i32> {
let (tx, rx) = mpsc::channel(1);
thread::spawn(move || {
block_on(send_one_two_three(tx));
});
rx
}
for _ in 0..ITER {
let v: Vec<_> = block_on(list().collect());
assert_eq!(v, vec![1, 2, 3]);
}
}
fn send_one_two_three(mut tx: mpsc::Sender<i32>) -> StackFuture<'static, (), 512> {
StackFuture::from(async move {
for i in 1..=3 {
tx.send(i).await.unwrap();
}
})
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels