Support async trait bounds in macros

This commit is contained in:
Michael Goulet 2024-02-20 16:09:03 +00:00
parent 29f87ade9d
commit 9c8b107955
16 changed files with 229 additions and 31 deletions

View file

@ -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,
}

View file

@ -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.

View file

@ -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`