about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTaylor Cramer <cramertj@google.com>2018-06-18 16:49:34 -0700
committerTaylor Cramer <cramertj@google.com>2018-06-21 22:37:17 -0700
commit09f6caabe5dbb758b678dd81a6f3d98fbd41f590 (patch)
treea6be6882ecfa6ba56a7a6b4f54fc34be1a1dc163
parentcf844b547dbec1f23982fca8e07ec65800ed5d6d (diff)
downloadrust-09f6caabe5dbb758b678dd81a6f3d98fbd41f590.tar.gz
rust-09f6caabe5dbb758b678dd81a6f3d98fbd41f590.zip
Parse `unsafe async fn` instead of `async unsafe fn`
-rw-r--r--src/libsyntax/parse/parser.rs14
-rw-r--r--src/test/run-pass/async-await.rs13
2 files changed, 23 insertions, 4 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index e5ac0b8ed7c..c2abb79a93a 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -6744,13 +6744,19 @@ impl<'a> Parser<'a> {
                                     maybe_append(attrs, extra_attrs));
             return Ok(Some(item));
         }
-        if self.check_keyword(keywords::Async) &&
-            (self.look_ahead(1, |t| t.is_keyword(keywords::Fn)) ||
-             self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)))
+
+        // `unsafe async fn` or `async fn`
+        if (
+            self.check_keyword(keywords::Unsafe) &&
+            self.look_ahead(1, |t| t.is_keyword(keywords::Async))
+        ) || (
+            self.check_keyword(keywords::Async) &&
+            self.look_ahead(1, |t| t.is_keyword(keywords::Fn))
+        )
         {
             // ASYNC FUNCTION ITEM
-            self.expect_keyword(keywords::Async)?;
             let unsafety = self.parse_unsafety();
+            self.expect_keyword(keywords::Async)?;
             self.expect_keyword(keywords::Fn)?;
             let fn_span = self.prev_span;
             let (ident, item_, extra_attrs) =
diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs
index 6b2c01f5769..bc8b8a152fb 100644
--- a/src/test/run-pass/async-await.rs
+++ b/src/test/run-pass/async-await.rs
@@ -99,6 +99,19 @@ fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
     }
 }
 
+unsafe async fn unsafe_async_fn(x: u8) -> u8 {
+    await!(wake_and_yield_once());
+    x
+}
+
+struct Foo {
+    async fn async_method(x: u8) -> u8 {
+        unsafe {
+            await!(unsafe_async_fn())
+        }
+    }
+}
+
 fn test_future_yields_once_then_returns<F, Fut>(f: F)
 where
     F: FnOnce(u8) -> Fut,