Skip to content

Commit 5082fd8

Browse files
committed
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 <[email protected]>
1 parent f753850 commit 5082fd8

File tree

5 files changed

+96
-52
lines changed

5 files changed

+96
-52
lines changed

compiler/rustc_parse/src/errors.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -2830,19 +2830,21 @@ pub(crate) struct DynAfterMut {
28302830
pub(crate) struct FnPointerCannotBeConst {
28312831
#[primary_span]
28322832
pub span: Span,
2833-
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
28342833
#[label]
28352834
pub qualifier: Span,
2835+
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
2836+
pub suggestion: Span,
28362837
}
28372838

28382839
#[derive(Diagnostic)]
28392840
#[diag(parse_fn_pointer_cannot_be_async)]
28402841
pub(crate) struct FnPointerCannotBeAsync {
28412842
#[primary_span]
28422843
pub span: Span,
2843-
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
28442844
#[label]
28452845
pub qualifier: Span,
2846+
#[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
2847+
pub suggestion: Span,
28462848
}
28472849

28482850
#[derive(Diagnostic)]

compiler/rustc_parse/src/parser/ty.rs

+46-4
Original file line numberDiff line numberDiff line change
@@ -609,16 +609,58 @@ impl<'a> Parser<'a> {
609609
let span_start = self.token.span;
610610
let ast::FnHeader { ext, safety, constness, coroutine_kind } =
611611
self.parse_fn_front_matter(&inherited_vis, Case::Sensitive)?;
612+
let fn_start_lo = self.prev_token.span.lo();
612613
if self.may_recover() && self.token == TokenKind::Lt {
613614
self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
614615
}
615616
let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
616617
let whole_span = lo.to(self.prev_token.span);
617-
if let ast::Const::Yes(span) = constness {
618-
self.dcx().emit_err(FnPointerCannotBeConst { span: whole_span, qualifier: span });
618+
619+
// Order/parsing of "front matter" follows:
620+
// `<constness> <coroutine_kind> <safety> <extern> fn()`
621+
// ^ ^ ^ ^ ^
622+
// | | | | fn_start_lo
623+
// | | | ext_sp.lo
624+
// | | safety_sp.lo
625+
// | coroutine_sp.lo
626+
// const_sp.lo
627+
if let ast::Const::Yes(const_span) = constness {
628+
let next_token_lo = if let Some(
629+
ast::CoroutineKind::Async { span, .. }
630+
| ast::CoroutineKind::Gen { span, .. }
631+
| ast::CoroutineKind::AsyncGen { span, .. },
632+
) = coroutine_kind
633+
{
634+
span.lo()
635+
} else if let ast::Safety::Unsafe(span) | ast::Safety::Safe(span) = safety {
636+
span.lo()
637+
} else if let ast::Extern::Implicit(span) | ast::Extern::Explicit(_, span) = ext {
638+
span.lo()
639+
} else {
640+
fn_start_lo
641+
};
642+
let sugg_span = const_span.with_hi(next_token_lo);
643+
self.dcx().emit_err(FnPointerCannotBeConst {
644+
span: whole_span,
645+
qualifier: const_span,
646+
suggestion: sugg_span,
647+
});
619648
}
620-
if let Some(ast::CoroutineKind::Async { span, .. }) = coroutine_kind {
621-
self.dcx().emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span });
649+
if let Some(ast::CoroutineKind::Async { span: async_span, .. }) = coroutine_kind {
650+
let next_token_lo = if let ast::Safety::Unsafe(span) | ast::Safety::Safe(span) = safety
651+
{
652+
span.lo()
653+
} else if let ast::Extern::Implicit(span) | ast::Extern::Explicit(_, span) = ext {
654+
span.lo()
655+
} else {
656+
fn_start_lo
657+
};
658+
let sugg_span = async_span.with_hi(next_token_lo);
659+
self.dcx().emit_err(FnPointerCannotBeAsync {
660+
span: whole_span,
661+
qualifier: async_span,
662+
suggestion: sugg_span,
663+
});
622664
}
623665
// FIXME(gen_blocks): emit a similar error for `gen fn()`
624666
let decl_span = span_start.to(self.prev_token.span);

tests/ui/parser/bad-fn-ptr-qualifier.fixed

+14-14
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@
22
//@ edition:2018
33
// Most of items are taken from ./recover-const-async-fn-ptr.rs but this is able to apply rustfix.
44

5-
pub type T0 = fn(); //~ ERROR an `fn` pointer type cannot be `const`
6-
pub type T1 = extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
7-
pub type T2 = unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
8-
pub type T3 = fn(); //~ ERROR an `fn` pointer type cannot be `async`
9-
pub type T4 = extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
10-
pub type T5 = unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
11-
pub type T6 = unsafe extern "C" fn();
5+
pub type T0 = fn(); //~ ERROR an `fn` pointer type cannot be `const`
6+
pub type T1 = extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
7+
pub type T2 = unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
8+
pub type T3 = fn(); //~ ERROR an `fn` pointer type cannot be `async`
9+
pub type T4 = extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
10+
pub type T5 = unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
11+
pub type T6 = unsafe extern "C" fn();
1212
//~^ ERROR an `fn` pointer type cannot be `const`
1313
//~| ERROR an `fn` pointer type cannot be `async`
1414

15-
pub type FTT0 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `const`
16-
pub type FTT1 = for<'a> extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
17-
pub type FTT2 = for<'a> unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
18-
pub type FTT3 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `async`
19-
pub type FTT4 = for<'a> extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
20-
pub type FTT5 = for<'a> unsafe extern "C" fn();
15+
pub type FTT0 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `const`
16+
pub type FTT1 = for<'a> extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
17+
pub type FTT2 = for<'a> unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
18+
pub type FTT3 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `async`
19+
pub type FTT4 = for<'a> extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
20+
pub type FTT5 = for<'a> unsafe extern "C" fn();
2121
//~^ ERROR an `fn` pointer type cannot be `async`
22-
pub type FTT6 = for<'a> unsafe extern "C" fn();
22+
pub type FTT6 = for<'a> unsafe extern "C" fn();
2323
//~^ ERROR an `fn` pointer type cannot be `const`
2424
//~| ERROR an `fn` pointer type cannot be `async`
2525

tests/ui/parser/bad-fn-ptr-qualifier.stderr

+16-16
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | pub type T0 = const fn();
99
help: remove the `const` qualifier
1010
|
1111
LL - pub type T0 = const fn();
12-
LL + pub type T0 = fn();
12+
LL + pub type T0 = fn();
1313
|
1414

1515
error: an `fn` pointer type cannot be `const`
@@ -23,7 +23,7 @@ LL | pub type T1 = const extern "C" fn();
2323
help: remove the `const` qualifier
2424
|
2525
LL - pub type T1 = const extern "C" fn();
26-
LL + pub type T1 = extern "C" fn();
26+
LL + pub type T1 = extern "C" fn();
2727
|
2828

2929
error: an `fn` pointer type cannot be `const`
@@ -37,7 +37,7 @@ LL | pub type T2 = const unsafe extern "C" fn();
3737
help: remove the `const` qualifier
3838
|
3939
LL - pub type T2 = const unsafe extern "C" fn();
40-
LL + pub type T2 = unsafe extern "C" fn();
40+
LL + pub type T2 = unsafe extern "C" fn();
4141
|
4242

4343
error: an `fn` pointer type cannot be `async`
@@ -51,7 +51,7 @@ LL | pub type T3 = async fn();
5151
help: remove the `async` qualifier
5252
|
5353
LL - pub type T3 = async fn();
54-
LL + pub type T3 = fn();
54+
LL + pub type T3 = fn();
5555
|
5656

5757
error: an `fn` pointer type cannot be `async`
@@ -65,7 +65,7 @@ LL | pub type T4 = async extern "C" fn();
6565
help: remove the `async` qualifier
6666
|
6767
LL - pub type T4 = async extern "C" fn();
68-
LL + pub type T4 = extern "C" fn();
68+
LL + pub type T4 = extern "C" fn();
6969
|
7070

7171
error: an `fn` pointer type cannot be `async`
@@ -79,7 +79,7 @@ LL | pub type T5 = async unsafe extern "C" fn();
7979
help: remove the `async` qualifier
8080
|
8181
LL - pub type T5 = async unsafe extern "C" fn();
82-
LL + pub type T5 = unsafe extern "C" fn();
82+
LL + pub type T5 = unsafe extern "C" fn();
8383
|
8484

8585
error: an `fn` pointer type cannot be `const`
@@ -93,7 +93,7 @@ LL | pub type T6 = const async unsafe extern "C" fn();
9393
help: remove the `const` qualifier
9494
|
9595
LL - pub type T6 = const async unsafe extern "C" fn();
96-
LL + pub type T6 = async unsafe extern "C" fn();
96+
LL + pub type T6 = async unsafe extern "C" fn();
9797
|
9898

9999
error: an `fn` pointer type cannot be `async`
@@ -107,7 +107,7 @@ LL | pub type T6 = const async unsafe extern "C" fn();
107107
help: remove the `async` qualifier
108108
|
109109
LL - pub type T6 = const async unsafe extern "C" fn();
110-
LL + pub type T6 = const unsafe extern "C" fn();
110+
LL + pub type T6 = const unsafe extern "C" fn();
111111
|
112112

113113
error: an `fn` pointer type cannot be `const`
@@ -121,7 +121,7 @@ LL | pub type FTT0 = for<'a> const fn();
121121
help: remove the `const` qualifier
122122
|
123123
LL - pub type FTT0 = for<'a> const fn();
124-
LL + pub type FTT0 = for<'a> fn();
124+
LL + pub type FTT0 = for<'a> fn();
125125
|
126126

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

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

155155
error: an `fn` pointer type cannot be `async`
@@ -163,7 +163,7 @@ LL | pub type FTT3 = for<'a> async fn();
163163
help: remove the `async` qualifier
164164
|
165165
LL - pub type FTT3 = for<'a> async fn();
166-
LL + pub type FTT3 = for<'a> fn();
166+
LL + pub type FTT3 = for<'a> fn();
167167
|
168168

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

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

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

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

225225
error: aborting due to 16 previous errors

0 commit comments

Comments
 (0)