Skip to content

Commit 2ebfbb4

Browse files
committed
Parse 'async unsafe fn' instead of 'unsafe async fn'.
1 parent 0bfbaa6 commit 2ebfbb4

File tree

3 files changed

+36
-39
lines changed

3 files changed

+36
-39
lines changed

src/libsyntax/parse/parser.rs

+34-37
Original file line numberDiff line numberDiff line change
@@ -7205,44 +7205,41 @@ impl<'a> Parser<'a> {
72057205
return Ok(Some(item));
72067206
}
72077207

7208-
// `unsafe async fn` or `async fn`
7209-
if (
7210-
self.check_keyword(kw::Unsafe) &&
7211-
self.is_keyword_ahead(1, &[kw::Async])
7212-
) || (
7213-
self.check_keyword(kw::Async) &&
7214-
self.is_keyword_ahead(1, &[kw::Fn])
7215-
)
7216-
{
7217-
// ASYNC FUNCTION ITEM
7218-
let unsafety = self.parse_unsafety();
7219-
self.expect_keyword(kw::Async)?;
7220-
let async_span = self.prev_span;
7221-
self.expect_keyword(kw::Fn)?;
7222-
let fn_span = self.prev_span;
7223-
let (ident, item_, extra_attrs) =
7224-
self.parse_item_fn(unsafety,
7225-
respan(async_span, IsAsync::Async {
7226-
closure_id: ast::DUMMY_NODE_ID,
7227-
return_impl_trait_id: ast::DUMMY_NODE_ID,
7228-
arguments: Vec::new(),
7229-
}),
7230-
respan(fn_span, Constness::NotConst),
7231-
Abi::Rust)?;
7232-
let prev_span = self.prev_span;
7233-
let item = self.mk_item(lo.to(prev_span),
7234-
ident,
7235-
item_,
7236-
visibility,
7237-
maybe_append(attrs, extra_attrs));
7238-
if self.span.rust_2015() {
7239-
self.diagnostic().struct_span_err_with_code(
7240-
async_span,
7241-
"`async fn` is not permitted in the 2015 edition",
7242-
DiagnosticId::Error("E0670".into())
7243-
).emit();
7208+
// Parse `async unsafe? fn`.
7209+
if self.check_keyword(kw::Async) {
7210+
let async_span = self.span;
7211+
if self.is_keyword_ahead(1, &[kw::Fn])
7212+
|| self.is_keyword_ahead(2, &[kw::Fn])
7213+
{
7214+
// ASYNC FUNCTION ITEM
7215+
self.bump(); // `async`
7216+
let unsafety = self.parse_unsafety(); // `unsafe`?
7217+
self.expect_keyword(kw::Fn)?; // `fn`
7218+
let fn_span = self.prev_span;
7219+
let (ident, item_, extra_attrs) =
7220+
self.parse_item_fn(unsafety,
7221+
respan(async_span, IsAsync::Async {
7222+
closure_id: ast::DUMMY_NODE_ID,
7223+
return_impl_trait_id: ast::DUMMY_NODE_ID,
7224+
arguments: Vec::new(),
7225+
}),
7226+
respan(fn_span, Constness::NotConst),
7227+
Abi::Rust)?;
7228+
let prev_span = self.prev_span;
7229+
let item = self.mk_item(lo.to(prev_span),
7230+
ident,
7231+
item_,
7232+
visibility,
7233+
maybe_append(attrs, extra_attrs));
7234+
if self.span.rust_2015() {
7235+
self.diagnostic().struct_span_err_with_code(
7236+
async_span,
7237+
"`async fn` is not permitted in the 2015 edition",
7238+
DiagnosticId::Error("E0670".into())
7239+
).emit();
7240+
}
7241+
return Ok(Some(item));
72447242
}
7245-
return Ok(Some(item));
72467243
}
72477244
if self.check_keyword(kw::Unsafe) &&
72487245
self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])

src/test/ui/async-await/async-await.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
122122
}
123123
}
124124

125-
unsafe async fn unsafe_async_fn(x: u8) -> u8 {
125+
async unsafe fn unsafe_async_fn(x: u8) -> u8 {
126126
wake_and_yield_once().await;
127127
x
128128
}

src/test/ui/async-await/await-macro.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
122122
}
123123
}
124124

125-
unsafe async fn unsafe_async_fn(x: u8) -> u8 {
125+
async unsafe fn unsafe_async_fn(x: u8) -> u8 {
126126
await!(wake_and_yield_once());
127127
x
128128
}

0 commit comments

Comments
 (0)