Skip to content

Commit 37f5569

Browse files
committed
Ported FunctionPointerSuggestion
1 parent be8e5ba commit 37f5569

File tree

3 files changed

+75
-21
lines changed

3 files changed

+75
-21
lines changed

compiler/rustc_infer/messages.ftl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,8 @@ infer_prlf_known_limitation = this is a known limitation that will be removed in
348348
349349
infer_opaque_captures_lifetime = hidden type for `{$opaque_ty}` captures lifetime that does not appear in bounds
350350
.label = opaque type defined here
351+
352+
infer_fps_use_ref = consider using a reference
353+
infer_fps_remove_ref = consider removing the reference
354+
infer_fps_cast = consider casting to a fn pointer
355+
infer_fps_items_are_distinct = fn items are distinct from fn pointers

compiler/rustc_infer/src/errors/mod.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,3 +1157,63 @@ pub struct OpaqueCapturesLifetime<'tcx> {
11571157
pub opaque_ty_span: Span,
11581158
pub opaque_ty: Ty<'tcx>,
11591159
}
1160+
1161+
#[derive(Subdiagnostic)]
1162+
pub enum FunctionPointerSuggestion<'a> {
1163+
#[suggestion(
1164+
infer_fps_use_ref,
1165+
code = "&{fn_name}",
1166+
style = "verbose",
1167+
applicability = "maybe-incorrect"
1168+
)]
1169+
UseRef {
1170+
#[primary_span]
1171+
span: Span,
1172+
#[skip_arg]
1173+
fn_name: String,
1174+
},
1175+
#[suggestion(
1176+
infer_fps_remove_ref,
1177+
code = "{fn_name}",
1178+
style = "verbose",
1179+
applicability = "maybe-incorrect"
1180+
)]
1181+
RemoveRef {
1182+
#[primary_span]
1183+
span: Span,
1184+
#[skip_arg]
1185+
fn_name: String,
1186+
},
1187+
#[suggestion(
1188+
infer_fps_cast,
1189+
code = "&({fn_name} as {sig})",
1190+
style = "verbose",
1191+
applicability = "maybe-incorrect"
1192+
)]
1193+
CastRef {
1194+
#[primary_span]
1195+
span: Span,
1196+
#[skip_arg]
1197+
fn_name: String,
1198+
#[skip_arg]
1199+
sig: Binder<'a, FnSig<'a>>,
1200+
},
1201+
#[suggestion(
1202+
infer_fps_cast,
1203+
code = "{fn_name} as {sig}",
1204+
style = "verbose",
1205+
applicability = "maybe-incorrect"
1206+
)]
1207+
Cast {
1208+
#[primary_span]
1209+
span: Span,
1210+
#[skip_arg]
1211+
fn_name: String,
1212+
#[skip_arg]
1213+
sig: Binder<'a, FnSig<'a>>,
1214+
},
1215+
}
1216+
1217+
#[derive(Subdiagnostic)]
1218+
#[note(infer_fps_items_are_distinct)]
1219+
pub struct FnItemsAreDistinct;

compiler/rustc_infer/src/infer/error_reporting/suggest.rs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use rustc_span::{sym, BytePos, Span};
1313
use rustc_target::abi::FieldIdx;
1414

1515
use crate::errors::{
16-
ConsiderAddingAwait, SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding,
16+
ConsiderAddingAwait, FnItemsAreDistinct, FunctionPointerSuggestion, SuggAddLetForLetChains,
17+
SuggestRemoveSemiOrReturnBinding,
1718
};
1819

1920
use super::TypeErrCtxt;
@@ -362,31 +363,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
362363
return;
363364
}
364365

365-
let (msg, sug) = match (expected.is_ref(), found.is_ref()) {
366-
(true, false) => {
367-
let msg = "consider using a reference";
368-
let sug = format!("&{fn_name}");
369-
(msg, sug)
370-
}
371-
(false, true) => {
372-
let msg = "consider removing the reference";
373-
let sug = format!("{fn_name}");
374-
(msg, sug)
375-
}
366+
let sugg = match (expected.is_ref(), found.is_ref()) {
367+
(true, false) => FunctionPointerSuggestion::UseRef { span, fn_name },
368+
(false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name },
376369
(true, true) => {
377-
diag.note("fn items are distinct from fn pointers");
378-
let msg = "consider casting to a fn pointer";
379-
let sug = format!("&({fn_name} as {sig})");
380-
(msg, sug)
370+
diag.subdiagnostic(FnItemsAreDistinct);
371+
FunctionPointerSuggestion::CastRef { span, fn_name, sig: *sig }
381372
}
382373
(false, false) => {
383-
diag.note("fn items are distinct from fn pointers");
384-
let msg = "consider casting to a fn pointer";
385-
let sug = format!("{fn_name} as {sig}");
386-
(msg, sug)
374+
diag.subdiagnostic(FnItemsAreDistinct);
375+
FunctionPointerSuggestion::Cast { span, fn_name, sig: *sig }
387376
}
388377
};
389-
diag.span_suggestion_verbose(span, msg, sug, Applicability::MaybeIncorrect);
378+
diag.subdiagnostic(sugg);
390379
}
391380
(ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
392381
let expected_sig =

0 commit comments

Comments
 (0)