Skip to content

Commit

Permalink
Parse 'async unsafe fn' instead of 'unsafe async fn'.
Browse files Browse the repository at this point in the history
  • Loading branch information
Centril committed May 30, 2019
1 parent 0bfbaa6 commit 2ebfbb4
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 39 deletions.
71 changes: 34 additions & 37 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7205,44 +7205,41 @@ impl<'a> Parser<'a> {
return Ok(Some(item));
}

// `unsafe async fn` or `async fn`
if (
self.check_keyword(kw::Unsafe) &&
self.is_keyword_ahead(1, &[kw::Async])
) || (
self.check_keyword(kw::Async) &&
self.is_keyword_ahead(1, &[kw::Fn])
)
{
// ASYNC FUNCTION ITEM
let unsafety = self.parse_unsafety();
self.expect_keyword(kw::Async)?;
let async_span = self.prev_span;
self.expect_keyword(kw::Fn)?;
let fn_span = self.prev_span;
let (ident, item_, extra_attrs) =
self.parse_item_fn(unsafety,
respan(async_span, IsAsync::Async {
closure_id: ast::DUMMY_NODE_ID,
return_impl_trait_id: ast::DUMMY_NODE_ID,
arguments: Vec::new(),
}),
respan(fn_span, Constness::NotConst),
Abi::Rust)?;
let prev_span = self.prev_span;
let item = self.mk_item(lo.to(prev_span),
ident,
item_,
visibility,
maybe_append(attrs, extra_attrs));
if self.span.rust_2015() {
self.diagnostic().struct_span_err_with_code(
async_span,
"`async fn` is not permitted in the 2015 edition",
DiagnosticId::Error("E0670".into())
).emit();
// Parse `async unsafe? fn`.
if self.check_keyword(kw::Async) {
let async_span = self.span;
if self.is_keyword_ahead(1, &[kw::Fn])
|| self.is_keyword_ahead(2, &[kw::Fn])
{
// ASYNC FUNCTION ITEM
self.bump(); // `async`
let unsafety = self.parse_unsafety(); // `unsafe`?
self.expect_keyword(kw::Fn)?; // `fn`
let fn_span = self.prev_span;
let (ident, item_, extra_attrs) =
self.parse_item_fn(unsafety,
respan(async_span, IsAsync::Async {
closure_id: ast::DUMMY_NODE_ID,
return_impl_trait_id: ast::DUMMY_NODE_ID,
arguments: Vec::new(),
}),
respan(fn_span, Constness::NotConst),
Abi::Rust)?;
let prev_span = self.prev_span;
let item = self.mk_item(lo.to(prev_span),
ident,
item_,
visibility,
maybe_append(attrs, extra_attrs));
if self.span.rust_2015() {
self.diagnostic().struct_span_err_with_code(
async_span,
"`async fn` is not permitted in the 2015 edition",
DiagnosticId::Error("E0670".into())
).emit();
}
return Ok(Some(item));
}
return Ok(Some(item));
}
if self.check_keyword(kw::Unsafe) &&
self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/async-await/async-await.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
}
}

unsafe async fn unsafe_async_fn(x: u8) -> u8 {
async unsafe fn unsafe_async_fn(x: u8) -> u8 {
wake_and_yield_once().await;
x
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/async-await/await-macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
}
}

unsafe async fn unsafe_async_fn(x: u8) -> u8 {
async unsafe fn unsafe_async_fn(x: u8) -> u8 {
await!(wake_and_yield_once());
x
}
Expand Down

0 comments on commit 2ebfbb4

Please sign in to comment.