about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorNathan Corbyn <me@nathancorbyn.com>2019-02-23 18:39:27 +0000
committerNathan Corbyn <me@nathancorbyn.com>2019-02-24 16:33:12 +0000
commit8300f51936149ec43eb063205e4d03c54a308f3c (patch)
treefa722c6f5a1cb29ffaec3477aa6b7b18d79e9660 /src/libsyntax/parse
parent7f19f161f24c9a02ff8c3f73122d0b015039221f (diff)
downloadrust-8300f51936149ec43eb063205e4d03c54a308f3c.tar.gz
rust-8300f51936149ec43eb063205e4d03c54a308f3c.zip
Deny `async fn` in 2015 edition
Fix style issues and update diagnostic messages

Update src/librustc_passes/diagnostics.rs

Co-Authored-By: doctorn <me@nathancorbyn.com>

Deny nested `async fn` in Rust 2015 edition

Deny nested `async fn` in Rust 2015 edition

Deny nested `async fn` in Rust 2015 edition
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs39
1 files changed, 28 insertions, 11 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 5a753e1f8c8..c257f05ae46 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -5001,6 +5001,11 @@ impl<'a> Parser<'a> {
         )
     }
 
+    fn is_async_fn(&mut self) -> bool {
+        self.token.is_keyword(keywords::Async) &&
+            self.look_ahead(1, |t| t.is_keyword(keywords::Fn))
+    }
+
     fn is_do_catch_block(&mut self) -> bool {
         self.token.is_keyword(keywords::Do) &&
         self.look_ahead(1, |t| t.is_keyword(keywords::Catch)) &&
@@ -5133,7 +5138,8 @@ impl<'a> Parser<'a> {
                   !self.is_union_item() &&
                   !self.is_crate_vis() &&
                   !self.is_existential_type_decl() &&
-                  !self.is_auto_trait_item() {
+                  !self.is_auto_trait_item() &&
+                  !self.is_async_fn() {
             let pth = self.parse_path(PathStyle::Expr)?;
 
             if !self.eat(&token::Not) {
@@ -6346,7 +6352,7 @@ impl<'a> Parser<'a> {
     /// Parses an item-position function declaration.
     fn parse_item_fn(&mut self,
                      unsafety: Unsafety,
-                     asyncness: IsAsync,
+                     asyncness: Spanned<IsAsync>,
                      constness: Spanned<Constness>,
                      abi: Abi)
                      -> PResult<'a, ItemInfo> {
@@ -6378,7 +6384,7 @@ impl<'a> Parser<'a> {
         -> PResult<'a, (
             Spanned<Constness>,
             Unsafety,
-            IsAsync,
+            Spanned<IsAsync>,
             Abi
         )>
     {
@@ -6386,6 +6392,7 @@ impl<'a> Parser<'a> {
         let const_span = self.prev_span;
         let unsafety = self.parse_unsafety();
         let asyncness = self.parse_asyncness();
+        let asyncness = respan(self.prev_span, asyncness);
         let (constness, unsafety, abi) = if is_const_fn {
             (respan(const_span, Constness::Const), unsafety, Abi::Rust)
         } else {
@@ -7796,7 +7803,7 @@ impl<'a> Parser<'a> {
                 let abi = opt_abi.unwrap_or(Abi::C);
                 let (ident, item_, extra_attrs) =
                     self.parse_item_fn(Unsafety::Normal,
-                                       IsAsync::NotAsync,
+                                       respan(fn_span, IsAsync::NotAsync),
                                        respan(fn_span, Constness::NotConst),
                                        abi)?;
                 let prev_span = self.prev_span;
@@ -7840,7 +7847,7 @@ impl<'a> Parser<'a> {
                 self.bump();
                 let (ident, item_, extra_attrs) =
                     self.parse_item_fn(unsafety,
-                                       IsAsync::NotAsync,
+                                       respan(const_span, IsAsync::NotAsync),
                                        respan(const_span, Constness::Const),
                                        Abi::Rust)?;
                 let prev_span = self.prev_span;
@@ -7888,14 +7895,15 @@ impl<'a> Parser<'a> {
             // ASYNC FUNCTION ITEM
             let unsafety = self.parse_unsafety();
             self.expect_keyword(keywords::Async)?;
+            let async_span = self.prev_span;
             self.expect_keyword(keywords::Fn)?;
             let fn_span = self.prev_span;
             let (ident, item_, extra_attrs) =
                 self.parse_item_fn(unsafety,
-                                   IsAsync::Async {
+                                   respan(async_span, IsAsync::Async {
                                        closure_id: ast::DUMMY_NODE_ID,
                                        return_impl_trait_id: ast::DUMMY_NODE_ID,
-                                   },
+                                   }),
                                    respan(fn_span, Constness::NotConst),
                                    Abi::Rust)?;
             let prev_span = self.prev_span;
@@ -7904,6 +7912,13 @@ impl<'a> Parser<'a> {
                                     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));
         }
         if self.check_keyword(keywords::Unsafe) &&
@@ -7951,7 +7966,7 @@ impl<'a> Parser<'a> {
             let fn_span = self.prev_span;
             let (ident, item_, extra_attrs) =
                 self.parse_item_fn(Unsafety::Normal,
-                                   IsAsync::NotAsync,
+                                   respan(fn_span, IsAsync::NotAsync),
                                    respan(fn_span, Constness::NotConst),
                                    Abi::Rust)?;
             let prev_span = self.prev_span;
@@ -7977,7 +7992,7 @@ impl<'a> Parser<'a> {
             let fn_span = self.prev_span;
             let (ident, item_, extra_attrs) =
                 self.parse_item_fn(Unsafety::Unsafe,
-                                   IsAsync::NotAsync,
+                                   respan(fn_span, IsAsync::NotAsync),
                                    respan(fn_span, Constness::NotConst),
                                    abi)?;
             let prev_span = self.prev_span;
@@ -8244,7 +8259,8 @@ impl<'a> Parser<'a> {
         lo: Span,
         visibility: Visibility
     ) -> PResult<'a, Option<P<Item>>> {
-        if macros_allowed && self.token.is_path_start() {
+        if macros_allowed && self.token.is_path_start() &&
+                !(self.is_async_fn() && self.span.rust_2015()) {
             // MACRO INVOCATION ITEM
 
             let prev_span = self.prev_span;
@@ -8299,7 +8315,8 @@ impl<'a> Parser<'a> {
     fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
                                at_end: &mut bool) -> PResult<'a, Option<Mac>>
     {
-        if self.token.is_path_start() {
+        if self.token.is_path_start() &&
+                !(self.is_async_fn() && self.span.rust_2015()) {
             let prev_span = self.prev_span;
             let lo = self.span;
             let pth = self.parse_path(PathStyle::Mod)?;