diff options
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/errors.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 9 |
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` |
