Ported FunctionPointerSuggestion
This commit is contained in:
parent
be8e5ba157
commit
37f55691f4
3 changed files with 75 additions and 21 deletions
|
@ -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
|
infer_opaque_captures_lifetime = hidden type for `{$opaque_ty}` captures lifetime that does not appear in bounds
|
||||||
.label = opaque type defined here
|
.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
|
||||||
|
|
|
@ -1157,3 +1157,63 @@ pub struct OpaqueCapturesLifetime<'tcx> {
|
||||||
pub opaque_ty_span: Span,
|
pub opaque_ty_span: Span,
|
||||||
pub opaque_ty: Ty<'tcx>,
|
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;
|
||||||
|
|
|
@ -13,7 +13,8 @@ use rustc_span::{sym, BytePos, Span};
|
||||||
use rustc_target::abi::FieldIdx;
|
use rustc_target::abi::FieldIdx;
|
||||||
|
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
ConsiderAddingAwait, SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding,
|
ConsiderAddingAwait, FnItemsAreDistinct, FunctionPointerSuggestion, SuggAddLetForLetChains,
|
||||||
|
SuggestRemoveSemiOrReturnBinding,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::TypeErrCtxt;
|
use super::TypeErrCtxt;
|
||||||
|
@ -362,31 +363,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (msg, sug) = match (expected.is_ref(), found.is_ref()) {
|
let sugg = match (expected.is_ref(), found.is_ref()) {
|
||||||
(true, false) => {
|
(true, false) => FunctionPointerSuggestion::UseRef { span, fn_name },
|
||||||
let msg = "consider using a reference";
|
(false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name },
|
||||||
let sug = format!("&{fn_name}");
|
|
||||||
(msg, sug)
|
|
||||||
}
|
|
||||||
(false, true) => {
|
|
||||||
let msg = "consider removing the reference";
|
|
||||||
let sug = format!("{fn_name}");
|
|
||||||
(msg, sug)
|
|
||||||
}
|
|
||||||
(true, true) => {
|
(true, true) => {
|
||||||
diag.note("fn items are distinct from fn pointers");
|
diag.subdiagnostic(FnItemsAreDistinct);
|
||||||
let msg = "consider casting to a fn pointer";
|
FunctionPointerSuggestion::CastRef { span, fn_name, sig: *sig }
|
||||||
let sug = format!("&({fn_name} as {sig})");
|
|
||||||
(msg, sug)
|
|
||||||
}
|
}
|
||||||
(false, false) => {
|
(false, false) => {
|
||||||
diag.note("fn items are distinct from fn pointers");
|
diag.subdiagnostic(FnItemsAreDistinct);
|
||||||
let msg = "consider casting to a fn pointer";
|
FunctionPointerSuggestion::Cast { span, fn_name, sig: *sig }
|
||||||
let sug = format!("{fn_name} as {sig}");
|
|
||||||
(msg, sug)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
diag.span_suggestion_verbose(span, msg, sug, Applicability::MaybeIncorrect);
|
diag.subdiagnostic(sugg);
|
||||||
}
|
}
|
||||||
(ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
|
(ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
|
||||||
let expected_sig =
|
let expected_sig =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue