Rollup merge of #133151 - tyrone-wu:trim-fn-ptr-whitespace, r=compiler-errors
Trim extra whitespace in fn ptr suggestion span Trim extra whitespace when suggesting removal of invalid qualifiers when parsing function pointer type. Fixes: #133083 --- I made a comment about the format of the diagnostic error message in https://github.com/rust-lang/rust/issues/133083#issuecomment-2480047875. I think the `.label` may be a little redundant if the diagnostic only highlights the bad qualifier instead of the entire `TyKind::BareFn` span. If it makes sense, I can include it in this PR.
This commit is contained in:
commit
c0005f1560
5 changed files with 96 additions and 52 deletions
|
@ -2830,9 +2830,10 @@ pub(crate) struct DynAfterMut {
|
||||||
pub(crate) struct FnPointerCannotBeConst {
|
pub(crate) struct FnPointerCannotBeConst {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
|
|
||||||
#[label]
|
#[label]
|
||||||
pub qualifier: Span,
|
pub qualifier: Span,
|
||||||
|
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
|
||||||
|
pub suggestion: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -2840,9 +2841,10 @@ pub(crate) struct FnPointerCannotBeConst {
|
||||||
pub(crate) struct FnPointerCannotBeAsync {
|
pub(crate) struct FnPointerCannotBeAsync {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
|
|
||||||
#[label]
|
#[label]
|
||||||
pub qualifier: Span,
|
pub qualifier: Span,
|
||||||
|
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
|
||||||
|
pub suggestion: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
|
|
@ -609,16 +609,58 @@ impl<'a> Parser<'a> {
|
||||||
let span_start = self.token.span;
|
let span_start = self.token.span;
|
||||||
let ast::FnHeader { ext, safety, constness, coroutine_kind } =
|
let ast::FnHeader { ext, safety, constness, coroutine_kind } =
|
||||||
self.parse_fn_front_matter(&inherited_vis, Case::Sensitive)?;
|
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 {
|
if self.may_recover() && self.token == TokenKind::Lt {
|
||||||
self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
|
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 decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
|
||||||
let whole_span = lo.to(self.prev_token.span);
|
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 {
|
if let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind {
|
||||||
self.dcx().emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span });
|
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()`
|
// FIXME(gen_blocks): emit a similar error for `gen fn()`
|
||||||
let decl_span = span_start.to(self.prev_token.span);
|
let decl_span = span_start.to(self.prev_token.span);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue