about summary refs log tree commit diff
path: root/tests/ui/async-await/async-fn-size-uninit-locals.rs
diff options
context:
space:
mode:
authorAlbert Larsan <74931857+albertlarsan68@users.noreply.github.com>2023-01-05 09:13:28 +0100
committerAlbert Larsan <74931857+albertlarsan68@users.noreply.github.com>2023-01-11 09:32:08 +0000
commitcf2dff2b1e3fa55fa5415d524200070d0d7aacfe (patch)
tree40a88d9a46aaf3e8870676eb2538378b75a263eb /tests/ui/async-await/async-fn-size-uninit-locals.rs
parentca855e6e42787ecd062d81d53336fe6788ef51a9 (diff)
downloadrust-cf2dff2b1e3fa55fa5415d524200070d0d7aacfe.tar.gz
rust-cf2dff2b1e3fa55fa5415d524200070d0d7aacfe.zip
Move /src/test to /tests
Diffstat (limited to 'tests/ui/async-await/async-fn-size-uninit-locals.rs')
-rw-r--r--tests/ui/async-await/async-fn-size-uninit-locals.rs102
1 files changed, 102 insertions, 0 deletions
diff --git a/tests/ui/async-await/async-fn-size-uninit-locals.rs b/tests/ui/async-await/async-fn-size-uninit-locals.rs
new file mode 100644
index 00000000000..54617269354
--- /dev/null
+++ b/tests/ui/async-await/async-fn-size-uninit-locals.rs
@@ -0,0 +1,102 @@
+// Test that we don't store uninitialized locals in futures from `async fn`.
+//
+// The exact sizes can change by a few bytes (we'd like to know when they do).
+// What we don't want to see is the wrong multiple of 1024 (the size of `Big`)
+// being reflected in the size.
+
+// ignore-emscripten (sizes don't match)
+// needs-unwind Size of Futures change on panic=abort
+// run-pass
+
+// edition:2018
+
+#![allow(unused_variables, unused_assignments)]
+
+use std::future::Future;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+const BIG_FUT_SIZE: usize = 1024;
+struct Big(#[allow(unused_tuple_struct_fields)] [u8; BIG_FUT_SIZE]);
+
+impl Big {
+    fn new() -> Self {
+        Big([0; BIG_FUT_SIZE])
+    }
+}
+
+impl Drop for Big {
+    fn drop(&mut self) {}
+}
+
+#[allow(dead_code)]
+struct Joiner {
+    a: Option<Big>,
+    b: Option<Big>,
+    c: Option<Big>,
+}
+
+impl Future for Joiner {
+    type Output = ();
+
+    fn poll(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll<Self::Output> {
+        Poll::Ready(())
+    }
+}
+
+fn noop() {}
+async fn fut() {}
+
+async fn single() {
+    let x;
+    fut().await;
+    x = Big::new();
+}
+
+async fn single_with_noop() {
+    let x;
+    fut().await;
+    noop();
+    x = Big::new();
+    noop();
+}
+
+async fn joined() {
+    let joiner;
+    let a = Big::new();
+    let b = Big::new();
+    let c = Big::new();
+
+    fut().await;
+    joiner = Joiner { a: Some(a), b: Some(b), c: Some(c) };
+}
+
+async fn joined_with_noop() {
+    let joiner;
+    let a = Big::new();
+    let b = Big::new();
+    let c = Big::new();
+
+    fut().await;
+    noop();
+    joiner = Joiner { a: Some(a), b: Some(b), c: Some(c) };
+    noop();
+}
+
+async fn join_retval() -> Joiner {
+    let a = Big::new();
+    let b = Big::new();
+    let c = Big::new();
+
+    fut().await;
+    noop();
+    Joiner { a: Some(a), b: Some(b), c: Some(c) }
+}
+
+fn main() {
+    assert_eq!(2, std::mem::size_of_val(&single()));
+    assert_eq!(3, std::mem::size_of_val(&single_with_noop()));
+    assert_eq!(3074, std::mem::size_of_val(&joined()));
+    assert_eq!(3078, std::mem::size_of_val(&joined_with_noop()));
+    assert_eq!(3074, std::mem::size_of_val(&join_retval()));
+}