From 028a920c5310afc918c617e50074348976332a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 2 Feb 2025 00:45:40 +0000 Subject: [PATCH] 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. --- .../src/error_reporting/infer/suggest.rs | 9 +++++---- compiler/rustc_trait_selection/src/errors.rs | 12 +++--------- tests/ui/fn/fn-pointer-mismatch.stderr | 2 +- tests/ui/force-inlining/cast.stderr | 4 ++-- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index 231fecf7a4a83..562000e28aca1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -418,7 +418,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; 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 }, (true, true) => { diag.subdiagnostic(FnItemsAreDistinct); @@ -426,7 +428,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } (false, false) => { diag.subdiagnostic(FnItemsAreDistinct); - FunctionPointerSuggestion::Cast { span, fn_name, sig } + FunctionPointerSuggestion::Cast { span: span.shrink_to_hi(), sig } } }; diag.subdiagnostic(sugg); @@ -466,8 +468,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } else { FunctionPointerSuggestion::CastBoth { - span, - fn_name, + span: span.shrink_to_hi(), found_sig: *found_sig, expected_sig: *expected_sig, } diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index c5ab8a71c780e..62cac5b17bd04 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -1391,15 +1391,13 @@ pub struct OpaqueCapturesLifetime<'tcx> { pub enum FunctionPointerSuggestion<'a> { #[suggestion( trait_selection_fps_use_ref, - code = "&{fn_name}", + code = "&", style = "verbose", applicability = "maybe-incorrect" )] UseRef { #[primary_span] span: Span, - #[skip_arg] - fn_name: String, }, #[suggestion( trait_selection_fps_remove_ref, @@ -1429,7 +1427,7 @@ pub enum FunctionPointerSuggestion<'a> { }, #[suggestion( trait_selection_fps_cast, - code = "{fn_name} as {sig}", + code = " as {sig}", style = "verbose", applicability = "maybe-incorrect" )] @@ -1437,13 +1435,11 @@ pub enum FunctionPointerSuggestion<'a> { #[primary_span] span: Span, #[skip_arg] - fn_name: String, - #[skip_arg] sig: Binder<'a, FnSig<'a>>, }, #[suggestion( trait_selection_fps_cast_both, - code = "{fn_name} as {found_sig}", + code = " as {found_sig}", style = "hidden", applicability = "maybe-incorrect" )] @@ -1451,8 +1447,6 @@ pub enum FunctionPointerSuggestion<'a> { #[primary_span] span: Span, #[skip_arg] - fn_name: String, - #[skip_arg] found_sig: Binder<'a, FnSig<'a>>, expected_sig: Binder<'a, FnSig<'a>>, }, diff --git a/tests/ui/fn/fn-pointer-mismatch.stderr b/tests/ui/fn/fn-pointer-mismatch.stderr index 9cda11639d0f5..2aa840911f66e 100644 --- a/tests/ui/fn/fn-pointer-mismatch.stderr +++ b/tests/ui/fn/fn-pointer-mismatch.stderr @@ -67,7 +67,7 @@ LL | let d: &fn(u32) -> u32 = foo; help: consider using a reference | LL | let d: &fn(u32) -> u32 = &foo; - | ~~~~ + | + error[E0308]: mismatched types --> $DIR/fn-pointer-mismatch.rs:48:30 diff --git a/tests/ui/force-inlining/cast.stderr b/tests/ui/force-inlining/cast.stderr index 116919e5fe7f0..5313295965956 100644 --- a/tests/ui/force-inlining/cast.stderr +++ b/tests/ui/force-inlining/cast.stderr @@ -12,7 +12,7 @@ LL | let _: fn(isize) -> usize = callee; help: consider casting to a fn pointer | LL | let _: 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 @@ -32,7 +32,7 @@ LL | callee, help: consider casting to a fn pointer | LL | callee as fn(isize) -> usize, - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++ error: aborting due to 3 previous errors