about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-01-30 05:31:04 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2020-02-13 10:39:24 +0100
commitc30f068dc8b2ef58678b9846ba834dd6dea3fe44 (patch)
tree82e59f521573df949dda750e7f1aa31588205b7d /src
parente839b2ec849246ec5efe5069c8d874dbef289462 (diff)
downloadrust-c30f068dc8b2ef58678b9846ba834dd6dea3fe44.tar.gz
rust-c30f068dc8b2ef58678b9846ba834dd6dea3fe44.zip
IsAsync -> enum Async { Yes { span: Span, .. }, No }
use new span for better diagnostics.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_ast_lowering/expr.rs2
-rw-r--r--src/librustc_ast_lowering/item.rs27
-rw-r--r--src/librustc_ast_passes/ast_validation.rs12
-rw-r--r--src/librustc_ast_pretty/pprust.rs4
-rw-r--r--src/librustc_builtin_macros/test.rs6
-rw-r--r--src/librustc_expand/build.rs4
-rw-r--r--src/librustc_parse/parser/expr.rs4
-rw-r--r--src/librustc_parse/parser/item.rs44
-rw-r--r--src/librustc_parse/parser/mod.rs9
-rw-r--r--src/librustc_resolve/def_collector.rs12
-rw-r--r--src/librustc_resolve/late.rs2
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs8
-rw-r--r--src/librustc_save_analysis/sig.rs4
-rw-r--r--src/libsyntax/ast.rs26
-rw-r--r--src/libsyntax/mut_visit.rs10
-rw-r--r--src/test/ui-fulldeps/pprust-expr-roundtrip.rs2
-rw-r--r--src/test/ui/async-await/async-trait-fn.stderr8
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.stderr4
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.stderr16
19 files changed, 96 insertions, 108 deletions
diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs
index dd3316979f6..b51d4765583 100644
--- a/src/librustc_ast_lowering/expr.rs
+++ b/src/librustc_ast_lowering/expr.rs
@@ -106,7 +106,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ref body,
                 fn_decl_span,
             ) => {
-                if let IsAsync::Async { closure_id, .. } = asyncness {
+                if let Async::Yes { closure_id, .. } = asyncness {
                     self.lower_expr_async_closure(
                         capture_clause,
                         closure_id,
diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs
index 8cc3479dd1b..73a25620b5a 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/src/librustc_ast_lowering/item.rs
@@ -299,7 +299,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     // `impl Future<Output = T>` here because lower_body
                     // only cares about the input argument patterns in the function
                     // declaration (decl), not the return types.
-                    let asyncness = header.asyncness.node;
+                    let asyncness = header.asyncness;
                     let body_id =
                         this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());
 
@@ -836,19 +836,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
             AssocItemKind::Fn(ref sig, ref body) => {
                 self.current_item = Some(i.span);
-                let body_id = self.lower_maybe_async_body(
-                    i.span,
-                    &sig.decl,
-                    sig.header.asyncness.node,
-                    body.as_deref(),
-                );
+                let asyncness = sig.header.asyncness;
+                let body_id =
+                    self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref());
                 let impl_trait_return_allow = !self.is_in_trait_impl;
                 let (generics, sig) = self.lower_method_sig(
                     &i.generics,
                     sig,
                     impl_item_def_id,
                     impl_trait_return_allow,
-                    sig.header.asyncness.node.opt_return_id(),
+                    asyncness.opt_return_id(),
                 );
 
                 (generics, hir::ImplItemKind::Method(sig, body_id))
@@ -1033,12 +1030,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
         &mut self,
         span: Span,
         decl: &FnDecl,
-        asyncness: IsAsync,
+        asyncness: Async,
         body: Option<&Block>,
     ) -> hir::BodyId {
         let closure_id = match asyncness {
-            IsAsync::Async { closure_id, .. } => closure_id,
-            IsAsync::NotAsync => return self.lower_fn_body_block(span, decl, body),
+            Async::Yes { closure_id, .. } => closure_id,
+            Async::No => return self.lower_fn_body_block(span, decl, body),
         };
 
         self.lower_body(|this| {
@@ -1248,7 +1245,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
         hir::FnHeader {
             unsafety: self.lower_unsafety(h.unsafety),
-            asyncness: self.lower_asyncness(h.asyncness.node),
+            asyncness: self.lower_asyncness(h.asyncness),
             constness: self.lower_constness(h.constness),
             abi: self.lower_extern(h.ext),
         }
@@ -1276,10 +1273,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
             .emit();
     }
 
-    fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
+    fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync {
         match a {
-            IsAsync::Async { .. } => hir::IsAsync::Async,
-            IsAsync::NotAsync => hir::IsAsync::NotAsync,
+            Async::Yes { .. } => hir::IsAsync::Async,
+            Async::No => hir::IsAsync::NotAsync,
         }
     }
 
diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index de4f092dbf0..e0217de1d3b 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -221,13 +221,13 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn check_trait_fn_not_async(&self, span: Span, asyncness: IsAsync) {
-        if asyncness.is_async() {
-            struct_span_err!(self.session, span, E0706, "trait fns cannot be declared `async`")
+    fn check_trait_fn_not_async(&self, fn_span: Span, asyncness: Async) {
+        if let Async::Yes { span, .. } = asyncness {
+            struct_span_err!(self.session, fn_span, E0706, "trait fns cannot be declared `async`")
+                .span_label(span, "`async` because of this")
                 .note("`async` trait functions are not currently supported")
                 .note(
-                    "consider using the `async-trait` crate: \
-                       https://crates.io/crates/async-trait",
+                    "consider using the `async-trait` crate: https://crates.io/crates/async-trait",
                 )
                 .emit();
         }
@@ -1144,7 +1144,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             self.invalid_visibility(&item.vis, None);
             if let AssocItemKind::Fn(sig, _) = &item.kind {
                 self.check_trait_fn_not_const(sig.header.constness);
-                self.check_trait_fn_not_async(item.span, sig.header.asyncness.node);
+                self.check_trait_fn_not_async(item.span, sig.header.asyncness);
             }
         }
 
diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs
index 633964683dc..b1fa818d0a8 100644
--- a/src/librustc_ast_pretty/pprust.rs
+++ b/src/librustc_ast_pretty/pprust.rs
@@ -2449,7 +2449,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_asyncness(&mut self, asyncness: ast::IsAsync) {
+    crate fn print_asyncness(&mut self, asyncness: ast::Async) {
         if asyncness.is_async() {
             self.word_nbsp("async");
         }
@@ -2734,7 +2734,7 @@ impl<'a> State<'a> {
         self.s.word(visibility_qualified(vis, ""));
 
         self.print_constness(header.constness);
-        self.print_asyncness(header.asyncness.node);
+        self.print_asyncness(header.asyncness);
         self.print_unsafety(header.unsafety);
 
         match header.ext {
diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs
index dd93596b3cf..a246e114953 100644
--- a/src/librustc_builtin_macros/test.rs
+++ b/src/librustc_builtin_macros/test.rs
@@ -381,8 +381,10 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
                 .emit();
             return false;
         }
-        if sig.header.asyncness.node.is_async() {
-            sd.span_err(i.span, "async functions cannot be used for tests");
+        if let ast::Async::Yes { span, .. } = sig.header.asyncness {
+            sd.struct_span_err(i.span, "async functions cannot be used for tests")
+                .span_label(span, "async because of this")
+                .emit();
             return false;
         }
 
diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs
index 11f94ab2e62..af22e46eb6a 100644
--- a/src/librustc_expand/build.rs
+++ b/src/librustc_expand/build.rs
@@ -507,7 +507,7 @@ impl<'a> ExtCtxt<'a> {
             span,
             ast::ExprKind::Closure(
                 ast::CaptureBy::Ref,
-                ast::IsAsync::NotAsync,
+                ast::Async::No,
                 ast::Movability::Movable,
                 fn_decl,
                 body,
@@ -530,7 +530,7 @@ impl<'a> ExtCtxt<'a> {
             span,
             ast::ExprKind::Closure(
                 ast::CaptureBy::Ref,
-                ast::IsAsync::NotAsync,
+                ast::Async::No,
                 ast::Movability::Movable,
                 fn_decl,
                 body,
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 77748d16653..5a4225ece65 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -13,7 +13,7 @@ use syntax::ast::{self, AttrStyle, AttrVec, CaptureBy, Field, Ident, Lit, DUMMY_
 use syntax::ast::{
     AnonConst, BinOp, BinOpKind, FnDecl, FunctionRetTy, Mac, Param, Ty, TyKind, UnOp,
 };
-use syntax::ast::{Arm, BlockCheckMode, Expr, ExprKind, IsAsync, Label, Movability, RangeLimits};
+use syntax::ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
 use syntax::ptr::P;
 use syntax::token::{self, Token, TokenKind};
 use syntax::util::classify;
@@ -1348,7 +1348,7 @@ impl<'a> Parser<'a> {
             if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable };
 
         let asyncness =
-            if self.token.span.rust_2018() { self.parse_asyncness() } else { IsAsync::NotAsync };
+            if self.token.span.rust_2018() { self.parse_asyncness() } else { Async::No };
         if asyncness.is_async() {
             // Feature-gate `async ||` closures.
             self.sess.gated_spans.gate(sym::async_closure, self.prev_span);
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index a66a85b2b83..aa43c15e286 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -6,13 +6,13 @@ use crate::maybe_whole;
 
 use rustc_ast_pretty::pprust;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult, StashKey};
-use rustc_span::source_map::{self, respan, Span};
+use rustc_span::source_map::{self, Span};
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::BytePos;
 use syntax::ast::{self, AttrKind, AttrStyle, AttrVec, Attribute, Ident, DUMMY_NODE_ID};
 use syntax::ast::{AssocItem, AssocItemKind, Item, ItemKind, UseTree, UseTreeKind};
+use syntax::ast::{Async, Const, Defaultness, Extern, IsAuto, PathSegment, StrLit, Unsafe};
 use syntax::ast::{BindingMode, Block, FnDecl, FnSig, Mac, MacArgs, MacDelimiter, Param, SelfKind};
-use syntax::ast::{Const, Defaultness, Extern, IsAsync, IsAuto, PathSegment, StrLit, Unsafe};
 use syntax::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData};
 use syntax::ast::{FnHeader, ForeignItem, ForeignItemKind, Mutability, Visibility, VisibilityKind};
 use syntax::ptr::P;
@@ -105,10 +105,9 @@ impl<'a> Parser<'a> {
 
             if self.eat_keyword(kw::Fn) {
                 // EXTERN FUNCTION ITEM
-                let fn_span = self.prev_span;
                 let header = FnHeader {
                     unsafety: Unsafe::No,
-                    asyncness: respan(fn_span, IsAsync::NotAsync),
+                    asyncness: Async::No,
                     constness: Const::No,
                     ext: Extern::from_abi(abi),
                 };
@@ -140,12 +139,7 @@ impl<'a> Parser<'a> {
                 let ext = self.parse_extern()?;
                 self.expect_keyword(kw::Fn)?;
 
-                let header = FnHeader {
-                    unsafety,
-                    asyncness: respan(const_span, IsAsync::NotAsync),
-                    constness,
-                    ext,
-                };
+                let header = FnHeader { unsafety, asyncness: Async::No, constness, ext };
                 return self.parse_item_fn(lo, vis, attrs, header);
             }
 
@@ -172,16 +166,9 @@ impl<'a> Parser<'a> {
             let async_span = self.token.span;
             if self.is_keyword_ahead(1, &[kw::Fn]) || self.is_keyword_ahead(2, &[kw::Fn]) {
                 // ASYNC FUNCTION ITEM
-                self.bump(); // `async`
+                let asyncness = self.parse_asyncness(); // `async`
                 let unsafety = self.parse_unsafety(); // `unsafe`?
                 self.expect_keyword(kw::Fn)?; // `fn`
-                let asyncness = respan(
-                    async_span,
-                    IsAsync::Async {
-                        closure_id: DUMMY_NODE_ID,
-                        return_impl_trait_id: DUMMY_NODE_ID,
-                    },
-                );
                 self.ban_async_in_2015(async_span);
                 let header =
                     FnHeader { unsafety, asyncness, constness: Const::No, ext: Extern::None };
@@ -211,13 +198,7 @@ impl<'a> Parser<'a> {
         if self.check_keyword(kw::Fn) {
             // FUNCTION ITEM
             self.bump();
-            let fn_span = self.prev_span;
-            let header = FnHeader {
-                unsafety: Unsafe::No,
-                asyncness: respan(fn_span, IsAsync::NotAsync),
-                constness: Const::No,
-                ext: Extern::None,
-            };
+            let header = FnHeader::default();
             return self.parse_item_fn(lo, vis, attrs, header);
         }
 
@@ -230,13 +211,7 @@ impl<'a> Parser<'a> {
             self.check(&token::OpenDelim(token::Brace));
             let ext = self.parse_extern()?;
             self.expect_keyword(kw::Fn)?;
-            let fn_span = self.prev_span;
-            let header = FnHeader {
-                unsafety,
-                asyncness: respan(fn_span, IsAsync::NotAsync),
-                constness: Const::No,
-                ext,
-            };
+            let header = FnHeader { unsafety, asyncness: Async::No, constness: Const::No, ext };
             return self.parse_item_fn(lo, vis, attrs, header);
         }
 
@@ -1788,10 +1763,9 @@ impl<'a> Parser<'a> {
     fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
         let constness = self.parse_constness();
         let asyncness = self.parse_asyncness();
-        if let IsAsync::Async { .. } = asyncness {
-            self.ban_async_in_2015(self.prev_span);
+        if let Async::Yes { span, .. } = asyncness {
+            self.ban_async_in_2015(span);
         }
-        let asyncness = respan(self.prev_span, asyncness);
         let unsafety = self.parse_unsafety();
         let (constness, unsafety, ext) = if let Const::Yes(_) = constness {
             (constness, unsafety, Extern::None)
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index bccf5968118..2f2f2f8f176 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -24,7 +24,7 @@ use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{FileName, Span, DUMMY_SP};
 use syntax::ast::DUMMY_NODE_ID;
 use syntax::ast::{self, AttrStyle, AttrVec, Const, CrateSugar, Extern, Ident, Unsafe};
-use syntax::ast::{IsAsync, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind};
+use syntax::ast::{Async, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind};
 use syntax::ptr::P;
 use syntax::token::{self, DelimToken, Token, TokenKind};
 use syntax::tokenstream::{self, DelimSpan, TokenStream, TokenTree, TreeAndJoint};
@@ -954,11 +954,12 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses asyncness: `async` or nothing.
-    fn parse_asyncness(&mut self) -> IsAsync {
+    fn parse_asyncness(&mut self) -> Async {
         if self.eat_keyword(kw::Async) {
-            IsAsync::Async { closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID }
+            let span = self.prev_span;
+            Async::Yes { span, closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID }
         } else {
-            IsAsync::NotAsync
+            Async::No
         }
     }
 
diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs
index 3a26197c160..fe80dec513c 100644
--- a/src/librustc_resolve/def_collector.rs
+++ b/src/librustc_resolve/def_collector.rs
@@ -48,8 +48,8 @@ impl<'a> DefCollector<'a> {
         decl: &'a FnDecl,
         body: Option<&'a Block>,
     ) {
-        let (closure_id, return_impl_trait_id) = match header.asyncness.node {
-            IsAsync::Async { closure_id, return_impl_trait_id } => {
+        let (closure_id, return_impl_trait_id) = match header.asyncness {
+            Async::Yes { span: _, closure_id, return_impl_trait_id } => {
                 (closure_id, return_impl_trait_id)
             }
             _ => unreachable!(),
@@ -117,7 +117,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
             | ItemKind::ExternCrate(..)
             | ItemKind::ForeignMod(..)
             | ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name),
-            ItemKind::Fn(sig, generics, body) if sig.header.asyncness.node.is_async() => {
+            ItemKind::Fn(sig, generics, body) if sig.header.asyncness.is_async() => {
                 return self.visit_async_fn(
                     i.id,
                     i.ident.name,
@@ -215,7 +215,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
 
     fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) {
         let def_data = match &i.kind {
-            AssocItemKind::Fn(FnSig { header, decl }, body) if header.asyncness.node.is_async() => {
+            AssocItemKind::Fn(FnSig { header, decl }, body) if header.asyncness.is_async() => {
                 return self.visit_async_fn(
                     i.id,
                     i.ident.name,
@@ -255,10 +255,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
                 // we must create two defs.
                 let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span);
                 match asyncness {
-                    IsAsync::Async { closure_id, .. } => {
+                    Async::Yes { closure_id, .. } => {
                         self.create_def(closure_id, DefPathData::ClosureExpr, expr.span)
                     }
-                    IsAsync::NotAsync => closure_def,
+                    Async::No => closure_def,
                 }
             }
             ExprKind::Async(_, async_id, _) => {
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 01a0e568137..58ff7f44789 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -2030,7 +2030,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             // `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
             // resolve the arguments within the proper scopes so that usages of them inside the
             // closure are detected as upvars rather than normal closure arg usages.
-            ExprKind::Closure(_, IsAsync::Async { .. }, _, ref fn_decl, ref body, _span) => {
+            ExprKind::Closure(_, Async::Yes { .. }, _, ref fn_decl, ref body, _span) => {
                 self.with_rib(ValueNS, NormalRibKind, |this| {
                     // Resolve arguments:
                     this.resolve_params(&fn_decl.inputs);
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 5ce81c104e1..01e3e3f3685 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -290,8 +290,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
                 // as an `impl Trait` existential type. Because of this, to match
                 // the definition paths when resolving nested types we need to
                 // start walking from the newly-created definition.
-                match sig.header.asyncness.node {
-                    ast::IsAsync::Async { return_impl_trait_id, .. } => {
+                match sig.header.asyncness {
+                    ast::Async::Yes { return_impl_trait_id, .. } => {
                         v.nest_tables(return_impl_trait_id, |v| v.visit_ty(ret_ty))
                     }
                     _ => v.visit_ty(ret_ty),
@@ -383,8 +383,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
                     // as an `impl Trait` existential type. Because of this, to match
                     // the definition paths when resolving nested types we need to
                     // start walking from the newly-created definition.
-                    match header.asyncness.node {
-                        ast::IsAsync::Async { return_impl_trait_id, .. } => {
+                    match header.asyncness {
+                        ast::Async::Yes { return_impl_trait_id, .. } => {
                             v.nest_tables(return_impl_trait_id, |v| v.visit_ty(ret_ty))
                         }
                         _ => v.visit_ty(ret_ty),
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index 820202c85ab..d3c4d6d5723 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -368,7 +368,7 @@ impl Sig for ast::Item {
                 if let ast::Const::Yes(_) = header.constness {
                     text.push_str("const ");
                 }
-                if header.asyncness.node.is_async() {
+                if header.asyncness.is_async() {
                     text.push_str("async ");
                 }
                 if let ast::Unsafe::Yes(_) = header.unsafety {
@@ -887,7 +887,7 @@ fn make_method_signature(
     if let ast::Const::Yes(_) = m.header.constness {
         text.push_str("const ");
     }
-    if m.header.asyncness.node.is_async() {
+    if m.header.asyncness.is_async() {
         text.push_str("async ");
     }
     if let ast::Unsafe::Yes(_) = m.header.unsafety {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index a7142dfda85..72430fa9c17 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -34,7 +34,7 @@ use rustc_data_structures::thin_vec::ThinVec;
 use rustc_index::vec::Idx;
 use rustc_macros::HashStable_Generic;
 use rustc_serialize::{self, Decoder, Encoder};
-use rustc_span::source_map::{dummy_spanned, respan, Spanned};
+use rustc_span::source_map::{respan, Spanned};
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 
@@ -1198,14 +1198,14 @@ pub enum ExprKind {
     /// A closure (e.g., `move |a, b, c| a + b + c`).
     ///
     /// The final span is the span of the argument block `|...|`.
-    Closure(CaptureBy, IsAsync, Movability, P<FnDecl>, P<Expr>, Span),
+    Closure(CaptureBy, Async, Movability, P<FnDecl>, P<Expr>, Span),
     /// A block (`'label: { ... }`).
     Block(P<Block>, Option<Label>),
     /// An async block (`async move { ... }`).
     ///
     /// The `NodeId` is the `NodeId` for the closure that results from
     /// desugaring an async block, just like the NodeId field in the
-    /// `IsAsync` enum. This is necessary in order to create a def for the
+    /// `Async::Yes` variant. This is necessary in order to create a def for the
     /// closure which can be used as a parent of any child defs. Defs
     /// created during lowering cannot be made the parent of any other
     /// preexisting defs.
@@ -2109,21 +2109,21 @@ pub enum Unsafe {
 }
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
-pub enum IsAsync {
-    Async { closure_id: NodeId, return_impl_trait_id: NodeId },
-    NotAsync,
+pub enum Async {
+    Yes { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
+    No,
 }
 
-impl IsAsync {
+impl Async {
     pub fn is_async(self) -> bool {
-        if let IsAsync::Async { .. } = self { true } else { false }
+        if let Async::Yes { .. } = self { true } else { false }
     }
 
     /// In ths case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
     pub fn opt_return_id(self) -> Option<NodeId> {
         match self {
-            IsAsync::Async { return_impl_trait_id, .. } => Some(return_impl_trait_id),
-            IsAsync::NotAsync => None,
+            Async::Yes { return_impl_trait_id, .. } => Some(return_impl_trait_id),
+            Async::No => None,
         }
     }
 }
@@ -2496,7 +2496,7 @@ impl Extern {
 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
 pub struct FnHeader {
     pub unsafety: Unsafe,
-    pub asyncness: Spanned<IsAsync>,
+    pub asyncness: Async,
     pub constness: Const,
     pub ext: Extern,
 }
@@ -2506,7 +2506,7 @@ impl FnHeader {
     pub fn has_qualifiers(&self) -> bool {
         let Self { unsafety, asyncness, constness, ext } = self;
         matches!(unsafety, Unsafe::Yes(_))
-            || asyncness.node.is_async()
+            || asyncness.is_async()
             || matches!(constness, Const::Yes(_))
             || !matches!(ext, Extern::None)
     }
@@ -2516,7 +2516,7 @@ impl Default for FnHeader {
     fn default() -> FnHeader {
         FnHeader {
             unsafety: Unsafe::No,
-            asyncness: dummy_spanned(IsAsync::NotAsync),
+            asyncness: Async::No,
             constness: Const::No,
             ext: Extern::None,
         }
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 8517f223f92..e0180d45193 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -114,7 +114,7 @@ pub trait MutVisitor: Sized {
         noop_visit_fn_decl(d, self);
     }
 
-    fn visit_asyncness(&mut self, a: &mut IsAsync) {
+    fn visit_asyncness(&mut self, a: &mut Async) {
         noop_visit_asyncness(a, self);
     }
 
@@ -728,13 +728,13 @@ pub fn noop_visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis:
     }
 }
 
-pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut IsAsync, vis: &mut T) {
+pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut Async, vis: &mut T) {
     match asyncness {
-        IsAsync::Async { closure_id, return_impl_trait_id } => {
+        Async::Yes { span: _, closure_id, return_impl_trait_id } => {
             vis.visit_id(closure_id);
             vis.visit_id(return_impl_trait_id);
         }
-        IsAsync::NotAsync => {}
+        Async::No => {}
     }
 }
 
@@ -980,7 +980,7 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
 
 pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
     let FnHeader { unsafety: _, asyncness, constness: _, ext: _ } = header;
-    vis.visit_asyncness(&mut asyncness.node);
+    vis.visit_asyncness(asyncness);
 }
 
 pub fn noop_visit_mod<T: MutVisitor>(Mod { inner, items, inline: _ }: &mut Mod, vis: &mut T) {
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index 0f6a88b2691..7ac75c605f2 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -121,7 +121,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
                 });
                 iter_exprs(depth - 1, &mut |e| g(
                         ExprKind::Closure(CaptureBy::Value,
-                                          IsAsync::NotAsync,
+                                          Async::No,
                                           Movability::Movable,
                                           decl.clone(),
                                           e,
diff --git a/src/test/ui/async-await/async-trait-fn.stderr b/src/test/ui/async-await/async-trait-fn.stderr
index 9acfa2cc069..04f72fb645e 100644
--- a/src/test/ui/async-await/async-trait-fn.stderr
+++ b/src/test/ui/async-await/async-trait-fn.stderr
@@ -2,7 +2,9 @@ error[E0706]: trait fns cannot be declared `async`
   --> $DIR/async-trait-fn.rs:3:5
    |
 LL |     async fn foo() {}
-   |     ^^^^^^^^^^^^^^^^^
+   |     -----^^^^^^^^^^^^
+   |     |
+   |     `async` because of this
    |
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
@@ -11,7 +13,9 @@ error[E0706]: trait fns cannot be declared `async`
   --> $DIR/async-trait-fn.rs:4:5
    |
 LL |     async fn bar(&self) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     -----^^^^^^^^^^^^^^^^^
+   |     |
+   |     `async` because of this
    |
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
index bb09ee9a932..e6859a3cd93 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
@@ -56,7 +56,9 @@ error[E0706]: trait fns cannot be declared `async`
   --> $DIR/edition-deny-async-fns-2015.rs:18:5
    |
 LL |     async fn foo() {}
-   |     ^^^^^^^^^^^^^^^^^
+   |     -----^^^^^^^^^^^^
+   |     |
+   |     `async` because of this
    |
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr
index 41d2d9b7faa..689bbdd8bab 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.stderr
+++ b/src/test/ui/parser/fn-header-semantic-fail.stderr
@@ -2,7 +2,9 @@ error[E0706]: trait fns cannot be declared `async`
   --> $DIR/fn-header-semantic-fail.rs:17:9
    |
 LL |         async fn ft1();
-   |         ^^^^^^^^^^^^^^^
+   |         -----^^^^^^^^^^
+   |         |
+   |         `async` because of this
    |
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
@@ -17,7 +19,9 @@ error[E0706]: trait fns cannot be declared `async`
   --> $DIR/fn-header-semantic-fail.rs:21:21
    |
 LL |         /* const */ async unsafe extern "C" fn ft5();
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                     |
+   |                     `async` because of this
    |
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
@@ -26,7 +30,9 @@ error[E0706]: trait fns cannot be declared `async`
   --> $DIR/fn-header-semantic-fail.rs:28:9
    |
 LL |         async fn ft1() {}
-   |         ^^^^^^^^^^^^^^^^^
+   |         -----^^^^^^^^^^^^
+   |         |
+   |         `async` because of this
    |
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
@@ -41,7 +47,9 @@ error[E0706]: trait fns cannot be declared `async`
   --> $DIR/fn-header-semantic-fail.rs:33:21
    |
 LL |         /* const */ async unsafe extern "C" fn ft5() {}
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                     |
+   |                     `async` because of this
    |
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait