| //@ edition: 2021 | |
| //@ run-pass | |
| #![allow(incomplete_features)] | |
| #![feature(move_expr)] | |
| use std::cell::Cell; | |
| use std::future::Future; | |
| use std::sync::Arc; | |
| use std::task::{Context, Poll, Waker}; | |
| fn block_on<F: Future>(future: F) -> F::Output { | |
| let mut future = Box::pin(future); | |
| let cx = &mut Context::from_waker(Waker::noop()); | |
| loop { | |
| match future.as_mut().poll(cx) { | |
| Poll::Ready(output) => return output, | |
| Poll::Pending => {} | |
| } | |
| } | |
| } | |
| fn main() { | |
| let created = Cell::new(0); | |
| let fut = async { | |
| let n = move({ | |
| created.set(created.get() + 1); | |
| created.get() | |
| }); | |
| n | |
| }; | |
| assert_eq!(created.get(), 1); | |
| drop(fut); | |
| let x = Arc::new(String::from("hello")); | |
| assert_eq!(Arc::strong_count(&x), 1); | |
| let fut = async { move(x.clone()) }; | |
| assert_eq!(Arc::strong_count(&x), 2); | |
| drop(fut); | |
| assert_eq!(Arc::strong_count(&x), 1); | |
| let y = Arc::new(String::from("nested once")); | |
| let weak = Arc::downgrade(&y); | |
| let fut = async { | |
| let inner = async { | |
| drop(move(y.clone())); | |
| }; | |
| assert_eq!(weak.strong_count(), 2); | |
| inner.await; | |
| assert_eq!(weak.strong_count(), 1); | |
| drop(y); | |
| }; | |
| assert_eq!(weak.strong_count(), 1); | |
| block_on(fut); | |
| assert_eq!(weak.strong_count(), 0); | |
| let y = Arc::new(String::from("nested twice")); | |
| let weak = Arc::downgrade(&y); | |
| let fut = async { | |
| let inner = async { | |
| drop(move(move(y.clone()))); | |
| }; | |
| assert_eq!(weak.strong_count(), 2); | |
| inner.await; | |
| assert_eq!(weak.strong_count(), 1); | |
| }; | |
| assert_eq!(weak.strong_count(), 2); | |
| block_on(fut); | |
| assert_eq!(weak.strong_count(), 1); | |
| assert_eq!(&*y, "nested twice"); | |
| let z = Arc::new(String::from("async move")); | |
| assert_eq!(Arc::strong_count(&z), 1); | |
| let fut = async move { move(z.clone()) }; | |
| assert_eq!(Arc::strong_count(&z), 2); | |
| drop(fut); | |
| assert_eq!(Arc::strong_count(&z), 1); | |
| } |