Skip to content

Commit

Permalink
Trim extra whitespace in fn ptr suggestion span
Browse files Browse the repository at this point in the history
Trim extra whitespace when suggesting removal of invalid qualifiers when
parsing function pointer type.

Fixes: #133083

Signed-off-by: Tyrone Wu <[email protected]>
  • Loading branch information
tyrone-wu committed Jan 27, 2025
1 parent f753850 commit 5082fd8
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 52 deletions.
6 changes: 4 additions & 2 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2830,19 +2830,21 @@ pub(crate) struct DynAfterMut {
pub(crate) struct FnPointerCannotBeConst {
#[primary_span]
pub span: Span,
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
#[label]
pub qualifier: Span,
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
pub suggestion: Span,
}

#[derive(Diagnostic)]
#[diag(parse_fn_pointer_cannot_be_async)]
pub(crate) struct FnPointerCannotBeAsync {
#[primary_span]
pub span: Span,
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
#[label]
pub qualifier: Span,
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
pub suggestion: Span,
}

#[derive(Diagnostic)]
Expand Down
50 changes: 46 additions & 4 deletions compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
28 changes: 14 additions & 14 deletions tests/ui/parser/bad-fn-ptr-qualifier.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
//@ edition:2018
// Most of items are taken from ./recover-const-async-fn-ptr.rs but this is able to apply rustfix.

pub type T0 = fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type T1 = extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type T2 = unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type T3 = fn(); //~ ERROR an `fn` pointer type cannot be `async`
pub type T4 = extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
pub type T5 = unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
pub type T6 = unsafe extern "C" fn();
pub type T0 = fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type T1 = extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type T2 = unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type T3 = fn(); //~ ERROR an `fn` pointer type cannot be `async`
pub type T4 = extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
pub type T5 = unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
pub type T6 = unsafe extern "C" fn();
//~^ ERROR an `fn` pointer type cannot be `const`
//~| ERROR an `fn` pointer type cannot be `async`

pub type FTT0 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type FTT1 = for<'a> extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type FTT2 = for<'a> unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type FTT3 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `async`
pub type FTT4 = for<'a> extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
pub type FTT5 = for<'a> unsafe extern "C" fn();
pub type FTT0 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type FTT1 = for<'a> extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type FTT2 = for<'a> unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
pub type FTT3 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `async`
pub type FTT4 = for<'a> extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
pub type FTT5 = for<'a> unsafe extern "C" fn();
//~^ ERROR an `fn` pointer type cannot be `async`
pub type FTT6 = for<'a> unsafe extern "C" fn();
pub type FTT6 = for<'a> unsafe extern "C" fn();
//~^ ERROR an `fn` pointer type cannot be `const`
//~| ERROR an `fn` pointer type cannot be `async`

Expand Down
32 changes: 16 additions & 16 deletions tests/ui/parser/bad-fn-ptr-qualifier.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ LL | pub type T0 = const fn();
help: remove the `const` qualifier
|
LL - pub type T0 = const fn();
LL + pub type T0 = fn();
LL + pub type T0 = fn();
|

error: an `fn` pointer type cannot be `const`
Expand All @@ -23,7 +23,7 @@ LL | pub type T1 = const extern "C" fn();
help: remove the `const` qualifier
|
LL - pub type T1 = const extern "C" fn();
LL + pub type T1 = extern "C" fn();
LL + pub type T1 = extern "C" fn();
|

error: an `fn` pointer type cannot be `const`
Expand All @@ -37,7 +37,7 @@ LL | pub type T2 = const unsafe extern "C" fn();
help: remove the `const` qualifier
|
LL - pub type T2 = const unsafe extern "C" fn();
LL + pub type T2 = unsafe extern "C" fn();
LL + pub type T2 = unsafe extern "C" fn();
|

error: an `fn` pointer type cannot be `async`
Expand All @@ -51,7 +51,7 @@ LL | pub type T3 = async fn();
help: remove the `async` qualifier
|
LL - pub type T3 = async fn();
LL + pub type T3 = fn();
LL + pub type T3 = fn();
|

error: an `fn` pointer type cannot be `async`
Expand All @@ -65,7 +65,7 @@ LL | pub type T4 = async extern "C" fn();
help: remove the `async` qualifier
|
LL - pub type T4 = async extern "C" fn();
LL + pub type T4 = extern "C" fn();
LL + pub type T4 = extern "C" fn();
|

error: an `fn` pointer type cannot be `async`
Expand All @@ -79,7 +79,7 @@ LL | pub type T5 = async unsafe extern "C" fn();
help: remove the `async` qualifier
|
LL - pub type T5 = async unsafe extern "C" fn();
LL + pub type T5 = unsafe extern "C" fn();
LL + pub type T5 = unsafe extern "C" fn();
|

error: an `fn` pointer type cannot be `const`
Expand All @@ -93,7 +93,7 @@ LL | pub type T6 = const async unsafe extern "C" fn();
help: remove the `const` qualifier
|
LL - pub type T6 = const async unsafe extern "C" fn();
LL + pub type T6 = async unsafe extern "C" fn();
LL + pub type T6 = async unsafe extern "C" fn();
|

error: an `fn` pointer type cannot be `async`
Expand All @@ -107,7 +107,7 @@ LL | pub type T6 = const async unsafe extern "C" fn();
help: remove the `async` qualifier
|
LL - pub type T6 = const async unsafe extern "C" fn();
LL + pub type T6 = const unsafe extern "C" fn();
LL + pub type T6 = const unsafe extern "C" fn();
|

error: an `fn` pointer type cannot be `const`
Expand All @@ -121,7 +121,7 @@ LL | pub type FTT0 = for<'a> const fn();
help: remove the `const` qualifier
|
LL - pub type FTT0 = for<'a> const fn();
LL + pub type FTT0 = for<'a> fn();
LL + pub type FTT0 = for<'a> fn();
|

error: an `fn` pointer type cannot be `const`
Expand All @@ -135,7 +135,7 @@ LL | pub type FTT1 = for<'a> const extern "C" fn();
help: remove the `const` qualifier
|
LL - pub type FTT1 = for<'a> const extern "C" fn();
LL + pub type FTT1 = for<'a> extern "C" fn();
LL + pub type FTT1 = for<'a> extern "C" fn();
|

error: an `fn` pointer type cannot be `const`
Expand All @@ -149,7 +149,7 @@ LL | pub type FTT2 = for<'a> const unsafe extern "C" fn();
help: remove the `const` qualifier
|
LL - pub type FTT2 = for<'a> const unsafe extern "C" fn();
LL + pub type FTT2 = for<'a> unsafe extern "C" fn();
LL + pub type FTT2 = for<'a> unsafe extern "C" fn();
|

error: an `fn` pointer type cannot be `async`
Expand All @@ -163,7 +163,7 @@ LL | pub type FTT3 = for<'a> async fn();
help: remove the `async` qualifier
|
LL - pub type FTT3 = for<'a> async fn();
LL + pub type FTT3 = for<'a> fn();
LL + pub type FTT3 = for<'a> fn();
|

error: an `fn` pointer type cannot be `async`
Expand All @@ -177,7 +177,7 @@ LL | pub type FTT4 = for<'a> async extern "C" fn();
help: remove the `async` qualifier
|
LL - pub type FTT4 = for<'a> async extern "C" fn();
LL + pub type FTT4 = for<'a> extern "C" fn();
LL + pub type FTT4 = for<'a> extern "C" fn();
|

error: an `fn` pointer type cannot be `async`
Expand All @@ -191,7 +191,7 @@ LL | pub type FTT5 = for<'a> async unsafe extern "C" fn();
help: remove the `async` qualifier
|
LL - pub type FTT5 = for<'a> async unsafe extern "C" fn();
LL + pub type FTT5 = for<'a> unsafe extern "C" fn();
LL + pub type FTT5 = for<'a> unsafe extern "C" fn();
|

error: an `fn` pointer type cannot be `const`
Expand All @@ -205,7 +205,7 @@ LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn();
help: remove the `const` qualifier
|
LL - pub type FTT6 = for<'a> const async unsafe extern "C" fn();
LL + pub type FTT6 = for<'a> async unsafe extern "C" fn();
LL + pub type FTT6 = for<'a> async unsafe extern "C" fn();
|

error: an `fn` pointer type cannot be `async`
Expand All @@ -219,7 +219,7 @@ LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn();
help: remove the `async` qualifier
|
LL - pub type FTT6 = for<'a> const async unsafe extern "C" fn();
LL + pub type FTT6 = for<'a> const unsafe extern "C" fn();
LL + pub type FTT6 = for<'a> const unsafe extern "C" fn();
|

error: aborting due to 16 previous errors
Expand Down
Loading

0 comments on commit 5082fd8

Please sign in to comment.