task: make LocalSet non-Send (#2398)

This does not count as a breaking change as it fixes a
regression and a soundness bug.
This commit is contained in:
Alice Ryhl 2020-04-12 23:55:37 +02:00 committed by GitHub
parent f39c15334e
commit 4fc2adae4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 0 deletions

View File

@ -7,6 +7,7 @@ use std::cell::{Cell, RefCell};
use std::collections::VecDeque;
use std::fmt;
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::task::Poll;
@ -114,6 +115,9 @@ cfg_rt_util! {
/// State available from thread-local
context: Context,
/// This type should not be Send.
_not_send: PhantomData<*const ()>,
}
}
@ -228,6 +232,7 @@ impl LocalSet {
waker: AtomicWaker::new(),
}),
},
_not_send: PhantomData,
}
}

View File

@ -41,6 +41,44 @@ macro_rules! into_todo {
x
}};
}
macro_rules! assert_value {
($type:ty: Send & Sync) => {
#[allow(unreachable_code)]
#[allow(unused_variables)]
const _: fn() = || {
let f: $type = todo!();
require_send(&f);
require_sync(&f);
};
};
($type:ty: !Send & Sync) => {
#[allow(unreachable_code)]
#[allow(unused_variables)]
const _: fn() = || {
let f: $type = todo!();
AmbiguousIfSend::some_item(&f);
require_sync(&f);
};
};
($type:ty: Send & !Sync) => {
#[allow(unreachable_code)]
#[allow(unused_variables)]
const _: fn() = || {
let f: $type = todo!();
require_send(&f);
AmbiguousIfSync::some_item(&f);
};
};
($type:ty: !Send & !Sync) => {
#[allow(unreachable_code)]
#[allow(unused_variables)]
const _: fn() = || {
let f: $type = todo!();
AmbiguousIfSend::some_item(&f);
AmbiguousIfSync::some_item(&f);
};
};
}
macro_rules! async_assert_fn {
($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): Send & Sync) => {
#[allow(unreachable_code)]
@ -206,6 +244,7 @@ async_assert_fn!(tokio::task::LocalKey<Rc<u32>>::scope(_, Rc<u32>, BoxFutureSync
async_assert_fn!(tokio::task::LocalKey<Rc<u32>>::scope(_, Rc<u32>, BoxFutureSend<()>): !Send & !Sync);
async_assert_fn!(tokio::task::LocalKey<Rc<u32>>::scope(_, Rc<u32>, BoxFuture<()>): !Send & !Sync);
async_assert_fn!(tokio::task::LocalSet::run_until(_, BoxFutureSync<()>): !Send & !Sync);
assert_value!(tokio::task::LocalSet: !Send & !Sync);
async_assert_fn!(tokio::time::advance(Duration): Send & Sync);
async_assert_fn!(tokio::time::delay_for(Duration): Send & Sync);