1
Fork 0

Rollup merge of #136412 - estebank:fn-ptr-cast-suggestion, r=jieyouxu

Tweak fn pointer suggestion span

Use a more targeted span when suggesting casting an `fn` item to an `fn` pointer.

```
error[E0308]: cannot coerce functions which must be inlined to function pointers
  --> $DIR/cast.rs:10:33
   |
LL |     let _: fn(isize) -> usize = callee;
   |            ------------------   ^^^^^^ cannot coerce functions which must be inlined to function pointers
   |            |
   |            expected due to this
   |
   = note: expected fn pointer `fn(_) -> _`
                 found fn item `fn(_) -> _ {callee}`
   = note: fn items are distinct from fn pointers
help: consider casting to a fn pointer
   |
LL |     let _: fn(isize) -> usize = callee as fn(isize) -> usize;
   |                                        +++++++++++++++++++++
```
```
error[E0308]: mismatched types
  --> $DIR/fn-pointer-mismatch.rs:42:30
   |
LL |     let d: &fn(u32) -> u32 = foo;
   |            ---------------   ^^^ expected `&fn(u32) -> u32`, found fn item
   |            |
   |            expected due to this
   |
   = note: expected reference `&fn(_) -> _`
                found fn item `fn(_) -> _ {foo}`
help: consider using a reference
   |
LL |     let d: &fn(u32) -> u32 = &foo;
   |                              +
```
Previously we'd point at the whole expression for replacement, instead of marking what was being added.

We could also modify the suggestions for `&(name as fn())`, but for that we require storing more accurate spans than we have now.
This commit is contained in:
Matthias Krüger 2025-02-02 12:31:58 +01:00 committed by GitHub
commit 44def58274
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 11 additions and 16 deletions

View file

@ -418,7 +418,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}; };
let sugg = match (expected.is_ref(), found.is_ref()) { let sugg = match (expected.is_ref(), found.is_ref()) {
(true, false) => FunctionPointerSuggestion::UseRef { span, fn_name }, (true, false) => {
FunctionPointerSuggestion::UseRef { span: span.shrink_to_lo() }
}
(false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name }, (false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name },
(true, true) => { (true, true) => {
diag.subdiagnostic(FnItemsAreDistinct); diag.subdiagnostic(FnItemsAreDistinct);
@ -426,7 +428,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
(false, false) => { (false, false) => {
diag.subdiagnostic(FnItemsAreDistinct); diag.subdiagnostic(FnItemsAreDistinct);
FunctionPointerSuggestion::Cast { span, fn_name, sig } FunctionPointerSuggestion::Cast { span: span.shrink_to_hi(), sig }
} }
}; };
diag.subdiagnostic(sugg); diag.subdiagnostic(sugg);
@ -466,8 +468,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
} else { } else {
FunctionPointerSuggestion::CastBoth { FunctionPointerSuggestion::CastBoth {
span, span: span.shrink_to_hi(),
fn_name,
found_sig: *found_sig, found_sig: *found_sig,
expected_sig: *expected_sig, expected_sig: *expected_sig,
} }

View file

@ -1391,15 +1391,13 @@ pub struct OpaqueCapturesLifetime<'tcx> {
pub enum FunctionPointerSuggestion<'a> { pub enum FunctionPointerSuggestion<'a> {
#[suggestion( #[suggestion(
trait_selection_fps_use_ref, trait_selection_fps_use_ref,
code = "&{fn_name}", code = "&",
style = "verbose", style = "verbose",
applicability = "maybe-incorrect" applicability = "maybe-incorrect"
)] )]
UseRef { UseRef {
#[primary_span] #[primary_span]
span: Span, span: Span,
#[skip_arg]
fn_name: String,
}, },
#[suggestion( #[suggestion(
trait_selection_fps_remove_ref, trait_selection_fps_remove_ref,
@ -1429,7 +1427,7 @@ pub enum FunctionPointerSuggestion<'a> {
}, },
#[suggestion( #[suggestion(
trait_selection_fps_cast, trait_selection_fps_cast,
code = "{fn_name} as {sig}", code = " as {sig}",
style = "verbose", style = "verbose",
applicability = "maybe-incorrect" applicability = "maybe-incorrect"
)] )]
@ -1437,13 +1435,11 @@ pub enum FunctionPointerSuggestion<'a> {
#[primary_span] #[primary_span]
span: Span, span: Span,
#[skip_arg] #[skip_arg]
fn_name: String,
#[skip_arg]
sig: Binder<'a, FnSig<'a>>, sig: Binder<'a, FnSig<'a>>,
}, },
#[suggestion( #[suggestion(
trait_selection_fps_cast_both, trait_selection_fps_cast_both,
code = "{fn_name} as {found_sig}", code = " as {found_sig}",
style = "hidden", style = "hidden",
applicability = "maybe-incorrect" applicability = "maybe-incorrect"
)] )]
@ -1451,8 +1447,6 @@ pub enum FunctionPointerSuggestion<'a> {
#[primary_span] #[primary_span]
span: Span, span: Span,
#[skip_arg] #[skip_arg]
fn_name: String,
#[skip_arg]
found_sig: Binder<'a, FnSig<'a>>, found_sig: Binder<'a, FnSig<'a>>,
expected_sig: Binder<'a, FnSig<'a>>, expected_sig: Binder<'a, FnSig<'a>>,
}, },

View file

@ -67,7 +67,7 @@ LL | let d: &fn(u32) -> u32 = foo;
help: consider using a reference help: consider using a reference
| |
LL | let d: &fn(u32) -> u32 = &foo; LL | let d: &fn(u32) -> u32 = &foo;
| ~~~~ | +
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch.rs:48:30 --> $DIR/fn-pointer-mismatch.rs:48:30

View file

@ -12,7 +12,7 @@ LL | let _: fn(isize) -> usize = callee;
help: consider casting to a fn pointer help: consider casting to a fn pointer
| |
LL | let _: fn(isize) -> usize = callee as fn(isize) -> usize; LL | let _: fn(isize) -> usize = callee as fn(isize) -> usize;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +++++++++++++++++++++
error[E0605]: non-primitive cast: `fn(isize) -> usize {callee}` as `fn(isize) -> usize` error[E0605]: non-primitive cast: `fn(isize) -> usize {callee}` as `fn(isize) -> usize`
--> $DIR/cast.rs:15:13 --> $DIR/cast.rs:15:13
@ -32,7 +32,7 @@ LL | callee,
help: consider casting to a fn pointer help: consider casting to a fn pointer
| |
LL | callee as fn(isize) -> usize, LL | callee as fn(isize) -> usize,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +++++++++++++++++++++
error: aborting due to 3 previous errors error: aborting due to 3 previous errors