about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/errors.rs7
-rw-r--r--compiler/rustc_parse/src/parser/item.rs29
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs9
3 files changed, 26 insertions, 19 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index fde67ac089a..2d4447a42c2 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -2975,3 +2975,10 @@ pub(crate) struct ArrayIndexInOffsetOf(#[primary_span] pub Span);
 #[derive(Diagnostic)]
 #[diag(parse_invalid_offset_of)]
 pub(crate) struct InvalidOffsetOf(#[primary_span] pub Span);
+
+#[derive(Diagnostic)]
+#[diag(parse_async_impl)]
+pub(crate) struct AsyncImpl {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index e7b9076bd3c..77381ef4626 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -562,6 +562,15 @@ impl<'a> Parser<'a> {
             self.sess.gated_spans.gate(sym::const_trait_impl, span);
         }
 
+        // Parse stray `impl async Trait`
+        if (self.token.uninterpolated_span().at_least_rust_2018()
+            && self.token.is_keyword(kw::Async))
+            || self.is_kw_followed_by_ident(kw::Async)
+        {
+            self.bump();
+            self.dcx().emit_err(errors::AsyncImpl { span: self.prev_token.span });
+        }
+
         let polarity = self.parse_polarity();
 
         // Parse both types and traits as a type, then reinterpret if necessary.
@@ -592,22 +601,10 @@ impl<'a> Parser<'a> {
             // We need to report this error after `cfg` expansion for compatibility reasons
             self.bump(); // `..`, do not add it to expected tokens
 
-            // FIXME(nnethercote): AST validation later detects this
-            // `TyKind::Err` and emits an errors. So why the unchecked
-            // ErrorGuaranteed?
-            // - A `span_delayed_bug` doesn't work here, because rustfmt can
-            //   hit this path but then not hit the follow-up path in the AST
-            //   validator that issues the error, which results in ICEs.
-            // - `TyKind::Dummy` doesn't work, because it ends up reaching HIR
-            //   lowering, which results in ICEs. Changing `TyKind::Dummy` to
-            //   `TyKind::Err` during AST validation might fix that, but that's
-            //   not possible because AST validation doesn't allow mutability.
-            //
-            // #121072 will hopefully remove all this special handling of the
-            // obsolete `impl Trait for ..` and then this can go away.
-            #[allow(deprecated)]
-            let guar = rustc_errors::ErrorGuaranteed::unchecked_error_guaranteed();
-            Some(self.mk_ty(self.prev_token.span, TyKind::Err(guar)))
+            // AST validation later detects this `TyKind::Dummy` and emits an
+            // error. (#121072 will hopefully remove all this special handling
+            // of the obsolete `impl Trait for ..` and then this can go away.)
+            Some(self.mk_ty(self.prev_token.span, TyKind::Dummy))
         } else if has_for || self.token.can_begin_type() {
             Some(self.parse_ty()?)
         } else {
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index f79f2a813b2..23a92e6dd3d 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -778,9 +778,10 @@ impl<'a> Parser<'a> {
             || self.check(&token::Not)
             || self.check(&token::Question)
             || self.check(&token::Tilde)
-            || self.check_keyword(kw::Const)
             || self.check_keyword(kw::For)
             || self.check(&token::OpenDelim(Delimiter::Parenthesis))
+            || self.check_keyword(kw::Const)
+            || self.check_keyword(kw::Async)
     }
 
     /// Parses a bound according to the grammar:
@@ -882,11 +883,13 @@ impl<'a> Parser<'a> {
             BoundConstness::Never
         };
 
-        let asyncness = if self.token.span.at_least_rust_2018() && self.eat_keyword(kw::Async) {
+        let asyncness = if self.token.uninterpolated_span().at_least_rust_2018()
+            && self.eat_keyword(kw::Async)
+        {
             self.sess.gated_spans.gate(sym::async_closure, self.prev_token.span);
             BoundAsyncness::Async(self.prev_token.span)
         } else if self.may_recover()
-            && self.token.span.is_rust_2015()
+            && self.token.uninterpolated_span().is_rust_2015()
             && self.is_kw_followed_by_ident(kw::Async)
         {
             self.bump(); // eat `async`