diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2025-01-29 15:29:27 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-29 15:29:27 +0100 |
| commit | f8d103df43deaa0fbe4c1916186c4c8c275ce636 (patch) | |
| tree | 39861f1451489d772182457a1e9d44aedbc2a5f5 /compiler/rustc_trait_selection | |
| parent | 61cc3e51f8bf5c12595a4d61a5ee9de812974b43 (diff) | |
| parent | 4203627cedc5a6b5a7b7605888b5c33876e2b0e2 (diff) | |
| download | rust-f8d103df43deaa0fbe4c1916186c4c8c275ce636.tar.gz rust-f8d103df43deaa0fbe4c1916186c4c8c275ce636.zip | |
Rollup merge of #133382 - mu001999-contrib:diag/fnitem, r=lcnr
Suggest considering casting fn item as fn pointer in more cases Fixes #132648
Diffstat (limited to 'compiler/rustc_trait_selection')
5 files changed, 44 insertions, 6 deletions
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index 750d2756b4a..7c72318b4d7 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -165,6 +165,8 @@ trait_selection_explicit_lifetime_required_with_param_type = explicit lifetime r trait_selection_fn_consider_casting = consider casting the fn item to a fn pointer: `{$casting}` +trait_selection_fn_consider_casting_both = consider casting both fn items to fn pointers using `as {$sig}` + trait_selection_fn_uniq_types = different fn items have unique types, even if their signatures are the same trait_selection_fps_cast = consider casting to a fn pointer trait_selection_fps_cast_both = consider casting both fn items to fn pointers using `as {$expected_sig}` diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 5f3f65e4696..9eacd377361 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1844,7 +1844,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.suggest_tuple_pattern(cause, &exp_found, diag); self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag); self.suggest_await_on_expect_found(cause, span, &exp_found, diag); - self.suggest_function_pointers(cause, span, &exp_found, diag); + self.suggest_function_pointers(cause, span, &exp_found, terr, diag); self.suggest_turning_stmt_into_expr(cause, &exp_found, diag); } } 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 af7e56961b7..231fecf7a4a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -12,6 +12,7 @@ use rustc_middle::traits::{ IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, StatementAsExpression, }; +use rustc_middle::ty::error::TypeError; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt}; use rustc_span::{Span, sym}; @@ -20,7 +21,7 @@ use tracing::debug; use crate::error_reporting::TypeErrCtxt; use crate::error_reporting::infer::hir::Path; use crate::errors::{ - ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes, + ConsiderAddingAwait, FnConsiderCasting, FnConsiderCastingBoth, FnItemsAreDistinct, FnUniqTypes, FunctionPointerSuggestion, SuggestAccessingField, SuggestRemoveSemiOrReturnBinding, SuggestTuplePatternMany, SuggestTuplePatternOne, TypeErrorAdditionalDiags, }; @@ -381,14 +382,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - pub(super) fn suggest_function_pointers( + pub fn suggest_function_pointers_impl( &self, - cause: &ObligationCause<'tcx>, - span: Span, + span: Option<Span>, exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, diag: &mut Diag<'_>, ) { - debug!("suggest_function_pointers(cause={:?}, exp_found={:?})", cause, exp_found); let ty::error::ExpectedFound { expected, found } = exp_found; let expected_inner = expected.peel_refs(); let found_inner = found.peel_refs(); @@ -411,6 +410,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return; } + let Some(span) = span else { + let casting = format!("{fn_name} as {sig}"); + diag.subdiagnostic(FnItemsAreDistinct); + diag.subdiagnostic(FnConsiderCasting { casting }); + return; + }; + let sugg = match (expected.is_ref(), found.is_ref()) { (true, false) => FunctionPointerSuggestion::UseRef { span, fn_name }, (false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name }, @@ -445,6 +451,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } let fn_name = self.tcx.def_path_str_with_args(*did2, args2); + + let Some(span) = span else { + diag.subdiagnostic(FnConsiderCastingBoth { sig: *expected_sig }); + return; + }; + let sug = if found.is_ref() { FunctionPointerSuggestion::CastBothRef { span, @@ -488,6 +500,23 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; } + pub(super) fn suggest_function_pointers( + &self, + cause: &ObligationCause<'tcx>, + span: Span, + exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, + terr: TypeError<'tcx>, + diag: &mut Diag<'_>, + ) { + debug!("suggest_function_pointers(cause={:?}, exp_found={:?})", cause, exp_found); + + if exp_found.expected.peel_refs().is_fn() && exp_found.found.peel_refs().is_fn() { + self.suggest_function_pointers_impl(Some(span), exp_found, diag); + } else if let TypeError::Sorts(exp_found) = terr { + self.suggest_function_pointers_impl(None, &exp_found, diag); + } + } + pub fn should_suggest_as_ref_kind( &self, expected: Ty<'tcx>, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 5021fd8bf83..6d39cbce3b7 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1969,6 +1969,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { StringPart::highlighted(exp_found.found.to_string()), StringPart::normal("`"), ]); + self.suggest_function_pointers_impl(None, &exp_found, err); } true diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 2dfa72972ba..c8672b9dbd2 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -1497,6 +1497,12 @@ pub struct FnConsiderCasting { } #[derive(Subdiagnostic)] +#[help(trait_selection_fn_consider_casting_both)] +pub struct FnConsiderCastingBoth<'a> { + pub sig: Binder<'a, FnSig<'a>>, +} + +#[derive(Subdiagnostic)] pub enum SuggestAccessingField<'a> { #[suggestion( trait_selection_suggest_accessing_field, |
