From fd70a4ca1741d1147ba2288d909857566598efee Mon Sep 17 00:00:00 2001
From: Arthur Cohen <arthur.cohen@embecosm.com>
Date: Tue, 7 Nov 2023 13:17:00 +0100
Subject: [PATCH] test: Add test for async-move in 2015 Rust proc macro

Add a test to ensure issue #89699 does not show up again. This test
emits an `async move` closure in a proc macro, which is used in a
test program compiled with edition 2015. We make sure the error message
is nice and shows up properly.
---
 .../edition-gated-async-move-syntax.rs        | 39 +++++++++++++++++++
 ...tion-gated-async-move-syntax-issue89699.rs | 10 +++++
 ...-gated-async-move-syntax-issue89699.stderr |  8 ++++
 3 files changed, 57 insertions(+)
 create mode 100644 tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs
 create mode 100644 tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs
 create mode 100644 tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.stderr

diff --git a/tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs b/tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs
new file mode 100644
index 0000000000000..ce7e60356f279
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs
@@ -0,0 +1,39 @@
+// force-host
+// no-prefer-dynamic
+
+// Proc macro helper for issue #89699, used by tests/ui/proc-macro/edition-gated-async-move-
+// syntax-issue89699.rs, emitting an `async move` closure. This syntax is only available in
+// editions 2018 and up, but is used in edition 2015 in the test.
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro_attribute]
+pub fn foo(_attr: TokenStream, item: TokenStream) -> TokenStream {
+    let tt = item.into_iter().next().unwrap();
+    let sp = tt.span();
+    let mut arg = TokenStream::new();
+    let mut g = Group::new(Delimiter::Brace, TokenStream::new());
+    g.set_span(sp);
+    arg.extend([
+        TokenTree::Ident(Ident::new("async", sp)),
+        TokenTree::Ident(Ident::new("move", sp)),
+        TokenTree::Group(g),
+    ]);
+    let mut body = TokenStream::new();
+    body.extend([
+        TokenTree::Ident(Ident::new("async_main", sp)),
+        TokenTree::Group(Group::new(Delimiter::Parenthesis, arg)),
+    ]);
+
+    let mut ret = TokenStream::new();
+    ret.extend([
+        TokenTree::Ident(Ident::new("fn", sp)),
+        TokenTree::Ident(Ident::new("main", sp)),
+        TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
+        TokenTree::Group(Group::new(Delimiter::Brace, body)),
+    ]);
+    ret
+}
diff --git a/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs b/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs
new file mode 100644
index 0000000000000..1a9d4601acafe
--- /dev/null
+++ b/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs
@@ -0,0 +1,10 @@
+// aux-build:edition-gated-async-move-syntax.rs
+// edition: 2015
+
+// Non-regression test for issue #89699, where a proc-macro emitting syntax only available in
+// edition 2018 and up (`async move`) is used on edition 2015
+
+extern crate edition_gated_async_move_syntax;
+
+#[edition_gated_async_move_syntax::foo]
+fn foo() {} //~ ERROR `async move` blocks are only allowed in Rust 2018 or later
diff --git a/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.stderr b/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.stderr
new file mode 100644
index 0000000000000..a0dcc84eef8fa
--- /dev/null
+++ b/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.stderr
@@ -0,0 +1,8 @@
+error: `async move` blocks are only allowed in Rust 2018 or later
+  --> $DIR/edition-gated-async-move-syntax-issue89699.rs:10:1
+   |
+LL | fn foo() {}
+   | ^^
+
+error: aborting due to previous error
+