Trim extra whitespace in fn ptr suggestion span

Trim extra whitespace when suggesting removal of invalid qualifiers when
parsing function pointer type.

Fixes: #133083

Signed-off-by: Tyrone Wu <wudevelops@gmail.com>
This commit is contained in:
Tyrone Wu 2024-11-17 21:02:05 +00:00
parent f753850659
commit 5082fd8b1e
No known key found for this signature in database
GPG key ID: 978B1A1B79210AD6
5 changed files with 96 additions and 52 deletions

View file

@ -609,16 +609,58 @@ impl<'a> Parser<'a> {
let span_start = self.token.span;
let ast::FnHeader { ext, safety, constness, coroutine_kind } =
self.parse_fn_front_matter(&inherited_vis, Case::Sensitive)?;
let fn_start_lo = self.prev_token.span.lo();
if self.may_recover() && self.token == TokenKind::Lt {
self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
}
let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
let whole_span = lo.to(self.prev_token.span);
if let ast::Const::Yes(span) = constness {
self.dcx().emit_err(FnPointerCannotBeConst { span: whole_span, qualifier: span });
// Order/parsing of "front matter" follows:
// `<constness> <coroutine_kind> <safety> <extern> fn()`
// ^ ^ ^ ^ ^
// | | | | fn_start_lo
// | | | ext_sp.lo
// | | safety_sp.lo
// | coroutine_sp.lo
// const_sp.lo
if let ast::Const::Yes(const_span) = constness {
let next_token_lo = if let Some(
ast::CoroutineKind::Async { span, .. }
| ast::CoroutineKind::Gen { span, .. }
| ast::CoroutineKind::AsyncGen { span, .. },
) = coroutine_kind
{
span.lo()
} else if let ast::Safety::Unsafe(span) | ast::Safety::Safe(span) = safety {
span.lo()
} else if let ast::Extern::Implicit(span) | ast::Extern::Explicit(_, span) = ext {
span.lo()
} else {
fn_start_lo
};
let sugg_span = const_span.with_hi(next_token_lo);
self.dcx().emit_err(FnPointerCannotBeConst {
span: whole_span,
qualifier: const_span,
suggestion: sugg_span,
});
}
if let Some(ast::CoroutineKind::Async { span, .. }) = coroutine_kind {
self.dcx().emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span });
if let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind {
let next_token_lo = if let ast::Safety::Unsafe(span) | ast::Safety::Safe(span) = safety
{
span.lo()
} else if let ast::Extern::Implicit(span) | ast::Extern::Explicit(_, span) = ext {
span.lo()
} else {
fn_start_lo
};
let sugg_span = async_span.with_hi(next_token_lo);
self.dcx().emit_err(FnPointerCannotBeAsync {
span: whole_span,
qualifier: async_span,
suggestion: sugg_span,
});
}
// FIXME(gen_blocks): emit a similar error for `gen fn()`
let decl_span = span_start.to(self.prev_token.span);