diff options
| author | IQuant <quant3234@gmail.com> | 2023-02-23 16:38:12 +0300 | 
|---|---|---|
| committer | IQuant <quant3234@gmail.com> | 2023-04-04 18:34:50 +0300 | 
| commit | 37f55691f46741d783ba482d42f1cf5ef60593a9 (patch) | |
| tree | 8d72125b2dd94d9bf5f94c9165a1cc0f8b978acf | |
| parent | be8e5ba157a4ae494f9b4219b3b848e44ea5e8d3 (diff) | |
| download | rust-37f55691f46741d783ba482d42f1cf5ef60593a9.tar.gz rust-37f55691f46741d783ba482d42f1cf5ef60593a9.zip | |
Ported FunctionPointerSuggestion
| -rw-r--r-- | compiler/rustc_infer/messages.ftl | 5 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/errors/mod.rs | 60 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/suggest.rs | 31 | 
3 files changed, 75 insertions, 21 deletions
| diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index 15780898dc6..9d5933d5ab5 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -348,3 +348,8 @@ infer_prlf_known_limitation = this is a known limitation that will be removed in infer_opaque_captures_lifetime = hidden type for `{$opaque_ty}` captures lifetime that does not appear in bounds .label = opaque type defined here + +infer_fps_use_ref = consider using a reference +infer_fps_remove_ref = consider removing the reference +infer_fps_cast = consider casting to a fn pointer +infer_fps_items_are_distinct = fn items are distinct from fn pointers diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 6bbd3fd3e6e..8c4f44a5b80 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1157,3 +1157,63 @@ pub struct OpaqueCapturesLifetime<'tcx> { pub opaque_ty_span: Span, pub opaque_ty: Ty<'tcx>, } + +#[derive(Subdiagnostic)] +pub enum FunctionPointerSuggestion<'a> { + #[suggestion( + infer_fps_use_ref, + code = "&{fn_name}", + style = "verbose", + applicability = "maybe-incorrect" + )] + UseRef { + #[primary_span] + span: Span, + #[skip_arg] + fn_name: String, + }, + #[suggestion( + infer_fps_remove_ref, + code = "{fn_name}", + style = "verbose", + applicability = "maybe-incorrect" + )] + RemoveRef { + #[primary_span] + span: Span, + #[skip_arg] + fn_name: String, + }, + #[suggestion( + infer_fps_cast, + code = "&({fn_name} as {sig})", + style = "verbose", + applicability = "maybe-incorrect" + )] + CastRef { + #[primary_span] + span: Span, + #[skip_arg] + fn_name: String, + #[skip_arg] + sig: Binder<'a, FnSig<'a>>, + }, + #[suggestion( + infer_fps_cast, + code = "{fn_name} as {sig}", + style = "verbose", + applicability = "maybe-incorrect" + )] + Cast { + #[primary_span] + span: Span, + #[skip_arg] + fn_name: String, + #[skip_arg] + sig: Binder<'a, FnSig<'a>>, + }, +} + +#[derive(Subdiagnostic)] +#[note(infer_fps_items_are_distinct)] +pub struct FnItemsAreDistinct; diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 8ad143247e8..e4b3cf6905d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -13,7 +13,8 @@ use rustc_span::{sym, BytePos, Span}; use rustc_target::abi::FieldIdx; use crate::errors::{ - ConsiderAddingAwait, SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding, + ConsiderAddingAwait, FnItemsAreDistinct, FunctionPointerSuggestion, SuggAddLetForLetChains, + SuggestRemoveSemiOrReturnBinding, }; use super::TypeErrCtxt; @@ -362,31 +363,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return; } - let (msg, sug) = match (expected.is_ref(), found.is_ref()) { - (true, false) => { - let msg = "consider using a reference"; - let sug = format!("&{fn_name}"); - (msg, sug) - } - (false, true) => { - let msg = "consider removing the reference"; - let sug = format!("{fn_name}"); - (msg, sug) - } + let sugg = match (expected.is_ref(), found.is_ref()) { + (true, false) => FunctionPointerSuggestion::UseRef { span, fn_name }, + (false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name }, (true, true) => { - diag.note("fn items are distinct from fn pointers"); - let msg = "consider casting to a fn pointer"; - let sug = format!("&({fn_name} as {sig})"); - (msg, sug) + diag.subdiagnostic(FnItemsAreDistinct); + FunctionPointerSuggestion::CastRef { span, fn_name, sig: *sig } } (false, false) => { - diag.note("fn items are distinct from fn pointers"); - let msg = "consider casting to a fn pointer"; - let sug = format!("{fn_name} as {sig}"); - (msg, sug) + diag.subdiagnostic(FnItemsAreDistinct); + FunctionPointerSuggestion::Cast { span, fn_name, sig: *sig } } }; - diag.span_suggestion_verbose(span, msg, sug, Applicability::MaybeIncorrect); + diag.subdiagnostic(sugg); } (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => { let expected_sig = | 
