summaryrefslogtreecommitdiffstats
path: root/tests/ui/async-await/auxiliary
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/async-await/auxiliary
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/async-await/auxiliary')
-rw-r--r--tests/ui/async-await/auxiliary/arc_wake.rs64
-rw-r--r--tests/ui/async-await/auxiliary/issue-107036.rs12
-rw-r--r--tests/ui/async-await/auxiliary/issue-72470-lib.rs175
3 files changed, 251 insertions, 0 deletions
diff --git a/tests/ui/async-await/auxiliary/arc_wake.rs b/tests/ui/async-await/auxiliary/arc_wake.rs
new file mode 100644
index 000000000..c21886f26
--- /dev/null
+++ b/tests/ui/async-await/auxiliary/arc_wake.rs
@@ -0,0 +1,64 @@
+// edition:2018
+
+use std::sync::Arc;
+use std::task::{
+ Waker, RawWaker, RawWakerVTable,
+};
+
+macro_rules! waker_vtable {
+ ($ty:ident) => {
+ &RawWakerVTable::new(
+ clone_arc_raw::<$ty>,
+ wake_arc_raw::<$ty>,
+ wake_by_ref_arc_raw::<$ty>,
+ drop_arc_raw::<$ty>,
+ )
+ };
+}
+
+pub trait ArcWake {
+ fn wake(self: Arc<Self>);
+
+ fn wake_by_ref(arc_self: &Arc<Self>) {
+ arc_self.clone().wake()
+ }
+
+ fn into_waker(wake: Arc<Self>) -> Waker where Self: Sized
+ {
+ let ptr = Arc::into_raw(wake) as *const ();
+
+ unsafe {
+ Waker::from_raw(RawWaker::new(ptr, waker_vtable!(Self)))
+ }
+ }
+}
+
+unsafe fn increase_refcount<T: ArcWake>(data: *const ()) {
+ // Retain Arc by creating a copy
+ let arc: Arc<T> = Arc::from_raw(data as *const T);
+ let arc_clone = arc.clone();
+ // Forget the Arcs again, so that the refcount isn't decrased
+ let _ = Arc::into_raw(arc);
+ let _ = Arc::into_raw(arc_clone);
+}
+
+unsafe fn clone_arc_raw<T: ArcWake>(data: *const ()) -> RawWaker {
+ increase_refcount::<T>(data);
+ RawWaker::new(data, waker_vtable!(T))
+}
+
+unsafe fn drop_arc_raw<T: ArcWake>(data: *const ()) {
+ // Drop Arc
+ let _: Arc<T> = Arc::from_raw(data as *const T);
+}
+
+unsafe fn wake_arc_raw<T: ArcWake>(data: *const ()) {
+ let arc: Arc<T> = Arc::from_raw(data as *const T);
+ ArcWake::wake(arc);
+}
+
+unsafe fn wake_by_ref_arc_raw<T: ArcWake>(data: *const ()) {
+ let arc: Arc<T> = Arc::from_raw(data as *const T);
+ ArcWake::wake_by_ref(&arc);
+ let _ = Arc::into_raw(arc);
+}
diff --git a/tests/ui/async-await/auxiliary/issue-107036.rs b/tests/ui/async-await/auxiliary/issue-107036.rs
new file mode 100644
index 000000000..c3f6141b2
--- /dev/null
+++ b/tests/ui/async-await/auxiliary/issue-107036.rs
@@ -0,0 +1,12 @@
+// edition:2021
+
+pub trait T {}
+impl T for () {}
+
+pub struct S {}
+
+impl S {
+ pub async fn f<'a>(&self) -> impl T + 'a {
+ ()
+ }
+}
diff --git a/tests/ui/async-await/auxiliary/issue-72470-lib.rs b/tests/ui/async-await/auxiliary/issue-72470-lib.rs
new file mode 100644
index 000000000..8383eba89
--- /dev/null
+++ b/tests/ui/async-await/auxiliary/issue-72470-lib.rs
@@ -0,0 +1,175 @@
+// compile-flags: -C opt-level=3
+// edition:2018
+
+use std::future::Future;
+use std::marker::PhantomData;
+use std::pin::Pin;
+use std::sync::atomic::AtomicUsize;
+use std::sync::Arc;
+use std::task::Poll::{Pending, Ready};
+use std::task::Waker;
+use std::task::{Context, Poll};
+use std::{
+ ptr,
+ task::{RawWaker, RawWakerVTable},
+};
+
+/// Future for the [`poll_fn`] function.
+pub struct PollFn<F> {
+ f: F,
+}
+
+impl<F> Unpin for PollFn<F> {}
+
+/// Creates a new future wrapping around a function returning [`Poll`].
+pub fn poll_fn<T, F>(f: F) -> PollFn<F>
+where
+ F: FnMut(&mut Context<'_>) -> Poll<T>,
+{
+ PollFn { f }
+}
+
+impl<T, F> Future for PollFn<F>
+where
+ F: FnMut(&mut Context<'_>) -> Poll<T>,
+{
+ type Output = T;
+
+ fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
+ (&mut self.f)(cx)
+ }
+}
+pub fn run<F: Future>(future: F) -> F::Output {
+ BasicScheduler.block_on(future)
+}
+
+pub(crate) struct BasicScheduler;
+
+impl BasicScheduler {
+ pub(crate) fn block_on<F>(&mut self, mut future: F) -> F::Output
+ where
+ F: Future,
+ {
+ let waker = unsafe { Waker::from_raw(raw_waker()) };
+ let mut cx = std::task::Context::from_waker(&waker);
+
+ let mut future = unsafe { Pin::new_unchecked(&mut future) };
+
+ loop {
+ if let Ready(v) = future.as_mut().poll(&mut cx) {
+ return v;
+ }
+ }
+ }
+}
+
+// ===== impl Spawner =====
+
+fn raw_waker() -> RawWaker {
+ RawWaker::new(ptr::null(), waker_vtable())
+}
+
+fn waker_vtable() -> &'static RawWakerVTable {
+ &RawWakerVTable::new(
+ clone_arc_raw,
+ wake_arc_raw,
+ wake_by_ref_arc_raw,
+ drop_arc_raw,
+ )
+}
+
+unsafe fn clone_arc_raw(_: *const ()) -> RawWaker {
+ raw_waker()
+}
+
+unsafe fn wake_arc_raw(_: *const ()) {}
+
+unsafe fn wake_by_ref_arc_raw(_: *const ()) {}
+
+unsafe fn drop_arc_raw(_: *const ()) {}
+
+struct AtomicWaker {}
+
+impl AtomicWaker {
+ /// Create an `AtomicWaker`
+ fn new() -> AtomicWaker {
+ AtomicWaker {}
+ }
+
+ fn register_by_ref(&self, _waker: &Waker) {}
+}
+
+#[allow(dead_code)]
+struct Tx<T> {
+ inner: Arc<Chan<T>>,
+}
+
+struct Rx<T> {
+ inner: Arc<Chan<T>>,
+}
+
+#[allow(dead_code)]
+struct Chan<T> {
+ tx: PhantomData<T>,
+ semaphore: Sema,
+ rx_waker: AtomicWaker,
+ rx_closed: bool,
+}
+
+fn channel<T>() -> (Tx<T>, Rx<T>) {
+ let chan = Arc::new(Chan {
+ tx: PhantomData,
+ semaphore: Sema(AtomicUsize::new(0)),
+ rx_waker: AtomicWaker::new(),
+ rx_closed: false,
+ });
+
+ (
+ Tx {
+ inner: chan.clone(),
+ },
+ Rx { inner: chan },
+ )
+}
+
+// ===== impl Rx =====
+
+impl<T> Rx<T> {
+ /// Receive the next value
+ fn recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<T>> {
+ self.inner.rx_waker.register_by_ref(cx.waker());
+
+ if self.inner.rx_closed && self.inner.semaphore.is_idle() {
+ Ready(None)
+ } else {
+ Pending
+ }
+ }
+}
+
+struct Sema(AtomicUsize);
+
+impl Sema {
+ fn is_idle(&self) -> bool {
+ false
+ }
+}
+
+pub struct UnboundedReceiver<T> {
+ chan: Rx<T>,
+}
+
+pub fn unbounded_channel<T>() -> UnboundedReceiver<T> {
+ let (tx, rx) = channel();
+
+ drop(tx);
+ let rx = UnboundedReceiver { chan: rx };
+
+ rx
+}
+
+impl<T> UnboundedReceiver<T> {
+ pub async fn recv(&mut self) -> Option<T> {
+ poll_fn(|cx| self.chan.recv(cx)).await
+ }
+}